// src/sigpro-grid.js import { h, watch, onUnmount } from "sigpro"; // node_modules/ag-grid-community/dist/package/main.esm.mjs function _last(arr) { if (!arr?.length) { return; } return arr[arr.length - 1]; } function _areEqual(a, b, comparator) { if (a === b) { return true; } if (!a || !b) { return a == null && b == null; } const len = a.length; if (len !== b.length) { return false; } for (let i = 0;i < len; i++) { if (a[i] !== b[i] && !comparator?.(a[i], b[i])) { return false; } } return true; } function _forAll(array, callback) { if (!array) { return; } for (const value of array) { if (callback(value)) { return true; } } } function _removeFromArray(array, object) { const index = array.indexOf(object); if (index >= 0) { array.splice(index, 1); } } function _removeAllFromArray(array, elementsToRemove) { let i = 0; let j = 0; for (;i < array.length; i++) { if (!elementsToRemove.includes(array[i])) { array[j] = array[i]; j++; } } while (j < array.length) { array.pop(); } } function _moveInArray(array, objectsToMove, toIndex) { for (let i = 0;i < objectsToMove.length; i++) { _removeFromArray(array, objectsToMove[i]); } for (let i = objectsToMove.length - 1;i >= 0; i--) { array.splice(toIndex, 0, objectsToMove[i]); } } var _makeNull = (value) => { if (value == null || value === "") { return null; } return value; }; function _exists(value) { return value != null && value !== ""; } function _missing(value) { return !_exists(value); } var _toStringOrNull = (value) => { return value != null && typeof value.toString === "function" ? value.toString() : null; }; var _jsonEquals = (val1, val2) => { const val1Json = val1 ? JSON.stringify(val1) : null; const val2Json = val2 ? JSON.stringify(val2) : null; return val1Json === val2Json; }; var _defaultComparator = (valueA, valueB, accentedCompare = false) => { if (valueA == null) { return valueB == null ? 0 : -1; } if (valueB == null) { return 1; } if (typeof valueA === "object" && valueA.toNumber) { valueA = valueA.toNumber(); } if (typeof valueB === "object" && valueB.toNumber) { valueB = valueB.toNumber(); } if (!accentedCompare || typeof valueA !== "string") { if (valueA > valueB) { return 1; } if (valueA < valueB) { return -1; } return 0; } return valueA.localeCompare(valueB); }; var LocalEventService = class { constructor() { this.allSyncListeners = /* @__PURE__ */ new Map; this.allAsyncListeners = /* @__PURE__ */ new Map; this.globalSyncListeners = /* @__PURE__ */ new Set; this.globalAsyncListeners = /* @__PURE__ */ new Set; this.asyncFunctionsQueue = []; this.scheduled = false; this.firedEvents = {}; } setFrameworkOverrides(frameworkOverrides) { this.frameworkOverrides = frameworkOverrides; } getListeners(eventType, async, autoCreateListenerCollection) { const listenerMap = async ? this.allAsyncListeners : this.allSyncListeners; let listeners = listenerMap.get(eventType); if (!listeners && autoCreateListenerCollection) { listeners = /* @__PURE__ */ new Set; listenerMap.set(eventType, listeners); } return listeners; } noRegisteredListenersExist() { return this.allSyncListeners.size === 0 && this.allAsyncListeners.size === 0 && this.globalSyncListeners.size === 0 && this.globalAsyncListeners.size === 0; } addEventListener(eventType, listener, async = false) { this.getListeners(eventType, async, true).add(listener); } removeEventListener(eventType, listener, async = false) { const listeners = this.getListeners(eventType, async, false); if (!listeners) { return; } listeners.delete(listener); if (listeners.size === 0) { (async ? this.allAsyncListeners : this.allSyncListeners).delete(eventType); } } addGlobalListener(listener, async = false) { this.getGlobalListeners(async).add(listener); } removeGlobalListener(listener, async = false) { this.getGlobalListeners(async).delete(listener); } dispatchEvent(event) { this.dispatchToListeners(event, true); this.dispatchToListeners(event, false); this.firedEvents[event.type] = true; } dispatchEventOnce(event) { if (!this.firedEvents[event.type]) { this.dispatchEvent(event); } } dispatchToListeners(event, async) { const eventType = event.type; if (async && "event" in event) { const browserEvent = event.event; if (browserEvent instanceof Event) { event.eventPath = browserEvent.composedPath(); } } const { frameworkOverrides } = this; const runCallback = (func) => { const callback = frameworkOverrides ? () => frameworkOverrides.wrapIncoming(func) : func; if (async) { this.dispatchAsync(callback); } else { callback(); } }; const originalListeners = this.getListeners(eventType, async, false); if ((originalListeners?.size ?? 0) > 0) { const listeners = new Set(originalListeners); for (const listener of listeners) { if (!originalListeners?.has(listener)) { continue; } runCallback(() => listener(event)); } } const globalListenersSrc = this.getGlobalListeners(async); if (globalListenersSrc.size > 0) { const globalListeners = new Set(globalListenersSrc); for (const listener of globalListeners) { runCallback(() => listener(eventType, event)); } } } getGlobalListeners(async) { return async ? this.globalAsyncListeners : this.globalSyncListeners; } dispatchAsync(func) { this.asyncFunctionsQueue.push(func); if (!this.scheduled) { const flush = () => { window.setTimeout(this.flushAsyncQueue.bind(this), 0); }; const frameworkOverrides = this.frameworkOverrides; if (frameworkOverrides) { frameworkOverrides.wrapIncoming(flush); } else { flush(); } this.scheduled = true; } } flushAsyncQueue() { this.scheduled = false; const queueCopy = this.asyncFunctionsQueue.slice(); this.asyncFunctionsQueue = []; for (const func of queueCopy) { func(); } } }; var reUnescapedHtml = /[&<>"']/g; var HTML_ESCAPES = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }; function _toString(toEscape) { return toEscape?.toString().toString() ?? null; } function _escapeString(toEscape) { return _toString(toEscape)?.replace(reUnescapedHtml, (chr) => HTML_ESCAPES[chr]) ?? null; } function _isExpressionString(value) { return typeof value === "string" && value.startsWith("=") && value.length > 1; } function _camelCaseToHumanText(camelCase) { if (!camelCase || camelCase == null) { return null; } const rex = /([a-z])([A-Z])/g; const rexCaps = /([A-Z]+)([A-Z])([a-z])/g; const words = camelCase.replace(rex, "$1 $2").replace(rexCaps, "$1 $2$3").replace(/\./g, " ").split(" "); return words.map((word) => word.substring(0, 1).toUpperCase() + (word.length > 1 ? word.substring(1, word.length) : "")).join(" "); } function _getRootNode(beans) { return beans.eRootDiv.getRootNode(); } function _getActiveDomElement(beans) { return _getRootNode(beans).activeElement; } function _getDocument(beans) { const { gos, eRootDiv } = beans; let result = null; const optionsGetDocument = gos.get("getDocument"); if (optionsGetDocument && _exists(optionsGetDocument)) { result = optionsGetDocument(); } else if (eRootDiv) { result = eRootDiv.ownerDocument; } if (result && _exists(result)) { return result; } return document; } function _isNothingFocused(beans) { const activeEl = _getActiveDomElement(beans); return activeEl === null || activeEl === _getDocument(beans).body; } function _getWindow(beans) { const eDocument = _getDocument(beans); return eDocument.defaultView || window; } function _getPageBody(beans) { let rootNode = null; let targetEl = null; try { rootNode = _getDocument(beans).fullscreenElement; } catch (e) {} finally { if (!rootNode) { rootNode = _getRootNode(beans); } const body = rootNode.querySelector("body"); if (body) { targetEl = body; } else if (rootNode instanceof ShadowRoot) { targetEl = rootNode; } else if (rootNode instanceof Document) { targetEl = rootNode?.documentElement; } else { targetEl = rootNode; } } return targetEl; } function _getBodyWidth(beans) { const body = _getPageBody(beans); return body?.clientWidth ?? (window.innerWidth || -1); } function _getBodyHeight(beans) { const body = _getPageBody(beans); return body?.clientHeight ?? (window.innerHeight || -1); } function _toggleAriaAttribute(element, attribute, value) { if (value == null || typeof value === "string" && value == "") { _removeAriaAttribute(element, attribute); } else { _setAriaAttribute(element, attribute, value); } } function _setAriaAttribute(element, attribute, value) { element.setAttribute(_ariaAttributeName(attribute), value.toString()); } function _removeAriaAttribute(element, attribute) { element.removeAttribute(_ariaAttributeName(attribute)); } function _ariaAttributeName(attribute) { return `aria-${attribute}`; } function _setAriaRole(element, role) { if (role) { element.setAttribute("role", role); } else { element.removeAttribute("role"); } } function _getAriaSortState(directionOrDef) { const direction = directionOrDef?.direction; if (direction === "asc") { return "ascending"; } else if (direction === "desc") { return "descending"; } else if (direction === "mixed") { return "other"; } return "none"; } function _getAriaPosInSet(element) { return Number.parseInt(element.getAttribute("aria-posinset"), 10); } function _getAriaLabel(element) { return element.getAttribute("aria-label"); } function _setAriaLabel(element, label) { _toggleAriaAttribute(element, "label", label); } function _setAriaLabelledBy(element, labelledBy) { _toggleAriaAttribute(element, "labelledby", labelledBy); } function _setAriaDescribedBy(element, describedby) { _toggleAriaAttribute(element, "describedby", describedby); } function _setAriaLive(element, live) { _toggleAriaAttribute(element, "live", live); } function _setAriaAtomic(element, atomic) { _toggleAriaAttribute(element, "atomic", atomic); } function _setAriaRelevant(element, relevant) { _toggleAriaAttribute(element, "relevant", relevant); } function _setAriaInvalid(element, invalid) { _toggleAriaAttribute(element, "invalid", invalid); } function _setAriaLevel(element, level) { _toggleAriaAttribute(element, "level", level); } function _setAriaDisabled(element, disabled) { _toggleAriaAttribute(element, "disabled", disabled); } function _setAriaHidden(element, hidden) { _toggleAriaAttribute(element, "hidden", hidden); } function _setAriaExpanded(element, expanded) { _setAriaAttribute(element, "expanded", expanded); } function _removeAriaExpanded(element) { _removeAriaAttribute(element, "expanded"); } function _setAriaSetSize(element, setsize) { _setAriaAttribute(element, "setsize", setsize); } function _setAriaPosInSet(element, position) { _setAriaAttribute(element, "posinset", position); } function _setAriaMultiSelectable(element, multiSelectable) { _setAriaAttribute(element, "multiselectable", multiSelectable); } function _setAriaRowCount(element, rowCount) { _setAriaAttribute(element, "rowcount", rowCount); } function _setAriaRowIndex(element, rowIndex) { _setAriaAttribute(element, "rowindex", rowIndex); } function _setAriaColCount(element, colCount) { _setAriaAttribute(element, "colcount", colCount); } function _setAriaColIndex(element, colIndex) { _setAriaAttribute(element, "colindex", colIndex); } function _setAriaColSpan(element, colSpan) { _setAriaAttribute(element, "colspan", colSpan); } function _setAriaSort(element, sort) { _setAriaAttribute(element, "sort", sort); } function _removeAriaSort(element) { _removeAriaAttribute(element, "sort"); } function _setAriaSelected(element, selected) { _toggleAriaAttribute(element, "selected", selected); } function _setAriaChecked(element, checked) { _setAriaAttribute(element, "checked", checked === undefined ? "mixed" : checked); } function _setAriaControls(controllerElement, controlledId) { _toggleAriaAttribute(controllerElement, "controls", controlledId); } function _setAriaControlsAndLabel(controllerElement, controlledElement) { _setAriaControls(controllerElement, controlledElement.id); _setAriaLabelledBy(controlledElement, controllerElement.id); } function _setAriaOwns(ownerElement, ownedId) { _toggleAriaAttribute(ownerElement, "owns", ownedId); } function _setAriaHasPopup(element, hasPopup) { _toggleAriaAttribute(element, "haspopup", hasPopup === false ? null : hasPopup); } function _getAriaCheckboxStateName(translate, state) { return state === undefined ? translate("ariaIndeterminate", "indeterminate") : state === true ? translate("ariaChecked", "checked") : translate("ariaUnchecked", "unchecked"); } function _radioCssClass(element, elementClass, otherElementClass) { const parent = element.parentElement; let sibling = parent && parent.firstChild; while (sibling) { if (elementClass) { sibling.classList.toggle(elementClass, sibling === element); } if (otherElementClass) { sibling.classList.toggle(otherElementClass, sibling !== element); } sibling = sibling.nextSibling; } } var FOCUSABLE_SELECTOR = "[tabindex], input, select, button, textarea, [href]"; var FOCUSABLE_EXCLUDE = "[disabled], .ag-disabled:not(.ag-button), .ag-disabled *"; function _isFocusableFormField(element) { if (!element) { return false; } const isFocusable = element.matches("input, select, button, textarea"); if (!isFocusable) { return false; } const isNotFocusable = element.matches(FOCUSABLE_EXCLUDE); if (!isNotFocusable) { return false; } return _isVisible(element); } function _setDisplayed(element, displayed, options = {}) { const { skipAriaHidden } = options; element.classList.toggle("ag-hidden", !displayed); if (!skipAriaHidden) { _setAriaHidden(element, !displayed); } } function _setVisible(element, visible, options = {}) { const { skipAriaHidden } = options; element.classList.toggle("ag-invisible", !visible); if (!skipAriaHidden) { _setAriaHidden(element, !visible); } } function _setDisabled(element, disabled) { const attributeName = "disabled"; const addOrRemoveDisabledAttribute = disabled ? (e) => e.setAttribute(attributeName, "") : (e) => e.removeAttribute(attributeName); addOrRemoveDisabledAttribute(element); const inputs = element.querySelectorAll("input") ?? []; for (const input of inputs) { addOrRemoveDisabledAttribute(input); } } function _isElementChildOfClass(element, cls, maxNest) { let counter = 0; while (element) { if (element.classList.contains(cls)) { return true; } element = element.parentElement; if (typeof maxNest == "number") { if (++counter > maxNest) { break; } } else if (element === maxNest) { break; } } return false; } function _getElementSize(el) { const { height, width, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, paddingTop, paddingRight, paddingBottom, paddingLeft, marginTop, marginRight, marginBottom, marginLeft, boxSizing } = window.getComputedStyle(el); const pf = Number.parseFloat; return { height: pf(height || "0"), width: pf(width || "0"), borderTopWidth: pf(borderTopWidth || "0"), borderRightWidth: pf(borderRightWidth || "0"), borderBottomWidth: pf(borderBottomWidth || "0"), borderLeftWidth: pf(borderLeftWidth || "0"), paddingTop: pf(paddingTop || "0"), paddingRight: pf(paddingRight || "0"), paddingBottom: pf(paddingBottom || "0"), paddingLeft: pf(paddingLeft || "0"), marginTop: pf(marginTop || "0"), marginRight: pf(marginRight || "0"), marginBottom: pf(marginBottom || "0"), marginLeft: pf(marginLeft || "0"), boxSizing }; } function _getInnerHeight(el) { const size = _getElementSize(el); if (size.boxSizing === "border-box") { return size.height - size.paddingTop - size.paddingBottom - size.borderTopWidth - size.borderBottomWidth; } return size.height; } function _getInnerWidth(el) { const size = _getElementSize(el); if (size.boxSizing === "border-box") { return size.width - size.paddingLeft - size.paddingRight - size.borderLeftWidth - size.borderRightWidth; } return size.width; } function _getAbsoluteHeight(el) { const { height, marginBottom, marginTop } = _getElementSize(el); return Math.floor(height + marginBottom + marginTop); } function _getAbsoluteWidth(el) { const { width, marginLeft, marginRight } = _getElementSize(el); return Math.floor(width + marginLeft + marginRight); } function _getElementRectWithOffset(el) { const offsetElementRect = el.getBoundingClientRect(); const { borderTopWidth, borderLeftWidth, borderRightWidth, borderBottomWidth } = _getElementSize(el); return { top: offsetElementRect.top + (borderTopWidth || 0), left: offsetElementRect.left + (borderLeftWidth || 0), right: offsetElementRect.right + (borderRightWidth || 0), bottom: offsetElementRect.bottom + (borderBottomWidth || 0) }; } function _getScrollLeft(element, rtl) { let scrollLeft = element.scrollLeft; if (rtl) { scrollLeft = Math.abs(scrollLeft); } return scrollLeft; } function _setScrollLeft(element, value, rtl) { if (rtl) { value *= -1; } element.scrollLeft = value; } function _clearElement(el) { while (el?.firstChild) { el.firstChild.remove(); } } function _removeFromParent(node) { if (node?.parentNode) { node.remove(); } } function _isInDOM(element) { return !!element.offsetParent; } function _isVisible(element) { if (element.checkVisibility) { return element.checkVisibility({ checkVisibilityCSS: true }); } const isHidden = !_isInDOM(element) || window.getComputedStyle(element).visibility !== "visible"; return !isHidden; } function _loadTemplate(template) { const tempDiv = document.createElement("div"); tempDiv.innerHTML = (template || "").trim(); return tempDiv.firstChild; } function _ensureDomOrder(eContainer, eChild, eChildBefore) { if (eChildBefore && eChildBefore.nextSibling === eChild) { return; } if (!eContainer.firstChild) { eContainer.appendChild(eChild); } else if (eChildBefore) { if (eChildBefore.nextSibling) { eContainer.insertBefore(eChild, eChildBefore.nextSibling); } else { eContainer.appendChild(eChild); } } else if (eContainer.firstChild && eContainer.firstChild !== eChild) { eContainer.prepend(eChild); } } function _setDomChildOrder(eContainer, orderedChildren) { for (let i = 0;i < orderedChildren.length; i++) { const correctCellAtIndex = orderedChildren[i]; const actualCellAtIndex = eContainer.children[i]; if (actualCellAtIndex !== correctCellAtIndex) { eContainer.insertBefore(correctCellAtIndex, actualCellAtIndex); } } } function _camelCaseToHyphenated(camelCase) { return camelCase.replace(/[A-Z]/g, (s) => `-${s.toLocaleLowerCase()}`); } function _addStylesToElement(eElement, styles) { if (!styles) { return; } for (const key of Object.keys(styles)) { const value = styles[key]; if (!key?.length || value == null) { continue; } const parsedKey = _camelCaseToHyphenated(key); const valueAsString = value.toString(); const parsedValue = valueAsString.replace(/\s*!important/g, ""); const priority = parsedValue.length != valueAsString.length ? "important" : undefined; eElement.style.setProperty(parsedKey, parsedValue, priority); } } function _isElementOverflowingCallback(getElement2) { return () => { const element = getElement2(); if (!element) { return true; } return _isHorizontalScrollShowing(element) || _isVerticalScrollShowing(element); }; } function _isHorizontalScrollShowing(element) { return element.clientWidth < element.scrollWidth; } function _isVerticalScrollShowing(element) { return element.clientHeight < element.scrollHeight; } function _setElementWidth(element, width) { if (width === "flex") { element.style.removeProperty("width"); element.style.removeProperty("minWidth"); element.style.removeProperty("maxWidth"); element.style.flex = "1 1 auto"; } else { _setFixedWidth(element, width); } } function _setFixedWidth(element, width) { width = _formatSize(width); element.style.width = width; element.style.maxWidth = width; element.style.minWidth = width; } function _setFixedHeight(element, height) { height = _formatSize(height); element.style.height = height; element.style.maxHeight = height; element.style.minHeight = height; } function _formatSize(size) { return typeof size === "number" ? `${size}px` : size; } function _isNodeOrElement(o) { return o instanceof Node || o instanceof HTMLElement; } function _addOrRemoveAttribute(element, name, value) { if (value == null || value === "") { element.removeAttribute(name); } else { element.setAttribute(name, value.toString()); } } function _placeCaretAtEnd(beans, contentElement) { if (!contentElement.isContentEditable) { return; } const selection = _getWindow(beans).getSelection(); if (!selection) { return; } const range = _getDocument(beans).createRange(); range.selectNodeContents(contentElement); range.collapse(false); selection.removeAllRanges(); selection.addRange(range); } function _observeResize(beans, element, callback) { const win = _getWindow(beans); const ResizeObserverImpl = win.ResizeObserver; const resizeObserver = ResizeObserverImpl ? new ResizeObserverImpl(callback) : null; resizeObserver?.observe(element); return () => resizeObserver?.disconnect(); } function _requestAnimationFrame(beans, callback) { const win = _getWindow(beans); if (win.requestAnimationFrame) { win.requestAnimationFrame(callback); } else if (win.webkitRequestAnimationFrame) { win.webkitRequestAnimationFrame(callback); } else { win.setTimeout(callback, 0); } } var DataRefAttribute = "data-ref"; var whitespaceNode; function getWhitespaceNode() { whitespaceNode ?? (whitespaceNode = document.createTextNode(" ")); return whitespaceNode.cloneNode(); } function _createAgElement(params) { const { attrs, children, cls, ref, role, tag } = params; const element = document.createElement(tag); if (cls) { element.className = cls; } if (ref) { element.setAttribute(DataRefAttribute, ref); } if (role) { element.setAttribute("role", role); } if (attrs) { for (const key of Object.keys(attrs)) { element.setAttribute(key, attrs[key]); } } if (children) { if (typeof children === "string") { element.textContent = children; } else { let addFirstWhitespace = true; for (const child of children) { if (child) { if (typeof child === "string") { element.appendChild(document.createTextNode(child)); addFirstWhitespace = false; } else if (typeof child === "function") { element.appendChild(child()); } else { if (addFirstWhitespace) { element.appendChild(getWhitespaceNode()); addFirstWhitespace = false; } element.append(_createAgElement(child)); element.appendChild(getWhitespaceNode()); } } } } } return element; } var PASSIVE_EVENTS = ["touchstart", "touchend", "touchmove", "touchcancel", "scroll"]; var NON_PASSIVE_EVENTS = ["wheel"]; var supports = {}; var _isEventSupported = /* @__PURE__ */ (() => { const tags = { select: "input", change: "input", submit: "form", reset: "form", error: "img", load: "img", abort: "img" }; const eventChecker = (eventName) => { if (typeof supports[eventName] === "boolean") { return supports[eventName]; } const el = document.createElement(tags[eventName] || "div"); eventName = "on" + eventName; return supports[eventName] = eventName in el; }; return eventChecker; })(); function _isElementInEventPath(element, event) { if (!event || !element) { return false; } return _getEventPath(event).indexOf(element) >= 0; } function _createEventPath(event) { const res = []; let pointer = event.target; while (pointer) { res.push(pointer); pointer = pointer.parentElement; } return res; } function _getEventPath(event) { const eventNoType = event; if (eventNoType.path) { return eventNoType.path; } if (eventNoType.composedPath) { return eventNoType.composedPath(); } return _createEventPath(eventNoType); } function _addSafePassiveEventListener(eElement, event, listener) { const passive = getPassiveStateForEvent(event); let options; if (passive != null) { options = { passive }; } eElement.addEventListener(event, listener, options); } var getPassiveStateForEvent = (event) => { const isPassive = PASSIVE_EVENTS.includes(event); const isNonPassive = NON_PASSIVE_EVENTS.includes(event); if (isPassive) { return true; } if (isNonPassive) { return false; } }; function _areEventsNear(e1, e2, pixelCount) { if (pixelCount === 0) { return false; } const diffX = Math.abs(e1.clientX - e2.clientX); const diffY = Math.abs(e1.clientY - e2.clientY); return Math.max(diffX, diffY) <= pixelCount; } var _getFirstActiveTouch = (touch, touchList) => { const identifier = touch.identifier; for (let i = 0, len = touchList.length;i < len; ++i) { const item = touchList[i]; if (item.identifier === identifier) { return item; } } return null; }; function _isEventFromThisInstance(beans, event) { return beans.gos.isElementInThisInstance(event.target); } function _anchorElementToMouseMoveEvent(element, mouseMoveEvent, beans) { const eRect = element.getBoundingClientRect(); const height = eRect.height; const browserWidth = _getBodyWidth(beans) - 2; const browserHeight = _getBodyHeight(beans) - 2; const offsetParent = element.offsetParent; if (!offsetParent) { return; } const offsetParentSize = _getElementRectWithOffset(element.offsetParent); const { clientY, clientX } = mouseMoveEvent; let top = clientY - offsetParentSize.top - height / 2; let left = clientX - offsetParentSize.left - 10; const eDocument = _getDocument(beans); const win = eDocument.defaultView || window; const windowScrollY = win.pageYOffset || eDocument.documentElement.scrollTop; const windowScrollX = win.pageXOffset || eDocument.documentElement.scrollLeft; if (browserWidth > 0 && left + element.clientWidth > browserWidth + windowScrollX) { left = browserWidth + windowScrollX - element.clientWidth; } if (left < 0) { left = 0; } if (browserHeight > 0 && top + element.clientHeight > browserHeight + windowScrollY) { top = browserHeight + windowScrollY - element.clientHeight; } if (top < 0) { top = 0; } element.style.left = `${left}px`; element.style.top = `${top}px`; } var addTempEventHandlers = (list, ...handlers) => { for (const handler of handlers) { const [target, type, eventListener, options] = handler; target.addEventListener(type, eventListener, options); list.push(handler); } }; var clearTempEventHandlers = (list) => { if (list) { for (const [target, type, listener, options] of list) { target.removeEventListener(type, listener, options); } list.length = 0; } }; var preventEventDefault = (event) => { if (event.cancelable) { event.preventDefault(); } }; function defaultLocaleTextFunc(_key, defaultValue) { return defaultValue; } function _getLocaleTextFunc(localeSvc) { return localeSvc?.getLocaleTextFunc() ?? defaultLocaleTextFunc; } function _translate(bean, localeValues, key, variableValues) { const defaultValue = localeValues[key]; return bean.getLocaleTextFunc()(key, typeof defaultValue === "function" ? defaultValue(variableValues) : defaultValue, variableValues); } var AgBeanStub = class { constructor() { this.destroyFunctions = []; this.destroyed = false; this.__v_skip = true; this.propertyListenerId = 0; this.lastChangeSetIdLookup = {}; this.isAlive = () => !this.destroyed; } preWireBeans(beans) { this.beans = beans; this.stubContext = beans.context; this.eventSvc = beans.eventSvc; this.gos = beans.gos; } destroy() { const { destroyFunctions } = this; for (let i = 0;i < destroyFunctions.length; i++) { destroyFunctions[i](); } destroyFunctions.length = 0; this.destroyed = true; this.dispatchLocalEvent({ type: "destroyed" }); } addEventListener(eventType, listener, async) { if (!this.localEventService) { this.localEventService = new LocalEventService; } this.localEventService.addEventListener(eventType, listener, async); } removeEventListener(eventType, listener, async) { this.localEventService?.removeEventListener(eventType, listener, async); } dispatchLocalEvent(event) { this.localEventService?.dispatchEvent(event); } addManagedElementListeners(object, handlers) { return this._setupListeners(object, handlers); } addManagedEventListeners(handlers) { return this._setupListeners(this.eventSvc, handlers); } addManagedListeners(object, handlers) { return this._setupListeners(object, handlers); } _setupListeners(object, handlers) { const destroyFuncs = []; for (const k of Object.keys(handlers)) { const handler = handlers[k]; if (handler) { destroyFuncs.push(this._setupListener(object, k, handler)); } } return destroyFuncs; } _setupListener(object, event, listener) { if (this.destroyed) { return () => null; } let destroyFunc; if (isAgEventEmitter(object)) { object.__addEventListener(event, listener); destroyFunc = () => { object.__removeEventListener(event, listener); return null; }; } else { const objIsEventService = isEventService(object); if (object instanceof HTMLElement) { _addSafePassiveEventListener(object, event, listener); } else if (objIsEventService) { object.addListener(event, listener); } else { object.addEventListener(event, listener); } destroyFunc = objIsEventService ? () => { object.removeListener(event, listener); return null; } : () => { object.removeEventListener(event, listener); return null; }; } this.destroyFunctions.push(destroyFunc); return () => { destroyFunc(); this.destroyFunctions = this.destroyFunctions.filter((fn) => fn !== destroyFunc); return null; }; } setupPropertyListener(event, listener) { const { gos } = this; gos.addPropertyEventListener(event, listener); const destroyFunc = () => { gos.removePropertyEventListener(event, listener); return null; }; this.destroyFunctions.push(destroyFunc); return () => { destroyFunc(); this.destroyFunctions = this.destroyFunctions.filter((fn) => fn !== destroyFunc); return null; }; } addManagedPropertyListener(event, listener) { if (this.destroyed) { return () => null; } return this.setupPropertyListener(event, listener); } addManagedPropertyListeners(events, listener) { if (this.destroyed) { return; } const eventsKey = events.join("-") + this.propertyListenerId++; const wrappedListener = (event) => { if (event.changeSet) { if (event.changeSet && event.changeSet.id === this.lastChangeSetIdLookup[eventsKey]) { return; } this.lastChangeSetIdLookup[eventsKey] = event.changeSet.id; } const propertiesChangeEvent = { type: "propertyChanged", changeSet: event.changeSet, source: event.source }; listener(propertiesChangeEvent); }; for (const event of events) { this.setupPropertyListener(event, wrappedListener); } } getLocaleTextFunc() { return _getLocaleTextFunc(this.beans.localeSvc); } addDestroyFunc(func) { if (this.isAlive()) { this.destroyFunctions.push(func); } else { func(); } } createOptionalManagedBean(bean, context) { return bean ? this.createManagedBean(bean, context) : undefined; } createManagedBean(bean, context) { const res = this.createBean(bean, context); this.addDestroyFunc(this.destroyBean.bind(this, bean, context)); return res; } createBean(bean, context, afterPreCreateCallback) { return (context || this.stubContext).createBean(bean, afterPreCreateCallback); } destroyBean(bean, context) { return (context || this.stubContext).destroyBean(bean); } destroyBeans(beans, context) { return (context || this.stubContext).destroyBeans(beans); } }; function isAgEventEmitter(object) { return object.__addEventListener !== undefined; } function isEventService(object) { return object.eventServiceType === "global"; } var BeanStub = class extends AgBeanStub { }; var doOnceSet = /* @__PURE__ */ new Set; var _doOnce = (func, key) => { if (!doOnceSet.has(key)) { doOnceSet.add(key); func(); } }; _doOnce._set = doOnceSet; var batchedCallsSetTimeout = { pending: false, funcs: [] }; var batchedCallsRaf = { pending: false, funcs: [] }; function _batchCall(func, mode = "setTimeout", beans) { const batch = mode === "raf" ? batchedCallsRaf : batchedCallsSetTimeout; batch.funcs.push(func); if (batch.pending) { return; } batch.pending = true; const runBatch = () => { const funcsCopy = batch.funcs.slice(); batch.funcs.length = 0; batch.pending = false; for (const func2 of funcsCopy) { func2(); } }; if (mode === "raf") { _requestAnimationFrame(beans, runBatch); } else { window.setTimeout(runBatch, 0); } } function _debounce(bean, func, delay) { let timeout; return function(...args) { const context = this; window.clearTimeout(timeout); timeout = window.setTimeout(function() { if (bean.isAlive()) { func.apply(context, args); } }, delay); return timeout; }; } function _throttle(func, wait) { let previousCall = 0; return function(...args) { const context = this; const currentCall = Date.now(); if (currentCall - previousCall < wait) { return; } previousCall = currentCall; func.apply(context, args); }; } function _waitUntil(bean, condition, callback, timeout = 100) { const timeStamp = Date.now(); let interval = null; let executed = false; const clearWait = () => { if (interval != null) { window.clearInterval(interval); interval = null; } }; bean.addDestroyFunc(clearWait); const internalCallback = () => { const reachedTimeout = Date.now() - timeStamp > timeout; if (condition() || reachedTimeout) { callback(); executed = true; clearWait(); } }; internalCallback(); if (!executed) { interval = window.setInterval(internalCallback, 10); } } var SKIP_JS_BUILTINS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]); function _iterateObject(object, callback) { if (object == null) { return; } if (Array.isArray(object)) { for (let i = 0;i < object.length; i++) { callback(i.toString(), object[i]); } return; } for (const key of Object.keys(object).filter((key2) => !SKIP_JS_BUILTINS.has(key2))) { callback(key, object[key]); } } function _mergeDeep(dest, source, copyUndefined = true, makeCopyOfSimpleObjects = false) { if (!_exists(source)) { return; } _iterateObject(source, (key, sourceValue) => { let destValue = dest[key]; if (destValue === sourceValue) { return; } if (makeCopyOfSimpleObjects) { const objectIsDueToBeCopied = destValue == null && sourceValue != null; if (objectIsDueToBeCopied) { const doNotCopyAsSourceIsSimpleObject = typeof sourceValue === "object" && sourceValue.constructor === Object; if (doNotCopyAsSourceIsSimpleObject) { destValue = {}; dest[key] = destValue; } } } if (_isNonNullObject(sourceValue) && _isNonNullObject(destValue) && !Array.isArray(destValue)) { _mergeDeep(destValue, sourceValue, copyUndefined, makeCopyOfSimpleObjects); } else if (copyUndefined || sourceValue !== undefined) { dest[key] = sourceValue; } }); } function _isNonNullObject(value) { return typeof value === "object" && value !== null; } var _GlobalGridOptions = class _GlobalGridOptions2 { static applyGlobalGridOptions(providedOptions) { if (!_GlobalGridOptions2.gridOptions) { return { ...providedOptions }; } let mergedGridOps = {}; _mergeDeep(mergedGridOps, _GlobalGridOptions2.gridOptions, true, true); if (_GlobalGridOptions2.mergeStrategy === "deep") { _mergeDeep(mergedGridOps, providedOptions, true, true); } else { mergedGridOps = { ...mergedGridOps, ...providedOptions }; } if (_GlobalGridOptions2.gridOptions.context) { mergedGridOps.context = _GlobalGridOptions2.gridOptions.context; } if (providedOptions.context) { if (_GlobalGridOptions2.mergeStrategy === "deep" && mergedGridOps.context) { _mergeDeep(providedOptions.context, mergedGridOps.context, true, true); } mergedGridOps.context = providedOptions.context; } return mergedGridOps; } static applyGlobalGridOption(optionKey, providedValue) { if (_GlobalGridOptions2.mergeStrategy === "deep") { const globalValue = _getGlobalGridOption(optionKey); if (globalValue && typeof globalValue === "object" && typeof providedValue === "object") { return _GlobalGridOptions2.applyGlobalGridOptions({ [optionKey]: providedValue })[optionKey]; } } return providedValue; } }; _GlobalGridOptions.gridOptions = undefined; _GlobalGridOptions.mergeStrategy = "shallow"; var GlobalGridOptions = _GlobalGridOptions; function _getGlobalGridOption(gridOption) { return GlobalGridOptions.gridOptions?.[gridOption]; } var GRID_OPTION_DEFAULTS = { suppressContextMenu: false, preventDefaultOnContextMenu: false, allowContextMenuWithControlKey: false, suppressMenuHide: true, enableBrowserTooltips: false, tooltipTrigger: "hover", tooltipShowDelay: 2000, tooltipSwitchShowDelay: 200, tooltipHideDelay: 1e4, tooltipMouseTrack: false, tooltipShowMode: "standard", tooltipInteraction: false, copyHeadersToClipboard: false, copyGroupHeadersToClipboard: false, clipboardDelimiter: "\t", suppressCopyRowsToClipboard: false, suppressCopySingleCellRanges: false, suppressLastEmptyLineOnPaste: false, suppressClipboardPaste: false, suppressClipboardApi: false, suppressCutToClipboard: false, maintainColumnOrder: false, enableStrictPivotColumnOrder: false, suppressFieldDotNotation: false, allowDragFromColumnsToolPanel: false, suppressMovableColumns: false, suppressColumnMoveAnimation: false, suppressMoveWhenColumnDragging: false, suppressDragLeaveHidesColumns: false, suppressRowGroupHidesColumns: false, suppressAutoSize: false, autoSizePadding: 20, skipHeaderOnAutoSize: false, singleClickEdit: false, suppressClickEdit: false, readOnlyEdit: false, stopEditingWhenCellsLoseFocus: false, enterNavigatesVertically: false, enterNavigatesVerticallyAfterEdit: false, enableCellEditingOnBackspace: false, undoRedoCellEditing: false, undoRedoCellEditingLimit: 10, suppressCsvExport: false, suppressExcelExport: false, cacheQuickFilter: false, includeHiddenColumnsInQuickFilter: false, excludeChildrenWhenTreeDataFiltering: false, enableAdvancedFilter: false, includeHiddenColumnsInAdvancedFilter: false, enableCharts: false, masterDetail: false, keepDetailRows: false, keepDetailRowsCount: 10, detailRowAutoHeight: false, tabIndex: 0, rowBuffer: 10, valueCache: false, valueCacheNeverExpires: false, enableCellExpressions: false, suppressTouch: false, suppressFocusAfterRefresh: false, suppressBrowserResizeObserver: false, suppressPropertyNamesCheck: false, suppressChangeDetection: false, debug: false, suppressLoadingOverlay: false, suppressNoRowsOverlay: false, pagination: false, paginationPageSize: 100, paginationPageSizeSelector: true, paginationAutoPageSize: false, paginateChildRows: false, suppressPaginationPanel: false, pivotMode: false, pivotPanelShow: "never", pivotDefaultExpanded: 0, pivotSuppressAutoColumn: false, suppressExpandablePivotGroups: false, functionsReadOnly: false, suppressAggFuncInHeader: false, alwaysAggregateAtRootLevel: false, aggregateOnlyChangedColumns: false, suppressAggFilteredOnly: false, removePivotHeaderRowWhenSingleValueColumn: false, animateRows: true, cellFlashDuration: 500, cellFadeDuration: 1000, allowShowChangeAfterFilter: false, domLayout: "normal", ensureDomOrder: false, enableRtl: false, suppressColumnVirtualisation: false, suppressMaxRenderedRowRestriction: false, suppressRowVirtualisation: false, rowDragManaged: false, refreshAfterGroupEdit: false, rowDragInsertDelay: 500, suppressRowDrag: false, suppressMoveWhenRowDragging: false, rowDragEntireRow: false, rowDragMultiRow: false, embedFullWidthRows: false, groupDisplayType: "singleColumn", groupDefaultExpanded: 0, groupMaintainOrder: false, groupSelectsChildren: false, groupSuppressBlankHeader: false, groupSelectsFiltered: false, showOpenedGroup: false, groupRemoveSingleChildren: false, groupRemoveLowestSingleChildren: false, groupHideOpenParents: false, groupHideColumnsUntilExpanded: false, groupAllowUnbalanced: false, rowGroupPanelShow: "never", suppressMakeColumnVisibleAfterUnGroup: false, treeData: false, rowGroupPanelSuppressSort: false, suppressGroupRowsSticky: false, rowModelType: "clientSide", asyncTransactionWaitMillis: 50, suppressModelUpdateAfterUpdateTransaction: false, cacheOverflowSize: 1, infiniteInitialRowCount: 1, serverSideInitialRowCount: 1, cacheBlockSize: 100, maxBlocksInCache: -1, maxConcurrentDatasourceRequests: 2, blockLoadDebounceMillis: 0, purgeClosedRowNodes: false, serverSideSortAllLevels: false, serverSideOnlyRefreshFilteredGroups: false, serverSidePivotResultFieldSeparator: "_", viewportRowModelPageSize: 5, viewportRowModelBufferSize: 5, alwaysShowHorizontalScroll: false, alwaysShowVerticalScroll: false, debounceVerticalScrollbar: false, suppressHorizontalScroll: false, suppressScrollOnNewData: false, suppressScrollWhenPopupsAreOpen: false, suppressAnimationFrame: false, suppressMiddleClickScrolls: false, suppressPreventDefaultOnMouseWheel: false, rowMultiSelectWithClick: false, suppressRowDeselection: false, suppressRowClickSelection: false, suppressCellFocus: false, suppressHeaderFocus: false, suppressMultiRangeSelection: false, enableCellTextSelection: false, enableRangeSelection: false, enableRangeHandle: false, enableFillHandle: false, fillHandleDirection: "xy", suppressClearOnFillReduction: false, accentedSort: false, unSortIcon: false, suppressMultiSort: false, alwaysMultiSort: false, suppressMaintainUnsortedOrder: false, suppressRowHoverHighlight: false, suppressRowTransform: false, columnHoverHighlight: false, deltaSort: false, enableGroupEdit: false, groupLockGroupColumns: 0, serverSideEnableClientSideSort: false, suppressServerSideFullWidthLoadingRow: false, pivotMaxGeneratedColumns: -1, columnMenu: "new", reactiveCustomComponents: true, suppressSetFilterByDefault: false, enableFilterHandlers: false }; var BASE_URL = "https://www.ag-grid.com"; function _logIfDebug(gos, message, ...args) { if (gos.get("debug")) { console.log("AG Grid: " + message, ...args); } } function _warnOnce(msg, ...args) { _doOnce(() => _consoleWarn(msg, ...args), msg + args?.join("")); } function _errorOnce(msg, ...args) { _doOnce(() => _consoleError(msg, ...args), msg + args?.join("")); } function _consoleError(msg, ...args) { console.error("AG Grid: " + msg, ...args); } function _consoleWarn(msg, ...args) { console.warn("AG Grid: " + msg, ...args); } var allRegisteredModules = /* @__PURE__ */ new Set; var globalModulesMap = {}; var gridModulesMap = {}; var currentModuleVersion; var userHasRegistered = false; var areGridScopedModules = false; var isUmd = false; function isValidModuleVersion(module) { const [moduleMajor, moduleMinor] = module.version.split(".") || []; const [currentModuleMajor, currentModuleMinor] = currentModuleVersion.split(".") || []; return moduleMajor === currentModuleMajor && moduleMinor === currentModuleMinor; } function runVersionChecks(module) { if (!currentModuleVersion) { currentModuleVersion = module.version; } const errorMsg = (details) => `You are using incompatible versions of AG Grid modules. Major and minor versions should always match across modules. ${details} Please update all modules to the same version.`; if (!module.version) { _errorOnce(errorMsg(`'${module.moduleName}' is incompatible.`)); } else if (!isValidModuleVersion(module)) { _errorOnce(errorMsg(`'${module.moduleName}' is version ${module.version} but the other modules are version ${currentModuleVersion}.`)); } const result = module.validate?.(); if (result && !result.isValid) { _errorOnce(`${result.message}`); } } function _registerModule(module, gridId, isInternalRegistration = false) { if (!isInternalRegistration) { userHasRegistered = true; } runVersionChecks(module); const rowModels = module.rowModels ?? ["all"]; allRegisteredModules.add(module); let moduleStore; if (gridId !== undefined) { areGridScopedModules = true; if (gridModulesMap[gridId] === undefined) { gridModulesMap[gridId] = {}; } moduleStore = gridModulesMap[gridId]; } else { moduleStore = globalModulesMap; } for (const rowModel of rowModels) { if (moduleStore[rowModel] === undefined) { moduleStore[rowModel] = {}; } moduleStore[rowModel][module.moduleName] = module; } if (module.dependsOn) { for (const dependency of module.dependsOn) { _registerModule(dependency, gridId, isInternalRegistration); } } } function _unRegisterGridModules(gridId) { delete gridModulesMap[gridId]; } function _isModuleRegistered(moduleName, gridId, rowModel) { const isRegisteredForRowModel = (model) => !!globalModulesMap[model]?.[moduleName] || !!gridModulesMap[gridId]?.[model]?.[moduleName]; return isRegisteredForRowModel(rowModel) || isRegisteredForRowModel("all"); } function _areModulesGridScoped() { return areGridScopedModules; } function _getRegisteredModules(gridId, rowModel) { const gridModules = gridModulesMap[gridId] ?? {}; return [ ...Object.values(globalModulesMap["all"] ?? {}), ...Object.values(gridModules["all"] ?? {}), ...Object.values(globalModulesMap[rowModel] ?? {}), ...Object.values(gridModules[rowModel] ?? {}) ]; } function _getAllRegisteredModules() { return new Set(allRegisteredModules); } function _getGridRegisteredModules(gridId, rowModel) { const gridModules = gridModulesMap[gridId] ?? {}; return [...Object.values(gridModules["all"] ?? {}), ...Object.values(gridModules[rowModel] ?? {})]; } function _hasUserRegistered() { return userHasRegistered; } function _isUmd() { return isUmd; } var ModuleRegistry = class { static register(module) { _registerModule(module, undefined); } static registerModules(modules) { for (const module of modules) { _registerModule(module, undefined); } } }; var VERSION = "35.2.1"; var MAX_URL_LENGTH = 2000; var MIN_PARAM_LENGTH = 100; var VERSION_PARAM_NAME = "_version_"; var getConsoleMessage = null; var baseDocLink = `${BASE_URL}/javascript-data-grid`; function provideValidationServiceLogger(logger) { getConsoleMessage = logger; } function setValidationDocLink(docLink) { baseDocLink = docLink; } function getErrorParts(id, args, defaultMessage) { return getConsoleMessage?.(id, args) ?? [minifiedLog(id, args, defaultMessage)]; } function getMsgOrDefault(logger, id, args, isWarning, defaultMessage) { logger(`${isWarning ? "warning" : "error"} #${id}`, ...getErrorParts(id, args, defaultMessage)); } function stringifyObject(inputObj) { if (!inputObj) { return String(inputObj); } const object = {}; for (const prop of Object.keys(inputObj)) { if (typeof inputObj[prop] !== "object" && typeof inputObj[prop] !== "function") { object[prop] = inputObj[prop]; } } return JSON.stringify(object); } function stringifyValue(value) { let output = value; if (value instanceof Error) { output = value.toString(); } else if (typeof value === "object") { output = stringifyObject(value); } return output; } function toStringWithNullUndefined(str) { return str === undefined ? "undefined" : str === null ? "null" : str; } function getParamsUrl(baseUrl, params) { return `${baseUrl}?${params.toString()}`; } function truncateUrl(baseUrl, params, maxLength) { const sortedParams = Array.from(params.entries()).sort((a, b) => b[1].length - a[1].length); let url = getParamsUrl(baseUrl, params); for (const [key, value] of sortedParams) { if (key === VERSION_PARAM_NAME) { continue; } const excessLength = url.length - maxLength; if (excessLength <= 0) { break; } const ellipse = "..."; const truncateAmount = excessLength + ellipse.length; const truncatedValue = value.length - truncateAmount > MIN_PARAM_LENGTH ? value.slice(0, value.length - truncateAmount) + ellipse : value.slice(0, MIN_PARAM_LENGTH) + ellipse; params.set(key, truncatedValue); url = getParamsUrl(baseUrl, params); } return url; } function getErrorLink(errorNum, args) { const params = new URLSearchParams; params.append(VERSION_PARAM_NAME, VERSION); if (args) { for (const key of Object.keys(args)) { params.append(key, stringifyValue(args[key])); } } const baseUrl = `${baseDocLink}/errors/${errorNum}`; const url = getParamsUrl(baseUrl, params); return url.length <= MAX_URL_LENGTH ? url : truncateUrl(baseUrl, params, MAX_URL_LENGTH); } var minifiedLog = (errorNum, args, defaultMessage) => { const errorLink = getErrorLink(errorNum, args); const prefix = `${defaultMessage ? defaultMessage + ` ` : ""}Visit ${errorLink}`; if (_isUmd()) { return prefix; } return `${prefix}${defaultMessage ? "" : ` Alternatively register the ValidationModule to see the full message in the console.`}`; }; function _warn(...args) { getMsgOrDefault(_warnOnce, args[0], args[1], true); } function _error(...args) { getMsgOrDefault(_errorOnce, args[0], args[1], false); } function _logPreInitErr(id, args, defaultMessage) { getMsgOrDefault(_errorOnce, id, args, false, defaultMessage); } function _logPreInitWarn(id, args, defaultMessage) { getMsgOrDefault(_warnOnce, id, args, true, defaultMessage); } function getErrMsg(defaultMessage, args) { const id = args[0]; return `error #${id} ` + getErrorParts(id, args[1], defaultMessage).join(" "); } function _errMsg(...args) { return getErrMsg(undefined, args); } function isRowModelType(gos, rowModelType) { return gos.get("rowModelType") === rowModelType; } function _isClientSideRowModel(gos, rowModel) { return isRowModelType(gos, "clientSide"); } function _isServerSideRowModel(gos, rowModel) { return isRowModelType(gos, "serverSide"); } function _isDomLayout(gos, domLayout) { return gos.get("domLayout") === domLayout; } function _isRowSelection(gos) { return _getRowSelectionMode(gos) !== undefined; } function _isGetRowHeightFunction(gos) { return typeof gos.get("getRowHeight") === "function"; } function _shouldMaintainColumnOrder(gos, isPivotColumns) { if (isPivotColumns) { return !gos.get("enableStrictPivotColumnOrder"); } return gos.get("maintainColumnOrder"); } function _isRowNumbers({ gos, formula }) { const rowNumbers = gos.get("rowNumbers"); return rowNumbers || !!formula?.active && rowNumbers !== false; } function _getRowHeightForNode(beans, rowNode, allowEstimate = false, defaultRowHeight) { const { gos, environment } = beans; if (defaultRowHeight == null) { defaultRowHeight = environment.getDefaultRowHeight(); } if (_isGetRowHeightFunction(gos)) { if (allowEstimate) { return { height: defaultRowHeight, estimated: true }; } const params = { node: rowNode, data: rowNode.data }; const height = gos.getCallback("getRowHeight")(params); if (isNumeric(height)) { if (height === 0) { _warn(23); } return { height: Math.max(1, height), estimated: false }; } } if (rowNode.detail && gos.get("masterDetail")) { return getMasterDetailRowHeight(gos); } const gridOptionsRowHeight = gos.get("rowHeight"); const rowHeight = gridOptionsRowHeight && isNumeric(gridOptionsRowHeight) ? gridOptionsRowHeight : defaultRowHeight; return { height: rowHeight, estimated: false }; } function getMasterDetailRowHeight(gos) { if (gos.get("detailRowAutoHeight")) { return { height: 1, estimated: false }; } const defaultRowHeight = gos.get("detailRowHeight"); if (isNumeric(defaultRowHeight)) { return { height: defaultRowHeight, estimated: false }; } return { height: 300, estimated: false }; } function _getRowHeightAsNumber(beans) { const { environment, gos } = beans; const gridOptionsRowHeight = gos.get("rowHeight"); if (!gridOptionsRowHeight || _missing(gridOptionsRowHeight)) { return environment.getDefaultRowHeight(); } const rowHeight = environment.refreshRowHeightVariable(); if (rowHeight !== -1) { return rowHeight; } _warn(24); return environment.getDefaultRowHeight(); } function isNumeric(value) { return !isNaN(value) && typeof value === "number" && isFinite(value); } function _getDomData(gos, element, key) { const domData = element[gos.getDomDataKey()]; return domData ? domData[key] : undefined; } function _setDomData(gos, element, key, value) { const domDataKey = gos.getDomDataKey(); let domData = element[domDataKey]; if (_missing(domData)) { domData = {}; element[domDataKey] = domData; } domData[key] = value; } function _isAnimateRows(gos) { if (gos.get("ensureDomOrder")) { return false; } return gos.get("animateRows"); } function _isGroupRowsSticky(gos) { return !(gos.get("paginateChildRows") || gos.get("groupHideOpenParents") || _isDomLayout(gos, "print")); } function _isColumnsSortingCoupledToGroup(gos) { const autoGroupColumnDef = gos.get("autoGroupColumnDef"); return !autoGroupColumnDef?.comparator && !gos.get("treeData"); } function _getGroupAggFiltering(gos) { const userValue = gos.get("groupAggFiltering"); if (typeof userValue === "function") { return gos.getCallback("groupAggFiltering"); } if (userValue === true) { return () => true; } return; } function _getGrandTotalRow(gos) { return gos.get("grandTotalRow"); } function _getGroupTotalRowCallback(gos) { const userValue = gos.get("groupTotalRow"); if (typeof userValue === "function") { return gos.getCallback("groupTotalRow"); } return () => userValue ?? undefined; } function _isGroupMultiAutoColumn(gos) { const isHideOpenParents = !!gos.get("groupHideOpenParents"); if (isHideOpenParents) { return true; } return gos.get("groupDisplayType") === "multipleColumns"; } function _isGroupHideColumnsUntilExpanded(gos) { return _isGroupMultiAutoColumn(gos) && gos.get("groupHideColumnsUntilExpanded") && _isClientSideRowModel(gos); } function _isGroupUseEntireRow(gos, pivotMode) { if (pivotMode) { return false; } return gos.get("groupDisplayType") === "groupRows"; } function _isFullWidthGroupRow(gos, node, pivotMode) { return !!node.group && !node.footer && _isGroupUseEntireRow(gos, pivotMode); } function _getRowIdCallback(gos) { const getRowId = gos.getCallback("getRowId"); if (getRowId === undefined) { return getRowId; } return (params) => { let id = getRowId(params); if (typeof id !== "string") { _doOnce(() => _warn(25, { id }), "getRowIdString"); id = String(id); } return id; }; } function _canSkipShowingRowGroup(gos, node) { const isSkippingGroups = gos.get("groupHideParentOfSingleChild"); if (isSkippingGroups === true) { return true; } if (isSkippingGroups === "leafGroupsOnly" && node.leafGroup) { return true; } if (gos.get("groupRemoveSingleChildren")) { return true; } if (gos.get("groupRemoveLowestSingleChildren") && node.leafGroup) { return true; } return false; } function _shouldUpdateColVisibilityAfterGroup(gos, isGrouped) { const preventVisibilityChanges = gos.get("suppressGroupChangesColumnVisibility"); if (preventVisibilityChanges === true) { return false; } if (isGrouped && preventVisibilityChanges === "suppressHideOnGroup") { return false; } if (!isGrouped && preventVisibilityChanges === "suppressShowOnUngroup") { return false; } const legacySuppressOnGroup = gos.get("suppressRowGroupHidesColumns"); if (isGrouped && legacySuppressOnGroup === true) { return false; } const legacySuppressOnUngroup = gos.get("suppressMakeColumnVisibleAfterUnGroup"); if (!isGrouped && legacySuppressOnUngroup === true) { return false; } return true; } function _getCheckboxes(selection) { return selection?.checkboxes ?? true; } function _getHeaderCheckbox(selection) { return selection?.mode === "multiRow" && (selection.headerCheckbox ?? true); } function _getCheckboxLocation(rowSelection) { if (typeof rowSelection !== "object") { return; } return rowSelection.checkboxLocation ?? "selectionColumn"; } function _getHideDisabledCheckboxes(selection) { return selection?.hideDisabledCheckboxes ?? false; } function _isUsingNewRowSelectionAPI(gos) { const rowSelection = gos.get("rowSelection"); return typeof rowSelection !== "string"; } function _isUsingNewCellSelectionAPI(gos) { return gos.get("cellSelection") !== undefined; } function _getSuppressMultiRanges(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== undefined; if (!useNewAPI) { return gos.get("suppressMultiRangeSelection"); } return typeof selection !== "boolean" ? selection?.suppressMultiRanges ?? false : false; } function _isCellSelectionEnabled(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== undefined; return useNewAPI ? !!selection : gos.get("enableRangeSelection"); } function _getFillHandle(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== undefined; if (!useNewAPI) { return { mode: "fill", setFillValue: gos.get("fillOperation"), direction: gos.get("fillHandleDirection"), suppressClearOnFillReduction: gos.get("suppressClearOnFillReduction") }; } return typeof selection !== "boolean" && selection.handle?.mode === "fill" ? selection.handle : undefined; } function _getEnableColumnSelection(gos) { const cellSelection = gos.get("cellSelection") ?? false; return (typeof cellSelection === "object" && cellSelection.enableColumnSelection) ?? false; } function _getEnableClickSelection(gos) { const selection = gos.get("rowSelection") ?? "single"; if (typeof selection === "string") { const suppressRowClickSelection = gos.get("suppressRowClickSelection"); const suppressRowDeselection = gos.get("suppressRowDeselection"); if (suppressRowClickSelection && suppressRowDeselection) { return false; } else if (suppressRowClickSelection) { return "enableDeselection"; } else if (suppressRowDeselection) { return "enableSelection"; } else { return true; } } return selection.mode === "singleRow" || selection.mode === "multiRow" ? selection.enableClickSelection ?? false : false; } function _getEnableSelection(gos) { const enableClickSelection = _getEnableClickSelection(gos); return enableClickSelection === true || enableClickSelection === "enableSelection"; } function _getEnableDeselection(gos) { const enableClickSelection = _getEnableClickSelection(gos); return enableClickSelection === true || enableClickSelection === "enableDeselection"; } function _getIsRowSelectable(gos) { const selection = gos.get("rowSelection"); if (typeof selection === "string") { return gos.get("isRowSelectable"); } return selection?.isRowSelectable; } function _getRowSelectionMode(arg) { const selection = "beanName" in arg && arg.beanName === "gos" ? arg.get("rowSelection") : arg.rowSelection; if (typeof selection === "string") { switch (selection) { case "multiple": return "multiRow"; case "single": return "singleRow"; default: return; } } switch (selection?.mode) { case "multiRow": case "singleRow": return selection.mode; default: return; } } function _isMultiRowSelection(arg) { const mode = _getRowSelectionMode(arg); return mode === "multiRow"; } function _getEnableSelectionWithoutKeys(gos) { const selection = gos.get("rowSelection"); if (typeof selection === "string") { return gos.get("rowMultiSelectWithClick"); } return selection?.enableSelectionWithoutKeys ?? false; } function _getGroupSelection(gos) { const selection = gos.get("rowSelection"); if (typeof selection === "string") { const groupSelectsChildren = gos.get("groupSelectsChildren"); const groupSelectsFiltered = gos.get("groupSelectsFiltered"); if (groupSelectsChildren && groupSelectsFiltered) { return "filteredDescendants"; } else if (groupSelectsChildren) { return "descendants"; } else { return "self"; } } return selection?.mode === "multiRow" ? selection.groupSelects : undefined; } function _getSelectAll(gos, defaultValue = true) { const rowSelection = gos.get("rowSelection"); if (typeof rowSelection !== "object") { return defaultValue ? "all" : undefined; } return rowSelection.mode === "multiRow" ? rowSelection.selectAll : "all"; } function _getCtrlASelectsRows(gos) { const rowSelection = gos.get("rowSelection"); if (typeof rowSelection === "string") { return false; } return rowSelection?.mode === "multiRow" ? rowSelection.ctrlASelectsRows ?? false : false; } function _getGroupSelectsDescendants(gos) { const groupSelection = _getGroupSelection(gos); return groupSelection === "descendants" || groupSelection === "filteredDescendants"; } function _getMasterSelects(gos) { const rowSelection = gos.get("rowSelection"); return typeof rowSelection === "object" && rowSelection.masterSelects || "self"; } function _isSetFilterByDefault(gos) { return gos.isModuleRegistered("SetFilter") && !gos.get("suppressSetFilterByDefault"); } function _isLegacyMenuEnabled(gos) { return gos.get("columnMenu") === "legacy"; } function _isColumnMenuAnchoringEnabled(gos) { return !_isLegacyMenuEnabled(gos); } function _getCallbackForEvent(eventName) { if (!eventName || eventName.length < 2) { return eventName; } return "on" + eventName[0].toUpperCase() + eventName.substring(1); } function _addGridCommonParams(gos, params) { return gos.addCommon(params); } function _interpretAsRightClick({ gos }, event) { return event.button === 2 || event.ctrlKey && gos.get("allowContextMenuWithControlKey"); } var COL_DEF_DEFAULTS = { resizable: true, sortable: true }; var instanceIdSequence = 0; function getNextColInstanceId() { return instanceIdSequence++; } function isColumn(col) { return col instanceof AgColumn; } var DEFAULT_SORTING_ORDER = ["asc", "desc", null]; var DEFAULT_ABSOLUTE_SORTING_ORDER = [ { type: "absolute", direction: "asc" }, { type: "absolute", direction: "desc" }, null ]; var AgColumn = class extends BeanStub { constructor(colDef, userProvidedColDef, colId, primary) { super(); this.colDef = colDef; this.userProvidedColDef = userProvidedColDef; this.colId = colId; this.primary = primary; this.isColumn = true; this.instanceId = getNextColInstanceId(); this.autoHeaderHeight = null; this.sortDef = _getSortDefFromInput(); this._wasSortExplicitlyRemoved = false; this.moving = false; this.resizing = false; this.menuVisible = false; this.formulaRef = null; this.lastLeftPinned = false; this.firstRightPinned = false; this.filterActive = false; this.colEventSvc = new LocalEventService; this.tooltipEnabled = false; this.rowGroupActive = false; this.pivotActive = false; this.aggregationActive = false; this.flex = null; this.colIdSanitised = _escapeString(colId); } destroy() { super.destroy(); this.beans.rowSpanSvc?.deregister(this); } getInstanceId() { return this.instanceId; } initState() { const { colDef, beans: { sortSvc, pinnedCols, colFlex } } = this; sortSvc?.initCol(this); const hide = colDef.hide; if (hide !== undefined) { this.visible = !hide; } else { this.visible = !colDef.initialHide; } pinnedCols?.initCol(this); colFlex?.initCol(this); } setColDef(colDef, userProvidedColDef, source) { const colSpanChanged = colDef.spanRows !== this.colDef.spanRows; this.colDef = colDef; this.userProvidedColDef = userProvidedColDef; this.initMinAndMaxWidths(); this.initDotNotation(); this.initTooltip(); if (colSpanChanged) { this.beans.rowSpanSvc?.deregister(this); this.initRowSpan(); } this.dispatchColEvent("colDefChanged", source); } getUserProvidedColDef() { return this.userProvidedColDef; } getParent() { return this.parent; } getOriginalParent() { return this.originalParent; } postConstruct() { this.initState(); this.initMinAndMaxWidths(); this.resetActualWidth("gridInitializing"); this.initDotNotation(); this.initTooltip(); this.initRowSpan(); this.addPivotListener(); } initDotNotation() { const { gos, colDef: { field, tooltipField } } = this; const suppressDotNotation = gos.get("suppressFieldDotNotation"); this.fieldContainsDots = _exists(field) && field.includes(".") && !suppressDotNotation; this.tooltipFieldContainsDots = _exists(tooltipField) && tooltipField.includes(".") && !suppressDotNotation; } initMinAndMaxWidths() { const colDef = this.colDef; this.minWidth = colDef.minWidth ?? this.beans.environment.getDefaultColumnMinWidth(); this.maxWidth = colDef.maxWidth ?? Number.MAX_SAFE_INTEGER; } initTooltip() { this.beans.tooltipSvc?.initCol(this); } initRowSpan() { if (this.colDef.spanRows) { this.beans.rowSpanSvc?.register(this); } } addPivotListener() { const pivotColDefSvc = this.beans.pivotColDefSvc; const pivotValueColumn = this.colDef.pivotValueColumn; if (!pivotColDefSvc || !pivotValueColumn) { return; } this.addManagedListeners(pivotValueColumn, { colDefChanged: (evt) => { const colDef = pivotColDefSvc.recreateColDef(this.colDef); this.setColDef(colDef, colDef, evt.source); } }); } resetActualWidth(source) { const initialWidth = this.calculateColInitialWidth(this.colDef); this.setActualWidth(initialWidth, source, true); } calculateColInitialWidth(colDef) { const width = colDef.width ?? colDef.initialWidth ?? 200; return Math.max(Math.min(width, this.maxWidth), this.minWidth); } isEmptyGroup() { return false; } isRowGroupDisplayed(colId) { return this.beans.showRowGroupCols?.isRowGroupDisplayed(this, colId) ?? false; } isPrimary() { return this.primary; } isFilterAllowed() { const filterDefined = !!this.colDef.filter; return filterDefined; } isFieldContainsDots() { return this.fieldContainsDots; } isTooltipEnabled() { return this.tooltipEnabled; } isTooltipFieldContainsDots() { return this.tooltipFieldContainsDots; } getHighlighted() { return this.highlighted; } __addEventListener(eventType, listener) { this.colEventSvc.addEventListener(eventType, listener); } __removeEventListener(eventType, listener) { this.colEventSvc.removeEventListener(eventType, listener); } addEventListener(eventType, userListener) { this.frameworkEventListenerService = this.beans.frameworkOverrides.createLocalEventListenerWrapper?.(this.frameworkEventListenerService, this.colEventSvc); const listener = this.frameworkEventListenerService?.wrap(eventType, userListener) ?? userListener; this.colEventSvc.addEventListener(eventType, listener); } removeEventListener(eventType, userListener) { const listener = this.frameworkEventListenerService?.unwrap(eventType, userListener) ?? userListener; this.colEventSvc.removeEventListener(eventType, listener); } createColumnFunctionCallbackParams(rowNode) { return _addGridCommonParams(this.gos, { node: rowNode, data: rowNode.data, column: this, colDef: this.colDef }); } isSuppressNavigable(rowNode) { return this.beans.cellNavigation?.isSuppressNavigable(this, rowNode) ?? false; } isCellEditable(rowNode) { return this.beans.editSvc?.isCellEditable({ rowNode, column: this }) ?? false; } isSuppressFillHandle() { return !!this.colDef.suppressFillHandle; } isAutoHeight() { return !!this.colDef.autoHeight; } isAutoHeaderHeight() { return !!this.colDef.autoHeaderHeight; } isRowDrag(rowNode) { return this.isColumnFunc(rowNode, this.colDef.rowDrag); } isDndSource(rowNode) { return this.isColumnFunc(rowNode, this.colDef.dndSource); } isCellCheckboxSelection(rowNode) { return this.beans.selectionSvc?.isCellCheckboxSelection(this, rowNode) ?? false; } isSuppressPaste(rowNode) { return this.isColumnFunc(rowNode, this.colDef?.suppressPaste ?? null); } isResizable() { return !!this.getColDefValue("resizable"); } getColDefValue(key) { return this.colDef[key] ?? COL_DEF_DEFAULTS[key]; } isColumnFunc(rowNode, value) { if (typeof value === "boolean") { return value; } if (typeof value === "function") { const params = this.createColumnFunctionCallbackParams(rowNode); const editableFunc = value; return editableFunc(params); } return false; } createColumnEvent(type, source) { return _addGridCommonParams(this.gos, { type, column: this, columns: [this], source }); } isMoving() { return this.moving; } getSort() { return this.sortDef.direction; } getSortDef() { if (!this.sortDef.direction) { return null; } return this.sortDef; } getColDefAllowedSortTypes() { const res = []; const { sort, initialSort } = this.colDef; const colDefSortType = sort === null ? sort : _normalizeSortType(sort?.type); const colDefInitialSortType = initialSort === null ? initialSort : _normalizeSortType(initialSort?.type); if (colDefSortType) { res.push(colDefSortType); } if (colDefInitialSortType) { res.push(colDefInitialSortType); } return res; } getSortingOrder() { const defaultSortingOrder = this.getColDefAllowedSortTypes().includes("absolute") ? DEFAULT_ABSOLUTE_SORTING_ORDER : DEFAULT_SORTING_ORDER; return (this.colDef.sortingOrder ?? this.gos.get("sortingOrder") ?? defaultSortingOrder).map((objOrDirection) => _getSortDefFromInput(objOrDirection)); } getAvailableSortTypes() { const explicitSortTypesFromSortingOrder = this.getSortingOrder().reduce((acc, so) => { if (so.direction) { acc.push(so.type); } return acc; }, this.getColDefAllowedSortTypes()); return new Set(explicitSortTypesFromSortingOrder); } get wasSortExplicitlyRemoved() { return this._wasSortExplicitlyRemoved; } setSortDef(sortDef, initial = false) { if (!initial) { this._wasSortExplicitlyRemoved = !sortDef.direction; } this.sortDef = sortDef; } isSortable() { return !!this.getColDefValue("sortable"); } isSortAscending() { return this.getSort() === "asc"; } isSortDescending() { return this.getSort() === "desc"; } isSortNone() { return _missing(this.getSort()); } isSorting() { return _exists(this.getSort()); } getSortIndex() { return this.sortIndex; } isMenuVisible() { return this.menuVisible; } getAggFunc() { return this.aggFunc; } getLeft() { return this.left; } getOldLeft() { return this.oldLeft; } getRight() { return this.left + this.actualWidth; } setLeft(left, source) { this.oldLeft = this.left; if (this.left !== left) { this.left = left; this.dispatchColEvent("leftChanged", source); } } isFilterActive() { return this.filterActive; } isHovered() { _warn(261); return !!this.beans.colHover?.isHovered(this); } setFirstRightPinned(firstRightPinned, source) { if (this.firstRightPinned !== firstRightPinned) { this.firstRightPinned = firstRightPinned; this.dispatchColEvent("firstRightPinnedChanged", source); } } setLastLeftPinned(lastLeftPinned, source) { if (this.lastLeftPinned !== lastLeftPinned) { this.lastLeftPinned = lastLeftPinned; this.dispatchColEvent("lastLeftPinnedChanged", source); } } isFirstRightPinned() { return this.firstRightPinned; } isLastLeftPinned() { return this.lastLeftPinned; } isPinned() { return this.pinned === "left" || this.pinned === "right"; } isPinnedLeft() { return this.pinned === "left"; } isPinnedRight() { return this.pinned === "right"; } getPinned() { return this.pinned; } setVisible(visible, source) { const newValue = visible === true; if (this.visible !== newValue) { this.visible = newValue; this.dispatchColEvent("visibleChanged", source); } this.dispatchStateUpdatedEvent("hide"); } isVisible() { return this.visible; } isSpanHeaderHeight() { const colDef = this.getColDef(); return !colDef.suppressSpanHeaderHeight; } getFirstRealParent() { let parent = this.getOriginalParent(); while (parent?.isPadding()) { parent = parent.getOriginalParent(); } return parent; } getColumnGroupPaddingInfo() { let parent = this.getParent(); if (!parent?.isPadding()) { return { numberOfParents: 0, isSpanningTotal: false }; } const numberOfParents = parent.getPaddingLevel() + 1; let isSpanningTotal = true; while (parent) { if (!parent.isPadding()) { isSpanningTotal = false; break; } parent = parent.getParent(); } return { numberOfParents, isSpanningTotal }; } getColDef() { return this.colDef; } getDefinition() { return this.colDef; } getColumnGroupShow() { return this.colDef.columnGroupShow; } getColId() { return this.colId; } getId() { return this.colId; } getUniqueId() { return this.colId; } getActualWidth() { return this.actualWidth; } getAutoHeaderHeight() { return this.autoHeaderHeight; } setAutoHeaderHeight(height) { const changed = height !== this.autoHeaderHeight; this.autoHeaderHeight = height; return changed; } createBaseColDefParams(rowNode) { const params = _addGridCommonParams(this.gos, { node: rowNode, data: rowNode.data, colDef: this.colDef, column: this }); return params; } getColSpan(rowNode) { if (_missing(this.colDef.colSpan)) { return 1; } const params = this.createBaseColDefParams(rowNode); const colSpan = this.colDef.colSpan(params); return Math.max(colSpan, 1); } getRowSpan(rowNode) { if (_missing(this.colDef.rowSpan)) { return 1; } const params = this.createBaseColDefParams(rowNode); const rowSpan = this.colDef.rowSpan(params); return Math.max(rowSpan, 1); } setActualWidth(actualWidth, source, silent = false) { actualWidth = Math.max(actualWidth, this.minWidth); actualWidth = Math.min(actualWidth, this.maxWidth); if (this.actualWidth !== actualWidth) { this.actualWidth = actualWidth; if (this.flex != null && source !== "flex" && source !== "gridInitializing") { this.flex = null; } if (!silent) { this.fireColumnWidthChangedEvent(source); } } this.dispatchStateUpdatedEvent("width"); } fireColumnWidthChangedEvent(source) { this.dispatchColEvent("widthChanged", source); } isGreaterThanMax(width) { return width > this.maxWidth; } getMinWidth() { return this.minWidth; } getMaxWidth() { return this.maxWidth; } getFlex() { return this.flex; } isRowGroupActive() { return this.rowGroupActive; } isPivotActive() { return this.pivotActive; } isAnyFunctionActive() { return this.isPivotActive() || this.isRowGroupActive() || this.isValueActive(); } isAnyFunctionAllowed() { return this.isAllowPivot() || this.isAllowRowGroup() || this.isAllowValue(); } isValueActive() { return this.aggregationActive; } isAllowPivot() { return this.colDef.enablePivot === true; } isAllowValue() { return this.colDef.enableValue === true; } isAllowRowGroup() { return this.colDef.enableRowGroup === true; } isAllowFormula() { return this.colDef.allowFormula === true; } dispatchColEvent(type, source, additionalEventAttributes) { const colEvent = this.createColumnEvent(type, source); if (additionalEventAttributes) { _mergeDeep(colEvent, additionalEventAttributes); } this.colEventSvc.dispatchEvent(colEvent); } dispatchStateUpdatedEvent(key) { this.colEventSvc.dispatchEvent({ type: "columnStateUpdated", key }); } }; function _getSortDefFromInput(input) { if (_isSortDefValid(input)) { return { direction: input.direction, type: input.type }; } return { direction: _normalizeSortDirection(input), type: _normalizeSortType(input) }; } function _isSortDirectionValid(maybeSortDir) { return maybeSortDir === "asc" || maybeSortDir === "desc" || maybeSortDir === null; } function _isSortTypeValid(maybeSortType) { return maybeSortType === "default" || maybeSortType === "absolute"; } function _isSortDefValid(maybeSortDef) { if (!maybeSortDef || typeof maybeSortDef !== "object") { return false; } const maybeSortDefT = maybeSortDef; return _isSortTypeValid(maybeSortDefT.type) && _isSortDirectionValid(maybeSortDefT.direction); } function _areSortDefsEqual(sortDef1, sortDef2) { if (!sortDef1) { return sortDef2 ? sortDef2.direction === null : true; } if (!sortDef2) { return sortDef1 ? sortDef1.direction === null : true; } return sortDef1.type === sortDef2.type && sortDef1.direction === sortDef2.direction; } function _normalizeSortDirection(sortDirectionLike) { return _isSortDirectionValid(sortDirectionLike) ? sortDirectionLike : null; } function _normalizeSortType(sortTypeLike) { return _isSortTypeValid(sortTypeLike) ? sortTypeLike : "default"; } function _getDisplaySortForColumn(column, beans, getSortDefOverride) { const overrideSortDef = getSortDefOverride?.(); const sortDef = overrideSortDef ?? beans.sortSvc.getDisplaySortForColumn(column); const type = _normalizeSortType(sortDef?.type); const direction = _normalizeSortDirection(sortDef?.direction); const allowedSortTypes = column.getAvailableSortTypes(); const isDefaultSortAllowed = allowedSortTypes.has("default"); const isAbsoluteSortAllowed = allowedSortTypes.has("absolute"); const isAbsoluteSort = type === "absolute"; const isDefaultSort = type === "default"; const isAscending = direction === "asc"; const isDescending = direction === "desc"; return { isDefaultSortAllowed, isAbsoluteSortAllowed, isAbsoluteSort, isDefaultSort, isAscending, isDescending, direction }; } function isProvidedColumnGroup(col) { return col instanceof AgProvidedColumnGroup; } var AgProvidedColumnGroup = class extends BeanStub { constructor(colGroupDef, groupId, padding, level) { super(); this.colGroupDef = colGroupDef; this.groupId = groupId; this.padding = padding; this.level = level; this.isColumn = false; this.expandable = false; this.instanceId = getNextColInstanceId(); this.expandableListenerRemoveCallback = null; this.expanded = !!colGroupDef?.openByDefault; } destroy() { if (this.expandableListenerRemoveCallback) { this.reset(null, undefined); } super.destroy(); } reset(colGroupDef, level) { this.colGroupDef = colGroupDef; this.level = level; this.originalParent = null; if (this.expandableListenerRemoveCallback) { this.expandableListenerRemoveCallback(); } this.children = undefined; this.expandable = undefined; } getInstanceId() { return this.instanceId; } getOriginalParent() { return this.originalParent; } getLevel() { return this.level; } isVisible() { if (this.children) { return this.children.some((child) => child.isVisible()); } return false; } isPadding() { return this.padding; } setExpanded(expanded) { this.expanded = expanded === undefined ? false : expanded; this.dispatchLocalEvent({ type: "expandedChanged" }); } isExpandable() { return this.expandable; } isExpanded() { return this.expanded; } getGroupId() { return this.groupId; } getId() { return this.getGroupId(); } setChildren(children) { this.children = children; } getChildren() { return this.children; } getColGroupDef() { return this.colGroupDef; } getLeafColumns() { const result = []; this.addLeafColumns(result); return result; } forEachLeafColumn(callback) { if (!this.children) { return; } for (const child of this.children) { if (isColumn(child)) { callback(child); } else if (isProvidedColumnGroup(child)) { child.forEachLeafColumn(callback); } } } addLeafColumns(leafColumns) { if (!this.children) { return; } for (const child of this.children) { if (isColumn(child)) { leafColumns.push(child); } else if (isProvidedColumnGroup(child)) { child.addLeafColumns(leafColumns); } } } getColumnGroupShow() { const colGroupDef = this.colGroupDef; if (!colGroupDef) { return; } return colGroupDef.columnGroupShow; } setupExpandable() { this.setExpandable(); if (this.expandableListenerRemoveCallback) { this.expandableListenerRemoveCallback(); } const listener = this.onColumnVisibilityChanged.bind(this); for (const col of this.getLeafColumns()) { col.__addEventListener("visibleChanged", listener); } this.expandableListenerRemoveCallback = () => { for (const col of this.getLeafColumns()) { col.__removeEventListener("visibleChanged", listener); } this.expandableListenerRemoveCallback = null; }; } setExpandable() { if (this.isPadding()) { return; } let atLeastOneShowingWhenOpen = false; let atLeastOneShowingWhenClosed = false; let atLeastOneChangeable = false; const children = this.findChildrenRemovingPadding(); for (let i = 0, j = children.length;i < j; i++) { const abstractColumn = children[i]; if (!abstractColumn.isVisible()) { continue; } const headerGroupShow = abstractColumn.getColumnGroupShow(); if (headerGroupShow === "open") { atLeastOneShowingWhenOpen = true; atLeastOneChangeable = true; } else if (headerGroupShow === "closed") { atLeastOneShowingWhenClosed = true; atLeastOneChangeable = true; } else { atLeastOneShowingWhenOpen = true; atLeastOneShowingWhenClosed = true; } } const expandable = atLeastOneShowingWhenOpen && atLeastOneShowingWhenClosed && atLeastOneChangeable; if (this.expandable !== expandable) { this.expandable = expandable; this.dispatchLocalEvent({ type: "expandableChanged" }); } } findChildrenRemovingPadding() { const res = []; const process = (items) => { for (const item of items) { const skipBecausePadding = isProvidedColumnGroup(item) && item.isPadding(); if (skipBecausePadding) { process(item.children); } else { res.push(item); } } }; process(this.children); return res; } onColumnVisibilityChanged() { this.setExpandable(); } }; var DefaultColumnTypes = { numericColumn: { headerClass: "ag-right-aligned-header", cellClass: "ag-right-aligned-cell" }, rightAligned: { headerClass: "ag-right-aligned-header", cellClass: "ag-right-aligned-cell" } }; function createMergedColGroupDef(beans, colGroupDef, groupId) { const colGroupDefMerged = {}; const gos = beans.gos; Object.assign(colGroupDefMerged, gos.get("defaultColGroupDef")); Object.assign(colGroupDefMerged, colGroupDef); gos.validateColDef(colGroupDefMerged, groupId); return colGroupDefMerged; } var ColumnKeyCreator = class { constructor() { this.existingKeys = {}; } addExistingKeys(keys) { for (let i = 0;i < keys.length; i++) { this.existingKeys[keys[i]] = true; } } getUniqueKey(colId, colField) { colId = _toStringOrNull(colId); let count = 0; while (true) { let idToTry = colId ?? colField; if (idToTry) { if (count !== 0) { idToTry += "_" + count; } } else { idToTry = count; } if (!this.existingKeys[idToTry]) { const usedId = String(idToTry); if (colId && count > 0) { _warn(273, { providedId: colId, usedId }); } this.existingKeys[usedId] = true; return usedId; } count++; } } }; var depthFirstCallback = (child, parent) => { if (isProvidedColumnGroup(child)) { child.setupExpandable(); } child.originalParent = parent; }; function _createColumnTreeWithIds(beans, defs = null, primaryColumns, existingTree, source) { const { existingCols, existingGroups } = extractExistingTreeData(existingTree); const colIdMap = new Map(existingCols.map((col) => [col.getId(), col])); const colGroupIdMap = new Map(existingGroups.map((group) => [group.getId(), group])); let maxDepth = 0; const recursivelyProcessColDef = (def, level) => { maxDepth = Math.max(maxDepth, level); if (isColumnGroupDef(def)) { if (!beans.colGroupSvc) { return null; } const groupId = def.groupId; const group = colGroupIdMap.get(groupId); const colGroupDef = createMergedColGroupDef(beans, def, groupId); const newGroup = new AgProvidedColumnGroup(colGroupDef, groupId, false, level); beans.context.createBean(newGroup); if (group) { newGroup.setExpanded(group.isExpanded()); } newGroup.setChildren(def.children.map((child) => recursivelyProcessColDef(child, level + 1))); return newGroup; } const colId = def.colId; let column = colIdMap.get(colId); const colDefMerged = _addColumnDefaultAndTypes(beans, def, column?.getColId() ?? colId); if (!column) { column = new AgColumn(colDefMerged, def, colId, primaryColumns); beans.context.createBean(column); } else { column.setColDef(colDefMerged, def, source); _updateColumnState(beans, column, colDefMerged, source); } beans.dataTypeSvc?.addColumnListeners(column); return column; }; const root = defs?.map((def) => recursivelyProcessColDef(def, 0)) ?? []; let counter = 0; const keyCreator = { getUniqueKey: (_colId, _field) => String(++counter) }; const columnTree = beans.colGroupSvc ? beans.colGroupSvc.balanceColumnTree(root, 0, maxDepth, keyCreator) : root; depthFirstOriginalTreeSearch(null, columnTree, depthFirstCallback); return { columnTree, treeDepth: maxDepth }; } function _createColumnTree(beans, defs = null, primaryColumns, existingTree, source) { const columnKeyCreator = new ColumnKeyCreator; const { existingCols, existingGroups, existingColKeys } = extractExistingTreeData(existingTree); columnKeyCreator.addExistingKeys(existingColKeys); const unbalancedTree = _recursivelyCreateColumns(beans, defs, 0, primaryColumns, existingCols, columnKeyCreator, existingGroups, source); const { colGroupSvc } = beans; const treeDepth = colGroupSvc?.findMaxDepth(unbalancedTree, 0) ?? 0; const columnTree = colGroupSvc ? colGroupSvc.balanceColumnTree(unbalancedTree, 0, treeDepth, columnKeyCreator) : unbalancedTree; depthFirstOriginalTreeSearch(null, columnTree, depthFirstCallback); return { columnTree, treeDepth }; } function extractExistingTreeData(existingTree) { const existingCols = []; const existingGroups = []; const existingColKeys = []; if (existingTree) { depthFirstOriginalTreeSearch(null, existingTree, (item) => { if (isProvidedColumnGroup(item)) { const group = item; existingGroups.push(group); } else { const col = item; existingColKeys.push(col.getId()); existingCols.push(col); } }); } return { existingCols, existingGroups, existingColKeys }; } function _recursivelyCreateColumns(beans, defs, level, primaryColumns, existingColsCopy, columnKeyCreator, existingGroups, source) { if (!defs) { return []; } const { colGroupSvc } = beans; const result = new Array(defs.length); for (let i = 0;i < result.length; i++) { const def = defs[i]; if (colGroupSvc && isColumnGroupDef(def)) { result[i] = colGroupSvc.createProvidedColumnGroup(primaryColumns, def, level, existingColsCopy, columnKeyCreator, existingGroups, source); } else { result[i] = createColumn(beans, primaryColumns, def, existingColsCopy, columnKeyCreator, source); } } return result; } function createColumn(beans, primaryColumns, colDef, existingColsCopy, columnKeyCreator, source) { const existingColAndIndex = findExistingColumn(colDef, existingColsCopy); if (existingColAndIndex) { existingColsCopy?.splice(existingColAndIndex.idx, 1); } let column = existingColAndIndex?.column; if (!column) { const colId = columnKeyCreator.getUniqueKey(colDef.colId, colDef.field); const colDefMerged = _addColumnDefaultAndTypes(beans, colDef, colId); column = new AgColumn(colDefMerged, colDef, colId, primaryColumns); beans.context.createBean(column); } else { const colDefMerged = _addColumnDefaultAndTypes(beans, colDef, column.getColId()); column.setColDef(colDefMerged, colDef, source); _updateColumnState(beans, column, colDefMerged, source); } beans.dataTypeSvc?.addColumnListeners(column); return column; } function updateSomeColumnState(beans, column, hide, sort, sortIndex, pinned, flex, source) { const { sortSvc, pinnedCols, colFlex } = beans; if (hide !== undefined) { column.setVisible(!hide, source); } if (sortSvc) { sortSvc.updateColSort(column, sort, source); if (sortIndex !== undefined) { sortSvc.setColSortIndex(column, sortIndex); } } if (pinned !== undefined) { pinnedCols?.setColPinned(column, pinned); } if (flex !== undefined) { colFlex?.setColFlex(column, flex); } } function _updateColumnState(beans, column, colDef, source) { updateSomeColumnState(beans, column, colDef.hide, colDef.sort, colDef.sortIndex, colDef.pinned, colDef.flex, source); const colFlex = column.getFlex(); if (colFlex != null && colFlex > 0) { return; } if (colDef.width != null) { column.setActualWidth(colDef.width, source); } else { const widthBeforeUpdate = column.getActualWidth(); column.setActualWidth(widthBeforeUpdate, source); } } function findExistingColumn(newColDef, existingColsCopy) { if (!existingColsCopy) { return; } for (let i = 0;i < existingColsCopy.length; i++) { const def = existingColsCopy[i].getUserProvidedColDef(); if (!def) { continue; } const newHasId = newColDef.colId != null; if (newHasId) { if (existingColsCopy[i].getId() === newColDef.colId) { return { idx: i, column: existingColsCopy[i] }; } continue; } const newHasField = newColDef.field != null; if (newHasField) { if (def.field === newColDef.field) { return { idx: i, column: existingColsCopy[i] }; } continue; } if (def === newColDef) { return { idx: i, column: existingColsCopy[i] }; } } return; } function _addColumnDefaultAndTypes(beans, colDef, colId, isAutoCol) { const { gos, dataTypeSvc } = beans; const res = {}; const defaultColDef = gos.get("defaultColDef"); _mergeDeep(res, defaultColDef, false, true); const columnType = updateColDefAndGetColumnType(beans, res, colDef, colId); if (columnType) { assignColumnTypes(beans, columnType, res); } const cellDataType = res.cellDataType; _mergeDeep(res, colDef, false, true); if (cellDataType !== undefined) { res.cellDataType = cellDataType; } const autoGroupColDef = gos.get("autoGroupColumnDef"); const isSortingCoupled = _isColumnsSortingCoupledToGroup(gos); if (colDef.rowGroup && autoGroupColDef && isSortingCoupled) { _mergeDeep(res, { sort: autoGroupColDef.sort, initialSort: autoGroupColDef.initialSort }, false, true); } dataTypeSvc?.postProcess(res); dataTypeSvc?.validateColDef(res, colDef, defaultColDef, colId); gos.validateColDef(res, colId, isAutoCol); return res; } function updateColDefAndGetColumnType(beans, colDef, userColDef, colId) { const dataTypeDefinitionColumnType = beans.dataTypeSvc?.updateColDefAndGetColumnType(colDef, userColDef, colId); const columnTypes = userColDef.type ?? dataTypeDefinitionColumnType ?? colDef.type; colDef.type = columnTypes; return columnTypes ? convertColumnTypes(columnTypes) : undefined; } function assignColumnTypes(beans, typeKeys, colDefMerged) { if (!typeKeys.length) { return; } const allColumnTypes = Object.assign({}, DefaultColumnTypes); const userTypes = beans.gos.get("columnTypes") || {}; for (const key of Object.keys(userTypes)) { const value = userTypes[key]; if (key in allColumnTypes) { _warn(34, { key }); } else { const colType = value; if (colType.type) { _warn(35); } allColumnTypes[key] = value; } } for (const t of typeKeys) { const typeColDef = allColumnTypes[t.trim()]; if (typeColDef) { _mergeDeep(colDefMerged, typeColDef, false, true); } else { _warn(36, { t }); } } } function isColumnGroupDef(abstractColDef) { return abstractColDef.children !== undefined; } function depthFirstOriginalTreeSearch(parent, tree, callback) { if (!tree) { return; } for (let i = 0;i < tree.length; i++) { const child = tree[i]; if (isProvidedColumnGroup(child)) { depthFirstOriginalTreeSearch(child, child.getChildren(), callback); } callback(child, parent); } } var GROUP_AUTO_COLUMN_ID = "ag-Grid-AutoColumn"; var SELECTION_COLUMN_ID = "ag-Grid-SelectionColumn"; var ROW_NUMBERS_COLUMN_ID = "ag-Grid-RowNumbersColumn"; var GROUP_HIERARCHY_COLUMN_ID_PREFIX = "ag-Grid-HierarchyColumn"; function _getColumnsFromTree(rootColumns) { const result = []; const recursiveFindColumns = (childColumns) => { for (let i = 0;i < childColumns.length; i++) { const child = childColumns[i]; if (isColumn(child)) { result.push(child); } else if (isProvidedColumnGroup(child)) { recursiveFindColumns(child.getChildren()); } } }; recursiveFindColumns(rootColumns); return result; } function getWidthOfColsInList(columnList) { return columnList.reduce((width, col) => width + col.getActualWidth(), 0); } function _destroyColumnTree(beans, oldTree, newTree) { const oldObjectsById = {}; if (!oldTree) { return; } depthFirstOriginalTreeSearch(null, oldTree, (child) => { oldObjectsById[child.getInstanceId()] = child; }); if (newTree) { depthFirstOriginalTreeSearch(null, newTree, (child) => { oldObjectsById[child.getInstanceId()] = null; }); } const colsToDestroy = Object.values(oldObjectsById).filter((item) => item != null); beans.context.destroyBeans(colsToDestroy); } function isColumnGroupAutoCol(col) { const colId = col.getId(); return colId.startsWith(GROUP_AUTO_COLUMN_ID); } function isColumnSelectionCol(col) { const id = typeof col === "string" ? col : ("getColId" in col) ? col.getColId() : col.colId; return id?.startsWith(SELECTION_COLUMN_ID) ?? false; } function isRowNumberCol(col) { const id = typeof col === "string" ? col : ("getColId" in col) ? col.getColId() : col.colId; return id?.startsWith(ROW_NUMBERS_COLUMN_ID) ?? false; } function isSpecialCol(col) { return isColumnSelectionCol(col) || isRowNumberCol(col); } function convertColumnTypes(type) { let typeKeys = []; if (type instanceof Array) { typeKeys = type; } else if (typeof type === "string") { typeKeys = type.split(","); } return typeKeys; } function _areColIdsEqual(colsA, colsB) { return _areEqual(colsA, colsB, (a, b) => a.getColId() === b.getColId()); } function _updateColsMap(cols) { cols.map = {}; for (const col of cols.list) { cols.map[col.getId()] = col; } } function _convertColumnEventSourceType(source) { return source === "optionsUpdated" ? "gridOptionsChanged" : source; } function _columnsMatch(column, key) { return column === key || column.colId == key || column.getColDef() === key; } var getValueFactory = (stateItem, defaultState) => (key1, key2) => { const obj = { value1: undefined, value2: undefined }; let calculated = false; if (stateItem) { if (stateItem[key1] !== undefined) { obj.value1 = stateItem[key1]; calculated = true; } if (_exists(key2) && stateItem[key2] !== undefined) { obj.value2 = stateItem[key2]; calculated = true; } } if (!calculated && defaultState) { if (defaultState[key1] !== undefined) { obj.value1 = defaultState[key1]; } if (_exists(key2) && defaultState[key2] !== undefined) { obj.value2 = defaultState[key2]; } } return obj; }; function _getColumnStateFromColDef(colDef, colId) { const state = { ...colDef, sort: undefined, colId }; const sortDef = _getSortDefFromColDef(colDef); if (sortDef) { state.sort = sortDef.direction; state.sortType = sortDef.type; } return state; } function _getSortDefFromColDef(colDef) { const { sort, initialSort } = colDef; const sortIsValid = _isSortDefValid(sort) || _isSortDirectionValid(sort); const initialSortIsValid = _isSortDefValid(initialSort) || _isSortDirectionValid(initialSort); if (sortIsValid) { return _getSortDefFromInput(sort); } if (initialSortIsValid) { return _getSortDefFromInput(initialSort); } return null; } function createUniqueColumnGroupId(groupId, instanceId) { return groupId + "_" + instanceId; } function isColumnGroup(col) { return col instanceof AgColumnGroup; } var AgColumnGroup = class extends BeanStub { constructor(providedColumnGroup, groupId, partId, pinned) { super(); this.providedColumnGroup = providedColumnGroup; this.groupId = groupId; this.partId = partId; this.pinned = pinned; this.isColumn = false; this.displayedChildren = []; this.autoHeaderHeight = null; this.parent = null; this.colIdSanitised = _escapeString(this.getUniqueId()); } reset() { this.parent = null; this.children = null; this.displayedChildren = null; } getParent() { return this.parent; } getUniqueId() { return createUniqueColumnGroupId(this.groupId, this.partId); } isEmptyGroup() { return this.displayedChildren.length === 0; } isMoving() { const allLeafColumns = this.getProvidedColumnGroup().getLeafColumns(); if (!allLeafColumns || allLeafColumns.length === 0) { return false; } return allLeafColumns.every((col) => col.isMoving()); } checkLeft() { for (const child of this.displayedChildren) { if (isColumnGroup(child)) { child.checkLeft(); } } if (this.displayedChildren.length > 0) { if (this.gos.get("enableRtl")) { const lastChild = _last(this.displayedChildren); const lastChildLeft = lastChild.getLeft(); this.setLeft(lastChildLeft); } else { const firstChildLeft = this.displayedChildren[0].getLeft(); this.setLeft(firstChildLeft); } } else { this.setLeft(null); } } getLeft() { return this.left; } getOldLeft() { return this.oldLeft; } setLeft(left) { this.oldLeft = this.left; if (this.left !== left) { this.left = left; this.dispatchLocalEvent({ type: "leftChanged" }); } } getPinned() { return this.pinned; } getGroupId() { return this.groupId; } getPartId() { return this.partId; } getActualWidth() { let groupActualWidth = 0; for (const child of this.displayedChildren ?? []) { groupActualWidth += child.getActualWidth(); } return groupActualWidth; } isResizable() { if (!this.displayedChildren) { return false; } let result = false; for (const child of this.displayedChildren) { if (child.isResizable()) { result = true; } } return result; } getMinWidth() { let result = 0; for (const groupChild of this.displayedChildren) { result += groupChild.getMinWidth(); } return result; } addChild(child) { if (!this.children) { this.children = []; } this.children.push(child); } getDisplayedChildren() { return this.displayedChildren; } getLeafColumns() { const result = []; this.addLeafColumns(result); return result; } getDisplayedLeafColumns() { const result = []; this.addDisplayedLeafColumns(result); return result; } getDefinition() { return this.providedColumnGroup.getColGroupDef(); } getColGroupDef() { return this.providedColumnGroup.getColGroupDef(); } isPadding() { return this.providedColumnGroup.isPadding(); } isExpandable() { return this.providedColumnGroup.isExpandable(); } isExpanded() { return this.providedColumnGroup.isExpanded(); } setExpanded(expanded) { this.providedColumnGroup.setExpanded(expanded); } isAutoHeaderHeight() { return !!this.getColGroupDef()?.autoHeaderHeight; } getAutoHeaderHeight() { return this.autoHeaderHeight; } setAutoHeaderHeight(height) { const changed = height !== this.autoHeaderHeight; this.autoHeaderHeight = height; return changed; } addDisplayedLeafColumns(leafColumns) { for (const child of this.displayedChildren ?? []) { if (isColumn(child)) { leafColumns.push(child); } else if (isColumnGroup(child)) { child.addDisplayedLeafColumns(leafColumns); } } } addLeafColumns(leafColumns) { for (const child of this.children ?? []) { if (isColumn(child)) { leafColumns.push(child); } else if (isColumnGroup(child)) { child.addLeafColumns(leafColumns); } } } getChildren() { return this.children; } getColumnGroupShow() { return this.providedColumnGroup.getColumnGroupShow(); } getProvidedColumnGroup() { return this.providedColumnGroup; } getPaddingLevel() { const parent = this.getParent(); if (!this.isPadding() || !parent?.isPadding()) { return 0; } return 1 + parent.getPaddingLevel(); } calculateDisplayedColumns() { this.displayedChildren = []; let parentWithExpansion = this; while (parentWithExpansion?.isPadding()) { parentWithExpansion = parentWithExpansion.getParent(); } const isExpandable = parentWithExpansion ? parentWithExpansion.getProvidedColumnGroup().isExpandable() : false; if (!isExpandable) { this.displayedChildren = this.children; this.dispatchLocalEvent({ type: "displayedChildrenChanged" }); return; } for (const child of this.children ?? []) { const emptyGroup = isColumnGroup(child) && !child.displayedChildren?.length; if (emptyGroup) { continue; } const headerGroupShow = child.getColumnGroupShow(); switch (headerGroupShow) { case "open": if (parentWithExpansion.getProvidedColumnGroup().isExpanded()) { this.displayedChildren.push(child); } break; case "closed": if (!parentWithExpansion.getProvidedColumnGroup().isExpanded()) { this.displayedChildren.push(child); } break; default: this.displayedChildren.push(child); break; } } this.dispatchLocalEvent({ type: "displayedChildrenChanged" }); } }; var KeyCode = { BACKSPACE: "Backspace", TAB: "Tab", ENTER: "Enter", ESCAPE: "Escape", SPACE: " ", LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", DOWN: "ArrowDown", DELETE: "Delete", F2: "F2", PAGE_UP: "PageUp", PAGE_DOWN: "PageDown", PAGE_HOME: "Home", PAGE_END: "End", A: "KeyA", C: "KeyC", D: "KeyD", V: "KeyV", X: "KeyX", Y: "KeyY", Z: "KeyZ" }; var A_KEYCODE = 65; var C_KEYCODE = 67; var V_KEYCODE = 86; var D_KEYCODE = 68; var Z_KEYCODE = 90; var Y_KEYCODE = 89; function _normaliseQwertyAzerty(keyboardEvent) { const { keyCode } = keyboardEvent; let code; switch (keyCode) { case A_KEYCODE: code = KeyCode.A; break; case C_KEYCODE: code = KeyCode.C; break; case V_KEYCODE: code = KeyCode.V; break; case D_KEYCODE: code = KeyCode.D; break; case Z_KEYCODE: code = KeyCode.Z; break; case Y_KEYCODE: code = KeyCode.Y; break; default: code = keyboardEvent.code; } return code; } function _isPromise(fn) { return typeof fn.then === "function"; } function _wrapInterval(action, timeout) { return new AgPromise((resolve) => { resolve(window.setInterval(action, timeout)); }); } var AgPromise = class _AgPromise { constructor(callback) { this.status = 0; this.resolution = null; this.waiters = []; callback((value) => this.onDone(value), (params) => this.onReject(params)); } static all(promises) { return promises.length ? new _AgPromise((resolve) => { let remainingToResolve = promises.length; const combinedValues = new Array(remainingToResolve); promises.forEach((promise, index) => { promise.then((value) => { combinedValues[index] = value; remainingToResolve--; if (remainingToResolve === 0) { resolve(combinedValues); } }); }); }) : _AgPromise.resolve(); } static resolve(value = null) { return new _AgPromise((resolve) => resolve(value)); } then(func) { return new _AgPromise((resolve) => { if (this.status === 1) { resolve(func(this.resolution)); } else { this.waiters.push((value) => resolve(func(value))); } }); } onDone(value) { this.status = 1; this.resolution = value; for (const waiter of this.waiters) { waiter(value); } } onReject(_) {} }; var BaseDragAndDropService = class extends AgBeanStub { constructor() { super(...arguments); this.beanName = "dragAndDrop"; this.dragSourceAndParamsList = []; this.dragItem = null; this.dragInitialSourcePointerOffsetX = 0; this.dragInitialSourcePointerOffsetY = 0; this.lastMouseEvent = null; this.lastDraggingEvent = null; this.dragSource = null; this.dragImageCompPromise = null; this.dragImageComp = null; this.dragImageLastIcon = undefined; this.dragImageLastLabel = undefined; this.dropTargets = []; this.externalDropZoneCount = 0; this.lastDropTarget = null; } addDragSource(dragSource, allowTouch = false) { const entry = { capturePointer: true, dragSource, eElement: dragSource.eElement, dragStartPixels: dragSource.dragStartPixels, onDragStart: (mouseEvent) => this.onDragStart(dragSource, mouseEvent), onDragStop: this.onDragStop.bind(this), onDragging: this.onDragging.bind(this), onDragCancel: this.onDragCancel.bind(this), includeTouch: allowTouch }; this.dragSourceAndParamsList.push(entry); this.beans.dragSvc.addDragSource(entry); } setDragImageCompIcon(iconName, shake = false) { const component = this.dragImageComp; if (component && (shake || this.dragImageLastIcon !== iconName)) { this.dragImageLastIcon = iconName; component.setIcon(iconName, shake); } } removeDragSource(dragSource) { const { dragSourceAndParamsList, beans } = this; for (let i = 0, len = dragSourceAndParamsList.length;i < len; i++) { if (dragSourceAndParamsList[i].dragSource === dragSource) { const sourceAndParams = dragSourceAndParamsList[i]; beans.dragSvc?.removeDragSource(sourceAndParams); dragSourceAndParamsList.splice(i, 1); break; } } } destroy() { const { dragSourceAndParamsList, dropTargets, beans } = this; const dragSvc = beans.dragSvc; for (const sourceAndParams of dragSourceAndParamsList) { dragSvc?.removeDragSource(sourceAndParams); } dragSourceAndParamsList.length = 0; dropTargets.length = 0; this.externalDropZoneCount = 0; this.clearDragAndDropProperties(); super.destroy(); } nudge() { const lastMouseEvent = this.lastMouseEvent; if (lastMouseEvent) { this.onDragging(lastMouseEvent, true); } } onDragStart(dragSource, mouseEvent) { this.lastMouseEvent = mouseEvent; this.dragSource = dragSource; this.dragItem = dragSource.getDragItem(); const rect = dragSource.eElement.getBoundingClientRect(); this.dragInitialSourcePointerOffsetX = mouseEvent.clientX - rect.left; this.dragInitialSourcePointerOffsetY = mouseEvent.clientY - rect.top; dragSource.onDragStarted?.(); this.createAndUpdateDragImageComp(dragSource); } onDragStop(mouseEvent) { const { dragSource, lastDropTarget } = this; dragSource?.onDragStopped?.(); if (lastDropTarget) { const dragEndEvent = this.dropTargetEvent(lastDropTarget, mouseEvent, false); lastDropTarget.onDragStop?.(dragEndEvent); } this.clearDragAndDropProperties(); } onDragCancel() { const { dragSource, lastDropTarget, lastMouseEvent } = this; dragSource?.onDragCancelled?.(); if (lastDropTarget && lastMouseEvent) { const dragCancelEvent = this.dropTargetEvent(lastDropTarget, lastMouseEvent, false); lastDropTarget.onDragCancel?.(dragCancelEvent); } this.clearDragAndDropProperties(); } onDragging(mouseEvent, fromNudge = false) { this.positionDragImageComp(mouseEvent); const dropTarget = this.findCurrentDropTarget(mouseEvent); const { lastDropTarget, dragSource, dragItem } = this; let needUpdate = false; if (dropTarget !== lastDropTarget) { needUpdate = true; if (lastDropTarget) { const dragLeaveEvent = this.dropTargetEvent(lastDropTarget, mouseEvent, fromNudge); lastDropTarget.onDragLeave?.(dragLeaveEvent); } if (lastDropTarget !== null && !dropTarget) { this.handleExit(dragSource, dragItem); } else if (lastDropTarget === null && dropTarget) { this.handleEnter(dragSource, dragItem); } if (dropTarget) { const dragEnterEvent = this.dropTargetEvent(dropTarget, mouseEvent, fromNudge); dropTarget.onDragEnter?.(dragEnterEvent); } this.lastDropTarget = dropTarget; } else if (dropTarget) { const dragMoveEvent = this.dropTargetEvent(dropTarget, mouseEvent, fromNudge); dropTarget.onDragging?.(dragMoveEvent); if (dragMoveEvent?.changed) { needUpdate = true; } } this.lastMouseEvent = mouseEvent; if (needUpdate) { this.updateDragImageComp(); } } clearDragAndDropProperties() { this.removeDragImageComp(this.dragImageComp); this.dragImageCompPromise = null; this.dragImageLastIcon = undefined; this.dragImageLastLabel = undefined; this.lastMouseEvent = null; this.lastDraggingEvent = null; this.lastDropTarget = null; this.dragItem = null; this.dragInitialSourcePointerOffsetX = 0; this.dragInitialSourcePointerOffsetY = 0; this.dragSource = null; } getAllContainersFromDropTarget(dropTarget) { const primaryContainer = dropTarget.getContainer(); const secondaryContainers = dropTarget.getSecondaryContainers?.(); const secondaryContainersLen = secondaryContainers?.length; if (!secondaryContainersLen) { return [[primaryContainer]]; } const containers = new Array(secondaryContainersLen + 1); containers[0] = [primaryContainer]; for (let i = 0;i < secondaryContainersLen; ++i) { containers[i + 1] = secondaryContainers[i]; } return containers; } isMouseOnDropTarget(mouseEvent, dropTarget) { const allContainersFromDropTarget = this.getAllContainersFromDropTarget(dropTarget); let mouseOverTarget = false; const allContainersIntersect = (mouseEvent2, containers) => { for (const container of containers) { const { width, height, left, right, top, bottom } = container.getBoundingClientRect(); if (width === 0 || height === 0) { return false; } const horizontalFit = mouseEvent2.clientX >= left && mouseEvent2.clientX < right; const verticalFit = mouseEvent2.clientY >= top && mouseEvent2.clientY < bottom; if (!horizontalFit || !verticalFit) { return false; } } return true; }; for (const currentContainers of allContainersFromDropTarget) { if (allContainersIntersect(mouseEvent, currentContainers)) { mouseOverTarget = true; break; } } const { eElement, type } = this.dragSource; if (dropTarget.targetContainsSource && !dropTarget.getContainer().contains(eElement)) { return false; } return mouseOverTarget && dropTarget.isInterestedIn(type, eElement); } findCurrentDropTarget(mouseEvent) { const validDropTargets = []; const dropTargets = this.dropTargets; for (let i = 0, len2 = dropTargets.length;i < len2; ++i) { const target = dropTargets[i]; if (this.isMouseOnDropTarget(mouseEvent, target)) { validDropTargets.push(target); } } const len = validDropTargets.length; if (len === 0) { return null; } if (len === 1) { return validDropTargets[0]; } const rootNode = _getRootNode(this.beans); const elementStack = rootNode.elementsFromPoint(mouseEvent.clientX, mouseEvent.clientY); for (let i = 0, stackLen = elementStack.length;i < stackLen; ++i) { const el = elementStack[i]; for (let targetIndex = 0, targetsLen = validDropTargets.length;targetIndex < targetsLen; targetIndex++) { const dropTarget = validDropTargets[targetIndex]; const containerGroups = this.getAllContainersFromDropTarget(dropTarget); let matched = false; for (let groupIdx = 0, groupLen = containerGroups.length;groupIdx < groupLen && !matched; groupIdx++) { const group = containerGroups[groupIdx]; for (let elIdx = 0, elLen = group.length;elIdx < elLen; elIdx++) { if (group[elIdx] === el) { matched = true; break; } } } if (matched) { return dropTarget; } } } return null; } addDropTarget(dropTarget) { this.dropTargets.push(dropTarget); if (dropTarget.external) { this.externalDropZoneCount++; } } removeDropTarget(dropTarget) { const container = dropTarget.getContainer(); const dropTargets = this.dropTargets; let writeIndex = 0; for (let readIndex = 0, len = dropTargets.length;readIndex < len; ++readIndex) { const target = dropTargets[readIndex]; if (target.getContainer() === container) { if (target.external) { --this.externalDropZoneCount; } continue; } if (writeIndex !== readIndex) { dropTargets[writeIndex] = target; } ++writeIndex; } dropTargets.length = writeIndex; } hasExternalDropZones() { return this.externalDropZoneCount > 0; } findExternalZone(container) { const dropTargets = this.dropTargets; for (let i = 0, len = dropTargets.length;i < len; ++i) { const zone = dropTargets[i]; if (zone.external && zone.getContainer() === container) { return zone; } } return null; } dropTargetEvent(dropTarget, mouseEvent, fromNudge) { const { dragSource, dragItem, lastDraggingEvent, lastMouseEvent, dragInitialSourcePointerOffsetX, dragInitialSourcePointerOffsetY } = this; const dropZoneTarget = dropTarget.getContainer(); const rect = dropZoneTarget.getBoundingClientRect(); const { clientX, clientY } = mouseEvent; const xDir = clientX - (lastMouseEvent?.clientX || 0); const yDir = clientY - (lastMouseEvent?.clientY || 0); const draggingEvent = this.createEvent({ event: mouseEvent, x: clientX - rect.left, y: clientY - rect.top, vDirection: yDir > 0 ? "down" : yDir < 0 ? "up" : null, hDirection: xDir < 0 ? "left" : xDir > 0 ? "right" : null, initialSourcePointerOffsetX: dragInitialSourcePointerOffsetX, initialSourcePointerOffsetY: dragInitialSourcePointerOffsetY, dragSource, fromNudge, dragItem, dropZoneTarget, dropTarget: lastDraggingEvent?.dropTarget ?? null, changed: !!lastDraggingEvent?.changed }); this.lastDraggingEvent = draggingEvent; return draggingEvent; } positionDragImageComp(event) { const gui = this.dragImageComp?.getGui(); if (gui) { _anchorElementToMouseMoveEvent(gui, event, this.beans); } } removeDragImageComp(comp) { if (this.dragImageComp === comp) { this.dragImageComp = null; } if (comp) { comp.getGui()?.remove(); this.destroyBean(comp); } } createAndUpdateDragImageComp(dragSource) { const promise = this.createDragImageComp(dragSource) ?? null; this.dragImageCompPromise = promise; promise?.then((dragImageComp) => { const lastMouseEvent = this.lastMouseEvent; if (promise !== this.dragImageCompPromise || !lastMouseEvent || !this.isAlive()) { this.destroyBean(dragImageComp); return; } this.dragImageCompPromise = null; this.dragImageLastIcon = undefined; this.dragImageLastLabel = undefined; const oldDragImageComp = this.dragImageComp; if (oldDragImageComp !== dragImageComp) { this.dragImageComp = dragImageComp; this.removeDragImageComp(oldDragImageComp); } if (dragImageComp) { this.appendDragImageComp(dragImageComp); this.updateDragImageComp(); this.positionDragImageComp(lastMouseEvent); } }); } appendDragImageComp(component) { const eGui = component.getGui(); const style = eGui.style; style.position = "absolute"; style.zIndex = "9999"; if (this.beans.dragSvc?.hasPointerCapture()) { style.pointerEvents = "none"; } this.gos.setInstanceDomData(eGui); this.beans.environment.applyThemeClasses(eGui); style.top = "20px"; style.left = "20px"; const targetEl = _getPageBody(this.beans); if (!targetEl) { this.warnNoBody(); } else { targetEl.appendChild(eGui); } } updateDragImageComp() { const { dragImageComp, dragSource, lastDropTarget, lastDraggingEvent, dragImageLastLabel } = this; if (!dragImageComp) { return; } this.setDragImageCompIcon(lastDropTarget?.getIconName?.(lastDraggingEvent) ?? null); let label = dragSource?.dragItemName; if (typeof label === "function") { label = label(lastDraggingEvent); } label || (label = ""); if (dragImageLastLabel !== label) { this.dragImageLastLabel = label; dragImageComp.setLabel(label); } } }; function isColumnFilterComp(filter) { return typeof filter === "object" && !!filter.component; } function doesImplementIComponent(candidate) { if (!candidate) { return false; } return candidate.prototype && "getGui" in candidate.prototype; } function _getUserCompKeys(frameworkOverrides, defObject, type, params) { const { name } = type; let compName; let jsComp; let fwComp; let paramsFromSelector; let popupFromSelector; let popupPositionFromSelector; if (defObject) { const defObjectAny = defObject; const selectorFunc = defObjectAny[name + "Selector"]; const selectorRes = selectorFunc ? selectorFunc(params) : null; const assignComp = (providedJsComp) => { if (typeof providedJsComp === "string") { compName = providedJsComp; } else if (providedJsComp != null && providedJsComp !== true) { const isFwkComp = frameworkOverrides.isFrameworkComponent(providedJsComp); if (isFwkComp) { fwComp = providedJsComp; } else { jsComp = providedJsComp; } } }; if (selectorRes) { assignComp(selectorRes.component); paramsFromSelector = selectorRes.params; popupFromSelector = selectorRes.popup; popupPositionFromSelector = selectorRes.popupPosition; } else { assignComp(defObjectAny[name]); } } return { compName, jsComp, fwComp, paramsFromSelector, popupFromSelector, popupPositionFromSelector }; } var UserComponentFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "userCompFactory"; } wireBeans(beans) { this.agCompUtils = beans.agCompUtils; this.registry = beans.registry; this.frameworkCompWrapper = beans.frameworkCompWrapper; this.gridOptions = beans.gridOptions; } getCompDetailsFromGridOptions(type, defaultName, params, mandatory = false) { return this.getCompDetails(this.gridOptions, type, defaultName, params, mandatory); } getCompDetails(defObject, type, defaultName, params, mandatory = false) { const { name, cellRenderer } = type; let { compName, jsComp, fwComp, paramsFromSelector, popupFromSelector, popupPositionFromSelector } = _getUserCompKeys(this.beans.frameworkOverrides, defObject, type, params); let defaultCompParams; let defaultCompProcessParams; const lookupFromRegistry = (key) => { const item = this.registry.getUserComponent(name, key); if (item) { jsComp = !item.componentFromFramework ? item.component : undefined; fwComp = item.componentFromFramework ? item.component : undefined; defaultCompParams = item.params; defaultCompProcessParams = item.processParams; } }; if (compName != null) { lookupFromRegistry(compName); } if (jsComp == null && fwComp == null && defaultName != null) { lookupFromRegistry(defaultName); } if (jsComp && cellRenderer && !doesImplementIComponent(jsComp)) { jsComp = this.agCompUtils?.adaptFunction(type, jsComp); } if (!jsComp && !fwComp) { const { validation } = this.beans; if (mandatory && (compName !== defaultName || !defaultName)) { if (compName) { if (!validation?.isProvidedUserComp(compName)) { _error(50, { compName }); } } else if (defaultName) { if (!validation) { _error(260, { ...this.gos.getModuleErrorParams(), propName: name, compName: defaultName }); } } else { _error(216, { name }); } } else if (defaultName && !validation) { _error(146, { comp: defaultName }); } return; } const paramsMerged = this.mergeParams(defObject, type, params, paramsFromSelector, defaultCompParams, defaultCompProcessParams); const componentFromFramework = jsComp == null; const componentClass = jsComp ?? fwComp; return { componentFromFramework, componentClass, params: paramsMerged, type, popupFromSelector, popupPositionFromSelector, newAgStackInstance: () => this.newAgStackInstance(componentClass, componentFromFramework, paramsMerged, type) }; } newAgStackInstance(ComponentClass, componentFromFramework, params, type) { const jsComponent = !componentFromFramework; let instance; if (jsComponent) { instance = new ComponentClass; } else { instance = this.frameworkCompWrapper.wrap(ComponentClass, type.mandatoryMethods, type.optionalMethods, type); } this.createBean(instance); const deferredInit = instance.init?.(params); if (deferredInit == null) { return AgPromise.resolve(instance); } return deferredInit.then(() => instance); } mergeParams(defObject, type, paramsFromGrid, paramsFromSelector = null, defaultCompParams, defaultCompProcessParams) { const params = { ...paramsFromGrid, ...defaultCompParams }; const defObjectAny = defObject; const userParams = defObjectAny?.[type.name + "Params"]; if (typeof userParams === "function") { const userParamsFromFunc = userParams(paramsFromGrid); _mergeDeep(params, userParamsFromFunc); } else if (typeof userParams === "object") { _mergeDeep(params, userParams); } _mergeDeep(params, paramsFromSelector); return defaultCompProcessParams ? defaultCompProcessParams(params) : params; } }; var DateComponent = { name: "dateComponent", mandatoryMethods: ["getDate", "setDate"], optionalMethods: ["afterGuiAttached", "setInputPlaceholder", "setInputAriaLabel", "setDisabled", "refresh"] }; var DragAndDropImageComponent = { name: "dragAndDropImageComponent", mandatoryMethods: ["setIcon", "setLabel"] }; var HeaderComponent = { name: "headerComponent", optionalMethods: ["refresh"] }; var InnerHeaderComponent = { name: "innerHeaderComponent" }; var InnerHeaderGroupComponent = { name: "innerHeaderGroupComponent" }; var HeaderGroupComponent = { name: "headerGroupComponent" }; var InnerCellRendererComponent = { name: "innerRenderer", cellRenderer: true, optionalMethods: ["afterGuiAttached"] }; var CellRendererComponent = { name: "cellRenderer", optionalMethods: ["refresh", "afterGuiAttached"], cellRenderer: true }; var LoadingCellRendererComponent = { name: "loadingCellRenderer", cellRenderer: true }; var CellEditorComponent = { name: "cellEditor", mandatoryMethods: ["getValue"], optionalMethods: [ "isPopup", "isCancelBeforeStart", "isCancelAfterEnd", "getPopupPosition", "focusIn", "focusOut", "afterGuiAttached", "refresh" ] }; var TooltipComponent = { name: "tooltipComponent" }; var FilterComponent = { name: "filter", mandatoryMethods: ["isFilterActive", "doesFilterPass", "getModel", "setModel"], optionalMethods: [ "afterGuiAttached", "afterGuiDetached", "onNewRowsLoaded", "getModelAsString", "onFloatingFilterChanged", "onAnyFilterChanged", "refresh" ] }; var FloatingFilterComponent = { name: "floatingFilterComponent", mandatoryMethods: ["onParentModelChanged"], optionalMethods: ["afterGuiAttached", "refresh"] }; var FullWidth = { name: "fullWidthCellRenderer", optionalMethods: ["refresh", "afterGuiAttached"], cellRenderer: true }; var FullWidthLoading = { name: "loadingCellRenderer", cellRenderer: true }; var FullWidthGroup = { name: "groupRowRenderer", optionalMethods: ["afterGuiAttached"], cellRenderer: true }; var FullWidthDetail = { name: "detailCellRenderer", optionalMethods: ["refresh"], cellRenderer: true }; function _getDragAndDropImageCompDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(DragAndDropImageComponent, "agDragAndDropImage", params, true); } function _getInnerCellRendererDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, InnerCellRendererComponent, undefined, params); } function _getHeaderCompDetails(userCompFactory, colDef, params) { return userCompFactory.getCompDetails(colDef, HeaderComponent, "agColumnHeader", params); } function _getInnerHeaderCompDetails(userCompFactory, headerCompParams, params) { return userCompFactory.getCompDetails(headerCompParams, InnerHeaderComponent, undefined, params); } function _getHeaderGroupCompDetails(userCompFactory, params) { const colGroupDef = params.columnGroup.getColGroupDef(); return userCompFactory.getCompDetails(colGroupDef, HeaderGroupComponent, "agColumnGroupHeader", params); } function _getInnerHeaderGroupCompDetails(userCompFactory, headerGroupCompParams, params) { return userCompFactory.getCompDetails(headerGroupCompParams, InnerHeaderGroupComponent, undefined, params); } function _getFullWidthCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidth, undefined, params, true); } function _getFullWidthLoadingCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidthLoading, "agLoadingCellRenderer", params, true); } function _getFullWidthGroupCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidthGroup, "agGroupRowRenderer", params, true); } function _getFullWidthDetailCellRendererDetails(userCompFactory, params) { return userCompFactory.getCompDetailsFromGridOptions(FullWidthDetail, "agDetailCellRenderer", params, true); } function _getCellRendererDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, CellRendererComponent, undefined, params); } function _getLoadingCellRendererDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, LoadingCellRendererComponent, "agSkeletonCellRenderer", params, true); } function _getCellEditorDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, CellEditorComponent, "agCellEditor", params, true); } function _getFilterDetails(userCompFactory, def, params, defaultFilter) { const filter = def.filter; if (isColumnFilterComp(filter)) { def = { filter: filter.component, filterParams: def.filterParams }; } return userCompFactory.getCompDetails(def, FilterComponent, defaultFilter, params, true); } function _getDateCompDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, DateComponent, "agDateInput", params, true); } function _getTooltipCompDetails(userCompFactory, params) { return userCompFactory.getCompDetails(params.colDef, TooltipComponent, "agTooltipComponent", params, true); } function _getFloatingFilterCompDetails(userCompFactory, def, params, defaultFloatingFilter) { return userCompFactory.getCompDetails(def, FloatingFilterComponent, defaultFloatingFilter, params); } function _getFilterCompKeys(frameworkOverrides, def) { return _getUserCompKeys(frameworkOverrides, def, FilterComponent); } function _mergeFilterParamsWithApplicationProvidedParams(userCompFactory, defObject, paramsFromGrid) { return userCompFactory.mergeParams(defObject, FilterComponent, paramsFromGrid); } var DragSourceType = /* @__PURE__ */ ((DragSourceType2) => { DragSourceType2[DragSourceType2["ToolPanel"] = 0] = "ToolPanel"; DragSourceType2[DragSourceType2["HeaderCell"] = 1] = "HeaderCell"; DragSourceType2[DragSourceType2["RowDrag"] = 2] = "RowDrag"; DragSourceType2[DragSourceType2["ChartPanel"] = 3] = "ChartPanel"; DragSourceType2[DragSourceType2["AdvancedFilterBuilder"] = 4] = "AdvancedFilterBuilder"; return DragSourceType2; })(DragSourceType || {}); var DragAndDropService = class extends BaseDragAndDropService { createEvent(event) { return _addGridCommonParams(this.gos, event); } createDragImageComp(dragSource) { const { gos, beans } = this; const userCompDetails = _getDragAndDropImageCompDetails(beans.userCompFactory, _addGridCommonParams(gos, { dragSource })); return userCompDetails?.newAgStackInstance(); } handleEnter(dragSource, dragItem) { dragSource?.onGridEnter?.(dragItem); } handleExit(dragSource, dragItem) { dragSource?.onGridExit?.(dragItem); } warnNoBody() { _warn(54); } isDropZoneWithinThisGrid(draggingEvent) { return this.beans.ctrlsSvc.getGridBodyCtrl().eGridBody.contains(draggingEvent.dropZoneTarget); } registerGridDropTarget(elementFn, ctrl) { const dropTarget = { getContainer: elementFn, isInterestedIn: (type) => type === 1 || type === 0, getIconName: () => "notAllowed" }; this.addDropTarget(dropTarget); ctrl.addDestroyFunc(() => this.removeDropTarget(dropTarget)); } }; function isCombinedFilterModel(model) { return !!model.operator; } var RESIZE_CONTAINER_STYLE = "ag-resizer-wrapper"; var makeDiv = (dataRefPrefix, classSuffix) => ({ tag: "div", ref: `${dataRefPrefix}Resizer`, cls: `ag-resizer ag-resizer-${classSuffix}` }); var RESIZE_TEMPLATE = { tag: "div", cls: RESIZE_CONTAINER_STYLE, children: [ makeDiv("eTopLeft", "topLeft"), makeDiv("eTop", "top"), makeDiv("eTopRight", "topRight"), makeDiv("eRight", "right"), makeDiv("eBottomRight", "bottomRight"), makeDiv("eBottom", "bottom"), makeDiv("eBottomLeft", "bottomLeft"), makeDiv("eLeft", "left") ] }; var AgPositionableFeature = class extends AgBeanStub { constructor(element, config) { super(); this.element = element; this.dragStartPosition = { x: 0, y: 0 }; this.position = { x: 0, y: 0 }; this.lastSize = { width: -1, height: -1 }; this.positioned = false; this.resizersAdded = false; this.resizeListeners = []; this.boundaryEl = null; this.isResizing = false; this.isMoving = false; this.resizable = {}; this.movable = false; this.currentResizer = null; this.config = { popup: false, ...config }; } wireBeans(beans) { this.popupSvc = beans.popupSvc; this.dragSvc = beans.dragSvc; } center(postProcessCallback) { const { clientHeight, clientWidth } = this.offsetParent; const x = clientWidth / 2 - this.getWidth() / 2; const y = clientHeight / 2 - this.getHeight() / 2; this.offsetElement(x, y, postProcessCallback); } initialisePosition(postProcessCallback) { if (this.positioned) { return; } const { centered, forcePopupParentAsOffsetParent, minWidth, width, minHeight, height, x, y } = this.config; if (!this.offsetParent) { this.setOffsetParent(); } let computedMinHeight = 0; let computedMinWidth = 0; const isElementVisible = _isVisible(this.element); if (isElementVisible) { const boundaryEl = this.findBoundaryElement(); const offsetParentComputedStyles = window.getComputedStyle(boundaryEl); if (offsetParentComputedStyles.minWidth != null) { const paddingWidth = boundaryEl.offsetWidth - this.element.offsetWidth; computedMinWidth = Number.parseInt(offsetParentComputedStyles.minWidth, 10) - paddingWidth; } if (offsetParentComputedStyles.minHeight != null) { const paddingHeight = boundaryEl.offsetHeight - this.element.offsetHeight; computedMinHeight = Number.parseInt(offsetParentComputedStyles.minHeight, 10) - paddingHeight; } } this.minHeight = minHeight || computedMinHeight; this.minWidth = minWidth || computedMinWidth; if (width) { this.setWidth(width); } if (height) { this.setHeight(height); } if (!width || !height) { this.refreshSize(); } if (centered) { this.center(postProcessCallback); } else if (x || y) { this.offsetElement(x, y, postProcessCallback); } else if (isElementVisible && forcePopupParentAsOffsetParent) { let boundaryEl = this.boundaryEl; let initialisedDuringPositioning = true; if (!boundaryEl) { boundaryEl = this.findBoundaryElement(); initialisedDuringPositioning = false; } if (boundaryEl) { const top = Number.parseFloat(boundaryEl.style.top); const left = Number.parseFloat(boundaryEl.style.left); if (initialisedDuringPositioning) { this.offsetElement(Number.isNaN(left) ? 0 : left, Number.isNaN(top) ? 0 : top, postProcessCallback); } else { this.setPosition(left, top); } } } this.positioned = !!this.offsetParent; } isPositioned() { return this.positioned; } getPosition() { return this.position; } setMovable(movable, moveElement) { if (!this.config.popup || movable === this.movable) { return; } this.movable = movable; const params = this.moveElementDragListener || { eElement: moveElement, onDragStart: this.onMoveStart.bind(this), onDragging: this.onMove.bind(this), onDragStop: this.onMoveEnd.bind(this) }; if (movable) { this.dragSvc?.addDragSource(params); this.moveElementDragListener = params; } else { this.dragSvc?.removeDragSource(params); this.moveElementDragListener = undefined; } } setResizable(resizable) { this.clearResizeListeners(); if (resizable) { this.addResizers(); } else { this.removeResizers(); } if (typeof resizable === "boolean") { if (resizable === false) { return; } resizable = { topLeft: resizable, top: resizable, topRight: resizable, right: resizable, bottomRight: resizable, bottom: resizable, bottomLeft: resizable, left: resizable }; } for (const side of Object.keys(resizable)) { const isSideResizable = !!resizable[side]; const resizerEl = this.getResizerElement(side); const params = { dragStartPixels: 0, eElement: resizerEl, onDragStart: (e) => this.onResizeStart(e, side), onDragging: this.onResize.bind(this), onDragStop: (e) => this.onResizeEnd(e, side) }; if (isSideResizable || !this.isAlive() && !isSideResizable) { if (isSideResizable) { this.dragSvc?.addDragSource(params); this.resizeListeners.push(params); resizerEl.style.pointerEvents = "all"; } else { resizerEl.style.pointerEvents = "none"; } this.resizable[side] = isSideResizable; } } } removeSizeFromEl() { this.element.style.removeProperty("height"); this.element.style.removeProperty("width"); this.element.style.removeProperty("flex"); } restoreLastSize() { this.element.style.flex = "0 0 auto"; const { height, width } = this.lastSize; if (width !== -1) { this.element.style.width = `${width}px`; } if (height !== -1) { this.element.style.height = `${height}px`; } } getHeight() { return this.element.offsetHeight; } setHeight(height) { const { popup } = this.config; const eGui = this.element; let isPercent = false; if (typeof height === "string" && height.includes("%")) { _setFixedHeight(eGui, height); height = _getAbsoluteHeight(eGui); isPercent = true; } else { height = Math.max(this.minHeight, height); if (this.positioned) { const availableHeight = this.getAvailableHeight(); if (availableHeight && height > availableHeight) { height = availableHeight; } } } if (this.getHeight() === height) { return; } if (isPercent) { eGui.style.maxHeight = "unset"; eGui.style.minHeight = "unset"; } else if (popup) { _setFixedHeight(eGui, height); } else { eGui.style.height = `${height}px`; eGui.style.flex = "0 0 auto"; this.lastSize.height = typeof height === "number" ? height : Number.parseFloat(height); } } getAvailableHeight() { const { popup, forcePopupParentAsOffsetParent } = this.config; if (!this.positioned) { this.initialisePosition(); } const { clientHeight } = this.offsetParent; if (!clientHeight) { return null; } const elRect = this.element.getBoundingClientRect(); const offsetParentRect = this.offsetParent.getBoundingClientRect(); const yPosition = popup ? this.position.y : elRect.top; const parentTop = popup ? 0 : offsetParentRect.top; let additionalHeight = 0; if (forcePopupParentAsOffsetParent) { const parentEl = this.element.parentElement; if (parentEl) { const { bottom } = parentEl.getBoundingClientRect(); additionalHeight = bottom - elRect.bottom; } } const availableHeight = clientHeight + parentTop - yPosition - additionalHeight; return availableHeight; } getWidth() { return this.element.offsetWidth; } setWidth(width) { const eGui = this.element; const { popup } = this.config; let isPercent = false; if (typeof width === "string" && width.includes("%")) { _setFixedWidth(eGui, width); width = _getAbsoluteWidth(eGui); isPercent = true; } else if (this.positioned) { width = Math.max(this.minWidth, width); const { clientWidth } = this.offsetParent; const xPosition = popup ? this.position.x : this.element.getBoundingClientRect().left; if (clientWidth && width + xPosition > clientWidth) { width = clientWidth - xPosition; } } if (this.getWidth() === width) { return; } if (isPercent) { eGui.style.maxWidth = "unset"; eGui.style.minWidth = "unset"; } else if (this.config.popup) { _setFixedWidth(eGui, width); } else { eGui.style.width = `${width}px`; eGui.style.flex = " unset"; this.lastSize.width = typeof width === "number" ? width : Number.parseFloat(width); } } offsetElement(x = 0, y = 0, postProcessCallback) { const { forcePopupParentAsOffsetParent } = this.config; const ePopup = forcePopupParentAsOffsetParent ? this.boundaryEl : this.element; if (!ePopup) { return; } this.popupSvc?.positionPopup({ ePopup, keepWithinBounds: true, skipObserver: this.movable || this.isResizable(), updatePosition: () => ({ x, y }), postProcessCallback }); this.setPosition(Number.parseFloat(ePopup.style.left), Number.parseFloat(ePopup.style.top)); } constrainSizeToAvailableHeight(constrain) { if (!this.config.forcePopupParentAsOffsetParent) { return; } const applyMaxHeightToElement = () => { const availableHeight = this.getAvailableHeight(); this.element.style.setProperty("max-height", `${availableHeight}px`); }; if (constrain && this.popupSvc) { this.resizeObserverSubscriber?.(); this.resizeObserverSubscriber = _observeResize(this.beans, this.popupSvc?.getPopupParent(), applyMaxHeightToElement); } else { this.element.style.removeProperty("max-height"); if (this.resizeObserverSubscriber) { this.resizeObserverSubscriber(); this.resizeObserverSubscriber = undefined; } } } setPosition(x, y) { this.position.x = x; this.position.y = y; } updateDragStartPosition(x, y) { this.dragStartPosition = { x, y }; } calculateMouseMovement(params) { const { e, isLeft, isTop, anywhereWithin, topBuffer } = params; const xDiff = e.clientX - this.dragStartPosition.x; const yDiff = e.clientY - this.dragStartPosition.y; const movementX = this.shouldSkipX(e, !!isLeft, !!anywhereWithin, xDiff) ? 0 : xDiff; const movementY = this.shouldSkipY(e, !!isTop, topBuffer, yDiff) ? 0 : yDiff; return { movementX, movementY }; } shouldSkipX(e, isLeft, anywhereWithin, diff) { const elRect = this.element.getBoundingClientRect(); const parentRect = this.offsetParent.getBoundingClientRect(); const boundaryElRect = this.boundaryEl.getBoundingClientRect(); const xPosition = this.config.popup ? this.position.x : elRect.left; let skipX = xPosition <= 0 && parentRect.left >= e.clientX || parentRect.right <= e.clientX && parentRect.right <= boundaryElRect.right; if (skipX) { return true; } if (isLeft) { skipX = diff < 0 && e.clientX > xPosition + parentRect.left || diff > 0 && e.clientX < xPosition + parentRect.left; } else if (anywhereWithin) { skipX = diff < 0 && e.clientX > boundaryElRect.right || diff > 0 && e.clientX < xPosition + parentRect.left; } else { skipX = diff < 0 && e.clientX > boundaryElRect.right || diff > 0 && e.clientX < boundaryElRect.right; } return skipX; } shouldSkipY(e, isTop, topBuffer = 0, diff) { const elRect = this.element.getBoundingClientRect(); const parentRect = this.offsetParent.getBoundingClientRect(); const boundaryElRect = this.boundaryEl.getBoundingClientRect(); const yPosition = this.config.popup ? this.position.y : elRect.top; let skipY = yPosition <= 0 && parentRect.top >= e.clientY || parentRect.bottom <= e.clientY && parentRect.bottom <= boundaryElRect.bottom; if (skipY) { return true; } if (isTop) { skipY = diff < 0 && e.clientY > yPosition + parentRect.top + topBuffer || diff > 0 && e.clientY < yPosition + parentRect.top; } else { skipY = diff < 0 && e.clientY > boundaryElRect.bottom || diff > 0 && e.clientY < boundaryElRect.bottom; } return skipY; } createResizeMap() { const getElement2 = (ref) => ({ element: this.element.querySelector(`[data-ref=${ref}Resizer]`) }); this.resizerMap = { topLeft: getElement2("eTopLeft"), top: getElement2("eTop"), topRight: getElement2("eTopRight"), right: getElement2("eRight"), bottomRight: getElement2("eBottomRight"), bottom: getElement2("eBottom"), bottomLeft: getElement2("eBottomLeft"), left: getElement2("eLeft") }; } addResizers() { if (this.resizersAdded) { return; } const eGui = this.element; if (!eGui) { return; } eGui.appendChild(_createAgElement(RESIZE_TEMPLATE)); this.createResizeMap(); this.resizersAdded = true; } removeResizers() { this.resizerMap = undefined; const resizerEl = this.element.querySelector(`.${RESIZE_CONTAINER_STYLE}`); resizerEl?.remove(); this.resizersAdded = false; } getResizerElement(side) { return this.resizerMap[side].element; } onResizeStart(e, side) { this.boundaryEl = this.findBoundaryElement(); if (!this.positioned) { this.initialisePosition(); } this.currentResizer = { isTop: !!side.match(/top/i), isRight: !!side.match(/right/i), isBottom: !!side.match(/bottom/i), isLeft: !!side.match(/left/i) }; this.element.classList.add("ag-resizing"); this.resizerMap[side].element.classList.add("ag-active"); const { popup, forcePopupParentAsOffsetParent } = this.config; if (!popup && !forcePopupParentAsOffsetParent) { this.applySizeToSiblings(this.currentResizer.isBottom || this.currentResizer.isTop); } this.isResizing = true; this.updateDragStartPosition(e.clientX, e.clientY); } getSiblings() { const element = this.element; const parent = element.parentElement; if (!parent) { return null; } return Array.prototype.slice.call(parent.children).filter((el) => !el.classList.contains("ag-hidden")); } getMinSizeOfSiblings() { const siblings = this.getSiblings() || []; let height = 0; let width = 0; for (const currentEl of siblings) { const isFlex = !!currentEl.style.flex && currentEl.style.flex !== "0 0 auto"; if (currentEl === this.element) { continue; } let nextHeight = this.minHeight || 0; let nextWidth = this.minWidth || 0; if (isFlex) { const computedStyle = window.getComputedStyle(currentEl); if (computedStyle.minHeight) { nextHeight = Number.parseInt(computedStyle.minHeight, 10); } if (computedStyle.minWidth) { nextWidth = Number.parseInt(computedStyle.minWidth, 10); } } else { nextHeight = currentEl.offsetHeight; nextWidth = currentEl.offsetWidth; } height += nextHeight; width += nextWidth; } return { height, width }; } applySizeToSiblings(vertical) { let containerToFlex = null; const siblings = this.getSiblings(); if (!siblings) { return; } for (let i = 0;i < siblings.length; i++) { const el = siblings[i]; if (el === containerToFlex) { continue; } if (vertical) { el.style.height = `${el.offsetHeight}px`; } else { el.style.width = `${el.offsetWidth}px`; } el.style.flex = "0 0 auto"; if (el === this.element) { containerToFlex = siblings[i + 1]; } } if (containerToFlex) { containerToFlex.style.removeProperty("height"); containerToFlex.style.removeProperty("min-height"); containerToFlex.style.removeProperty("max-height"); containerToFlex.style.flex = "1 1 auto"; } } isResizable() { return Object.values(this.resizable).some((value) => value); } onResize(e) { if (!this.isResizing || !this.currentResizer) { return; } const { popup, forcePopupParentAsOffsetParent } = this.config; const { isTop, isRight, isBottom, isLeft } = this.currentResizer; const isHorizontal = isRight || isLeft; const isVertical = isBottom || isTop; const { movementX, movementY } = this.calculateMouseMovement({ e, isLeft, isTop }); const xPosition = this.position.x; const yPosition = this.position.y; let offsetLeft = 0; let offsetTop = 0; if (isHorizontal && movementX) { const direction = isLeft ? -1 : 1; const oldWidth = this.getWidth(); const newWidth = oldWidth + movementX * direction; let skipWidth = false; if (isLeft) { offsetLeft = oldWidth - newWidth; if (xPosition + offsetLeft <= 0 || newWidth <= this.minWidth) { skipWidth = true; offsetLeft = 0; } } if (!skipWidth) { this.setWidth(newWidth); } } if (isVertical && movementY) { const direction = isTop ? -1 : 1; const oldHeight = this.getHeight(); const newHeight = oldHeight + movementY * direction; let skipHeight = false; if (isTop) { offsetTop = oldHeight - newHeight; if (yPosition + offsetTop <= 0 || newHeight <= this.minHeight) { skipHeight = true; offsetTop = 0; } } else if (!this.config.popup && !this.config.forcePopupParentAsOffsetParent && oldHeight < newHeight && this.getMinSizeOfSiblings().height + newHeight > this.element.parentElement.offsetHeight) { skipHeight = true; } if (!skipHeight) { this.setHeight(newHeight); } } this.updateDragStartPosition(e.clientX, e.clientY); if ((popup || forcePopupParentAsOffsetParent) && offsetLeft || offsetTop) { this.offsetElement(xPosition + offsetLeft, yPosition + offsetTop); } } onResizeEnd(e, side) { this.isResizing = false; this.currentResizer = null; this.boundaryEl = null; this.element.classList.remove("ag-resizing"); this.resizerMap[side].element.classList.remove("ag-active"); this.dispatchLocalEvent({ type: "resize" }); } refreshSize() { const eGui = this.element; if (this.config.popup) { if (!this.config.width) { this.setWidth(eGui.offsetWidth); } if (!this.config.height) { this.setHeight(eGui.offsetHeight); } } } onMoveStart(e) { this.boundaryEl = this.findBoundaryElement(); if (!this.positioned) { this.initialisePosition(); } this.isMoving = true; this.element.classList.add("ag-moving"); this.updateDragStartPosition(e.clientX, e.clientY); } onMove(e) { if (!this.isMoving) { return; } const { x, y } = this.position; let topBuffer; if (this.config.calculateTopBuffer) { topBuffer = this.config.calculateTopBuffer(); } const { movementX, movementY } = this.calculateMouseMovement({ e, isTop: true, anywhereWithin: true, topBuffer }); this.offsetElement(x + movementX, y + movementY); this.updateDragStartPosition(e.clientX, e.clientY); } onMoveEnd() { this.isMoving = false; this.boundaryEl = null; this.element.classList.remove("ag-moving"); } setOffsetParent() { if (this.config.forcePopupParentAsOffsetParent && this.popupSvc) { this.offsetParent = this.popupSvc.getPopupParent(); } else { this.offsetParent = this.element.offsetParent; } } findBoundaryElement() { let el = this.element; while (el) { if (window.getComputedStyle(el).position !== "static") { return el; } el = el.parentElement; } return this.element; } clearResizeListeners() { while (this.resizeListeners.length) { const params = this.resizeListeners.pop(); this.dragSvc?.removeDragSource(params); } } destroy() { super.destroy(); if (this.moveElementDragListener) { this.dragSvc?.removeDragSource(this.moveElementDragListener); } this.constrainSizeToAvailableHeight(false); this.clearResizeListeners(); this.removeResizers(); } }; var PositionableFeature = class extends AgPositionableFeature { }; var RefPlaceholder = null; function _isComponent(item) { return typeof item?.getGui === "function"; } var CssClassManager = class { constructor(getGui) { this.cssClassStates = {}; this.getGui = getGui; } toggleCss(className, addOrRemove) { if (!className) { return; } if (className.includes(" ")) { const list = (className || "").split(" "); if (list.length > 1) { for (const cls of list) { this.toggleCss(cls, addOrRemove); } return; } } const updateNeeded = this.cssClassStates[className] !== addOrRemove; if (updateNeeded && className.length) { this.getGui()?.classList.toggle(className, addOrRemove); this.cssClassStates[className] = addOrRemove; } } }; var compIdSequence = 0; var AgComponentStub = class extends AgBeanStub { constructor(templateOrParams, componentSelectors) { super(); this.suppressDataRefValidation = false; this.displayed = true; this.visible = true; this.compId = compIdSequence++; this.cssManager = new CssClassManager(() => this.eGui); this.componentSelectors = new Map((componentSelectors ?? []).map((comp) => [comp.selector, comp])); if (templateOrParams) { this.setTemplate(templateOrParams); } } preConstruct() { this.wireTemplate(this.getGui()); this.addGlobalCss(); } wireTemplate(element, paramsMap) { if (element && this.gos) { this.applyElementsToComponent(element); this.createChildComponentsFromTags(element, paramsMap); } } getCompId() { return this.compId; } getDataRefAttribute(element) { if (element.getAttribute) { return element.getAttribute(DataRefAttribute); } return null; } applyElementsToComponent(element, elementRef, paramsMap, newComponent = null) { if (elementRef === undefined) { elementRef = this.getDataRefAttribute(element); } if (elementRef) { const current = this[elementRef]; if (current === RefPlaceholder) { this[elementRef] = newComponent ?? element; } else { const usedAsParamRef = paramsMap?.[elementRef]; if (!this.suppressDataRefValidation && !usedAsParamRef) { throw new Error(`data-ref: ${elementRef} on ${this.constructor.name} with ${current}`); } } } } createChildComponentsFromTags(parentNode, paramsMap) { const childNodeList = []; for (const childNode of parentNode.childNodes ?? []) { childNodeList.push(childNode); } for (const childNode of childNodeList) { if (!(childNode instanceof HTMLElement)) { continue; } const childComp = this.createComponentFromElement(childNode, (childComp2) => { const childGui = childComp2.getGui(); if (childGui) { for (const attr of childNode.attributes ?? []) { childGui.setAttribute(attr.name, attr.value); } } }, paramsMap); if (childComp) { if (childComp.addItems && childNode.children.length) { this.createChildComponentsFromTags(childNode, paramsMap); const items = Array.prototype.slice.call(childNode.children); childComp.addItems(items); } this.swapComponentForNode(childComp, parentNode, childNode); } else if (childNode.childNodes) { this.createChildComponentsFromTags(childNode, paramsMap); } } } createComponentFromElement(element, afterPreCreateCallback, paramsMap) { const key = element.nodeName; const elementRef = this.getDataRefAttribute(element); const isAgGridComponent = key.indexOf("AG-") === 0; const componentSelector = isAgGridComponent ? this.componentSelectors.get(key) : null; let newComponent = null; if (componentSelector) { const componentParams = paramsMap && elementRef ? paramsMap[elementRef] : undefined; newComponent = new componentSelector.component(componentParams); newComponent.setParentComponent(this); this.createBean(newComponent, null, afterPreCreateCallback); } else if (isAgGridComponent) { throw new Error(`selector: ${key}`); } this.applyElementsToComponent(element, elementRef, paramsMap, newComponent); return newComponent; } swapComponentForNode(newComponent, parentNode, childNode) { const eComponent = newComponent.getGui(); parentNode.replaceChild(eComponent, childNode); parentNode.insertBefore(document.createComment(childNode.nodeName), eComponent); this.addDestroyFunc(this.destroyBean.bind(this, newComponent)); } activateTabIndex(elements, overrideTabIndex) { const tabIndex = overrideTabIndex ?? this.gos.get("tabIndex"); if (!elements) { elements = []; } if (!elements.length) { elements.push(this.getGui()); } for (const el of elements) { el.setAttribute("tabindex", tabIndex.toString()); } } setTemplate(templateOrParams, componentSelectors, paramsMap) { let eGui; if (typeof templateOrParams === "string" || templateOrParams == null) { eGui = _loadTemplate(templateOrParams); } else { eGui = _createAgElement(templateOrParams); } this.setTemplateFromElement(eGui, componentSelectors, paramsMap); } setTemplateFromElement(element, components, paramsMap, suppressDataRefValidation = false) { this.eGui = element; this.suppressDataRefValidation = suppressDataRefValidation; if (components) { for (let i = 0;i < components.length; i++) { const component = components[i]; this.componentSelectors.set(component.selector, component); } } this.wireTemplate(element, paramsMap); } getGui() { return this.eGui; } getFocusableElement() { return this.eGui; } getAriaElement() { return this.getFocusableElement(); } setParentComponent(component) { this.parentComponent = component; } getParentComponent() { return this.parentComponent; } setGui(eGui) { this.eGui = eGui; } queryForHtmlElement(cssSelector) { return this.eGui.querySelector(cssSelector); } getContainerAndElement(newChild, container) { let parent = container; if (newChild == null) { return null; } if (!parent) { parent = this.eGui; } if (_isNodeOrElement(newChild)) { return { element: newChild, parent }; } return { element: newChild.getGui(), parent }; } prependChild(newChild, container) { const { element, parent } = this.getContainerAndElement(newChild, container) || {}; if (!element || !parent) { return; } parent.prepend(element); } appendChild(newChild, container) { const { element, parent } = this.getContainerAndElement(newChild, container) || {}; if (!element || !parent) { return; } parent.appendChild(element); } isDisplayed() { return this.displayed; } setVisible(visible, options = {}) { if (visible !== this.visible) { this.visible = visible; const { skipAriaHidden } = options; _setVisible(this.eGui, visible, { skipAriaHidden }); } } setDisplayed(displayed, options = {}) { if (displayed !== this.displayed) { this.displayed = displayed; const { skipAriaHidden } = options; _setDisplayed(this.eGui, displayed, { skipAriaHidden }); const event = { type: "displayChanged", visible: this.displayed }; this.dispatchLocalEvent(event); } } destroy() { if (this.parentComponent) { this.parentComponent = undefined; } super.destroy(); } addGuiEventListener(event, listener, options) { this.eGui.addEventListener(event, listener, options); this.addDestroyFunc(() => this.eGui.removeEventListener(event, listener)); } addCss(className) { this.cssManager.toggleCss(className, true); } removeCss(className) { this.cssManager.toggleCss(className, false); } toggleCss(className, addOrRemove) { this.cssManager.toggleCss(className, addOrRemove); } registerCSS(css) { if (this.css === globalCssAdded) { this.css = [css]; this.addGlobalCss(); } else { this.css || (this.css = []); this.css.push(css); } } addGlobalCss() { if (Array.isArray(this.css)) { const debugId = "component-" + Object.getPrototypeOf(this)?.constructor?.name; for (const css of this.css ?? []) { this.beans.environment.addGlobalCSS(css, debugId); } } this.css = globalCssAdded; } }; var globalCssAdded = Symbol(); var Component = class extends AgComponentStub { }; var isSafari; var isFirefox; var isMacOs; var isIOS; var invisibleScrollbar; var browserScrollbarWidth; var maxDivHeight; function _isBrowserSafari() { if (isSafari === undefined) { isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); } return isSafari; } function _isBrowserFirefox() { if (isFirefox === undefined) { isFirefox = /(firefox)/i.test(navigator.userAgent); } return isFirefox; } function _isMacOsUserAgent() { if (isMacOs === undefined) { isMacOs = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform); } return isMacOs; } function _isIOSUserAgent() { if (isIOS === undefined) { isIOS = /iPad|iPhone|iPod/.test(navigator.platform) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1; } return isIOS; } function _getTabIndex(el) { if (!el) { return null; } const numberTabIndex = el.tabIndex; const tabIndex = el.getAttribute("tabIndex"); if (numberTabIndex === -1 && (tabIndex === null || tabIndex === "" && !_isBrowserFirefox())) { return null; } return numberTabIndex.toString(); } function _getMaxDivHeight() { if (maxDivHeight !== undefined) { return maxDivHeight; } if (!document.body) { return -1; } let res = 1e6; const testUpTo = _isBrowserFirefox() ? 6000000 : 1e9; const div = document.createElement("div"); document.body.appendChild(div); while (true) { const test = res * 2; div.style.height = test + "px"; if (test > testUpTo || div.clientHeight !== test) { break; } else { res = test; } } div.remove(); maxDivHeight = res; return res; } function _getScrollbarWidth() { if (browserScrollbarWidth == null) { initScrollbarWidthAndVisibility(); } return browserScrollbarWidth; } function initScrollbarWidthAndVisibility() { const body = document.body; const div = document.createElement("div"); div.style.width = div.style.height = "100px"; div.style.opacity = "0"; div.style.overflow = "scroll"; div.style.msOverflowStyle = "scrollbar"; div.style.position = "absolute"; body.appendChild(div); let width = div.offsetWidth - div.clientWidth; if (width === 0 && div.clientWidth === 0) { width = null; } if (div.parentNode) { div.remove(); } if (width != null) { browserScrollbarWidth = width; invisibleScrollbar = width === 0; } } function _isInvisibleScrollbar() { if (invisibleScrollbar == null) { initScrollbarWidthAndVisibility(); } return invisibleScrollbar; } var keyboardModeActive = false; var instanceCount = 0; function addKeyboardModeEvents(doc) { if (instanceCount > 0) { return; } doc.addEventListener("keydown", toggleKeyboardMode); doc.addEventListener("mousedown", toggleKeyboardMode); } function removeKeyboardModeEvents(doc) { if (instanceCount > 0) { return; } doc.removeEventListener("keydown", toggleKeyboardMode); doc.removeEventListener("mousedown", toggleKeyboardMode); } function toggleKeyboardMode(event) { const isKeyboardActive = keyboardModeActive; const isKeyboardEvent = event.type === "keydown"; if (isKeyboardEvent) { if (event.ctrlKey || event.metaKey || event.altKey) { return; } } if (isKeyboardActive === isKeyboardEvent) { return; } keyboardModeActive = isKeyboardEvent; } function _registerKeyboardFocusEvents(beans) { const eDocument = _getDocument(beans); addKeyboardModeEvents(eDocument); instanceCount++; return () => { instanceCount--; removeKeyboardModeEvents(eDocument); }; } function _isKeyboardMode() { return keyboardModeActive; } function _findFocusableElements(rootNode, exclude, onlyUnmanaged = false) { const focusableString = FOCUSABLE_SELECTOR; let excludeString = FOCUSABLE_EXCLUDE; if (exclude) { excludeString += ", " + exclude; } if (onlyUnmanaged) { excludeString += ', [tabindex="-1"]'; } const nodes = Array.prototype.slice.apply(rootNode.querySelectorAll(focusableString)).filter((node) => { return _isVisible(node); }); const excludeNodes = Array.prototype.slice.apply(rootNode.querySelectorAll(excludeString)); if (!excludeNodes.length) { return nodes; } const diff = (a, b) => a.filter((element) => b.indexOf(element) === -1); return diff(nodes, excludeNodes); } function _focusInto(rootNode, up = false, onlyUnmanaged = false, excludeTabGuards = false) { const focusableElements = _findFocusableElements(rootNode, excludeTabGuards ? ".ag-tab-guard" : null, onlyUnmanaged); const toFocus = up ? _last(focusableElements) : focusableElements[0]; if (toFocus) { toFocus.focus({ preventScroll: true }); return true; } return false; } function _findNextFocusableElement(beans, rootNode, onlyManaged, backwards) { const focusable = _findFocusableElements(rootNode, onlyManaged ? ':not([tabindex="-1"])' : null); const activeEl = _getActiveDomElement(beans); let currentIndex; if (onlyManaged) { currentIndex = focusable.findIndex((el) => el.contains(activeEl)); } else { currentIndex = focusable.indexOf(activeEl); } const nextIndex = currentIndex + (backwards ? -1 : 1); if (nextIndex < 0 || nextIndex >= focusable.length) { return null; } return focusable[nextIndex]; } function _findTabbableParent(node, limit = 5) { let counter = 0; while (node && _getTabIndex(node) === null && ++counter <= limit) { node = node.parentElement; } if (_getTabIndex(node) === null) { return null; } return node; } var FOCUS_MANAGED_CLASS = "ag-focus-managed"; var AgManagedFocusFeature = class extends AgBeanStub { constructor(eFocusable, stopPropagationCallbacks = { isStopPropagation: () => false, stopPropagation: () => {} }, callbacks = {}) { super(); this.eFocusable = eFocusable; this.stopPropagationCallbacks = stopPropagationCallbacks; this.callbacks = callbacks; this.callbacks = { shouldStopEventPropagation: () => false, onTabKeyDown: (e) => { if (e.defaultPrevented) { return; } const nextRoot = _findNextFocusableElement(this.beans, this.eFocusable, false, e.shiftKey); if (!nextRoot) { return; } nextRoot.focus(); e.preventDefault(); }, ...callbacks }; } postConstruct() { const { eFocusable, callbacks: { onFocusIn, onFocusOut } } = this; eFocusable.classList.add(FOCUS_MANAGED_CLASS); this.addKeyDownListeners(eFocusable); if (onFocusIn) { this.addManagedElementListeners(eFocusable, { focusin: onFocusIn }); } if (onFocusOut) { this.addManagedElementListeners(eFocusable, { focusout: onFocusOut }); } } addKeyDownListeners(eGui) { this.addManagedElementListeners(eGui, { keydown: (e) => { if (e.defaultPrevented || this.stopPropagationCallbacks.isStopPropagation(e)) { return; } const { callbacks } = this; if (callbacks.shouldStopEventPropagation(e)) { this.stopPropagationCallbacks.stopPropagation(e); return; } if (e.key === KeyCode.TAB) { callbacks.onTabKeyDown(e); } else if (callbacks.handleKeyDown) { callbacks.handleKeyDown(e); } } }); } }; var AG_GRID_STOP_PROPAGATION = "__ag_Grid_Stop_Propagation"; function _stopPropagationForAgGrid(event) { event[AG_GRID_STOP_PROPAGATION] = true; } function _isStopPropagationForAgGrid(event) { return event[AG_GRID_STOP_PROPAGATION] === true; } var STOP_PROPAGATION_CALLBACKS = { isStopPropagation: _isStopPropagationForAgGrid, stopPropagation: _stopPropagationForAgGrid }; var ManagedFocusFeature = class extends AgManagedFocusFeature { constructor(eFocusable, callbacks) { super(eFocusable, STOP_PROPAGATION_CALLBACKS, callbacks); } }; var FILTER_LOCALE_TEXT = { applyFilter: "Apply", clearFilter: "Clear", resetFilter: "Reset", cancelFilter: "Cancel", textFilter: "Text Filter", numberFilter: "Number Filter", bigintFilter: "BigInt Filter", dateFilter: "Date Filter", setFilter: "Set Filter", filterOoo: "Filter...", empty: "Choose one", equals: "Equals", notEqual: "Does not equal", lessThan: "Less than", greaterThan: "Greater than", inRange: "Between", inRangeStart: "From", inRangeEnd: "To", lessThanOrEqual: "Less than or equal to", greaterThanOrEqual: "Greater than or equal to", contains: "Contains", notContains: "Does not contain", startsWith: "Begins with", endsWith: "Ends with", blank: "Blank", notBlank: "Not blank", before: "Before", after: "After", andCondition: "AND", orCondition: "OR", dateFormatOoo: "yyyy-mm-dd", filterSummaryInactive: "is (All)", filterSummaryContains: "contains", filterSummaryNotContains: "does not contain", filterSummaryTextEquals: "equals", filterSummaryTextNotEqual: "does not equal", filterSummaryStartsWith: "begins with", filterSummaryEndsWith: "ends with", filterSummaryBlank: "is blank", filterSummaryNotBlank: "is not blank", filterSummaryEquals: "=", filterSummaryNotEqual: "!=", filterSummaryGreaterThan: ">", filterSummaryGreaterThanOrEqual: ">=", filterSummaryLessThan: "<", filterSummaryLessThanOrEqual: "<=", filterSummaryInRange: "between", yesterday: "Yesterday", today: "Today", tomorrow: "Tomorrow", last7Days: "Last 7 Days", lastWeek: "Last Week", thisWeek: "This Week", nextWeek: "Next Week", last30Days: "Last 30 Days", lastMonth: "Last Month", thisMonth: "This Month", nextMonth: "Next Month", last90Days: "Last 90 Days", lastQuarter: "Last Quarter", thisQuarter: "This Quarter", nextQuarter: "Next Quarter", lastYear: "Last Year", thisYear: "This Year", yearToDate: "Year To Date", nextYear: "Next Year", last6Months: "Last 6 Months", last12Months: "Last 12 Months", last24Months: "Last 24 Months", filterSummaryInRangeValues: (variableValues) => `(${variableValues[0]}, ${variableValues[1]})`, filterSummaryTextQuote: (variableValues) => `"${variableValues[0]}"`, minDateValidation: (variableValues) => `Date must be after ${variableValues[0]}`, maxDateValidation: (variableValues) => `Date must be before ${variableValues[0]}`, strictMinValueValidation: (variableValues) => `Must be greater than ${variableValues[0]}`, strictMaxValueValidation: (variableValues) => `Must be less than ${variableValues[0]}` }; function translateForFilter(bean, key, variableValues) { return _translate(bean, FILTER_LOCALE_TEXT, key, variableValues); } function getDebounceMs(params, debounceDefault) { const { debounceMs } = params; if (_isUseApplyButton(params)) { if (debounceMs != null) { _warn(71); } return 0; } return debounceMs ?? debounceDefault; } function _isUseApplyButton(params) { return (params.buttons?.indexOf("apply") ?? -1) >= 0; } function getPlaceholderText(bean, filterPlaceholder, defaultPlaceholder, filterOptionKey) { let placeholder = translateForFilter(bean, defaultPlaceholder); if (typeof filterPlaceholder === "function") { const filterOption = translateForFilter(bean, filterOptionKey); placeholder = filterPlaceholder({ filterOptionKey, filterOption, placeholder }); } else if (typeof filterPlaceholder === "string") { placeholder = filterPlaceholder; } return placeholder; } var ProvidedFilter = class extends Component { constructor(filterNameKey, cssIdentifier) { super(); this.filterNameKey = filterNameKey; this.cssIdentifier = cssIdentifier; this.applyActive = false; this.debouncePending = false; this.defaultDebounceMs = 0; } postConstruct() { const element = { tag: "div", cls: `ag-filter-body-wrapper ag-${this.cssIdentifier}-body-wrapper`, children: [this.createBodyTemplate()] }; this.setTemplate(element, this.getAgComponents()); this.createManagedBean(new ManagedFocusFeature(this.getFocusableElement(), { handleKeyDown: this.handleKeyDown.bind(this) })); this.positionableFeature = this.createBean(new PositionableFeature(this.getPositionableElement(), { forcePopupParentAsOffsetParent: true })); } handleKeyDown(_e) {} init(legacyParams) { const params = legacyParams; this.setParams(params); this.setModelIntoUi(params.state.model, true).then(() => this.updateUiVisibility()); } areStatesEqual(stateA, stateB) { return stateA === stateB; } refresh(legacyNewParams) { const newParams = legacyNewParams; const oldParams = this.params; this.params = newParams; const { source, state: newState, additionalEventAttributes } = newParams; if (source === "colDef") { this.updateParams(newParams, oldParams); } const oldState = this.state; this.state = newState; const fromAction = additionalEventAttributes?.fromAction; if (fromAction && fromAction !== "apply" || newState.model !== oldState.model || !this.areStatesEqual(newState.state, oldState.state)) { this.setModelIntoUi(newState.model); } return true; } setParams(params) { this.params = params; this.state = params.state; this.commonUpdateParams(params); } updateParams(newParams, oldParams) { this.commonUpdateParams(newParams, oldParams); } commonUpdateParams(newParams, _oldParams) { this.applyActive = _isUseApplyButton(newParams); this.setupApplyDebounced(); } doesFilterPass(params) { _warn(283); const { getHandler, model, column } = this.params; return getHandler().doesFilterPass({ ...params, model, handlerParams: this.beans.colFilter.getHandlerParams(column) }); } getFilterTitle() { return this.translate(this.filterNameKey); } isFilterActive() { _warn(284); return this.params.model != null; } setupApplyDebounced() { const debounceMs = getDebounceMs(this.params, this.defaultDebounceMs); const debounceFunc = _debounce(this, this.checkApplyDebounce.bind(this), debounceMs); this.applyDebounced = () => { this.debouncePending = true; debounceFunc(); }; } checkApplyDebounce() { if (this.debouncePending) { this.debouncePending = false; this.doApplyModel(); } } getModel() { _warn(285); return this.params.model; } setModel(model) { _warn(286); const { beans, params } = this; return beans.colFilter.setModelForColumnLegacy(params.column, model); } applyModel(_source = "api") { return this.doApplyModel(); } canApply(_model) { return true; } doApplyModel(additionalEventAttributes) { const { params, state: { valid = true, model } } = this; if (!valid) { return false; } const changed = !this.areModelsEqual(params.model, model); if (changed) { params.onAction("apply", additionalEventAttributes); } return changed; } onNewRowsLoaded() {} onUiChanged(apply, afterFloatingFilter = false) { this.updateUiVisibility(); const model = this.getModelFromUi(); const state = { model, state: this.getState(), valid: this.canApply(model) }; this.state = state; const { params, gos, eventSvc, applyActive } = this; params.onStateChange(state); params.onUiChange(this.getUiChangeEventParams()); if (!gos.get("enableFilterHandlers")) { eventSvc.dispatchEvent({ type: "filterModified", column: params.column, filterInstance: this }); } if (!state.valid) { return; } apply ?? (apply = applyActive ? undefined : "debounce"); if (apply === "immediately") { this.doApplyModel({ afterFloatingFilter, afterDataChange: false }); } else if (apply === "debounce") { this.applyDebounced(); } } getState() { return; } getUiChangeEventParams() { return; } afterGuiAttached(params) { this.lastContainerType = params?.container; this.refreshFilterResizer(params?.container); } refreshFilterResizer(containerType) { const { positionableFeature, gos } = this; if (!positionableFeature) { return; } const isResizable = containerType === "floatingFilter" || containerType === "columnFilter"; if (isResizable) { positionableFeature.restoreLastSize(); positionableFeature.setResizable(gos.get("enableRtl") ? { bottom: true, bottomLeft: true, left: true } : { bottom: true, bottomRight: true, right: true }); } else { positionableFeature.removeSizeFromEl(); positionableFeature.setResizable(false); } positionableFeature.constrainSizeToAvailableHeight(isResizable); } afterGuiDetached() { this.checkApplyDebounce(); this.positionableFeature?.constrainSizeToAvailableHeight(false); } destroy() { this.positionableFeature = this.destroyBean(this.positionableFeature); super.destroy(); } translate(key, variableValues) { return translateForFilter(this, key, variableValues); } getPositionableElement() { return this.getGui(); } areModelsEqual(a, b) { if (a === b || a == null && b == null) { return true; } if (a == null || b == null) { return false; } return this.areNonNullModelsEqual(a, b); } }; var AgPopupComponent = class extends AgComponentStub { isPopup() { return true; } setParentComponent(container) { container.addCss("ag-has-popup"); super.setParentComponent(container); } destroy() { const parentComp = this.parentComponent; const hasParent = parentComp?.isAlive(); if (hasParent) { parentComp.getGui().classList.remove("ag-has-popup"); } super.destroy(); } }; var AgAbstractCellEditor = class extends AgPopupComponent { constructor() { super(...arguments); this.errorMessages = null; } init(params) { this.params = params; this.initialiseEditor(params); this.eEditor.onValueChange(() => params.validate()); } destroy() { this.eEditor.destroy(); this.errorMessages = null; super.destroy(); } }; function _getClientSideRowModel(beans) { const rowModel = beans.rowModel; return rowModel.getType() === "clientSide" ? rowModel : undefined; } var ROW_ID_PREFIX_ROW_GROUP = "row-group-"; var ROW_ID_PREFIX_TOP_PINNED = "t-"; var ROW_ID_PREFIX_BOTTOM_PINNED = "b-"; var OBJECT_ID_SEQUENCE = 0; var RowNode = class { constructor(beans) { this.id = undefined; this.destroyed = false; this._groupData = undefined; this.master = false; this.detail = undefined; this.rowIndex = null; this.field = null; this.rowGroupColumn = null; this.key = null; this.sourceRowIndex = -1; this._leafs = undefined; this.childrenAfterGroup = null; this.childrenAfterFilter = null; this.childrenAfterAggFilter = null; this.childrenAfterSort = null; this.allChildrenCount = null; this.childrenMapped = null; this.treeParent = null; this.treeNodeFlags = 0; this._expanded = undefined; this.displayed = false; this.rowTop = null; this.oldRowTop = null; this.selectable = true; this.__objectId = OBJECT_ID_SEQUENCE++; this.alreadyRendered = false; this.formulaRowIndex = null; this.hovered = false; this.__selected = false; this.beans = beans; } get groupData() { const groupData = this._groupData; if (groupData !== undefined) { return groupData; } if (this.footer) { return this.sibling?.groupData; } return this.beans.groupStage?.loadGroupData(this) ?? null; } set groupData(value) { this._groupData = value; } get primaryRow() { let node = this.footer && this.sibling ? this.sibling : this; const { pinnedSibling } = node; if (pinnedSibling && node.rowPinned) { node = pinnedSibling; if (node.footer && node.sibling) { node = node.sibling; } } return node; } get allLeafChildren() { const leafs = this._leafs; return leafs === undefined ? this.beans.groupStage?.loadLeafs?.(this) ?? null : leafs; } set allLeafChildren(value) { this._leafs = value; } get expanded() { const expansionSvc = this.beans.expansionSvc; return expansionSvc ? expansionSvc.isExpanded(this) : this.level === -1 ? true : !!this._expanded; } set expanded(value) { this._expanded = value; } setData(data) { this.setDataCommon(data, false); } updateData(data) { this.setDataCommon(data, true); } setDataCommon(data, update) { const { valueCache, eventSvc } = this.beans; const oldData = this.data; this.data = data; valueCache?.onDataChanged(); this.updateDataOnDetailNode(); this.resetQuickFilterAggregateText(); const event = this.createDataChangedEvent(data, oldData, update); this.__localEventService?.dispatchEvent(event); if (this.sibling) { this.sibling.data = data; const event2 = this.sibling.createDataChangedEvent(data, oldData, update); this.sibling.__localEventService?.dispatchEvent(event2); } eventSvc.dispatchEvent({ type: "rowNodeDataChanged", node: this }); const pinnedSibling = this.pinnedSibling; if (pinnedSibling) { pinnedSibling.data = data; pinnedSibling.__localEventService?.dispatchEvent(pinnedSibling.createDataChangedEvent(data, oldData, update)); eventSvc.dispatchEvent({ type: "rowNodeDataChanged", node: pinnedSibling }); } } updateDataOnDetailNode() { const detailNode = this.detailNode; if (detailNode) { detailNode.data = this.data; } } createDataChangedEvent(newData, oldData, update) { return { type: "dataChanged", node: this, oldData, newData, update }; } getRowIndexString() { if (this.rowIndex == null) { _error(13); return null; } if (this.rowPinned === "top") { return ROW_ID_PREFIX_TOP_PINNED + this.rowIndex; } if (this.rowPinned === "bottom") { return ROW_ID_PREFIX_BOTTOM_PINNED + this.rowIndex; } return this.rowIndex.toString(); } setDataAndId(data, id) { const { selectionSvc } = this.beans; const oldNode = selectionSvc?.createDaemonNode?.(this); const oldData = this.data; this.data = data; this.updateDataOnDetailNode(); this.setId(id); if (selectionSvc) { selectionSvc.updateRowSelectable(this); selectionSvc.syncInRowNode(this, oldNode); } const event = this.createDataChangedEvent(data, oldData, false); this.__localEventService?.dispatchEvent(event); } setId(id) { const getRowIdFunc = _getRowIdCallback(this.beans.gos); if (getRowIdFunc) { if (this.data) { const parentKeys = this.parent?.getRoute() ?? []; this.id = getRowIdFunc({ data: this.data, parentKeys: parentKeys.length > 0 ? parentKeys : undefined, level: this.level, rowPinned: this.rowPinned }); if (this.id.startsWith(ROW_ID_PREFIX_ROW_GROUP)) { _error(14, { groupPrefix: ROW_ID_PREFIX_ROW_GROUP }); } } else { this.id = undefined; } } else { this.id = id; } } setRowTop(rowTop) { this.oldRowTop = this.rowTop; if (this.rowTop === rowTop) { return; } this.rowTop = rowTop; this.dispatchRowEvent("topChanged"); const displayed = rowTop !== null; if (this.displayed !== displayed) { this.displayed = displayed; this.dispatchRowEvent("displayedChanged"); } } clearRowTopAndRowIndex() { this.oldRowTop = null; this.setRowTop(null); this.setRowIndex(null); } setHovered(hovered) { this.hovered = hovered; } isHovered() { return this.hovered; } setRowHeight(rowHeight, estimated = false) { this.rowHeight = rowHeight; this.rowHeightEstimated = estimated; this.dispatchRowEvent("heightChanged"); } setExpanded(expanded, e, forceSync) { this.beans.expansionSvc?.setExpanded(this, expanded, e, forceSync); } setDataValue(colKey, newValue, eventSource) { const { colModel, valueSvc, gos, editSvc } = this.beans; if (colKey == null) { return false; } let column = colModel.getCol(colKey) ?? colModel.getColDefCol(colKey); if (!column) { return false; } if (!this.group) { const colDef = column.getColDef(); if (colDef.pivotValueColumn) { column = colDef.pivotValueColumn; } } const oldValue = valueSvc.getValueForDisplay({ column, node: this, from: "data" }).value; if (gos.get("readOnlyEdit")) { const { beans: { eventSvc }, data, rowIndex, rowPinned } = this; eventSvc.dispatchEvent({ type: "cellEditRequest", event: null, rowIndex, rowPinned, column, colDef: column.colDef, data, node: this, oldValue, newValue, value: newValue, source: eventSource }); return false; } if (eventSource !== "data" && editSvc && !editSvc.committing) { const result = editSvc.setDataValue({ rowNode: this, column }, newValue, eventSource); if (result != null) { return result; } } const valueChanged = valueSvc.setValue(this, column, newValue, eventSource); this.dispatchCellChangedEvent(column, newValue, oldValue); if (valueChanged) { this.pinnedSibling?.dispatchCellChangedEvent(column, newValue, oldValue); } return valueChanged; } getDataValue(colKey, from = "data") { const { colModel, valueSvc, formula } = this.beans; if (colKey == null) { return; } const column = colModel.getCol(colKey) ?? colModel.getColDefCol(colKey); if (!column) { return; } const dataRaw = from === "data-raw"; const resolvedFrom = dataRaw || from === "value" ? "data" : from; let value = valueSvc.getValue(column, this, resolvedFrom, dataRaw); if (!dataRaw) { if (formula && column.isAllowFormula() && formula.isFormula(value)) { value = formula.resolveValue(column, this); } if (from !== "data" && column.getAggFunc() && typeof value === "object" && value != null) { if (typeof value.toNumber === "function") { return value.toNumber(); } if ("value" in value) { return value.value; } } } return value; } updateHasChildren() { let newValue = this.group && !this.footer || !!this.childrenAfterGroup?.length; const { rowChildrenSvc } = this.beans; if (rowChildrenSvc) { newValue = rowChildrenSvc.getHasChildrenValue(this); } if (newValue !== this.__hasChildren) { this.__hasChildren = !!newValue; this.dispatchRowEvent("hasChildrenChanged"); } } hasChildren() { if (this.__hasChildren == null) { this.updateHasChildren(); } return this.__hasChildren; } dispatchCellChangedEvent(column, newValue, oldValue) { const cellChangedEvent = { type: "cellChanged", node: this, column, newValue, oldValue }; this.__localEventService?.dispatchEvent(cellChangedEvent); } resetQuickFilterAggregateText() { this.quickFilterAggregateText = null; } isExpandable() { return this.beans.expansionSvc?.isExpandable(this) ?? false; } isSelected() { if (this.footer) { return this.sibling.isSelected(); } const pinnedSibling = this.rowPinned && this.pinnedSibling; if (pinnedSibling) { return pinnedSibling.isSelected(); } return this.__selected; } depthFirstSearch(callback) { const childrenAfterGroup = this.childrenAfterGroup; if (childrenAfterGroup) { for (let i = 0, len = childrenAfterGroup.length;i < len; ++i) { childrenAfterGroup[i].depthFirstSearch(callback); } } callback(this); } getAggregatedChildren(colKey, recursive) { const beans = this.beans; return beans.aggChildrenSvc?.getAggregatedChildren(this, beans.colModel.getCol(colKey), recursive) ?? []; } dispatchRowEvent(type) { this.__localEventService?.dispatchEvent({ type, node: this }); } setSelected(newValue, clearSelection = false, source = "api") { this.beans.selectionSvc?.setNodesSelected({ nodes: [this], newValue, clearSelection, source }); } isRowPinned() { return !!this.rowPinned; } __addEventListener(eventType, listener) { const localEventService = this.__localEventService ?? (this.__localEventService = new LocalEventService); localEventService.addEventListener(eventType, listener); } __removeEventListener(eventType, listener) { this.removeLocalListener(eventType, listener); } addEventListener(eventType, userListener) { this.beans.validation?.checkRowEvents(eventType); const localEventService = this.__localEventService ?? (this.__localEventService = new LocalEventService); this.frameworkEventListenerService = this.beans.frameworkOverrides.createLocalEventListenerWrapper?.(this.frameworkEventListenerService, localEventService); const listener = this.frameworkEventListenerService?.wrap(eventType, userListener) ?? userListener; localEventService.addEventListener(eventType, listener); } removeEventListener(eventType, userListener) { const listener = this.frameworkEventListenerService?.unwrap(eventType, userListener) ?? userListener; this.removeLocalListener(eventType, listener); } removeLocalListener(eventType, listener) { const localEventService = this.__localEventService; if (localEventService) { localEventService.removeEventListener(eventType, listener); if (localEventService.noRegisteredListenersExist()) { this.__localEventService = null; } } } isFullWidthCell() { _warn(61); if (this.detail) { return true; } const isFullWidthCellFunc = this.beans.gos.getCallback("isFullWidthRow"); return isFullWidthCellFunc ? isFullWidthCellFunc({ rowNode: this }) : false; } getRoute() { if (this.level === -1) { return []; } if (this.key == null) { return; } const res = []; let pointer = this; while (pointer?.key != null) { res.push(pointer.key); pointer = pointer.parent; } return res.reverse(); } setRowIndex(rowIndex) { if (this.rowIndex !== rowIndex) { this.rowIndex = rowIndex; this.dispatchRowEvent("rowIndexChanged"); } } setAllChildrenCount(allChildrenCount) { if (this.allChildrenCount !== allChildrenCount) { this.allChildrenCount = allChildrenCount; this.dispatchRowEvent("allChildrenCountChanged"); } } setUiLevel(uiLevel) { if (this.uiLevel !== uiLevel) { this.uiLevel = uiLevel; this.dispatchRowEvent("uiLevelChanged"); } } getFirstChild() { const childStore = this.childStore; if (childStore) { return childStore.getFirstNode(); } return this.childrenAfterSort?.[0] ?? null; } _destroy(fadeOut) { if (this.destroyed) { return false; } this.destroyed = true; const pinnedSibling = this.pinnedSibling; if (pinnedSibling?.rowPinned && !this.rowPinned) { this.beans.pinnedRowModel?.pinRow(pinnedSibling, null); } if (fadeOut) { this.clearRowTopAndRowIndex(); } else { this.setRowTop(null); this.setRowIndex(null); } if (!this.footer) { const detailNode = this.detailNode; if (detailNode) { detailNode._destroy(fadeOut); } const sibling = this.sibling; if (sibling) { sibling._destroy(fadeOut); } } return true; } }; function _createGlobalRowEvent(rowNode, gos, type) { return _addGridCommonParams(gos, { type, node: rowNode, data: rowNode.data, rowIndex: rowNode.rowIndex, rowPinned: rowNode.rowPinned }); } var IGNORED_SIBLING_PROPERTIES = /* @__PURE__ */ new Set([ "__autoHeights", "__checkAutoHeightsDebounced", "__localEventService", "__objectId", "_groupData", "_leafs", "childStore", "groupValue", "oldRowTop", "sticky", "treeNodeFlags", "treeParent" ]); var _createRowNodeSibling = (rowNode, beans) => { const sibling = new RowNode(beans); for (const key of Object.keys(rowNode)) { if (IGNORED_SIBLING_PROPERTIES.has(key)) { continue; } sibling[key] = rowNode[key]; } sibling.oldRowTop = null; return sibling; }; var _prevOrNextDisplayedRow = (rowModel, direction, initial) => { if (!initial) { return; } let rowIndex = initial.rowIndex; if (rowIndex == null) { return; } rowIndex += direction; const rowCount = rowModel.getRowCount(); while (rowIndex >= 0 && rowIndex < rowCount) { const row = rowModel.getRow(rowIndex); if (!row || !row.footer && !row.detail) { return row; } rowIndex += direction; } return; }; var DOUBLE_TAP_MILLISECONDS = 500; var LONG_PRESS_MILLISECONDS = 550; var handledTouchEvents; var addHandledTouchEvent = (event) => { if (!handledTouchEvents) { handledTouchEvents = /* @__PURE__ */ new WeakSet; } else if (handledTouchEvents.has(event)) { return false; } handledTouchEvents.add(event); return true; }; var TouchListener = class { constructor(eElement, preventClick = false) { this.eElement = eElement; this.preventClick = preventClick; this.startListener = null; this.handlers = []; this.eventSvc = undefined; this.touchStart = null; this.lastTapTime = null; this.longPressTimer = 0; this.moved = false; } addEventListener(eventType, listener) { let eventSvc = this.eventSvc; if (!eventSvc) { if (eventSvc === null) { return; } this.eventSvc = eventSvc = new LocalEventService; const startListener = this.onTouchStart.bind(this); this.startListener = startListener; this.eElement.addEventListener("touchstart", startListener, { passive: true }); } eventSvc.addEventListener(eventType, listener); } removeEventListener(eventType, listener) { this.eventSvc?.removeEventListener(eventType, listener); } onTouchStart(touchEvent) { if (this.touchStart || !addHandledTouchEvent(touchEvent)) { return; } const touchStart = touchEvent.touches[0]; this.touchStart = touchStart; const handlers = this.handlers; if (!handlers.length) { const eElement = this.eElement; const doc = eElement.ownerDocument; const touchMove = this.onTouchMove.bind(this); const touchEnd = this.onTouchEnd.bind(this); const touchCancel = this.onTouchCancel.bind(this); const passiveTrue = { passive: true }; const passiveFalse = { passive: false }; addTempEventHandlers(handlers, [eElement, "touchmove", touchMove, passiveTrue], [doc, "touchcancel", touchCancel, passiveTrue], [doc, "touchend", touchEnd, passiveFalse], [doc, "contextmenu", preventEventDefault, passiveFalse]); } this.clearLongPress(); this.longPressTimer = window.setTimeout(() => { this.longPressTimer = 0; if (this.touchStart === touchStart && !this.moved) { this.moved = true; this.eventSvc?.dispatchEvent({ type: "longTap", touchStart, touchEvent }); } }, LONG_PRESS_MILLISECONDS); } onTouchMove(touchEvent) { const { moved, touchStart } = this; if (!moved && touchStart) { const touch = _getFirstActiveTouch(touchStart, touchEvent.touches); const eventIsFarAway = touch && !_areEventsNear(touch, touchStart, 4); if (eventIsFarAway) { this.clearLongPress(); this.moved = true; } } } onTouchEnd(touchEvent) { const touchStart = this.touchStart; if (!touchStart || !_getFirstActiveTouch(touchStart, touchEvent.changedTouches)) { return; } if (!this.moved) { this.eventSvc?.dispatchEvent({ type: "tap", touchStart }); this.checkDoubleTap(touchStart); } if (this.preventClick) { preventEventDefault(touchEvent); } this.cancel(); } onTouchCancel(touchEvent) { const touchStart = this.touchStart; if (!touchStart || !_getFirstActiveTouch(touchStart, touchEvent.changedTouches)) { return; } this.lastTapTime = null; this.cancel(); } checkDoubleTap(touchStart) { let now = Date.now(); const lastTapTime = this.lastTapTime; if (lastTapTime) { const interval = now - lastTapTime; if (interval > DOUBLE_TAP_MILLISECONDS) { this.eventSvc?.dispatchEvent({ type: "doubleTap", touchStart }); now = null; } } this.lastTapTime = now; } cancel() { this.clearLongPress(); clearTempEventHandlers(this.handlers); this.touchStart = null; } clearLongPress() { window.clearTimeout(this.longPressTimer); this.longPressTimer = 0; this.moved = false; } destroy() { const startListener = this.startListener; if (startListener) { this.startListener = null; this.eElement.removeEventListener("touchstart", startListener); } this.cancel(); this.eElement = null; this.eventSvc = null; } }; var CellRangeType = /* @__PURE__ */ ((CellRangeType2) => { CellRangeType2[CellRangeType2["VALUE"] = 0] = "VALUE"; CellRangeType2[CellRangeType2["DIMENSION"] = 1] = "DIMENSION"; return CellRangeType2; })(CellRangeType || {}); var contextId = 1; var AgContext = class { constructor(params) { this.beans = {}; this.createdBeans = []; this.destroyed = false; this.instanceId = contextId++; if (!params?.beanClasses) { return; } this.beanDestroyComparator = params.beanDestroyComparator; this.init(params); } init(params) { this.id = params.id; this.beans.context = this; this.destroyCallback = params.destroyCallback; for (const beanName of Object.keys(params.providedBeanInstances)) { this.beans[beanName] = params.providedBeanInstances[beanName]; } for (const BeanClass of params.beanClasses) { const instance = new BeanClass; if (instance.beanName) { this.beans[instance.beanName] = instance; } else { console.error(`Bean ${BeanClass.name} is missing beanName`); } this.createdBeans.push(instance); } for (const beanFunc of params.derivedBeans ?? []) { const { beanName, bean } = beanFunc(this); this.beans[beanName] = bean; this.createdBeans.push(bean); } if (params.beanInitComparator) { this.createdBeans.sort(params.beanInitComparator); } this.initBeans(this.createdBeans); } getBeanInstances() { return Object.values(this.beans); } createBean(bean, afterPreCreateCallback) { this.initBeans([bean], afterPreCreateCallback); return bean; } initBeans(beanInstances, afterPreCreateCallback) { const beans = this.beans; for (const instance of beanInstances) { instance.preWireBeans?.(beans); instance.wireBeans?.(beans); } for (const instance of beanInstances) { instance.preConstruct?.(); } if (afterPreCreateCallback) { beanInstances.forEach(afterPreCreateCallback); } for (const instance of beanInstances) { instance.postConstruct?.(); } } getBeans() { return this.beans; } getBean(name) { return this.beans[name]; } getId() { return this.id; } destroy() { if (this.destroyed) { return; } this.destroyed = true; const beanInstances = this.getBeanInstances(); if (this.beanDestroyComparator) { beanInstances.sort(this.beanDestroyComparator); } this.destroyBeans(beanInstances); this.beans = {}; this.createdBeans = []; this.destroyCallback?.(); } destroyBean(bean) { bean?.destroy?.(); } destroyBeans(beans) { if (beans) { for (let i = 0;i < beans.length; i++) { this.destroyBean(beans[i]); } } return []; } isDestroyed() { return this.destroyed; } }; function createGridApi(context) { return { beanName: "gridApi", bean: context.getBean("apiFunctionSvc").api }; } var orderedCoreBeans = [ "licenseManager", "environment", "eventSvc", "gos", "paginationAutoPageSizeSvc", "apiFunctionSvc", "gridApi", "registry", "agCompUtils", "userCompFactory", "rowContainerHeight", "horizontalResizeSvc", "localeSvc", "pinnedRowModel", "dragSvc", "colGroupSvc", "visibleCols", "popupSvc", "selectionSvc", "colFilter", "quickFilter", "filterManager", "colModel", "headerNavigation", "pageBounds", "pagination", "pageBoundsListener", "rowSpanSvc", "stickyRowSvc", "rowRenderer", "expressionSvc", "alignedGridsSvc", "navigation", "valueCache", "valueSvc", "autoWidthCalc", "filterMenuFactory", "dragAndDrop", "focusSvc", "cellNavigation", "cellStyles", "scrollVisibleSvc", "sortSvc", "colHover", "colAnimation", "autoColSvc", "selectionColSvc", "changeDetectionSvc", "animationFrameSvc", "undoRedo", "colDefFactory", "rowStyleSvc", "rowNodeBlockLoader", "rowNodeSorter", "ctrlsSvc", "pinnedCols", "dataTypeSvc", "syncSvc", "overlays", "stateSvc", "expansionSvc", "apiEventSvc", "ariaAnnounce", "menuSvc", "colMoves", "colAutosize", "colFlex", "colResize", "pivotColsSvc", "valueColsSvc", "rowGroupColsSvc", "colNames", "colViewport", "pivotResultCols", "showRowGroupCols", "validation" ]; var beanNamePosition = Object.fromEntries(orderedCoreBeans.map((beanName, index) => [beanName, index])); function gridBeanInitComparator(bean1, bean2) { const index1 = (bean1.beanName ? beanNamePosition[bean1.beanName] : undefined) ?? Number.MAX_SAFE_INTEGER; const index2 = (bean2.beanName ? beanNamePosition[bean2.beanName] : undefined) ?? Number.MAX_SAFE_INTEGER; return index1 - index2; } function gridBeanDestroyComparator(bean1, bean2) { if (bean1?.beanName === "gridDestroySvc") { return -1; } if (bean2?.beanName === "gridDestroySvc") { return 1; } return 0; } function _createCellId(cellPosition) { const { rowIndex, rowPinned, column } = cellPosition; return `${rowIndex}.${rowPinned == null ? "null" : rowPinned}.${column.getId()}`; } function _areCellsEqual(cellA, cellB) { const colsMatch = cellA.column === cellB.column; const floatingMatch = cellA.rowPinned === cellB.rowPinned; const indexMatch = cellA.rowIndex === cellB.rowIndex; return colsMatch && floatingMatch && indexMatch; } function _isRowBefore(rowA, rowB) { switch (rowA.rowPinned) { case "top": if (rowB.rowPinned !== "top") { return true; } break; case "bottom": if (rowB.rowPinned !== "bottom") { return false; } break; default: if (_exists(rowB.rowPinned)) { return rowB.rowPinned !== "top"; } break; } return rowA.rowIndex < rowB.rowIndex; } function _isSameRow(rowA, rowB) { if (!rowA && !rowB) { return true; } if (!rowA || !rowB) { return false; } return rowA.rowIndex === rowB.rowIndex && rowA.rowPinned == rowB.rowPinned; } function _getFirstRow(beans) { let rowIndex = 0; let rowPinned; const { pinnedRowModel, rowModel, pageBounds } = beans; if (pinnedRowModel?.getPinnedTopRowCount()) { rowPinned = "top"; } else if (rowModel.getRowCount()) { rowPinned = null; rowIndex = pageBounds.getFirstRow(); } else if (pinnedRowModel?.getPinnedBottomRowCount()) { rowPinned = "bottom"; } return rowPinned === undefined ? null : { rowIndex, rowPinned }; } function _getLastRow(beans) { let rowIndex; let rowPinned = null; const { pinnedRowModel, pageBounds } = beans; const pinnedBottomCount = pinnedRowModel?.getPinnedBottomRowCount(); const pinnedTopCount = pinnedRowModel?.getPinnedTopRowCount(); if (pinnedBottomCount) { rowPinned = "bottom"; rowIndex = pinnedBottomCount - 1; } else if (beans.rowModel.getRowCount()) { rowIndex = pageBounds.getLastRow(); } else if (pinnedTopCount) { rowPinned = "top"; rowIndex = pinnedTopCount - 1; } return rowIndex === undefined ? null : { rowIndex, rowPinned }; } function _getRowNode(beans, gridRow) { switch (gridRow.rowPinned) { case "top": return beans.pinnedRowModel?.getPinnedTopRow(gridRow.rowIndex); case "bottom": return beans.pinnedRowModel?.getPinnedBottomRow(gridRow.rowIndex); default: return beans.rowModel.getRow(gridRow.rowIndex); } } function _getCellByPosition(beans, cellPosition) { const spannedCellCtrl = beans.spannedRowRenderer?.getCellByPosition(cellPosition); if (spannedCellCtrl) { return spannedCellCtrl; } const rowCtrl = beans.rowRenderer.getRowByPosition(cellPosition); if (!rowCtrl) { return null; } return rowCtrl.getCellCtrl(cellPosition.column); } function _getRowById(beans, rowId, rowPinned) { const { rowModel: rm, pinnedRowModel: prm } = beans; let node; node ?? (node = rm?.getRowNode(rowId)); if (rowPinned) { node ?? (node = prm?.getPinnedRowById(rowId, rowPinned)); } else { node ?? (node = prm?.getPinnedRowById(rowId, "top")); node ?? (node = prm?.getPinnedRowById(rowId, "bottom")); } return node; } function _getRowAbove(beans, rowPosition, checkSticky = false) { const { rowIndex: index, rowPinned: pinned } = rowPosition; const { pageBounds, pinnedRowModel, rowModel } = beans; if (index === 0) { if (pinned === "top") { return null; } if (pinned === "bottom" && rowModel.isRowsToRender()) { return { rowIndex: pageBounds.getLastRow(), rowPinned: null }; } return pinnedRowModel?.isRowsToRender("top") ? { rowIndex: pinnedRowModel.getPinnedTopRowCount() - 1, rowPinned: "top" } : null; } if (checkSticky) { const rowNode = pinned ? undefined : rowModel.getRow(index); return getNextStickyPosition(beans, rowNode, true) ?? { rowIndex: index - 1, rowPinned: pinned }; } return { rowIndex: index - 1, rowPinned: pinned }; } function _getAbsoluteRowIndex(beans, rowPosition) { const { pinnedRowModel, rowModel } = beans; const pinnedTopRowCount = pinnedRowModel?.getPinnedTopRowCount() ?? 0; const unpinnedRowCount = rowModel.getRowCount(); const { rowPinned, rowIndex } = rowPosition; if (rowPinned === "top") { return rowIndex; } if (rowPinned === "bottom") { return pinnedTopRowCount + unpinnedRowCount + rowIndex; } return pinnedTopRowCount + rowIndex; } function _getRowBelow(beans, rowPosition, checkSticky = false) { const { rowIndex: index, rowPinned: pinned } = rowPosition; const { pageBounds, pinnedRowModel, rowModel } = beans; if (isLastRowInContainer(beans, rowPosition)) { if (pinned === "bottom") { return null; } if (pinned === "top" && rowModel.isRowsToRender()) { return { rowIndex: pageBounds.getFirstRow(), rowPinned: null }; } return pinnedRowModel?.isRowsToRender("bottom") ? { rowIndex: 0, rowPinned: "bottom" } : null; } if (checkSticky) { const rowNode = pinned ? undefined : rowModel.getRow(index); return getNextStickyPosition(beans, rowNode) ?? { rowIndex: index + 1, rowPinned: pinned }; } return { rowIndex: index + 1, rowPinned: pinned }; } function getNextStickyPosition(beans, rowNode, up = false) { const { gos, rowRenderer } = beans; if (!rowNode?.sticky || !_isGroupRowsSticky(gos)) { return; } const stickyTopCtrls = rowRenderer.getStickyTopRowCtrls(); const stickyBottomCtrls = rowRenderer.getStickyBottomRowCtrls(); const isStickyTop = !stickyBottomCtrls.some((ctrl) => ctrl.rowNode.rowIndex === rowNode.rowIndex); const stickyRowCtrls = isStickyTop ? stickyTopCtrls : stickyBottomCtrls; const increment = (up ? -1 : 1) * (isStickyTop ? -1 : 1); let nextCtrl; for (let i = 0;i < stickyRowCtrls.length; i++) { if (stickyRowCtrls[i].rowNode.rowIndex === rowNode.rowIndex) { nextCtrl = stickyRowCtrls[i + increment]; break; } } return nextCtrl ? { rowIndex: nextCtrl.rowNode.rowIndex, rowPinned: null } : undefined; } function isLastRowInContainer(beans, rowPosition) { const { rowPinned, rowIndex } = rowPosition; const { pinnedRowModel, pageBounds } = beans; if (rowPinned === "top") { const lastTopIndex = (pinnedRowModel?.getPinnedTopRowCount() ?? 0) - 1; return lastTopIndex <= rowIndex; } if (rowPinned === "bottom") { const lastBottomIndex = (pinnedRowModel?.getPinnedBottomRowCount() ?? 0) - 1; return lastBottomIndex <= rowIndex; } const lastBodyIndex = pageBounds.getLastRow(); return lastBodyIndex <= rowIndex; } function _addFocusableContainerListener(beans, comp, eGui) { comp.addManagedElementListeners(eGui, { keydown: (e) => { if (!e.defaultPrevented && !_shouldSkipFocusableContainerListener(e) && e.key === KeyCode.TAB) { const backwards = e.shiftKey; if (!_findNextFocusableElement(beans, eGui, false, backwards)) { if (_focusNextGridCoreContainer(beans, backwards)) { e.preventDefault(); } } } } }); } function _isHeaderFocusSuppressed(beans) { return beans.gos.get("suppressHeaderFocus") || !!beans.overlays?.exclusive; } function _isCellFocusSuppressed(beans) { return beans.gos.get("suppressCellFocus") || !!beans.overlays?.exclusive; } function _focusNextGridCoreContainer(beans, backwards, forceOut = false) { const gridCtrl = beans.ctrlsSvc.get("gridCtrl"); const focusResult = gridCtrl.focusNextInnerContainer(backwards); if (focusResult === true) { return true; } if (focusResult === false) { return focusResult; } if (forceOut || !backwards && !gridCtrl.isDetailGrid() && gridCtrl.isFocusInsideGridBody()) { gridCtrl.forceFocusOutOfContainer(backwards); } return false; } function _attemptToRestoreCellFocus(beans, focusedCell) { const focusSvc = beans.focusSvc; const currentFocusedCell = focusSvc.getFocusedCell(); if (currentFocusedCell && focusedCell && _areCellsEqual(currentFocusedCell, focusedCell)) { const { rowIndex, rowPinned, column } = focusedCell; if (_isNothingFocused(beans)) { focusSvc.setFocusedCell({ rowIndex, column, rowPinned, forceBrowserFocus: true, preventScrollOnBrowserFocus: !_isKeyboardMode() }); } } } function _getDefaultTabTargetForContainer(container, getGridBodyTabTarget) { const containerName = container.getFocusableContainerName(); if (containerName === "gridBody") { return getGridBodyTabTarget(); } return _runWithContainerFocusAllowed(container, () => _findFocusableElements(container.getGui(), ".ag-tab-guard").length > 0) ? containerName : null; } function _runWithContainerFocusAllowed(container, callback) { container.setAllowFocus?.(true); try { return callback(); } finally { container.setAllowFocus?.(false); } } var AG_GRID_SKIP_FOCUSABLE_CONTAINER = "__ag_Grid_Skip_Focusable_Container"; function _skipFocusableContainerListenerForAgGrid(event) { event[AG_GRID_SKIP_FOCUSABLE_CONTAINER] = true; } function _shouldSkipFocusableContainerListener(event) { return event[AG_GRID_SKIP_FOCUSABLE_CONTAINER] === true; } function getHeaderRowCount(colModel) { if (!colModel.cols) { return -1; } return colModel.cols.treeDepth + 1; } function getFocusHeaderRowCount(beans) { return beans.ctrlsSvc.getHeaderRowContainerCtrl()?.getRowCount() ?? 0; } function getGroupRowsHeight(beans) { const heights = []; const headerRowContainerCtrls = beans.ctrlsSvc.getHeaderRowContainerCtrls(); for (const headerRowContainerCtrl of headerRowContainerCtrls) { if (!headerRowContainerCtrl) { continue; } const groupRowCount = headerRowContainerCtrl.getGroupRowCount() || 0; for (let i = 0;i < groupRowCount; i++) { const headerRowCtrl = headerRowContainerCtrl.getGroupRowCtrlAtIndex(i); const currentHeightAtPos = heights[i]; if (headerRowCtrl) { const newHeight = getColumnGroupHeaderRowHeight(beans, headerRowCtrl); if (currentHeightAtPos == null || newHeight > currentHeightAtPos) { heights[i] = newHeight; } } } } return heights; } function getColumnGroupHeaderRowHeight(beans, headerRowCtrl) { const defaultHeight = beans.colModel.isPivotMode() ? getPivotGroupHeaderHeight(beans) : getGroupHeaderHeight(beans); let maxDisplayedHeight = defaultHeight; const headerRowCellCtrls = headerRowCtrl.getHeaderCellCtrls(); for (const headerCellCtrl of headerRowCellCtrls) { const { column } = headerCellCtrl; const height = column.getAutoHeaderHeight(); if (height != null && height > maxDisplayedHeight && column.isAutoHeaderHeight()) { maxDisplayedHeight = height; } } return maxDisplayedHeight; } function getColumnHeaderRowHeight(beans) { const defaultHeight = beans.colModel.isPivotMode() ? getPivotHeaderHeight(beans) : getHeaderHeight(beans); let maxDisplayedHeight = defaultHeight; beans.colModel.forAllCols((col) => { const height = col.getAutoHeaderHeight(); if (height != null && height > maxDisplayedHeight && col.isAutoHeaderHeight()) { maxDisplayedHeight = height; } }); return maxDisplayedHeight; } function getHeaderHeight(beans) { return beans.gos.get("headerHeight") ?? beans.environment.getDefaultHeaderHeight(); } function getFloatingFiltersHeight(beans) { return beans.gos.get("floatingFiltersHeight") ?? getHeaderHeight(beans); } function getGroupHeaderHeight(beans) { return beans.gos.get("groupHeaderHeight") ?? getHeaderHeight(beans); } function getPivotHeaderHeight(beans) { return beans.gos.get("pivotHeaderHeight") ?? getHeaderHeight(beans); } function getPivotGroupHeaderHeight(beans) { return beans.gos.get("pivotGroupHeaderHeight") ?? getGroupHeaderHeight(beans); } function isHeaderPositionEqual(headerPosA, headerPosB) { return headerPosA.headerRowIndex === headerPosB.headerRowIndex && headerPosA.column === headerPosB.column; } function isHeaderPosition(position) { return position?.headerRowIndex != null; } var GridHeaderCtrl = class extends BeanStub { setComp(comp, eGui, eFocusableElement) { this.comp = comp; this.eGui = eGui; const { beans } = this; const { headerNavigation, touchSvc, ctrlsSvc } = beans; if (headerNavigation) { this.createManagedBean(new ManagedFocusFeature(eFocusableElement, { onTabKeyDown: this.onTabKeyDown.bind(this), handleKeyDown: this.handleKeyDown.bind(this), onFocusOut: this.onFocusOut.bind(this) })); } this.addManagedEventListeners({ columnPivotModeChanged: this.onPivotModeChanged.bind(this, beans), displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this, beans) }); this.onPivotModeChanged(beans); this.setupHeaderHeight(); const listener = this.onHeaderContextMenu.bind(this); this.addManagedElementListeners(this.eGui, { contextmenu: listener }); touchSvc?.mockHeaderContextMenu(this, listener); ctrlsSvc.register("gridHeaderCtrl", this); } setupHeaderHeight() { const listener = this.setHeaderHeight.bind(this); listener(); this.addManagedPropertyListeners([ "headerHeight", "pivotHeaderHeight", "groupHeaderHeight", "pivotGroupHeaderHeight", "floatingFiltersHeight" ], listener); this.addManagedEventListeners({ headerRowsChanged: listener, columnHeaderHeightChanged: listener, columnGroupHeaderHeightChanged: () => _requestAnimationFrame(this.beans, () => listener()), stylesChanged: listener, advancedFilterEnabledChanged: listener }); } setHeaderHeight() { const { beans } = this; let totalHeaderHeight = 0; const groupHeight = getGroupRowsHeight(beans).reduce((prev, curr) => prev + curr, 0); const headerHeight = getColumnHeaderRowHeight(beans); if (beans.filterManager?.hasFloatingFilters()) { totalHeaderHeight += getFloatingFiltersHeight(beans); } totalHeaderHeight += groupHeight; totalHeaderHeight += headerHeight; const headerBorderWidth = beans.environment.getHeaderRowBorderWidth(); const totalHeaderHeightWithBorder = totalHeaderHeight + headerBorderWidth; if (this.headerHeightWithBorder !== totalHeaderHeightWithBorder) { this.headerHeightWithBorder = totalHeaderHeightWithBorder; const px = `${totalHeaderHeightWithBorder}px`; this.comp.setHeightAndMinHeight(px); } if (this.headerHeight !== totalHeaderHeight) { this.headerHeight = totalHeaderHeight; this.eventSvc.dispatchEvent({ type: "headerHeightChanged" }); } } onPivotModeChanged(beans) { const pivotMode = beans.colModel.isPivotMode(); this.comp.toggleCss("ag-pivot-on", pivotMode); this.comp.toggleCss("ag-pivot-off", !pivotMode); } onDisplayedColumnsChanged(beans) { const columns = beans.visibleCols.allCols; const shouldAllowOverflow = columns.some((col) => col.isSpanHeaderHeight()); this.comp.toggleCss("ag-header-allow-overflow", shouldAllowOverflow); } onTabKeyDown(e) { const isRtl = this.gos.get("enableRtl"); const backwards = e.shiftKey; const direction = backwards !== isRtl ? "LEFT" : "RIGHT"; const { beans } = this; const { headerNavigation, focusSvc } = beans; if (headerNavigation.navigateHorizontally(direction, true, e) || !backwards && focusSvc.focusOverlay(false) || _focusNextGridCoreContainer(beans, backwards, true)) { e.preventDefault(); } } handleKeyDown(e) { let direction = null; const { headerNavigation } = this.beans; switch (e.key) { case KeyCode.LEFT: direction = "LEFT"; case KeyCode.RIGHT: { if (!_exists(direction)) { direction = "RIGHT"; } if (headerNavigation.navigateHorizontally(direction, false, e)) { e.preventDefault(); } break; } case KeyCode.UP: direction = "UP"; case KeyCode.DOWN: { if (!_exists(direction)) { direction = "DOWN"; } if (headerNavigation.navigateVertically(direction, e)) { e.preventDefault(); } break; } default: return; } } onFocusOut(e) { const { relatedTarget } = e; const { eGui, beans } = this; if (!relatedTarget && eGui.contains(_getActiveDomElement(beans))) { return; } if (!eGui.contains(relatedTarget)) { beans.focusSvc.focusedHeader = null; } } onHeaderContextMenu(mouseEvent, touch, touchEvent) { const { menuSvc, ctrlsSvc } = this.beans; if (!mouseEvent && !touchEvent || !menuSvc?.isHeaderContextMenuEnabled()) { return; } const { target } = mouseEvent ?? touch; if (target === this.eGui || target === ctrlsSvc.getHeaderRowContainerCtrl()?.eViewport) { menuSvc.showHeaderContextMenu(undefined, mouseEvent, touchEvent); } } }; var AbstractHeaderCellComp = class extends Component { constructor(template, ctrl) { super(template); this.ctrl = ctrl; } getCtrl() { return this.ctrl; } }; var HeaderCellElement = { tag: "div", cls: "ag-header-cell", role: "columnheader", children: [ { tag: "div", ref: "eResize", cls: "ag-header-cell-resize", role: "presentation" }, { tag: "div", ref: "eHeaderCompWrapper", cls: "ag-header-cell-comp-wrapper", role: "presentation" } ] }; var HeaderCellComp = class extends AbstractHeaderCellComp { constructor(ctrl) { super(HeaderCellElement, ctrl); this.eResize = RefPlaceholder; this.eHeaderCompWrapper = RefPlaceholder; this.headerCompVersion = 0; } postConstruct() { const eGui = this.getGui(); const refreshSelectAllGui = () => { const selectAllGui = this.ctrl.getSelectAllGui(); if (selectAllGui) { this.eResize.insertAdjacentElement("afterend", selectAllGui); this.addDestroyFunc(() => selectAllGui.remove()); } }; const compProxy = { setWidth: (width) => eGui.style.width = width, toggleCss: (cssClassName, on) => this.toggleCss(cssClassName, on), setUserStyles: (styles) => _addStylesToElement(eGui, styles), setAriaSort: (sort) => sort ? _setAriaSort(eGui, sort) : _removeAriaSort(eGui), setUserCompDetails: (compDetails) => this.setUserCompDetails(compDetails), getUserCompInstance: () => this.headerComp, refreshSelectAllGui, removeSelectAllGui: () => this.ctrl.getSelectAllGui()?.remove() }; this.ctrl.setComp(compProxy, this.getGui(), this.eResize, this.eHeaderCompWrapper, undefined); refreshSelectAllGui(); } destroy() { this.destroyHeaderComp(); super.destroy(); } destroyHeaderComp() { if (this.headerComp) { this.headerCompGui?.remove(); this.headerComp = this.destroyBean(this.headerComp); this.headerCompGui = undefined; } } setUserCompDetails(compDetails) { this.headerCompVersion++; const versionCopy = this.headerCompVersion; compDetails.newAgStackInstance().then((comp) => this.afterCompCreated(versionCopy, comp)); } afterCompCreated(version, headerComp) { if (version != this.headerCompVersion || !this.isAlive()) { this.destroyBean(headerComp); return; } this.destroyHeaderComp(); this.headerComp = headerComp; this.headerCompGui = headerComp.getGui(); this.eHeaderCompWrapper.appendChild(this.headerCompGui); this.ctrl.setDragSource(this.getGui()); } }; var HeaderGroupCellCompElement = { tag: "div", cls: "ag-header-group-cell", role: "columnheader", children: [ { tag: "div", ref: "eHeaderCompWrapper", cls: "ag-header-cell-comp-wrapper", role: "presentation" }, { tag: "div", ref: "eResize", cls: "ag-header-cell-resize", role: "presentation" } ] }; var HeaderGroupCellComp = class extends AbstractHeaderCellComp { constructor(ctrl) { super(HeaderGroupCellCompElement, ctrl); this.eResize = RefPlaceholder; this.eHeaderCompWrapper = RefPlaceholder; } postConstruct() { const eGui = this.getGui(); const setAttribute = (key, value) => value != null ? eGui.setAttribute(key, value) : eGui.removeAttribute(key); const compProxy = { toggleCss: (cssClassName, on) => this.toggleCss(cssClassName, on), setUserStyles: (styles) => _addStylesToElement(eGui, styles), setHeaderWrapperHidden: (hidden) => { if (hidden) { this.eHeaderCompWrapper.style.setProperty("display", "none"); } else { this.eHeaderCompWrapper.style.removeProperty("display"); } }, setHeaderWrapperMaxHeight: (value) => { if (value != null) { this.eHeaderCompWrapper.style.setProperty("max-height", `${value}px`); } else { this.eHeaderCompWrapper.style.removeProperty("max-height"); } this.eHeaderCompWrapper.classList.toggle("ag-header-cell-comp-wrapper-limited-height", value != null); }, setResizableDisplayed: (displayed) => _setDisplayed(this.eResize, displayed), setWidth: (width) => eGui.style.width = width, setAriaExpanded: (expanded) => setAttribute("aria-expanded", expanded), setUserCompDetails: (details) => this.setUserCompDetails(details), getUserCompInstance: () => this.headerGroupComp }; this.ctrl.setComp(compProxy, eGui, this.eResize, this.eHeaderCompWrapper, undefined); } setUserCompDetails(details) { details.newAgStackInstance().then((comp) => this.afterHeaderCompCreated(comp)); } afterHeaderCompCreated(headerGroupComp) { const destroyFunc = () => this.destroyBean(headerGroupComp); if (!this.isAlive()) { destroyFunc(); return; } const eGui = this.getGui(); const eHeaderGroupGui = headerGroupComp.getGui(); this.eHeaderCompWrapper.appendChild(eHeaderGroupGui); this.addDestroyFunc(destroyFunc); this.headerGroupComp = headerGroupComp; this.ctrl.setDragSource(eGui); } }; var HeaderFilterCellCompElement = { tag: "div", cls: "ag-header-cell ag-floating-filter", role: "gridcell", children: [ { tag: "div", ref: "eFloatingFilterBody", role: "presentation" }, { tag: "div", ref: "eButtonWrapper", cls: "ag-floating-filter-button ag-hidden", role: "presentation", children: [ { tag: "button", ref: "eButtonShowMainFilter", cls: "ag-button ag-floating-filter-button-button", attrs: { type: "button", tabindex: "-1" } } ] } ] }; var HeaderFilterCellComp = class extends AbstractHeaderCellComp { constructor(ctrl) { super(HeaderFilterCellCompElement, ctrl); this.eFloatingFilterBody = RefPlaceholder; this.eButtonWrapper = RefPlaceholder; this.eButtonShowMainFilter = RefPlaceholder; } postConstruct() { const eGui = this.getGui(); const compProxy = { toggleCss: (cssClassName, on) => this.toggleCss(cssClassName, on), setUserStyles: (styles) => _addStylesToElement(eGui, styles), addOrRemoveBodyCssClass: (cssClassName, on) => this.eFloatingFilterBody.classList.toggle(cssClassName, on), setButtonWrapperDisplayed: (displayed) => _setDisplayed(this.eButtonWrapper, displayed), setCompDetails: (compDetails) => this.setCompDetails(compDetails), getFloatingFilterComp: () => this.compPromise, setWidth: (width) => eGui.style.width = width, setMenuIcon: (eIcon) => this.eButtonShowMainFilter.appendChild(eIcon) }; this.ctrl.setComp(compProxy, eGui, this.eButtonShowMainFilter, this.eFloatingFilterBody, undefined); } setCompDetails(compDetails) { if (!compDetails) { this.destroyFloatingFilterComp(); this.compPromise = null; return; } this.compPromise = compDetails.newAgStackInstance(); this.compPromise.then((comp) => this.afterCompCreated(comp)); } destroy() { this.destroyFloatingFilterComp(); super.destroy(); } destroyFloatingFilterComp() { this.floatingFilterComp?.getGui().remove(); this.floatingFilterComp = this.destroyBean(this.floatingFilterComp); } afterCompCreated(comp) { if (!comp) { return; } if (!this.isAlive()) { this.destroyBean(comp); return; } this.destroyFloatingFilterComp(); this.floatingFilterComp = comp; this.eFloatingFilterBody.appendChild(comp.getGui()); comp.afterGuiAttached?.(); } }; var HeaderRowComp = class extends Component { constructor(ctrl) { super({ tag: "div", cls: ctrl.headerRowClass, role: "row" }); this.ctrl = ctrl; this.headerComps = {}; } postConstruct() { const eGui = this.getGui(); eGui.setAttribute("tabindex", String(this.gos.get("tabIndex"))); _setAriaRowIndex(this.getGui(), this.ctrl.getAriaRowIndex()); const compProxy = { setHeight: (height) => this.getGui().style.height = height, setTop: (top) => this.getGui().style.top = top, setHeaderCtrls: (ctrls, forceOrder) => this.setHeaderCtrls(ctrls, forceOrder), setWidth: (width) => this.getGui().style.width = width, setRowIndex: (rowIndex) => _setAriaRowIndex(this.getGui(), rowIndex) }; this.ctrl.setComp(compProxy, undefined); } destroy() { this.setHeaderCtrls([], false); super.destroy(); } setHeaderCtrls(ctrls, forceOrder) { if (!this.isAlive()) { return; } const oldComps = this.headerComps; this.headerComps = {}; for (const ctrl of ctrls) { const id = ctrl.instanceId; let comp = oldComps[id]; delete oldComps[id]; if (comp == null) { comp = this.createHeaderComp(ctrl); this.getGui().appendChild(comp.getGui()); } this.headerComps[id] = comp; } Object.values(oldComps).forEach((comp) => { comp.getGui().remove(); this.destroyBean(comp); }); if (forceOrder) { const comps = Object.values(this.headerComps); comps.sort((a, b) => { const leftA = a.getCtrl().column.getLeft(); const leftB = b.getCtrl().column.getLeft(); return leftA - leftB; }); const elementsInOrder = comps.map((c) => c.getGui()); _setDomChildOrder(this.getGui(), elementsInOrder); } } createHeaderComp(headerCtrl) { let result; switch (this.ctrl.type) { case "group": result = new HeaderGroupCellComp(headerCtrl); break; case "filter": result = new HeaderFilterCellComp(headerCtrl); break; default: result = new HeaderCellComp(headerCtrl); break; } this.createBean(result); result.setParentComponent(this); return result; } }; var CenterWidthFeature = class extends BeanStub { constructor(callback, addSpacer = false) { super(); this.callback = callback; this.addSpacer = addSpacer; } postConstruct() { const listener = this.setWidth.bind(this); this.addManagedPropertyListener("domLayout", listener); this.addManagedEventListeners({ columnContainerWidthChanged: listener, displayedColumnsChanged: listener, leftPinnedWidthChanged: listener }); if (this.addSpacer) { this.addManagedEventListeners({ rightPinnedWidthChanged: listener, scrollVisibilityChanged: listener, scrollbarWidthChanged: listener }); } this.setWidth(); } setWidth() { const printLayout = _isDomLayout(this.gos, "print"); const { visibleCols, scrollVisibleSvc } = this.beans; const centerWidth = visibleCols.bodyWidth; const leftWidth = visibleCols.getColsLeftWidth(); const rightWidth = visibleCols.getDisplayedColumnsRightWidth(); let totalWidth; if (printLayout) { totalWidth = centerWidth + leftWidth + rightWidth; } else { totalWidth = centerWidth; if (this.addSpacer) { const relevantWidth = this.gos.get("enableRtl") ? leftWidth : rightWidth; if (relevantWidth === 0 && scrollVisibleSvc.verticalScrollShowing) { totalWidth += scrollVisibleSvc.getScrollbarWidth(); } } } this.callback(totalWidth); } }; function setupCompBean(ctrl, ctx, compBean) { if (compBean) { ctrl.addDestroyFunc(() => ctx.destroyBean(compBean)); } return compBean ?? ctrl; } var SetLeftFeature = class extends BeanStub { constructor(columnOrGroup, eCell, beans, colsSpanning) { super(); this.columnOrGroup = columnOrGroup; this.eCell = eCell; this.colsSpanning = colsSpanning; this.columnOrGroup = columnOrGroup; this.ariaEl = eCell.querySelector("[role=columnheader]") || eCell; this.beans = beans; } setColsSpanning(colsSpanning) { this.colsSpanning = colsSpanning; this.onLeftChanged(); } getColumnOrGroup() { const { beans, colsSpanning } = this; if (beans.gos.get("enableRtl") && colsSpanning) { return _last(colsSpanning); } return this.columnOrGroup; } postConstruct() { const onLeftChanged = this.onLeftChanged.bind(this); this.addManagedListeners(this.columnOrGroup, { leftChanged: onLeftChanged }); this.setLeftFirstTime(); this.addManagedEventListeners({ displayedColumnsWidthChanged: onLeftChanged }); this.addManagedPropertyListener("domLayout", onLeftChanged); } setLeftFirstTime() { const { gos, colAnimation } = this.beans; const suppressMoveAnimation = gos.get("suppressColumnMoveAnimation"); const oldLeftExists = _exists(this.columnOrGroup.getOldLeft()); const animateColumnMove = colAnimation?.isActive() && oldLeftExists && !suppressMoveAnimation; if (animateColumnMove) { this.animateInLeft(); } else { this.onLeftChanged(); } } animateInLeft() { const colOrGroup = this.getColumnOrGroup(); const oldActualLeft = this.modifyLeftForPrintLayout(colOrGroup, colOrGroup.getOldLeft()); const actualLeft = this.modifyLeftForPrintLayout(colOrGroup, colOrGroup.getLeft()); this.setLeft(oldActualLeft); this.actualLeft = actualLeft; this.beans.colAnimation.executeNextVMTurn(() => { if (this.actualLeft === actualLeft) { this.setLeft(actualLeft); } }); } onLeftChanged() { const colOrGroup = this.getColumnOrGroup(); const left = colOrGroup.getLeft(); this.actualLeft = this.modifyLeftForPrintLayout(colOrGroup, left); this.setLeft(this.actualLeft); } modifyLeftForPrintLayout(colOrGroup, leftPosition) { const { gos, visibleCols } = this.beans; const printLayout = _isDomLayout(gos, "print"); if (!printLayout) { return leftPosition; } if (colOrGroup.getPinned() === "left") { return leftPosition; } const leftWidth = visibleCols.getColsLeftWidth(); if (colOrGroup.getPinned() === "right") { const bodyWidth = visibleCols.bodyWidth; return leftWidth + bodyWidth + leftPosition; } return leftWidth + leftPosition; } setLeft(value) { if (_exists(value)) { this.eCell.style.left = `${value}px`; } if (isColumnGroup(this.columnOrGroup)) { const children = this.columnOrGroup.getLeafColumns(); if (!children.length) { return; } if (children.length > 1) { _setAriaColSpan(this.ariaEl, children.length); } } } }; var CSS_FIRST_COLUMN = "ag-column-first"; var CSS_LAST_COLUMN = "ag-column-last"; function _getHeaderClassesFromColDef(abstractColDef, gos, column, columnGroup) { if (_missing(abstractColDef)) { return []; } return getColumnClassesFromCollDef(abstractColDef.headerClass, abstractColDef, gos, column, columnGroup); } function _getToolPanelClassesFromColDef(abstractColDef, gos, column, columnGroup) { if (_missing(abstractColDef)) { return []; } return getColumnClassesFromCollDef(abstractColDef.toolPanelClass, abstractColDef, gos, column, columnGroup); } function refreshFirstAndLastStyles(comp, column, presentedColsService) { comp.toggleCss(CSS_FIRST_COLUMN, presentedColsService.isColAtEdge(column, "first")); comp.toggleCss(CSS_LAST_COLUMN, presentedColsService.isColAtEdge(column, "last")); } function getClassParams(abstractColDef, gos, column, columnGroup) { return _addGridCommonParams(gos, { colDef: abstractColDef, column, columnGroup }); } function getColumnClassesFromCollDef(classesOrFunc, abstractColDef, gos, column, columnGroup) { if (_missing(classesOrFunc)) { return []; } let classToUse; if (typeof classesOrFunc === "function") { const params = getClassParams(abstractColDef, gos, column, columnGroup); classToUse = classesOrFunc(params); } else { classToUse = classesOrFunc; } if (typeof classToUse === "string") { return [classToUse]; } if (Array.isArray(classToUse)) { return [...classToUse]; } return []; } var instanceIdSequence2 = 0; var DOM_DATA_KEY_HEADER_CTRL = "headerCtrl"; var AbstractHeaderCellCtrl = class extends BeanStub { constructor(column, rowCtrl) { super(); this.column = column; this.rowCtrl = rowCtrl; this.resizeToggleTimeout = 0; this.resizeMultiplier = 1; this.resizeFeature = null; this.lastFocusEvent = null; this.dragSource = null; this.reAttemptToFocus = false; this.instanceId = column.getUniqueId() + "-" + instanceIdSequence2++; } postConstruct() { const refreshTabIndex = this.refreshTabIndex.bind(this); this.addManagedPropertyListeners(["suppressHeaderFocus"], refreshTabIndex); this.addManagedEventListeners({ overlayExclusiveChanged: refreshTabIndex }); } setComp(comp, eGui, eResize, eHeaderCompWrapper, compBean) { eGui.setAttribute("col-id", this.column.colIdSanitised); this.wireComp(comp, eGui, eResize, eHeaderCompWrapper, compBean); if (this.reAttemptToFocus) { this.reAttemptToFocus = false; this.focus(this.lastFocusEvent ?? undefined); } } shouldStopEventPropagation(event) { const { headerRowIndex, column } = this.beans.focusSvc.focusedHeader; const colDef = column.getDefinition(); const colDefFunc = colDef?.suppressHeaderKeyboardEvent; if (!_exists(colDefFunc)) { return false; } const params = _addGridCommonParams(this.gos, { colDef, column, headerRowIndex, event }); return !!colDefFunc(params); } getWrapperHasFocus() { const activeEl = _getActiveDomElement(this.beans); return activeEl === this.eGui; } setGui(eGui, compBean) { this.eGui = eGui; this.addDomData(compBean); compBean.addManagedListeners(this.beans.eventSvc, { displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this) }); compBean.addManagedElementListeners(this.eGui, { focus: this.onGuiFocus.bind(this) }); this.onDisplayedColumnsChanged(); this.refreshTabIndex(); } refreshHeaderStyles() { const colDef = this.column.getDefinition(); if (!colDef) { return; } const { headerStyle } = colDef; let styles; if (typeof headerStyle === "function") { const cellStyleParams = this.getHeaderClassParams(); styles = headerStyle(cellStyleParams); } else { styles = headerStyle; } if (styles) { this.comp.setUserStyles(styles); } } onGuiFocus() { this.eventSvc.dispatchEvent({ type: "headerFocused", column: this.column }); } setupAutoHeight(params) { const { wrapperElement, checkMeasuringCallback, compBean } = params; const { beans } = this; const measureHeight = (timesCalled) => { if (!this.isAlive() || !compBean.isAlive()) { return; } const { paddingTop, paddingBottom, borderBottomWidth, borderTopWidth } = _getElementSize(this.eGui); const extraHeight = paddingTop + paddingBottom + borderBottomWidth + borderTopWidth; const wrapperHeight = wrapperElement.offsetHeight; const autoHeight = wrapperHeight + extraHeight; if (timesCalled < 5) { const doc = _getDocument(beans); const notYetInDom = !doc?.contains(wrapperElement); const possiblyNoContentYet = autoHeight == 0; if (notYetInDom || possiblyNoContentYet) { _batchCall(() => measureHeight(timesCalled + 1), "raf", beans); return; } } this.setColHeaderHeight(this.column, autoHeight); }; let isMeasuring = false; let stopResizeObserver; const checkMeasuring = () => { const newValue = this.column.isAutoHeaderHeight(); if (newValue && !isMeasuring) { startMeasuring(); } if (!newValue && isMeasuring) { stopMeasuring(); } }; const startMeasuring = () => { isMeasuring = true; this.comp.toggleCss("ag-header-cell-auto-height", true); measureHeight(0); stopResizeObserver = _observeResize(this.beans, wrapperElement, () => measureHeight(0)); }; const stopMeasuring = () => { isMeasuring = false; if (stopResizeObserver) { stopResizeObserver(); } this.comp.toggleCss("ag-header-cell-auto-height", false); stopResizeObserver = undefined; }; checkMeasuring(); compBean.addDestroyFunc(() => stopMeasuring()); compBean.addManagedListeners(this.column, { widthChanged: () => isMeasuring && measureHeight(0) }); compBean.addManagedEventListeners({ sortChanged: () => { if (isMeasuring) { window.setTimeout(() => measureHeight(0)); } } }); if (checkMeasuringCallback) { checkMeasuringCallback(checkMeasuring); } } onDisplayedColumnsChanged() { const { comp, column, beans, eGui } = this; if (!comp || !column || !eGui) { return; } refreshFirstAndLastStyles(comp, column, beans.visibleCols); _setAriaColIndex(eGui, beans.visibleCols.getAriaColIndex(column)); } addResizeAndMoveKeyboardListeners(compBean) { compBean.addManagedListeners(this.eGui, { keydown: this.onGuiKeyDown.bind(this), keyup: this.onGuiKeyUp.bind(this) }); } refreshTabIndex() { const suppressHeaderFocus = _isHeaderFocusSuppressed(this.beans); if (this.eGui) { _addOrRemoveAttribute(this.eGui, "tabindex", suppressHeaderFocus ? null : "-1"); } } onGuiKeyDown(e) { const activeEl = _getActiveDomElement(this.beans); const isLeftOrRight = e.key === KeyCode.LEFT || e.key === KeyCode.RIGHT; if (this.isResizing) { e.preventDefault(); e.stopImmediatePropagation(); } if (activeEl !== this.eGui || !e.shiftKey && !e.altKey && !e.ctrlKey && !e.metaKey) { return; } if (this.isResizing || isLeftOrRight) { e.preventDefault(); e.stopImmediatePropagation(); } const isCopy = (e.ctrlKey || e.metaKey) && _normaliseQwertyAzerty(e) === KeyCode.C; if (isCopy) { return this.beans.clipboardSvc?.copyToClipboard(); } if (!isLeftOrRight) { return; } const isLeft = e.key === KeyCode.LEFT !== this.gos.get("enableRtl"); const direction = isLeft ? "left" : "right"; if (e.altKey) { this.isResizing = true; this.resizeMultiplier += 1; const diff = this.getViewportAdjustedResizeDiff(e); this.resizeHeader(diff, e.shiftKey); this.resizeFeature?.toggleColumnResizing(true); } else { this.moveHeader(direction); } } moveHeader(hDirection) { this.beans.colMoves?.moveHeader(hDirection, this.eGui, this.column, this.rowCtrl.pinned, this); } getViewportAdjustedResizeDiff(e) { const diff = this.getResizeDiff(e); const { pinnedCols } = this.beans; return pinnedCols ? pinnedCols.getHeaderResizeDiff(diff, this.column) : diff; } getResizeDiff(e) { const { gos, column } = this; let isLeft = e.key === KeyCode.LEFT !== gos.get("enableRtl"); const pinned = column.getPinned(); const isRtl = gos.get("enableRtl"); if (pinned) { if (isRtl !== (pinned === "right")) { isLeft = !isLeft; } } return (isLeft ? -1 : 1) * this.resizeMultiplier; } onGuiKeyUp() { if (!this.isResizing) { return; } if (this.resizeToggleTimeout) { window.clearTimeout(this.resizeToggleTimeout); this.resizeToggleTimeout = 0; } this.isResizing = false; this.resizeMultiplier = 1; this.resizeToggleTimeout = window.setTimeout(() => { this.resizeFeature?.toggleColumnResizing(false); }, 150); } handleKeyDown(e) { const wrapperHasFocus = this.getWrapperHasFocus(); switch (e.key) { case KeyCode.PAGE_DOWN: case KeyCode.PAGE_UP: case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: if (wrapperHasFocus) { e.preventDefault(); } } } addDomData(compBean) { const key = DOM_DATA_KEY_HEADER_CTRL; const { eGui, gos } = this; _setDomData(gos, eGui, key, this); compBean.addDestroyFunc(() => _setDomData(gos, eGui, key, null)); } focus(event) { if (!this.isAlive()) { return false; } const { eGui } = this; if (!eGui) { this.reAttemptToFocus = true; } else { this.lastFocusEvent = event || null; eGui.focus(); } return true; } focusThis() { this.beans.focusSvc.focusedHeader = { headerRowIndex: this.rowCtrl.rowIndex, column: this.column }; } removeDragSource() { if (this.dragSource) { this.beans.dragAndDrop?.removeDragSource(this.dragSource); this.dragSource = null; } } handleContextMenuMouseEvent(mouseEvent, touchEvent, column) { const event = mouseEvent ?? touchEvent; const { menuSvc, gos } = this.beans; if (gos.get("preventDefaultOnContextMenu")) { event.preventDefault(); } if (menuSvc?.isHeaderContextMenuEnabled(column)) { menuSvc.showHeaderContextMenu(column, mouseEvent, touchEvent); } this.dispatchColumnMouseEvent("columnHeaderContextMenu", column); } dispatchColumnMouseEvent(eventType, column) { this.eventSvc.dispatchEvent({ type: eventType, column }); } setColHeaderHeight(col, height) { if (!col.setAutoHeaderHeight(height)) { return; } const { eventSvc } = this; if (col.isColumn) { eventSvc.dispatchEvent({ type: "columnHeaderHeightChanged", column: col, columns: [col], source: "autosizeColumnHeaderHeight" }); } else { eventSvc.dispatchEvent({ type: "columnGroupHeaderHeightChanged", columnGroup: col, source: "autosizeColumnGroupHeaderHeight" }); } } clearComponent() { this.removeDragSource(); this.resizeFeature = null; this.comp = null; this.eGui = null; } destroy() { super.destroy(); this.column = null; this.lastFocusEvent = null; this.rowCtrl = null; } }; var HeaderCellCtrl = class extends AbstractHeaderCellCtrl { constructor() { super(...arguments); this.refreshFunctions = {}; this.userHeaderClasses = /* @__PURE__ */ new Set; this.ariaDescriptionProperties = /* @__PURE__ */ new Map; } wireComp(comp, eGui, eResize, eHeaderCompWrapper, compBeanInput) { this.comp = comp; const { rowCtrl, column, beans } = this; const { colResize, context, colHover, rangeSvc } = beans; const compBean = setupCompBean(this, context, compBeanInput); this.setGui(eGui, compBean); this.updateState(); this.setupWidth(compBean); this.setupMovingCss(compBean); this.setupMenuClass(compBean); this.setupSortableClass(compBean); this.setupWrapTextClass(); this.refreshSpanHeaderHeight(); this.setupAutoHeight({ wrapperElement: eHeaderCompWrapper, checkMeasuringCallback: (checkMeasuring) => this.setRefreshFunction("measuring", checkMeasuring), compBean }); this.addColumnHoverListener(compBean); this.setupFilterClass(compBean); this.setupStylesFromColDef(); this.setupClassesFromColDef(); this.setupTooltip(); this.addActiveHeaderMouseListeners(compBean); this.setupSelectAll(compBean); this.setupUserComp(); this.refreshAria(); if (colResize) { this.resizeFeature = compBean.createManagedBean(colResize.createResizeFeature(rowCtrl.pinned, column, eResize, comp, this)); } else { _setDisplayed(eResize, false); } colHover?.createHoverFeature(compBean, [column], eGui); rangeSvc?.createRangeHighlightFeature(compBean, column, comp); compBean.createManagedBean(new SetLeftFeature(column, eGui, beans)); compBean.createManagedBean(new ManagedFocusFeature(eGui, { shouldStopEventPropagation: (e) => this.shouldStopEventPropagation(e), onTabKeyDown: () => null, handleKeyDown: this.handleKeyDown.bind(this), onFocusIn: this.onFocusIn.bind(this), onFocusOut: this.onFocusOut.bind(this) })); this.addResizeAndMoveKeyboardListeners(compBean); compBean.addManagedPropertyListeners(["suppressMovableColumns", "suppressMenuHide", "suppressAggFuncInHeader", "enableAdvancedFilter"], () => this.refresh()); compBean.addManagedListeners(column, { colDefChanged: () => this.refresh(), formulaRefChanged: () => this.refresh(), headerHighlightChanged: this.onHeaderHighlightChanged.bind(this) }); const listener = () => this.checkDisplayName(); compBean.addManagedEventListeners({ columnValueChanged: listener, columnRowGroupChanged: listener, columnPivotChanged: listener, headerHeightChanged: this.onHeaderHeightChanged.bind(this) }); compBean.addDestroyFunc(() => { this.refreshFunctions = {}; this.selectAllFeature = null; this.dragSourceElement = undefined; this.userCompDetails = null; this.userHeaderClasses.clear(); this.ariaDescriptionProperties.clear(); this.clearComponent(); }); } resizeHeader(delta, shiftKey) { this.beans.colResize?.resizeHeader(this.column, delta, shiftKey); } getHeaderClassParams() { const { column, beans } = this; const colDef = column.colDef; return _addGridCommonParams(beans.gos, { colDef, column, floatingFilter: false }); } setupUserComp() { const compDetails = this.lookupUserCompDetails(); if (compDetails) { this.setCompDetails(compDetails); } } setCompDetails(compDetails) { this.userCompDetails = compDetails; this.comp.setUserCompDetails(compDetails); } lookupUserCompDetails() { const params = this.createParams(); const colDef = this.column.getColDef(); return _getHeaderCompDetails(this.beans.userCompFactory, colDef, params); } createParams() { const { menuSvc, sortSvc, colFilter, gos } = this.beans; const params = _addGridCommonParams(gos, { column: this.column, displayName: this.displayName, enableSorting: this.column.isSortable(), enableMenu: this.menuEnabled, enableFilterButton: this.openFilterEnabled && !!menuSvc?.isHeaderFilterButtonEnabled(this.column), enableFilterIcon: !!colFilter && (!this.openFilterEnabled || _isLegacyMenuEnabled(this.gos)), showColumnMenu: (buttonElement, onClosedCallback) => { menuSvc?.showColumnMenu({ column: this.column, buttonElement, positionBy: "button", onClosedCallback }); }, showColumnMenuAfterMouseClick: (mouseEvent, onClosedCallback) => { menuSvc?.showColumnMenu({ column: this.column, mouseEvent, positionBy: "mouse", onClosedCallback }); }, showFilter: (buttonElement) => { menuSvc?.showFilterMenu({ column: this.column, buttonElement, containerType: "columnFilter", positionBy: "button" }); }, progressSort: (multiSort) => { sortSvc?.progressSort(this.column, !!multiSort, "uiColumnSorted"); }, setSort: (sort, multiSort) => { sortSvc?.setSortForColumn(this.column, _getSortDefFromInput(sort), !!multiSort, "uiColumnSorted"); }, eGridHeader: this.eGui, setTooltip: (value, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); this.setupTooltip(value, shouldDisplayTooltip); } }); return params; } setupSelectAll(compBean) { const { selectionSvc } = this.beans; if (!selectionSvc) { return; } this.selectAllFeature = compBean.createOptionalManagedBean(selectionSvc.createSelectAllFeature(this.column)); this.selectAllFeature?.setComp(this); compBean.addManagedPropertyListener("rowSelection", () => { const selectAllFeature = selectionSvc.createSelectAllFeature(this.column); if (selectAllFeature && !this.selectAllFeature) { this.selectAllFeature = compBean.createManagedBean(selectAllFeature); this.selectAllFeature?.setComp(this); this.comp.refreshSelectAllGui(); } else if (this.selectAllFeature && !selectAllFeature) { this.comp.removeSelectAllGui(); this.selectAllFeature = this.destroyBean(this.selectAllFeature); } }); } getSelectAllGui() { return this.selectAllFeature?.getCheckboxGui(); } handleKeyDown(e) { super.handleKeyDown(e); if (e.key === KeyCode.SPACE) { this.selectAllFeature?.onSpaceKeyDown(e); } else if (e.key === KeyCode.ENTER) { this.onEnterKeyDown(e); } else if (e.key === KeyCode.DOWN && e.altKey) { this.showMenuOnKeyPress(e, false); } } onEnterKeyDown(e) { const { column, gos, sortable, beans } = this; let actioned = false; if (e.ctrlKey || e.metaKey) { actioned = this.showMenuOnKeyPress(e, true); } if (!actioned) { if (!e.altKey && _getEnableColumnSelection(gos)) { beans.rangeSvc?.handleColumnSelection(column, e); } else if (sortable) { beans.sortSvc?.progressSort(column, e.shiftKey, "uiColumnSorted"); } } } showMenuOnKeyPress(e, isFilterShortcut) { const headerComp = this.comp.getUserCompInstance(); if (!isHeaderComp(headerComp)) { return false; } if (headerComp.onMenuKeyboardShortcut(isFilterShortcut)) { e.preventDefault(); return true; } return false; } onFocusIn(e) { if (!this.eGui.contains(e.relatedTarget)) { this.focusThis(); this.announceAriaDescription(); } if (_isKeyboardMode()) { this.setActiveHeader(true); } } onFocusOut(e) { if (this.eGui.contains(e.relatedTarget)) { return; } this.setActiveHeader(false); } setupTooltip(value, shouldDisplayTooltip) { this.tooltipFeature = this.beans.tooltipSvc?.setupHeaderTooltip(this.tooltipFeature, this, value, shouldDisplayTooltip); } setupStylesFromColDef() { this.setRefreshFunction("headerStyles", this.refreshHeaderStyles.bind(this)); this.refreshHeaderStyles(); } setupClassesFromColDef() { const refreshHeaderClasses = () => { const colDef = this.column.getColDef(); const classes = _getHeaderClassesFromColDef(colDef, this.gos, this.column, null); const oldClasses = this.userHeaderClasses; this.userHeaderClasses = new Set(classes); for (const c of classes) { if (oldClasses.has(c)) { oldClasses.delete(c); } else { this.comp.toggleCss(c, true); } } for (const c of oldClasses) { this.comp.toggleCss(c, false); } }; this.setRefreshFunction("headerClasses", refreshHeaderClasses); refreshHeaderClasses(); } setDragSource(eSource) { this.dragSourceElement = eSource; this.removeDragSource(); if (!eSource || !this.draggable) { return; } this.dragSource = this.beans.colMoves?.setDragSourceForHeader(eSource, this.column, this.displayName) ?? null; } updateState() { const { menuSvc } = this.beans; this.menuEnabled = !!menuSvc?.isColumnMenuInHeaderEnabled(this.column); this.openFilterEnabled = !!menuSvc?.isFilterMenuInHeaderEnabled(this.column); this.sortable = this.column.isSortable(); this.displayName = this.calculateDisplayName(); this.draggable = this.workOutDraggable(); } setRefreshFunction(name, func) { this.refreshFunctions[name] = func; } refresh() { this.updateState(); this.refreshHeaderComp(); this.refreshAria(); for (const f of Object.values(this.refreshFunctions)) { f(); } } refreshHeaderComp() { const newCompDetails = this.lookupUserCompDetails(); if (!newCompDetails) { return; } const compInstance = this.comp.getUserCompInstance(); const attemptRefresh = compInstance != null && this.userCompDetails.componentClass == newCompDetails.componentClass; const headerCompRefreshed = attemptRefresh ? this.attemptHeaderCompRefresh(newCompDetails.params) : false; if (headerCompRefreshed) { this.setDragSource(this.dragSourceElement); } else { this.setCompDetails(newCompDetails); } } attemptHeaderCompRefresh(params) { const headerComp = this.comp.getUserCompInstance(); if (!headerComp) { return false; } if (!headerComp.refresh) { return false; } const res = headerComp.refresh(params); return res; } calculateDisplayName() { return this.beans.colNames.getDisplayNameForColumn(this.column, "header", true); } checkDisplayName() { if (this.displayName !== this.calculateDisplayName()) { this.refresh(); } } workOutDraggable() { const colDef = this.column.getColDef(); const isSuppressMovableColumns = this.gos.get("suppressMovableColumns"); const colCanMove = !isSuppressMovableColumns && !colDef.suppressMovable && !colDef.lockPosition; return !!colCanMove || !!colDef.enableRowGroup || !!colDef.enablePivot; } setupWidth(compBean) { const listener = () => { const columnWidth = this.column.getActualWidth(); this.comp.setWidth(`${columnWidth}px`); }; compBean.addManagedListeners(this.column, { widthChanged: listener }); listener(); } setupMovingCss(compBean) { const listener = () => { this.comp.toggleCss("ag-header-cell-moving", this.column.isMoving()); }; compBean.addManagedListeners(this.column, { movingChanged: listener }); listener(); } setupMenuClass(compBean) { const listener = () => { this.comp?.toggleCss("ag-column-menu-visible", this.column.isMenuVisible()); }; compBean.addManagedListeners(this.column, { menuVisibleChanged: listener }); listener(); } setupSortableClass(compBean) { const updateSortableCssClass = () => { this.comp.toggleCss("ag-header-cell-sortable", !!this.sortable); }; updateSortableCssClass(); this.setRefreshFunction("updateSortable", updateSortableCssClass); compBean.addManagedEventListeners({ sortChanged: this.refreshAriaSort.bind(this) }); } setupFilterClass(compBean) { const listener = () => { const isFilterActive = this.column.isFilterActive(); this.comp.toggleCss("ag-header-cell-filtered", isFilterActive); this.refreshAria(); }; compBean.addManagedListeners(this.column, { filterActiveChanged: listener }); listener(); } setupWrapTextClass() { const listener = () => { const wrapText = !!this.column.getColDef().wrapHeaderText; this.comp.toggleCss("ag-header-cell-wrap-text", wrapText); }; listener(); this.setRefreshFunction("wrapText", listener); } onHeaderHighlightChanged() { const highlighted = this.column.getHighlighted(); const beforeOn = highlighted === 0; const afterOn = highlighted === 1; this.comp.toggleCss("ag-header-highlight-before", beforeOn); this.comp.toggleCss("ag-header-highlight-after", afterOn); } onDisplayedColumnsChanged() { super.onDisplayedColumnsChanged(); if (!this.isAlive()) { return; } this.onHeaderHeightChanged(); } onHeaderHeightChanged() { this.refreshSpanHeaderHeight(); } refreshSpanHeaderHeight() { const { eGui, column, comp, beans } = this; const groupHeaderHeight = getGroupRowsHeight(this.beans); const isZeroGroupHeight = groupHeaderHeight.reduce((total, next) => total + next, 0) === 0; comp.toggleCss("ag-header-parent-hidden", isZeroGroupHeight); if (!column.isSpanHeaderHeight()) { eGui.style.removeProperty("top"); eGui.style.removeProperty("height"); comp.toggleCss("ag-header-span-height", false); comp.toggleCss("ag-header-span-total", false); return; } const { numberOfParents, isSpanningTotal } = this.column.getColumnGroupPaddingInfo(); comp.toggleCss("ag-header-span-height", numberOfParents > 0); const headerHeight = getColumnHeaderRowHeight(beans); if (numberOfParents === 0) { comp.toggleCss("ag-header-span-total", false); eGui.style.setProperty("top", `0px`); eGui.style.setProperty("height", `${headerHeight}px`); return; } comp.toggleCss("ag-header-span-total", isSpanningTotal); const indexToStartSpanning = (this.column.getFirstRealParent()?.getLevel() ?? -1) + 1; const rowsToSpan = groupHeaderHeight.length - indexToStartSpanning; let extraHeight = 0; for (let i = 0;i < rowsToSpan; i++) { extraHeight += groupHeaderHeight[groupHeaderHeight.length - 1 - i]; } eGui.style.setProperty("top", `${-extraHeight}px`); eGui.style.setProperty("height", `${headerHeight + extraHeight}px`); } refreshAriaSort() { let description = null; const { beans, column, comp, sortable } = this; if (sortable) { const translate = this.getLocaleTextFunc(); const sortDef = beans.sortSvc?.getDisplaySortForColumn(column) ?? null; comp.setAriaSort(_getAriaSortState(sortDef)); description = translate("ariaSortableColumn", "Press ENTER to sort"); } else { comp.setAriaSort(); } this.setAriaDescriptionProperty("sort", description); } refreshAriaMenu() { let description = null; if (this.menuEnabled) { const translate = this.getLocaleTextFunc(); description = translate("ariaMenuColumn", "Press ALT DOWN to open column menu"); } this.setAriaDescriptionProperty("menu", description); } refreshAriaFilterButton() { let description = null; const { openFilterEnabled, gos } = this; if (openFilterEnabled && !_isLegacyMenuEnabled(gos)) { const translate = this.getLocaleTextFunc(); description = translate("ariaFilterColumn", "Press CTRL ENTER to open filter"); } this.setAriaDescriptionProperty("filterButton", description); } refreshAriaFiltered() { let description = null; if (this.column.isFilterActive()) { const translate = this.getLocaleTextFunc(); description = translate("ariaColumnFiltered", "Column Filtered"); } this.setAriaDescriptionProperty("filter", description); } refreshAriaCellSelection() { let description = null; const { gos, column } = this; const enableColumnSelection = _getEnableColumnSelection(gos); if (enableColumnSelection && !isRowNumberCol(column)) { const translate = this.getLocaleTextFunc(); description = translate("ariaColumnCellSelection", "Press Enter to toggle selection for all visible cells in this column"); } this.setAriaDescriptionProperty("cellSelection", description); } setAriaDescriptionProperty(property, value) { const props = this.ariaDescriptionProperties; if (value != null) { props.set(property, value); } else { props.delete(property); } } announceAriaDescription() { const { beans, eGui, ariaDescriptionProperties } = this; if (!eGui.contains(_getActiveDomElement(beans))) { return; } const ariaDescription = Array.from(ariaDescriptionProperties.keys()).sort((a, b) => a === "filter" ? -1 : b.charCodeAt(0) - a.charCodeAt(0)).map((key) => ariaDescriptionProperties.get(key)).join(". "); beans.ariaAnnounce?.announceValue(ariaDescription, "columnHeader"); } refreshAria() { this.refreshAriaSort(); this.refreshAriaMenu(); this.refreshAriaFilterButton(); this.refreshAriaFiltered(); this.refreshAriaCellSelection(); } addColumnHoverListener(compBean) { this.beans.colHover?.addHeaderColumnHoverListener(compBean, this.comp, this.column); } addActiveHeaderMouseListeners(compBean) { const listener = (e) => this.handleMouseOverChange(e.type === "mouseenter"); const clickListener = () => { this.setActiveHeader(true); this.dispatchColumnMouseEvent("columnHeaderClicked", this.column); }; const contextMenuListener = (event) => this.handleContextMenuMouseEvent(event, undefined, this.column); compBean.addManagedListeners(this.eGui, { mouseenter: listener, mouseleave: listener, click: clickListener, contextmenu: contextMenuListener }); } handleMouseOverChange(isMouseOver) { this.setActiveHeader(isMouseOver); this.eventSvc.dispatchEvent({ type: isMouseOver ? "columnHeaderMouseOver" : "columnHeaderMouseLeave", column: this.column }); } setActiveHeader(active) { this.comp.toggleCss("ag-header-active", active); } getAnchorElementForMenu(isFilter) { const headerComp = this.comp.getUserCompInstance(); if (isHeaderComp(headerComp)) { return headerComp.getAnchorElementForMenu(isFilter); } return this.eGui; } destroy() { this.tooltipFeature = this.destroyBean(this.tooltipFeature); super.destroy(); } }; function isHeaderComp(headerComp) { return typeof headerComp?.getAnchorElementForMenu === "function" && typeof headerComp.onMenuKeyboardShortcut === "function"; } var instanceIdSequence3 = 0; var HeaderRowCtrl = class extends BeanStub { constructor(rowIndex, pinned, type) { super(); this.rowIndex = rowIndex; this.pinned = pinned; this.type = type; this.instanceId = instanceIdSequence3++; this.comp = null; this.allCtrls = []; let typeClass = "ag-header-row-column"; if (type === "group") { typeClass = "ag-header-row-group"; } else if (type === "filter") { typeClass = "ag-header-row-filter"; } this.headerRowClass = `ag-header-row ${typeClass}`; } setRowIndex(rowIndex) { this.rowIndex = rowIndex; this.comp?.setRowIndex(this.getAriaRowIndex()); this.onRowHeightChanged(); } postConstruct() { this.isPrintLayout = _isDomLayout(this.gos, "print"); this.isEnsureDomOrder = this.gos.get("ensureDomOrder"); } areCellsRendered() { if (!this.comp) { return false; } return this.allCtrls.every((ctrl) => ctrl.eGui != null); } setComp(comp, compBean, initCompState = true) { this.comp = comp; compBean = setupCompBean(this, this.beans.context, compBean); if (initCompState) { this.setRowIndex(this.rowIndex); this.onVirtualColumnsChanged(); } this.setWidth(); this.addEventListeners(compBean); } getAriaRowIndex() { return this.rowIndex + 1; } addEventListeners(compBean) { const onHeightChanged = this.onRowHeightChanged.bind(this); const onDisplayedColumnsChanged = this.onDisplayedColumnsChanged.bind(this); compBean.addManagedEventListeners({ columnResized: this.setWidth.bind(this), displayedColumnsChanged: onDisplayedColumnsChanged, virtualColumnsChanged: (params) => this.onVirtualColumnsChanged(params.afterScroll), columnGroupHeaderHeightChanged: onHeightChanged, columnHeaderHeightChanged: onHeightChanged, stylesChanged: onHeightChanged, advancedFilterEnabledChanged: onHeightChanged }); compBean.addManagedPropertyListener("domLayout", onDisplayedColumnsChanged); compBean.addManagedPropertyListener("ensureDomOrder", (e) => this.isEnsureDomOrder = e.currentValue); compBean.addManagedPropertyListeners([ "headerHeight", "pivotHeaderHeight", "groupHeaderHeight", "pivotGroupHeaderHeight", "floatingFiltersHeight" ], onHeightChanged); } onDisplayedColumnsChanged() { this.isPrintLayout = _isDomLayout(this.gos, "print"); this.onVirtualColumnsChanged(); this.setWidth(); this.onRowHeightChanged(); } setWidth() { if (!this.comp) { return; } const width = this.getWidthForRow(); this.comp.setWidth(`${width}px`); } getWidthForRow() { const { visibleCols } = this.beans; if (this.isPrintLayout) { const pinned = this.pinned != null; if (pinned) { return 0; } return visibleCols.getContainerWidth("right") + visibleCols.getContainerWidth("left") + visibleCols.getContainerWidth(null); } return visibleCols.getContainerWidth(this.pinned); } onRowHeightChanged() { if (!this.comp) { return; } const { topOffset, rowHeight } = this.getTopAndHeight(); this.comp.setTop(topOffset + "px"); this.comp.setHeight(rowHeight + "px"); } getTopAndHeight() { let topOffset = 0; const groupHeadersHeight = getGroupRowsHeight(this.beans); for (let i = 0;i < groupHeadersHeight.length; i++) { if (i === this.rowIndex && this.type === "group") { return { topOffset, rowHeight: groupHeadersHeight[i] }; } topOffset += groupHeadersHeight[i]; } const headerHeight = getColumnHeaderRowHeight(this.beans); if (this.type === "column") { return { topOffset, rowHeight: headerHeight }; } topOffset += headerHeight; const filterHeight = getFloatingFiltersHeight(this.beans); return { topOffset, rowHeight: filterHeight }; } onVirtualColumnsChanged(afterScroll = false) { if (!this.comp) { return; } const ctrlsToDisplay = this.getUpdatedHeaderCtrls(); const forceOrder = this.isEnsureDomOrder || this.isPrintLayout; this.comp.setHeaderCtrls(ctrlsToDisplay, forceOrder, afterScroll); } getUpdatedHeaderCtrls() { const oldCtrls = this.ctrlsById; this.ctrlsById = /* @__PURE__ */ new Map; const columns = this.getColumnsInViewport(); for (const child of columns) { this.recycleAndCreateHeaderCtrls(child, this.ctrlsById, oldCtrls); } const isFocusedAndDisplayed = (ctrl) => { const { focusSvc, visibleCols } = this.beans; const isFocused = focusSvc.isHeaderWrapperFocused(ctrl); if (!isFocused) { return false; } const isDisplayed = visibleCols.isVisible(ctrl.column); return isDisplayed; }; if (oldCtrls) { for (const [id, oldCtrl] of oldCtrls) { const keepCtrl = isFocusedAndDisplayed(oldCtrl); if (keepCtrl) { this.ctrlsById.set(id, oldCtrl); } else { this.destroyBean(oldCtrl); } } } this.allCtrls = Array.from(this.ctrlsById.values()); return this.allCtrls; } getHeaderCellCtrls() { return this.allCtrls; } recycleAndCreateHeaderCtrls(headerColumn, currCtrls, oldCtrls) { if (headerColumn.isEmptyGroup()) { return; } const idOfChild = headerColumn.getUniqueId(); let headerCtrl; if (oldCtrls) { headerCtrl = oldCtrls.get(idOfChild); oldCtrls.delete(idOfChild); } const forOldColumn = headerCtrl && headerCtrl.column != headerColumn; if (forOldColumn) { this.destroyBean(headerCtrl); headerCtrl = undefined; } if (headerCtrl == null) { switch (this.type) { case "filter": { headerCtrl = this.createBean(this.beans.registry.createDynamicBean("headerFilterCellCtrl", true, headerColumn, this)); break; } case "group": headerCtrl = this.createBean(this.beans.registry.createDynamicBean("headerGroupCellCtrl", true, headerColumn, this)); break; default: headerCtrl = this.createBean(new HeaderCellCtrl(headerColumn, this)); break; } } currCtrls.set(idOfChild, headerCtrl); } getColumnsInViewport() { if (!this.isPrintLayout) { return this.getComponentsToRender(); } if (this.pinned) { return []; } const viewportColumns = []; for (const pinned of ["left", null, "right"]) { viewportColumns.push(...this.getComponentsToRender(pinned)); } return viewportColumns; } getComponentsToRender(pinned = this.pinned) { if (this.type === "group") { return this.beans.colViewport.getHeadersToRender(pinned, this.rowIndex); } return this.beans.colViewport.getColumnHeadersToRender(pinned); } focusHeader(column, event) { const ctrl = this.allCtrls.find((ctrl2) => ctrl2.column == column); if (!ctrl) { return false; } const focused = ctrl.focus(event); return focused; } destroy() { this.allCtrls = this.destroyBeans(this.allCtrls); this.ctrlsById = undefined; this.comp = null; super.destroy(); } }; var HeaderRowContainerCtrl = class extends BeanStub { constructor(pinned) { super(); this.pinned = pinned; this.hidden = false; this.includeFloatingFilter = false; this.groupsRowCtrls = []; } setComp(comp, eGui) { this.comp = comp; this.eViewport = eGui; const { pinnedCols, ctrlsSvc, colModel, colMoves } = this.beans; this.setupCenterWidth(); pinnedCols?.setupHeaderPinnedWidth(this); this.setupDragAndDrop(colMoves, this.eViewport); const onDisplayedColsChanged = this.refresh.bind(this, true); this.addManagedEventListeners({ displayedColumnsChanged: onDisplayedColsChanged, advancedFilterEnabledChanged: onDisplayedColsChanged }); const headerType = `${typeof this.pinned === "string" ? this.pinned : "center"}Header`; ctrlsSvc.register(headerType, this); if (colModel.ready) { this.refresh(); } } getAllCtrls() { const res = [...this.groupsRowCtrls]; if (this.columnsRowCtrl) { res.push(this.columnsRowCtrl); } if (this.filtersRowCtrl) { res.push(this.filtersRowCtrl); } return res; } refresh(keepColumns = false) { const { focusSvc, filterManager, visibleCols } = this.beans; let sequence = 0; const focusedHeaderPosition = focusSvc.getFocusHeaderToUseAfterRefresh(); const refreshColumnGroups = () => { const groupRowCount = visibleCols.headerGroupRowCount; sequence = groupRowCount; if (!keepColumns) { this.groupsRowCtrls = this.destroyBeans(this.groupsRowCtrls); } const currentGroupCount = this.groupsRowCtrls.length; if (currentGroupCount === groupRowCount) { return; } if (currentGroupCount > groupRowCount) { for (let i = groupRowCount;i < currentGroupCount; i++) { this.destroyBean(this.groupsRowCtrls[i]); } this.groupsRowCtrls.length = groupRowCount; return; } for (let i = currentGroupCount;i < groupRowCount; i++) { const ctrl = this.createBean(new HeaderRowCtrl(i, this.pinned, "group")); this.groupsRowCtrls.push(ctrl); } }; const refreshColumns = () => { const rowIndex = sequence++; if (this.hidden) { this.columnsRowCtrl = this.destroyBean(this.columnsRowCtrl); return; } if (this.columnsRowCtrl == null || !keepColumns) { this.columnsRowCtrl = this.destroyBean(this.columnsRowCtrl); this.columnsRowCtrl = this.createBean(new HeaderRowCtrl(rowIndex, this.pinned, "column")); } else if (this.columnsRowCtrl.rowIndex !== rowIndex) { this.columnsRowCtrl.setRowIndex(rowIndex); } }; const refreshFilters = () => { this.includeFloatingFilter = !!filterManager?.hasFloatingFilters() && !this.hidden; const destroyPreviousComp = () => { this.filtersRowCtrl = this.destroyBean(this.filtersRowCtrl); }; if (!this.includeFloatingFilter) { destroyPreviousComp(); return; } if (!keepColumns) { destroyPreviousComp(); } const rowIndex = sequence++; if (this.filtersRowCtrl) { const rowIndexMismatch = this.filtersRowCtrl.rowIndex !== rowIndex; if (rowIndexMismatch) { this.filtersRowCtrl.setRowIndex(rowIndex); } } else { this.filtersRowCtrl = this.createBean(new HeaderRowCtrl(rowIndex, this.pinned, "filter")); } }; const oldCtrls = this.getAllCtrls(); refreshColumnGroups(); refreshColumns(); refreshFilters(); const allCtrls = this.getAllCtrls(); this.comp.setCtrls(allCtrls); this.restoreFocusOnHeader(focusSvc, focusedHeaderPosition); if (oldCtrls.length !== allCtrls.length) { this.beans.eventSvc.dispatchEvent({ type: "headerRowsChanged" }); } } getHeaderCtrlForColumn(column) { const findCtrl = (ctrl) => ctrl?.getHeaderCellCtrls().find((ctrl2) => ctrl2.column === column); if (isColumn(column)) { return findCtrl(this.columnsRowCtrl); } if (this.groupsRowCtrls.length === 0) { return; } for (let i = 0;i < this.groupsRowCtrls.length; i++) { const ctrl = findCtrl(this.groupsRowCtrls[i]); if (ctrl) { return ctrl; } } } getHtmlElementForColumnHeader(column) { return this.getHeaderCtrlForColumn(column)?.eGui ?? null; } getRowType(rowIndex) { return this.getAllCtrls()[rowIndex]?.type; } focusHeader(rowIndex, column, event) { const allCtrls = this.getAllCtrls(); const ctrl = allCtrls[rowIndex]; if (!ctrl) { return false; } return ctrl.focusHeader(column, event); } getGroupRowCount() { return this.groupsRowCtrls.length; } getGroupRowCtrlAtIndex(index) { return this.groupsRowCtrls[index]; } getRowCount() { return this.groupsRowCtrls.length + (this.columnsRowCtrl ? 1 : 0) + (this.filtersRowCtrl ? 1 : 0); } setHorizontalScroll(offset) { this.comp.setViewportScrollLeft(offset); } onScrollCallback(fn) { this.addManagedElementListeners(this.eViewport, { scroll: fn }); } destroy() { this.filtersRowCtrl = this.destroyBean(this.filtersRowCtrl); this.columnsRowCtrl = this.destroyBean(this.columnsRowCtrl); this.groupsRowCtrls = this.destroyBeans(this.groupsRowCtrls); super.destroy(); } setupDragAndDrop(colMoves, dropContainer) { const bodyDropTarget = colMoves?.createBodyDropTarget(this.pinned, dropContainer); if (bodyDropTarget) { this.createManagedBean(bodyDropTarget); } } restoreFocusOnHeader(focusSvc, position) { if (!position) { return; } const { column } = position; if (column.getPinned() != this.pinned) { return; } focusSvc.focusHeaderPosition({ headerPosition: position, scroll: false }); } setupCenterWidth() { if (this.pinned != null) { return; } this.createManagedBean(new CenterWidthFeature((width) => this.comp.setCenterWidth(`${width}px`), true)); } }; var PinnedLeftElement = { tag: "div", cls: "ag-pinned-left-header", role: "rowgroup" }; var PinnedRightElement = { tag: "div", cls: "ag-pinned-right-header", role: "rowgroup" }; var CenterElement = { tag: "div", cls: "ag-header-viewport", role: "rowgroup", attrs: { tabindex: "-1" }, children: [{ tag: "div", ref: "eCenterContainer", cls: "ag-header-container", role: "presentation" }] }; var HeaderRowContainerComp = class extends Component { constructor(pinned) { super(); this.eCenterContainer = RefPlaceholder; this.headerRowComps = {}; this.rowCompsList = []; this.pinned = pinned; } postConstruct() { this.selectAndSetTemplate(); const compProxy = { setDisplayed: (displayed) => this.setDisplayed(displayed), setCtrls: (ctrls) => this.setCtrls(ctrls), setCenterWidth: (width) => this.eCenterContainer.style.width = width, setViewportScrollLeft: (left) => this.getGui().scrollLeft = left, setPinnedContainerWidth: (width) => { const eGui = this.getGui(); eGui.style.width = width; eGui.style.maxWidth = width; eGui.style.minWidth = width; } }; const ctrl = this.createManagedBean(new HeaderRowContainerCtrl(this.pinned)); ctrl.setComp(compProxy, this.getGui()); } selectAndSetTemplate() { const pinnedLeft = this.pinned == "left"; const pinnedRight = this.pinned == "right"; const template = pinnedLeft ? PinnedLeftElement : pinnedRight ? PinnedRightElement : CenterElement; this.setTemplate(template); this.eRowContainer = this.eCenterContainer !== RefPlaceholder ? this.eCenterContainer : this.getGui(); } destroy() { this.setCtrls([]); super.destroy(); } destroyRowComp(rowComp) { this.destroyBean(rowComp); rowComp.getGui().remove(); } setCtrls(ctrls) { const oldRowComps = this.headerRowComps; this.headerRowComps = {}; this.rowCompsList = []; let prevGui; const appendEnsuringDomOrder = (rowComp) => { const eGui = rowComp.getGui(); const notAlreadyIn = eGui.parentElement != this.eRowContainer; if (notAlreadyIn) { this.eRowContainer.appendChild(eGui); } if (prevGui) { _ensureDomOrder(this.eRowContainer, eGui, prevGui); } prevGui = eGui; }; for (const ctrl of ctrls) { const ctrlId = ctrl.instanceId; const existingComp = oldRowComps[ctrlId]; delete oldRowComps[ctrlId]; const rowComp = existingComp ? existingComp : this.createBean(new HeaderRowComp(ctrl)); this.headerRowComps[ctrlId] = rowComp; this.rowCompsList.push(rowComp); appendEnsuringDomOrder(rowComp); } for (const c of Object.values(oldRowComps)) { this.destroyRowComp(c); } } }; var GridHeaderElement = { tag: "div", cls: "ag-header", role: "presentation" }; var GridHeaderComp = class extends Component { constructor() { super(GridHeaderElement); } postConstruct() { const compProxy = { toggleCss: (cssClassName, on) => this.toggleCss(cssClassName, on), setHeightAndMinHeight: (height) => { this.getGui().style.height = height; this.getGui().style.minHeight = height; } }; const ctrl = this.createManagedBean(new GridHeaderCtrl); ctrl.setComp(compProxy, this.getGui(), this.getFocusableElement()); const addContainer = (container) => { this.createManagedBean(container); this.appendChild(container); }; addContainer(new HeaderRowContainerComp("left")); addContainer(new HeaderRowContainerComp(null)); addContainer(new HeaderRowContainerComp("right")); } }; var GridHeaderSelector = { selector: "AG-HEADER-ROOT", component: GridHeaderComp }; var LayoutCssClasses = { AUTO_HEIGHT: "ag-layout-auto-height", NORMAL: "ag-layout-normal", PRINT: "ag-layout-print" }; var LayoutFeature = class extends BeanStub { constructor(view) { super(); this.view = view; } postConstruct() { this.addManagedPropertyListener("domLayout", this.updateLayoutClasses.bind(this)); this.updateLayoutClasses(); } updateLayoutClasses() { const domLayout = this.gos.get("domLayout"); const params = { autoHeight: domLayout === "autoHeight", normal: domLayout === "normal", print: domLayout === "print" }; const cssClass = params.autoHeight ? LayoutCssClasses.AUTO_HEIGHT : params.print ? LayoutCssClasses.PRINT : LayoutCssClasses.NORMAL; this.view.updateLayoutClasses(cssClass, params); } }; var AbstractFakeScrollComp = class extends Component { constructor(template, direction) { super(); this.direction = direction; this.eViewport = RefPlaceholder; this.eContainer = RefPlaceholder; this.hideTimeout = 0; this.setTemplate(template); } postConstruct() { this.addManagedEventListeners({ scrollVisibilityChanged: this.onScrollVisibilityChanged.bind(this) }); this.onScrollVisibilityChanged(); this.toggleCss("ag-apple-scrollbar", _isMacOsUserAgent() || _isIOSUserAgent()); } destroy() { super.destroy(); window.clearTimeout(this.hideTimeout); } initialiseInvisibleScrollbar() { if (this.invisibleScrollbar !== undefined) { return; } this.invisibleScrollbar = _isInvisibleScrollbar(); if (this.invisibleScrollbar) { this.hideAndShowInvisibleScrollAsNeeded(); this.addActiveListenerToggles(); } } addActiveListenerToggles() { const eGui = this.getGui(); const onActivate = () => this.toggleCss("ag-scrollbar-active", true); const onDeactivate = () => this.toggleCss("ag-scrollbar-active", false); this.addManagedListeners(eGui, { mouseenter: onActivate, mousedown: onActivate, touchstart: onActivate, mouseleave: onDeactivate, touchend: onDeactivate }); } onScrollVisibilityChanged() { if (this.invisibleScrollbar === undefined) { this.initialiseInvisibleScrollbar(); } _requestAnimationFrame(this.beans, () => this.setScrollVisible()); } hideAndShowInvisibleScrollAsNeeded() { this.addManagedEventListeners({ bodyScroll: (params) => { if (params.direction === this.direction) { if (this.hideTimeout) { window.clearTimeout(this.hideTimeout); this.hideTimeout = 0; } this.toggleCss("ag-scrollbar-scrolling", true); } }, bodyScrollEnd: () => { this.hideTimeout = window.setTimeout(() => { this.toggleCss("ag-scrollbar-scrolling", false); this.hideTimeout = 0; }, 400); } }); } attemptSettingScrollPosition(value) { const viewport = this.eViewport; _waitUntil(this, () => _isVisible(viewport), () => this.setScrollPosition(value), 100); } onScrollCallback(fn) { this.addManagedElementListeners(this.eViewport, { scroll: fn }); } }; var FakeHScrollElement = { tag: "div", cls: "ag-body-horizontal-scroll", attrs: { "aria-hidden": "true" }, children: [ { tag: "div", ref: "eLeftSpacer", cls: "ag-horizontal-left-spacer" }, { tag: "div", ref: "eViewport", cls: "ag-body-horizontal-scroll-viewport", children: [{ tag: "div", ref: "eContainer", cls: "ag-body-horizontal-scroll-container" }] }, { tag: "div", ref: "eRightSpacer", cls: "ag-horizontal-right-spacer" } ] }; var FakeHScrollComp = class extends AbstractFakeScrollComp { constructor() { super(FakeHScrollElement, "horizontal"); this.eLeftSpacer = RefPlaceholder; this.eRightSpacer = RefPlaceholder; this.setScrollVisibleDebounce = 0; } wireBeans(beans) { this.visibleCols = beans.visibleCols; this.scrollVisibleSvc = beans.scrollVisibleSvc; } postConstruct() { super.postConstruct(); const spacerWidthsListener = this.setFakeHScrollSpacerWidths.bind(this); this.addManagedEventListeners({ displayedColumnsChanged: spacerWidthsListener, displayedColumnsWidthChanged: spacerWidthsListener, pinnedRowDataChanged: this.refreshCompBottom.bind(this) }); this.addManagedPropertyListener("domLayout", spacerWidthsListener); this.beans.ctrlsSvc.register("fakeHScrollComp", this); this.createManagedBean(new CenterWidthFeature((width) => this.eContainer.style.width = `${width}px`)); this.addManagedPropertyListeners(["suppressHorizontalScroll"], this.onScrollVisibilityChanged.bind(this)); } destroy() { window.clearTimeout(this.setScrollVisibleDebounce); super.destroy(); } initialiseInvisibleScrollbar() { if (this.invisibleScrollbar !== undefined) { return; } this.enableRtl = this.gos.get("enableRtl"); super.initialiseInvisibleScrollbar(); if (this.invisibleScrollbar) { this.refreshCompBottom(); } } refreshCompBottom() { if (!this.invisibleScrollbar) { return; } const bottomPinnedHeight = this.beans.pinnedRowModel?.getPinnedBottomTotalHeight() ?? 0; this.getGui().style.bottom = `${bottomPinnedHeight}px`; } onScrollVisibilityChanged() { super.onScrollVisibilityChanged(); this.setFakeHScrollSpacerWidths(); } setFakeHScrollSpacerWidths() { const vScrollShowing = this.scrollVisibleSvc.verticalScrollShowing; let rightSpacing = this.visibleCols.getDisplayedColumnsRightWidth(); const scrollOnRight = !this.enableRtl && vScrollShowing; const scrollbarWidth = this.scrollVisibleSvc.getScrollbarWidth(); if (scrollOnRight) { rightSpacing += scrollbarWidth; } _setFixedWidth(this.eRightSpacer, rightSpacing); this.eRightSpacer.classList.toggle("ag-scroller-corner", rightSpacing <= scrollbarWidth); let leftSpacing = this.visibleCols.getColsLeftWidth(); const scrollOnLeft = this.enableRtl && vScrollShowing; if (scrollOnLeft) { leftSpacing += scrollbarWidth; } _setFixedWidth(this.eLeftSpacer, leftSpacing); this.eLeftSpacer.classList.toggle("ag-scroller-corner", leftSpacing <= scrollbarWidth); } setScrollVisible() { const hScrollShowing = this.scrollVisibleSvc.horizontalScrollShowing; const invisibleScrollbar2 = this.invisibleScrollbar; const isSuppressHorizontalScroll = this.gos.get("suppressHorizontalScroll"); const scrollbarWidth = hScrollShowing ? this.scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const adjustedScrollbarWidth = scrollbarWidth === 0 && invisibleScrollbar2 ? 16 : scrollbarWidth; const scrollContainerSize = !isSuppressHorizontalScroll ? adjustedScrollbarWidth : 0; const apply = () => { this.setScrollVisibleDebounce = 0; this.toggleCss("ag-scrollbar-invisible", invisibleScrollbar2); _setFixedHeight(this.getGui(), scrollContainerSize); _setFixedHeight(this.eViewport, scrollContainerSize); _setFixedHeight(this.eContainer, scrollContainerSize); if (!scrollContainerSize) { this.eContainer.style.setProperty("min-height", "1px"); } this.setVisible(hScrollShowing, { skipAriaHidden: true }); }; window.clearTimeout(this.setScrollVisibleDebounce); if (!hScrollShowing) { apply(); } else { this.setScrollVisibleDebounce = window.setTimeout(apply, 100); } } getScrollPosition() { return _getScrollLeft(this.eViewport, this.enableRtl); } setScrollPosition(value) { if (!_isVisible(this.eViewport)) { this.attemptSettingScrollPosition(value); } _setScrollLeft(this.eViewport, value, this.enableRtl); } }; var FakeHScrollSelector = { selector: "AG-FAKE-HORIZONTAL-SCROLL", component: FakeHScrollComp }; var SetHeightFeature = class extends BeanStub { constructor(eContainer, eViewport) { super(); this.eContainer = eContainer; this.eViewport = eViewport; } postConstruct() { this.addManagedEventListeners({ rowContainerHeightChanged: this.onHeightChanged.bind(this, this.beans.rowContainerHeight) }); } onHeightChanged(maxDivHeightScaler) { const height = maxDivHeightScaler.uiContainerHeight; const heightString = height != null ? `${height}px` : ``; this.eContainer.style.height = heightString; if (this.eViewport) { this.eViewport.style.height = heightString; } } }; var FakeVScrollElement = { tag: "div", cls: "ag-body-vertical-scroll", attrs: { "aria-hidden": "true" }, children: [ { tag: "div", ref: "eViewport", cls: "ag-body-vertical-scroll-viewport", children: [{ tag: "div", ref: "eContainer", cls: "ag-body-vertical-scroll-container" }] } ] }; var FakeVScrollComp = class extends AbstractFakeScrollComp { constructor() { super(FakeVScrollElement, "vertical"); } postConstruct() { super.postConstruct(); this.createManagedBean(new SetHeightFeature(this.eContainer)); const { ctrlsSvc } = this.beans; ctrlsSvc.register("fakeVScrollComp", this); this.addManagedEventListeners({ rowContainerHeightChanged: this.onRowContainerHeightChanged.bind(this, ctrlsSvc) }); } setScrollVisible() { const { scrollVisibleSvc } = this.beans; const vScrollShowing = scrollVisibleSvc.verticalScrollShowing; const invisibleScrollbar2 = this.invisibleScrollbar; const scrollbarWidth = vScrollShowing ? scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const adjustedScrollbarWidth = scrollbarWidth === 0 && invisibleScrollbar2 ? 16 : scrollbarWidth; this.toggleCss("ag-scrollbar-invisible", invisibleScrollbar2); _setFixedWidth(this.getGui(), adjustedScrollbarWidth); _setFixedWidth(this.eViewport, adjustedScrollbarWidth); _setFixedWidth(this.eContainer, adjustedScrollbarWidth); this.setDisplayed(vScrollShowing, { skipAriaHidden: true }); } onRowContainerHeightChanged(ctrlsSvc) { const gridBodyCtrl = ctrlsSvc.getGridBodyCtrl(); const gridBodyViewportEl = gridBodyCtrl.eBodyViewport; const eViewportScrollTop = this.getScrollPosition(); const gridBodyViewportScrollTop = gridBodyViewportEl.scrollTop; if (eViewportScrollTop != gridBodyViewportScrollTop) { this.setScrollPosition(gridBodyViewportScrollTop, true); } } getScrollPosition() { return this.eViewport.scrollTop; } setScrollPosition(value, force) { if (!force && !_isVisible(this.eViewport)) { this.attemptSettingScrollPosition(value); } this.eViewport.scrollTop = value; } }; var FakeVScrollSelector = { selector: "AG-FAKE-VERTICAL-SCROLL", component: FakeVScrollComp }; var VIEWPORT = "Viewport"; var FAKE_V_SCROLLBAR = "fakeVScrollComp"; var HORIZONTAL_SOURCES = [ "fakeHScrollComp", "centerHeader", "topCenter", "bottomCenter", "stickyTopCenter", "stickyBottomCenter" ]; var SCROLL_DEBOUNCE_TIMEOUT = 100; var SCROLL_END_TIMEOUT = 150; var GridBodyScrollFeature = class extends BeanStub { constructor(eBodyViewport) { super(); this.clearRetryListenerFncs = []; this.lastScrollSource = [null, null]; this.scrollLeft = -1; this.nextScrollTop = -1; this.scrollTop = -1; this.lastOffsetHeight = -1; this.lastScrollTop = -1; this.lastIsHorizontalScrollShowing = false; this.scrollTimer = 0; this.isScrollActive = false; this.isVerticalPositionInvalidated = true; this.isHorizontalPositionInvalidated = true; this.eBodyViewport = eBodyViewport; this.resetLastHScrollDebounced = _debounce(this, () => this.lastScrollSource[1] = null, SCROLL_END_TIMEOUT); this.resetLastVScrollDebounced = _debounce(this, () => this.lastScrollSource[0] = null, SCROLL_END_TIMEOUT); } wireBeans(beans) { this.ctrlsSvc = beans.ctrlsSvc; this.animationFrameSvc = beans.animationFrameSvc; this.visibleCols = beans.visibleCols; } destroy() { super.destroy(); this.clearRetryListenerFncs = []; window.clearTimeout(this.scrollTimer); } postConstruct() { this.enableRtl = this.gos.get("enableRtl"); const invalidateVerticalScroll = this.invalidateVerticalScroll.bind(this); const invalidateHorizontalScroll = this.invalidateHorizontalScroll.bind(this); this.addManagedEventListeners({ displayedColumnsWidthChanged: this.onDisplayedColumnsWidthChanged.bind(this), bodyHeightChanged: invalidateVerticalScroll, scrollGapChanged: invalidateHorizontalScroll }); this.addManagedElementListeners(this.eBodyViewport, { scroll: invalidateVerticalScroll }); this.ctrlsSvc.whenReady(this, (p) => { this.centerRowsCtrl = p.center; this.fakeVScrollComp = p.fakeVScrollComp; this.fakeHScrollComp = p.fakeHScrollComp; this.onDisplayedColumnsWidthChanged(); this.addScrollListener(); }); } invalidateHorizontalScroll() { this.isHorizontalPositionInvalidated = true; } invalidateVerticalScroll() { this.isVerticalPositionInvalidated = true; } addScrollListener() { this.addHorizontalScrollListeners(); this.addVerticalScrollListeners(); } addHorizontalScrollListeners() { this.addManagedElementListeners(this.centerRowsCtrl.eViewport, { scroll: this.onHScroll.bind(this, VIEWPORT) }); for (const source of HORIZONTAL_SOURCES) { const scrollPartner = this.ctrlsSvc.get(source); this.registerScrollPartner(scrollPartner, this.onHScroll.bind(this, source)); } } addVerticalScrollListeners() { const isDebounce = this.gos.get("debounceVerticalScrollbar"); const onVScroll = isDebounce ? _debounce(this, this.onVScroll.bind(this, VIEWPORT), SCROLL_DEBOUNCE_TIMEOUT) : this.onVScroll.bind(this, VIEWPORT); const onFakeVScroll = isDebounce ? _debounce(this, this.onVScroll.bind(this, FAKE_V_SCROLLBAR), SCROLL_DEBOUNCE_TIMEOUT) : this.onVScroll.bind(this, FAKE_V_SCROLLBAR); this.addManagedElementListeners(this.eBodyViewport, { scroll: onVScroll }); this.registerScrollPartner(this.fakeVScrollComp, onFakeVScroll); } registerScrollPartner(comp, callback) { comp.onScrollCallback(callback); } onDisplayedColumnsWidthChanged() { if (this.enableRtl) { this.horizontallyScrollHeaderCenterAndFloatingCenter(); } } horizontallyScrollHeaderCenterAndFloatingCenter(scrollLeft) { const notYetInitialised = this.centerRowsCtrl == null; if (notYetInitialised) { return; } if (scrollLeft === undefined) { scrollLeft = this.centerRowsCtrl.getCenterViewportScrollLeft(); } this.setScrollLeftForAllContainersExceptCurrent(Math.abs(scrollLeft)); } setScrollLeftForAllContainersExceptCurrent(scrollLeft) { for (const container of [...HORIZONTAL_SOURCES, VIEWPORT]) { if (this.lastScrollSource[1] === container) { continue; } const viewport = this.getViewportForSource(container); _setScrollLeft(viewport, scrollLeft, this.enableRtl); } } getViewportForSource(source) { if (source === VIEWPORT) { return this.centerRowsCtrl.eViewport; } return this.ctrlsSvc.get(source).eViewport; } isControllingScroll(source, direction) { if (this.lastScrollSource[direction] == null) { if (direction === 0) { this.lastScrollSource[0] = source; } else { this.lastScrollSource[1] = source; } return true; } return this.lastScrollSource[direction] === source; } onHScroll(source) { if (!this.isControllingScroll(source, 1)) { return; } const centerContainerViewport = this.centerRowsCtrl.eViewport; const { scrollLeft } = centerContainerViewport; if (this.shouldBlockScrollUpdate(1, scrollLeft, true)) { return; } const newScrollLeft = _getScrollLeft(this.getViewportForSource(source), this.enableRtl); this.doHorizontalScroll(newScrollLeft); this.resetLastHScrollDebounced(); } onVScroll(source) { if (!this.isControllingScroll(source, 0)) { return; } const requestedScrollTop = source === VIEWPORT ? this.eBodyViewport.scrollTop : this.fakeVScrollComp.getScrollPosition(); let scrollTop = requestedScrollTop; if (this.shouldBlockScrollUpdate(0, scrollTop, true)) { return; } if (source === VIEWPORT) { this.fakeVScrollComp.setScrollPosition(scrollTop); } else { this.eBodyViewport.scrollTop = requestedScrollTop; scrollTop = this.eBodyViewport.scrollTop; this.invalidateVerticalScroll(); if (scrollTop !== requestedScrollTop) { this.fakeVScrollComp.setScrollPosition(scrollTop, true); } } const { animationFrameSvc } = this; animationFrameSvc?.setScrollTop(scrollTop); this.nextScrollTop = scrollTop; if (animationFrameSvc?.active) { animationFrameSvc.schedule(); } else { this.scrollGridIfNeeded(true); } this.resetLastVScrollDebounced(); } doHorizontalScroll(scrollLeft) { const fakeScrollLeft = this.fakeHScrollComp.getScrollPosition(); if (this.scrollLeft === scrollLeft && scrollLeft === fakeScrollLeft) { return; } this.scrollLeft = scrollLeft; this.fireScrollEvent(1); this.horizontallyScrollHeaderCenterAndFloatingCenter(scrollLeft); this.centerRowsCtrl.onHorizontalViewportChanged(true); } isScrolling() { return this.isScrollActive; } fireScrollEvent(direction) { const bodyScrollEvent = { type: "bodyScroll", direction: direction === 1 ? "horizontal" : "vertical", left: this.scrollLeft, top: this.scrollTop }; this.isScrollActive = true; this.eventSvc.dispatchEvent(bodyScrollEvent); window.clearTimeout(this.scrollTimer); this.scrollTimer = window.setTimeout(() => { this.scrollTimer = 0; this.isScrollActive = false; this.eventSvc.dispatchEvent({ ...bodyScrollEvent, type: "bodyScrollEnd" }); }, SCROLL_END_TIMEOUT); } shouldBlockScrollUpdate(direction, scrollTo, touchOnly = false) { if (touchOnly && !_isIOSUserAgent()) { return false; } if (direction === 0) { return this.shouldBlockVerticalScroll(scrollTo); } return this.shouldBlockHorizontalScroll(scrollTo); } shouldBlockVerticalScroll(scrollTo) { const clientHeight = _getInnerHeight(this.eBodyViewport); const { scrollHeight } = this.eBodyViewport; return !!(scrollTo < 0 || scrollTo + clientHeight > scrollHeight); } shouldBlockHorizontalScroll(scrollTo) { const clientWidth = this.centerRowsCtrl.getCenterWidth(); const { scrollWidth } = this.centerRowsCtrl.eViewport; if (this.enableRtl) { if (scrollTo > 0) { return true; } } else if (scrollTo < 0) { return true; } return Math.abs(scrollTo) + clientWidth > scrollWidth; } redrawRowsAfterScroll() { this.fireScrollEvent(0); } checkScrollLeft() { const scrollLeft = this.scrollLeft; let hasHorizontalScrollersOutOfSync = false; for (const source of HORIZONTAL_SOURCES) { const viewport = this.getViewportForSource(source); if (viewport.scrollLeft !== scrollLeft) { hasHorizontalScrollersOutOfSync = true; break; } } if (hasHorizontalScrollersOutOfSync) { this.onHScroll(VIEWPORT); } } scrollGridIfNeeded(suppressedAnimationFrame = false) { const frameNeeded = this.scrollTop != this.nextScrollTop; if (frameNeeded) { this.scrollTop = this.nextScrollTop; if (suppressedAnimationFrame) { this.invalidateVerticalScroll(); } this.redrawRowsAfterScroll(); } return frameNeeded; } setHorizontalScrollPosition(hScrollPosition, fromAlignedGridsService = false) { const minScrollLeft = 0; const maxScrollLeft = this.centerRowsCtrl.eViewport.scrollWidth - this.centerRowsCtrl.getCenterWidth(); if (!fromAlignedGridsService && this.shouldBlockScrollUpdate(1, hScrollPosition)) { if (this.enableRtl) { hScrollPosition = hScrollPosition > 0 ? 0 : maxScrollLeft; } else { hScrollPosition = Math.min(Math.max(hScrollPosition, minScrollLeft), maxScrollLeft); } } _setScrollLeft(this.centerRowsCtrl.eViewport, Math.abs(hScrollPosition), this.enableRtl); this.doHorizontalScroll(hScrollPosition); } setVerticalScrollPosition(vScrollPosition) { this.invalidateVerticalScroll(); this.eBodyViewport.scrollTop = vScrollPosition; } getVScrollPosition() { if (!this.isVerticalPositionInvalidated) { const { lastOffsetHeight, lastScrollTop } = this; return { top: lastScrollTop, bottom: lastScrollTop + lastOffsetHeight }; } this.isVerticalPositionInvalidated = false; const { scrollTop, offsetHeight } = this.eBodyViewport; this.lastScrollTop = scrollTop; this.lastOffsetHeight = offsetHeight; return { top: scrollTop, bottom: scrollTop + offsetHeight }; } getApproximateVScollPosition() { if (this.lastScrollTop >= 0 && this.lastOffsetHeight >= 0) { return { top: this.scrollTop, bottom: this.scrollTop + this.lastOffsetHeight }; } return this.getVScrollPosition(); } getHScrollPosition() { return this.centerRowsCtrl.getHScrollPosition(); } isHorizontalScrollShowing() { if (this.isHorizontalPositionInvalidated) { this.lastIsHorizontalScrollShowing = this.centerRowsCtrl.isHorizontalScrollShowing(); this.isHorizontalPositionInvalidated = false; } return this.lastIsHorizontalScrollShowing; } scrollHorizontally(pixels) { const oldScrollPosition = this.centerRowsCtrl.eViewport.scrollLeft; this.setHorizontalScrollPosition(oldScrollPosition + pixels); return this.centerRowsCtrl.eViewport.scrollLeft - oldScrollPosition; } scrollToTop() { this.setVerticalScrollPosition(0); } ensureNodeVisible(comparator, position = null) { const { rowModel } = this.beans; const rowCount = rowModel.getRowCount(); let indexToSelect = -1; for (let i = 0;i < rowCount; i++) { const node = rowModel.getRow(i); if (typeof comparator === "function") { const predicate = comparator; if (node && predicate(node)) { indexToSelect = i; break; } } else if (comparator === node || comparator === node.data) { indexToSelect = i; break; } } if (indexToSelect >= 0) { this.ensureIndexVisible(indexToSelect, position); } } ensureIndexVisible(index, position, retry = 0) { if (_isDomLayout(this.gos, "print")) { return; } const { rowModel } = this.beans; const rowCount = rowModel.getRowCount(); if (typeof index !== "number" || index < 0 || index >= rowCount) { _warn(88, { index }); return; } this.clearRetryListeners(); const { frameworkOverrides, pageBounds, rowContainerHeight: heightScaler, rowRenderer } = this.beans; frameworkOverrides.wrapIncoming(() => { const gridBodyCtrl = this.ctrlsSvc.getGridBodyCtrl(); const rowNode = rowModel.getRow(index); let rowGotShiftedDuringOperation; let stickyHeightsChanged; let attempt = 0; this.invalidateVerticalScroll(); do { const { stickyTopHeight, stickyBottomHeight } = gridBodyCtrl; const startingRowTop = rowNode.rowTop; const startingRowHeight = rowNode.rowHeight; const paginationOffset = pageBounds.getPixelOffset(); const rowTopPixel = rowNode.rowTop - paginationOffset; const rowBottomPixel = rowTopPixel + rowNode.rowHeight; const scrollPosition = this.getVScrollPosition(); const heightOffset = heightScaler.divStretchOffset; const vScrollTop = scrollPosition.top + heightOffset; const vScrollBottom = scrollPosition.bottom + heightOffset; const viewportHeight = vScrollBottom - vScrollTop; const pxTop = heightScaler.getScrollPositionForPixel(rowTopPixel); const pxBottom = heightScaler.getScrollPositionForPixel(rowBottomPixel - viewportHeight); const pxMiddle = Math.min((pxTop + pxBottom) / 2, rowTopPixel); const rowAboveViewport = vScrollTop + stickyTopHeight > rowTopPixel; const rowBelowViewport = vScrollBottom - stickyBottomHeight < rowBottomPixel; let newScrollPosition = null; if (position === "top") { newScrollPosition = pxTop - stickyTopHeight; } else if (position === "bottom") { newScrollPosition = pxBottom + stickyBottomHeight; } else if (position === "middle") { newScrollPosition = pxMiddle; } else if (rowAboveViewport) { newScrollPosition = pxTop - stickyTopHeight; } else if (rowBelowViewport) { if (pxBottom - pxTop > viewportHeight) { newScrollPosition = pxTop - stickyTopHeight; } else { newScrollPosition = pxBottom + stickyBottomHeight; } } if (newScrollPosition !== null) { this.setVerticalScrollPosition(newScrollPosition); rowRenderer.redraw({ afterScroll: true }); } rowGotShiftedDuringOperation = startingRowTop !== rowNode.rowTop || startingRowHeight !== rowNode.rowHeight; stickyHeightsChanged = stickyTopHeight !== gridBodyCtrl.stickyTopHeight || stickyBottomHeight !== gridBodyCtrl.stickyBottomHeight; attempt++; } while ((rowGotShiftedDuringOperation || stickyHeightsChanged) && attempt < 10); this.animationFrameSvc?.flushAllFrames(); if (retry < 10 && (rowNode?.stub || !this.beans.rowAutoHeight?.areRowsMeasured())) { const scrollTop = this.getVScrollPosition().top; this.clearRetryListenerFncs = this.addManagedEventListeners({ bodyScroll: () => { const newScrollTop = this.getVScrollPosition().top; if (scrollTop === newScrollTop) { return; } this.clearRetryListeners(); }, modelUpdated: () => { this.clearRetryListeners(); if (index >= rowModel.getRowCount()) { return; } this.ensureIndexVisible(index, position, retry + 1); } }); } }); } clearRetryListeners() { for (const callback of this.clearRetryListenerFncs) { callback(); } this.clearRetryListenerFncs = []; } ensureColumnVisible(key, position = "auto") { const { colModel, frameworkOverrides } = this.beans; const column = colModel.getCol(key); if (!column) { return; } if (column.isPinned()) { return; } if (!this.visibleCols.isColDisplayed(column)) { return; } const newHorizontalScroll = this.getPositionedHorizontalScroll(column, position); frameworkOverrides.wrapIncoming(() => { if (newHorizontalScroll !== null) { this.centerRowsCtrl.setCenterViewportScrollLeft(newHorizontalScroll); } this.centerRowsCtrl.onHorizontalViewportChanged(); this.animationFrameSvc?.flushAllFrames(); }); } getPositionedHorizontalScroll(column, position) { const { columnBeforeStart, columnAfterEnd } = this.isColumnOutsideViewport(column); const viewportTooSmallForColumn = this.centerRowsCtrl.getCenterWidth() < column.getActualWidth(); const viewportWidth = this.centerRowsCtrl.getCenterWidth(); const isRtl = this.enableRtl; let alignColToStart = (isRtl ? columnBeforeStart : columnAfterEnd) || viewportTooSmallForColumn; let alignColToEnd = isRtl ? columnAfterEnd : columnBeforeStart; if (position !== "auto") { alignColToStart = position === "start"; alignColToEnd = position === "end"; } const isMiddle = position === "middle"; if (alignColToStart || alignColToEnd || isMiddle) { const { colLeft, colMiddle, colRight } = this.getColumnBounds(column); if (isMiddle) { return colMiddle - viewportWidth / 2; } if (alignColToStart) { return isRtl ? colRight : colLeft; } return isRtl ? colLeft - viewportWidth : colRight - viewportWidth; } return null; } isColumnOutsideViewport(column) { const { start: viewportStart, end: viewportEnd } = this.getViewportBounds(); const { colLeft, colRight } = this.getColumnBounds(column); const isRtl = this.enableRtl; const columnBeforeStart = isRtl ? viewportStart > colRight : viewportEnd < colRight; const columnAfterEnd = isRtl ? viewportEnd < colLeft : viewportStart > colLeft; return { columnBeforeStart, columnAfterEnd }; } getColumnBounds(column) { const isRtl = this.enableRtl; const bodyWidth = this.visibleCols.bodyWidth; const colWidth = column.getActualWidth(); const colLeft = column.getLeft(); const multiplier = isRtl ? -1 : 1; const colLeftPixel = isRtl ? bodyWidth - colLeft : colLeft; const colRightPixel = colLeftPixel + colWidth * multiplier; const colMidPixel = colLeftPixel + colWidth / 2 * multiplier; return { colLeft: colLeftPixel, colMiddle: colMidPixel, colRight: colRightPixel }; } getViewportBounds() { const viewportWidth = this.centerRowsCtrl.getCenterWidth(); const scrollPosition = this.centerRowsCtrl.getCenterViewportScrollLeft(); const viewportStartPixel = scrollPosition; const viewportEndPixel = viewportWidth + scrollPosition; return { start: viewportStartPixel, end: viewportEndPixel, width: viewportWidth }; } }; var AXES = { horizontal: { overflow: (el) => el.scrollWidth - el.clientWidth, scrollSize: (el) => el.scrollWidth, clientSize: (el) => el.clientWidth, opposite: "vertical" }, vertical: { overflow: (el) => el.scrollHeight - el.clientHeight, scrollSize: (el) => el.scrollHeight, clientSize: (el) => el.clientHeight, opposite: "horizontal" } }; function _shouldShowHorizontalScroll(horizontalElement, verticalScrollElement, scrollbarWidth = _getScrollbarWidth() || 0, primaryScrollbarElement, oppositeScrollbarElement) { return shouldShowScroll(horizontalElement, verticalScrollElement, "horizontal", scrollbarWidth, primaryScrollbarElement, oppositeScrollbarElement); } function _shouldShowVerticalScroll(verticalElement, horizontalScrollElement, scrollbarWidth = _getScrollbarWidth() || 0, primaryScrollbarElement, oppositeScrollbarElement) { return shouldShowScroll(verticalElement, horizontalScrollElement, "vertical", scrollbarWidth, primaryScrollbarElement, oppositeScrollbarElement); } function shouldShowScroll(primaryElement, oppositeElement, axis, scrollbarWidth, primaryScrollbarElement, oppositeScrollbarElement) { const primary = AXES[axis]; const opposite = AXES[primary.opposite]; const primaryScrollbarShowing = primaryScrollbarElement ? _isVisible(primaryScrollbarElement) : true; const oppositeScrollbarShowing = oppositeScrollbarElement ? _isVisible(oppositeScrollbarElement) : true; const primaryOverflow = primary.overflow(primaryElement); if (primaryOverflow <= 0) { return false; } if (!oppositeElement || scrollbarWidth === 0) { return true; } const oppositeOverflow = opposite.overflow(oppositeElement); if (oppositeOverflow <= 0) { return true; } if (primaryOverflow <= scrollbarWidth) { if (primaryScrollbarShowing && oppositeScrollbarShowing && isScrollbarCausedByOppositeAxis({ candidateOverflow: oppositeOverflow, candidateScrollSize: opposite.scrollSize(oppositeElement), candidateClientSize: opposite.clientSize(oppositeElement), scrollbarWidth })) { return false; } const sizeWithoutOppositeScrollbar = primary.clientSize(primaryElement) + scrollbarWidth; return primary.scrollSize(primaryElement) <= sizeWithoutOppositeScrollbar; } return true; } function isScrollbarCausedByOppositeAxis({ candidateOverflow, candidateScrollSize, candidateClientSize, scrollbarWidth }) { if (candidateOverflow <= 0 || candidateOverflow > scrollbarWidth) { return false; } const sizeWithoutOppositeScrollbar = candidateClientSize + scrollbarWidth; return candidateScrollSize > candidateClientSize && candidateScrollSize <= sizeWithoutOppositeScrollbar; } var ViewportSizeFeature = class extends BeanStub { constructor(centerContainerCtrl) { super(); this.centerContainerCtrl = centerContainerCtrl; } wireBeans(beans) { this.scrollVisibleSvc = beans.scrollVisibleSvc; } postConstruct() { this.beans.ctrlsSvc.whenReady(this, (p) => { this.gridBodyCtrl = p.gridBodyCtrl; this.listenForResize(); }); this.addManagedEventListeners({ scrollbarWidthChanged: this.onScrollbarWidthChanged.bind(this) }); this.addManagedPropertyListeners(["alwaysShowHorizontalScroll", "alwaysShowVerticalScroll"], () => { this.checkViewportAndScrolls(); }); } listenForResize() { const { beans, centerContainerCtrl, gridBodyCtrl } = this; const listener = () => { _requestAnimationFrame(beans, () => { this.onCenterViewportResized(); }); }; centerContainerCtrl.registerViewportResizeListener(listener); gridBodyCtrl.registerBodyViewportResizeListener(listener); } onScrollbarWidthChanged() { this.checkViewportAndScrolls(); } onCenterViewportResized() { this.scrollVisibleSvc.updateScrollGap(); if (this.centerContainerCtrl.isViewportInTheDOMTree()) { const { pinnedCols, colFlex } = this.beans; pinnedCols?.keepPinnedColumnsNarrowerThanViewport(); this.checkViewportAndScrolls(); const newWidth = this.centerContainerCtrl.getCenterWidth(); if (newWidth !== this.centerWidth) { this.centerWidth = newWidth; colFlex?.refreshFlexedColumns({ viewportWidth: this.centerWidth, updateBodyWidths: true, fireResizedEvent: true }); } } else { this.bodyHeight = 0; } } checkViewportAndScrolls() { this.updateScrollVisibleService(); this.checkBodyHeight(); this.onHorizontalViewportChanged(); this.gridBodyCtrl.scrollFeature.checkScrollLeft(); } getBodyHeight() { return this.bodyHeight; } checkBodyHeight() { const eBodyViewport = this.gridBodyCtrl.eBodyViewport; const bodyHeight = _getInnerHeight(eBodyViewport); if (this.bodyHeight !== bodyHeight) { this.bodyHeight = bodyHeight; this.eventSvc.dispatchEvent({ type: "bodyHeightChanged" }); } } updateScrollVisibleService() { this.updateScrollVisibleServiceImpl(); setTimeout(this.updateScrollVisibleServiceImpl.bind(this), 500); } updateScrollVisibleServiceImpl() { if (!this.isAlive()) { return; } const params = { horizontalScrollShowing: this.centerContainerCtrl.isHorizontalScrollShowing(), verticalScrollShowing: this.gridBodyCtrl.isVerticalScrollShowing() }; this.scrollVisibleSvc.setScrollsVisible(params); } onHorizontalViewportChanged() { const { centerContainerCtrl, beans } = this; const scrollWidth = centerContainerCtrl.getCenterWidth(); const scrollPosition = centerContainerCtrl.getViewportScrollLeft(); beans.colViewport.setScrollPosition(scrollWidth, scrollPosition); } }; function _isEventFromPrintableCharacter(event) { if (event.altKey || event.ctrlKey || event.metaKey) { return false; } const printableCharacter = event.key?.length === 1; return printableCharacter; } function _suppressCellMouseEvent(gos, column, node, event) { const suppressMouseEventHandling = column.getColDef().cellRendererParams?.suppressMouseEventHandling; return suppressMouseEvent(gos, column, node, event, suppressMouseEventHandling); } function _suppressFullWidthMouseEvent(gos, cellRendererParams, node, event) { const suppressMouseEventHandling = cellRendererParams?.suppressMouseEventHandling; return suppressMouseEvent(gos, undefined, node, event, suppressMouseEventHandling); } function suppressMouseEvent(gos, column, node, event, suppressMouseEventHandling) { if (!suppressMouseEventHandling) { return false; } return suppressMouseEventHandling(_addGridCommonParams(gos, { column, node, event })); } function _getCtrlForEventTarget(gos, eventTarget, type) { let sourceElement = eventTarget; while (sourceElement) { const renderedComp = _getDomData(gos, sourceElement, type); if (renderedComp) { return renderedComp; } sourceElement = sourceElement.parentElement; } return null; } var DOM_DATA_KEY_CELL_CTRL = "cellCtrl"; function _getCellCtrlForEventTarget(gos, eventTarget) { return _getCtrlForEventTarget(gos, eventTarget, DOM_DATA_KEY_CELL_CTRL); } var DOM_DATA_KEY_ROW_CTRL = "renderedRow"; function _getRowCtrlForEventTarget(gos, eventTarget) { return _getCtrlForEventTarget(gos, eventTarget, DOM_DATA_KEY_ROW_CTRL); } function _isUserSuppressingKeyboardEvent(gos, keyboardEvent, rowNode, column, editing) { const colDefFunc = column ? column.getColDef().suppressKeyboardEvent : undefined; if (!colDefFunc) { return false; } const params = _addGridCommonParams(gos, { event: keyboardEvent, editing, column, node: rowNode, data: rowNode.data, colDef: column.getColDef() }); if (colDefFunc) { const colDefFuncResult = colDefFunc(params); if (colDefFuncResult) { return true; } } return false; } function _selectAllCells(beans) { const { pinnedRowModel, rowModel, rangeSvc, visibleCols } = beans; if (!rangeSvc || visibleCols.allCols.length === 0) { return; } const isEmptyPinnedTop = pinnedRowModel?.isEmpty("top") ?? true; const isEmptyPinnedBottom = pinnedRowModel?.isEmpty("bottom") ?? true; const floatingStart = isEmptyPinnedTop ? null : "top"; let floatingEnd; let rowEnd; if (isEmptyPinnedBottom) { floatingEnd = null; rowEnd = rowModel.getRowCount() - 1; } else { floatingEnd = "bottom"; rowEnd = pinnedRowModel?.getPinnedBottomRowCount() ?? 0 - 1; } rangeSvc.setCellRange({ rowStartIndex: 0, rowStartPinned: floatingStart, rowEndIndex: rowEnd, rowEndPinned: floatingEnd }); } var RowContainerEventsFeature = class extends BeanStub { constructor(element) { super(); this.element = element; } postConstruct() { this.addKeyboardListeners(); this.addMouseListeners(); this.beans.touchSvc?.mockRowContextMenu(this); this.editSvc = this.beans.editSvc; } addKeyboardListeners() { const eventName = "keydown"; const listener = this.processKeyboardEvent.bind(this, eventName); this.addManagedElementListeners(this.element, { [eventName]: listener }); } addMouseListeners() { let mouseDownEvent = "mousedown"; if (_isEventSupported("pointerdown")) { mouseDownEvent = "pointerdown"; } else if (_isEventSupported("touchstart")) { mouseDownEvent = "touchstart"; } const eventNames = ["dblclick", "contextmenu", "mouseover", "mouseout", "click", mouseDownEvent]; for (const eventName of eventNames) { const listener = this.processMouseEvent.bind(this, eventName); this.addManagedElementListeners(this.element, { [eventName]: listener }); } } processMouseEvent(eventName, mouseEvent) { if (!_isEventFromThisInstance(this.beans, mouseEvent) || _isStopPropagationForAgGrid(mouseEvent)) { return; } const { cellCtrl, rowCtrl } = this.getControlsForEventTarget(mouseEvent.target); if (eventName === "contextmenu") { if (cellCtrl?.column) { cellCtrl.dispatchCellContextMenuEvent(mouseEvent); } this.beans.contextMenuSvc?.handleContextMenuMouseEvent(mouseEvent, undefined, rowCtrl, cellCtrl); } else { if (cellCtrl) { cellCtrl.onMouseEvent(eventName, mouseEvent); } if (rowCtrl) { rowCtrl.onMouseEvent(eventName, mouseEvent); } } } getControlsForEventTarget(target) { const { gos } = this; return { cellCtrl: _getCellCtrlForEventTarget(gos, target), rowCtrl: _getRowCtrlForEventTarget(gos, target) }; } processKeyboardEvent(eventName, keyboardEvent) { const { cellCtrl, rowCtrl } = this.getControlsForEventTarget(keyboardEvent.target); if (keyboardEvent.defaultPrevented) { return; } if (cellCtrl) { this.processCellKeyboardEvent(cellCtrl, eventName, keyboardEvent); } else if (rowCtrl?.isFullWidth()) { this.processFullWidthRowKeyboardEvent(rowCtrl, eventName, keyboardEvent); } } processCellKeyboardEvent(cellCtrl, eventName, keyboardEvent) { const editing = this.editSvc?.isEditing(cellCtrl, { withOpenEditor: true }) ?? false; const gridProcessingAllowed = !_isUserSuppressingKeyboardEvent(this.gos, keyboardEvent, cellCtrl.rowNode, cellCtrl.column, editing); if (gridProcessingAllowed) { if (eventName === "keydown") { const wasScrollKey = !editing && this.beans.navigation?.handlePageScrollingKey(keyboardEvent); if (!wasScrollKey) { cellCtrl.onKeyDown(keyboardEvent); } this.doGridOperations(keyboardEvent, editing); if (_isEventFromPrintableCharacter(keyboardEvent)) { cellCtrl.processCharacter(keyboardEvent); } } } if (eventName === "keydown") { this.eventSvc.dispatchEvent(cellCtrl.createEvent(keyboardEvent, "cellKeyDown")); } } processFullWidthRowKeyboardEvent(rowCtrl, eventName, keyboardEvent) { const { rowNode } = rowCtrl; const { focusSvc, navigation } = this.beans; const focusedCell = focusSvc.getFocusedCell(); const column = focusedCell?.column; const gridProcessingAllowed = !_isUserSuppressingKeyboardEvent(this.gos, keyboardEvent, rowNode, column, false); if (gridProcessingAllowed) { const key = keyboardEvent.key; if (eventName === "keydown") { switch (key) { case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: case KeyCode.PAGE_UP: case KeyCode.PAGE_DOWN: navigation?.handlePageScrollingKey(keyboardEvent, true); break; case KeyCode.LEFT: case KeyCode.RIGHT: if (!this.gos.get("embedFullWidthRows")) { break; } case KeyCode.UP: case KeyCode.DOWN: rowCtrl.onKeyboardNavigate(keyboardEvent); break; case KeyCode.TAB: rowCtrl.onTabKeyDown(keyboardEvent); break; default: } } } if (eventName === "keydown") { this.eventSvc.dispatchEvent(rowCtrl.createRowEvent("cellKeyDown", keyboardEvent)); } } doGridOperations(keyboardEvent, editing) { if (!keyboardEvent.ctrlKey && !keyboardEvent.metaKey) { return; } if (editing) { return; } if (!_isEventFromThisInstance(this.beans, keyboardEvent)) { return; } const keyCode = _normaliseQwertyAzerty(keyboardEvent); const { clipboardSvc, undoRedo } = this.beans; if (keyCode === KeyCode.A) { return this.onCtrlAndA(keyboardEvent); } if (keyCode === KeyCode.C) { return this.onCtrlAndC(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.D) { return this.onCtrlAndD(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.V) { return this.onCtrlAndV(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.X) { return this.onCtrlAndX(clipboardSvc, keyboardEvent); } if (keyCode === KeyCode.Y) { return this.onCtrlAndY(undoRedo); } if (keyCode === KeyCode.Z) { return this.onCtrlAndZ(undoRedo, keyboardEvent); } } onCtrlAndA(event) { const { beans: { rowModel, rangeSvc, selectionSvc }, gos } = this; if (rangeSvc && _isCellSelectionEnabled(gos) && !_getCtrlASelectsRows(gos) && rowModel.isRowsToRender()) { _selectAllCells(this.beans); } else if (selectionSvc) { selectionSvc.selectAllRowNodes({ source: "keyboardSelectAll", selectAll: _getSelectAll(gos) }); } event.preventDefault(); } onCtrlAndC(clipboardSvc, event) { if (!clipboardSvc || this.gos.get("enableCellTextSelection")) { return; } const { cellCtrl } = this.getControlsForEventTarget(event.target); if (this.editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { return; } event.preventDefault(); clipboardSvc.copyToClipboard(); } onCtrlAndX(clipboardSvc, event) { if (!clipboardSvc || this.gos.get("enableCellTextSelection") || this.gos.get("suppressCutToClipboard")) { return; } const { cellCtrl } = this.getControlsForEventTarget(event.target); if (this.editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { return; } event.preventDefault(); clipboardSvc.cutToClipboard(undefined, "ui"); } onCtrlAndV(clipboardSvc, event) { const { cellCtrl } = this.getControlsForEventTarget(event.target); if (this.editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { return; } if (clipboardSvc && !this.gos.get("suppressClipboardPaste")) { clipboardSvc.pasteFromClipboard(); } } onCtrlAndD(clipboardSvc, event) { if (clipboardSvc && !this.gos.get("suppressClipboardPaste")) { clipboardSvc.copyRangeDown(); } event.preventDefault(); } onCtrlAndZ(undoRedo, event) { if (!this.gos.get("undoRedoCellEditing") || !undoRedo) { return; } event.preventDefault(); if (event.shiftKey) { undoRedo.redo("ui"); } else { undoRedo.undo("ui"); } } onCtrlAndY(undoRedo) { undoRedo?.redo("ui"); } }; var getTopRowCtrls = (r) => r.topRowCtrls; var getStickyTopRowCtrls = (r) => r.getStickyTopRowCtrls(); var getStickyBottomRowCtrls = (r) => r.getStickyBottomRowCtrls(); var getBottomRowCtrls = (r) => r.bottomRowCtrls; var getCentreRowCtrls = (r) => r.allRowCtrls; var getSpannedTopRowCtrls = (r) => r.getCtrls("top"); var getSpannedCenterRowCtrls = (r) => r.getCtrls("center"); var getSpannedBottomRowCtrls = (r) => r.getCtrls("bottom"); var ContainerCssClasses = { center: { type: "center", name: "center-cols", getRowCtrls: getCentreRowCtrls, getSpannedRowCtrls: getSpannedCenterRowCtrls }, left: { type: "left", name: "pinned-left-cols", pinnedType: "left", getRowCtrls: getCentreRowCtrls, getSpannedRowCtrls: getSpannedCenterRowCtrls }, right: { type: "right", name: "pinned-right-cols", pinnedType: "right", getRowCtrls: getCentreRowCtrls, getSpannedRowCtrls: getSpannedCenterRowCtrls }, fullWidth: { type: "fullWidth", name: "full-width", fullWidth: true, getRowCtrls: getCentreRowCtrls }, topCenter: { type: "center", name: "floating-top", getRowCtrls: getTopRowCtrls, getSpannedRowCtrls: getSpannedTopRowCtrls }, topLeft: { type: "left", name: "pinned-left-floating", container: "ag-pinned-left-floating-top", pinnedType: "left", getRowCtrls: getTopRowCtrls, getSpannedRowCtrls: getSpannedTopRowCtrls }, topRight: { type: "right", name: "pinned-right-floating", container: "ag-pinned-right-floating-top", pinnedType: "right", getRowCtrls: getTopRowCtrls, getSpannedRowCtrls: getSpannedTopRowCtrls }, topFullWidth: { type: "fullWidth", name: "floating-top-full-width", fullWidth: true, getRowCtrls: getTopRowCtrls }, stickyTopCenter: { type: "center", name: "sticky-top", getRowCtrls: getStickyTopRowCtrls }, stickyTopLeft: { type: "left", name: "pinned-left-sticky-top", container: "ag-pinned-left-sticky-top", pinnedType: "left", getRowCtrls: getStickyTopRowCtrls }, stickyTopRight: { type: "right", name: "pinned-right-sticky-top", container: "ag-pinned-right-sticky-top", pinnedType: "right", getRowCtrls: getStickyTopRowCtrls }, stickyTopFullWidth: { type: "fullWidth", name: "sticky-top-full-width", fullWidth: true, getRowCtrls: getStickyTopRowCtrls }, stickyBottomCenter: { type: "center", name: "sticky-bottom", getRowCtrls: getStickyBottomRowCtrls }, stickyBottomLeft: { type: "left", name: "pinned-left-sticky-bottom", container: "ag-pinned-left-sticky-bottom", pinnedType: "left", getRowCtrls: getStickyBottomRowCtrls }, stickyBottomRight: { type: "right", name: "pinned-right-sticky-bottom", container: "ag-pinned-right-sticky-bottom", pinnedType: "right", getRowCtrls: getStickyBottomRowCtrls }, stickyBottomFullWidth: { type: "fullWidth", name: "sticky-bottom-full-width", fullWidth: true, getRowCtrls: getStickyBottomRowCtrls }, bottomCenter: { type: "center", name: "floating-bottom", getRowCtrls: getBottomRowCtrls, getSpannedRowCtrls: getSpannedBottomRowCtrls }, bottomLeft: { type: "left", name: "pinned-left-floating-bottom", container: "ag-pinned-left-floating-bottom", pinnedType: "left", getRowCtrls: getBottomRowCtrls, getSpannedRowCtrls: getSpannedBottomRowCtrls }, bottomRight: { type: "right", name: "pinned-right-floating-bottom", container: "ag-pinned-right-floating-bottom", pinnedType: "right", getRowCtrls: getBottomRowCtrls, getSpannedRowCtrls: getSpannedBottomRowCtrls }, bottomFullWidth: { type: "fullWidth", name: "floating-bottom-full-width", fullWidth: true, getRowCtrls: getBottomRowCtrls } }; function _getRowViewportClass(name) { const options = _getRowContainerOptions(name); return `ag-${options.name}-viewport`; } function _getRowContainerClass(name) { const options = _getRowContainerOptions(name); return options.container ?? `ag-${options.name}-container`; } function _getRowSpanContainerClass(name) { const options = _getRowContainerOptions(name); return `ag-${options.name}-spanned-cells-container`; } function _getRowContainerOptions(name) { return ContainerCssClasses[name]; } var allTopNoFW = ["topCenter", "topLeft", "topRight"]; var allBottomNoFW = ["bottomCenter", "bottomLeft", "bottomRight"]; var allMiddleNoFW = ["center", "left", "right"]; var allMiddle = ["center", "left", "right", "fullWidth"]; var allCenter = ["stickyTopCenter", "stickyBottomCenter", "center", "topCenter", "bottomCenter"]; var allLeft = ["left", "bottomLeft", "topLeft", "stickyTopLeft", "stickyBottomLeft"]; var allRight = ["right", "bottomRight", "topRight", "stickyTopRight", "stickyBottomRight"]; var allStickyTopNoFW = ["stickyTopCenter", "stickyTopLeft", "stickyTopRight"]; var allStickyBottomNoFW = ["stickyBottomCenter", "stickyBottomLeft", "stickyBottomRight"]; var allStickyContainers = [ ...allStickyTopNoFW, "stickyTopFullWidth", ...allStickyBottomNoFW, "stickyBottomFullWidth" ]; var allNoFW = [ ...allTopNoFW, ...allBottomNoFW, ...allMiddleNoFW, ...allStickyTopNoFW, ...allStickyBottomNoFW ]; var RowContainerCtrl = class extends BeanStub { constructor(name) { super(); this.name = name; this.visible = true; this.EMPTY_CTRLS = []; this.options = _getRowContainerOptions(name); } postConstruct() { this.enableRtl = this.gos.get("enableRtl"); this.forContainers(["center"], () => { this.viewportSizeFeature = this.createManagedBean(new ViewportSizeFeature(this)); this.addManagedEventListeners({ stickyTopOffsetChanged: this.onStickyTopOffsetChanged.bind(this) }); }); } onStickyTopOffsetChanged(event) { this.comp.setOffsetTop(`${event.offset}px`); } registerWithCtrlsService() { if (this.options.fullWidth) { return; } this.beans.ctrlsSvc.register(this.name, this); } forContainers(names, callback) { if (names.indexOf(this.name) >= 0) { callback(); } } setComp(view, eContainer, eSpannedContainer, eViewport) { this.comp = view; this.eContainer = eContainer; this.eSpannedContainer = eSpannedContainer; this.eViewport = eViewport; this.createManagedBean(new RowContainerEventsFeature(this.eViewport ?? this.eContainer)); this.addPreventScrollWhileDragging(); this.listenOnDomOrder(); const { pinnedCols, rangeSvc } = this.beans; const pinnedWidthChanged = () => this.onPinnedWidthChanged(); this.forContainers(allLeft, () => { this.pinnedWidthFeature = this.createOptionalManagedBean(pinnedCols?.createPinnedWidthFeature(true, this.eContainer, this.eSpannedContainer)); this.addManagedEventListeners({ leftPinnedWidthChanged: pinnedWidthChanged }); }); this.forContainers(allRight, () => { this.pinnedWidthFeature = this.createOptionalManagedBean(pinnedCols?.createPinnedWidthFeature(false, this.eContainer, this.eSpannedContainer)); this.addManagedEventListeners({ rightPinnedWidthChanged: pinnedWidthChanged }); }); this.forContainers(allMiddle, () => this.createManagedBean(new SetHeightFeature(this.eContainer, this.name === "center" ? eViewport : undefined))); if (rangeSvc) { this.forContainers(allNoFW, () => this.createManagedBean(rangeSvc.createDragListenerFeature(this.eContainer))); } this.forContainers(allCenter, () => this.createManagedBean(new CenterWidthFeature((width) => this.comp.setContainerWidth(`${width}px`)))); this.visible = this.isContainerVisible(); this.addListeners(); this.registerWithCtrlsService(); } onScrollCallback(fn) { this.addManagedElementListeners(this.eViewport, { scroll: fn }); } addListeners() { const { spannedRowRenderer, gos } = this.beans; const onDisplayedColumnsChanged = this.onDisplayedColumnsChanged.bind(this); this.addManagedEventListeners({ displayedColumnsChanged: onDisplayedColumnsChanged, displayedColumnsWidthChanged: onDisplayedColumnsChanged, displayedRowsChanged: (params) => this.onDisplayedRowsChanged(params.afterScroll) }); onDisplayedColumnsChanged(); this.onDisplayedRowsChanged(); if (spannedRowRenderer && this.options.getSpannedRowCtrls && gos.get("enableCellSpan")) { this.addManagedListeners(spannedRowRenderer, { spannedRowsUpdated: () => { const spannedCtrls = this.options.getSpannedRowCtrls(spannedRowRenderer); if (!spannedCtrls) { return; } this.comp.setSpannedRowCtrls(spannedCtrls, false); } }); } } listenOnDomOrder() { const isStickContainer = allStickyContainers.indexOf(this.name) >= 0; if (isStickContainer) { this.comp.setDomOrder(true); return; } const listener = () => { const isEnsureDomOrder = this.gos.get("ensureDomOrder"); const isPrintLayout = _isDomLayout(this.gos, "print"); this.comp.setDomOrder(isEnsureDomOrder || isPrintLayout); }; this.addManagedPropertyListener("domLayout", listener); listener(); } onDisplayedColumnsChanged() { this.forContainers(["center"], () => this.onHorizontalViewportChanged()); } addPreventScrollWhileDragging() { const { dragSvc } = this.beans; if (!dragSvc) { return; } const preventScroll = (e) => { if (dragSvc.dragging) { if (e.cancelable) { e.preventDefault(); } } }; this.eContainer.addEventListener("touchmove", preventScroll, { passive: false }); this.addDestroyFunc(() => this.eContainer.removeEventListener("touchmove", preventScroll)); } onHorizontalViewportChanged(afterScroll = false) { const scrollWidth = this.getCenterWidth(); const scrollPosition = this.getCenterViewportScrollLeft(); this.beans.colViewport.setScrollPosition(scrollWidth, scrollPosition, afterScroll); } hasHorizontalScrollGap() { return this.eContainer.clientWidth - this.eViewport.clientWidth < 0; } hasVerticalScrollGap() { return this.eContainer.clientHeight - this.eViewport.clientHeight < 0; } getCenterWidth() { return _getInnerWidth(this.eViewport); } getCenterViewportScrollLeft() { return _getScrollLeft(this.eViewport, this.enableRtl); } registerViewportResizeListener(listener) { const unsubscribeFromResize = _observeResize(this.beans, this.eViewport, listener); this.addDestroyFunc(() => unsubscribeFromResize()); } isViewportInTheDOMTree() { return _isInDOM(this.eViewport); } getViewportScrollLeft() { return _getScrollLeft(this.eViewport, this.enableRtl); } isHorizontalScrollShowing() { const { beans, gos, eViewport } = this; const isAlwaysShowHorizontalScroll = gos.get("alwaysShowHorizontalScroll"); const { ctrlsSvc } = beans; const verticalScrollElement = ctrlsSvc.getGridBodyCtrl()?.eBodyViewport; const hScrollEl = ctrlsSvc.get("fakeHScrollComp")?.getGui(); const vScrollEl = ctrlsSvc.get("fakeVScrollComp")?.getGui(); return isAlwaysShowHorizontalScroll || _shouldShowHorizontalScroll(eViewport, verticalScrollElement, undefined, hScrollEl, vScrollEl); } setHorizontalScroll(offset) { this.comp.setHorizontalScroll(offset); } getHScrollPosition() { const res = { left: this.eViewport.scrollLeft, right: this.eViewport.scrollLeft + this.eViewport.offsetWidth }; return res; } setCenterViewportScrollLeft(value) { _setScrollLeft(this.eViewport, value, this.enableRtl); } isContainerVisible() { const pinned = this.options.pinnedType != null; return !pinned || !!this.pinnedWidthFeature && this.pinnedWidthFeature.getWidth() > 0; } onPinnedWidthChanged() { const visible = this.isContainerVisible(); if (this.visible != visible) { this.visible = visible; this.onDisplayedRowsChanged(); } } onDisplayedRowsChanged(afterScroll = false) { const rows = this.options.getRowCtrls(this.beans.rowRenderer); if (!this.visible || rows.length === 0) { this.comp.setRowCtrls({ rowCtrls: this.EMPTY_CTRLS }); return; } const printLayout = _isDomLayout(this.gos, "print"); const embedFullWidthRows = this.gos.get("embedFullWidthRows"); const embedFW = embedFullWidthRows || printLayout; const rowsThisContainer = rows.filter((rowCtrl) => { const fullWidthRow = rowCtrl.isFullWidth(); const match = this.options.fullWidth ? !embedFW && fullWidthRow : embedFW || !fullWidthRow; return match; }); this.comp.setRowCtrls({ rowCtrls: rowsThisContainer, useFlushSync: afterScroll }); } }; var CSS_CLASS_FORCE_VERTICAL_SCROLL = "ag-force-vertical-scroll"; var CSS_CLASS_CELL_SELECTABLE = "ag-selectable"; var CSS_CLASS_COLUMN_MOVING = "ag-column-moving"; var GridBodyCtrl = class extends BeanStub { constructor() { super(...arguments); this.stickyTopHeight = 0; this.stickyBottomHeight = 0; } wireBeans(beans) { this.ctrlsSvc = beans.ctrlsSvc; this.colModel = beans.colModel; this.scrollVisibleSvc = beans.scrollVisibleSvc; this.pinnedRowModel = beans.pinnedRowModel; this.filterManager = beans.filterManager; this.rowGroupColsSvc = beans.rowGroupColsSvc; } setComp(comp, eGridBody, eBodyViewport, eTop, eBottom, eStickyTop, eStickyBottom) { this.comp = comp; this.eGridBody = eGridBody; this.eBodyViewport = eBodyViewport; this.eTop = eTop; this.eBottom = eBottom; this.eStickyTop = eStickyTop; this.eStickyBottom = eStickyBottom; this.eCenterColsViewport = eBodyViewport.querySelector(`.${_getRowViewportClass("center")}`); this.eFullWidthContainer = eBodyViewport.querySelector(`.${_getRowContainerClass("fullWidth")}`); this.setCellTextSelection(this.gos.get("enableCellTextSelection")); this.addManagedPropertyListener("enableCellTextSelection", (props) => this.setCellTextSelection(props.currentValue)); this.createManagedBean(new LayoutFeature(this.comp)); this.scrollFeature = this.createManagedBean(new GridBodyScrollFeature(eBodyViewport)); this.beans.rowDragSvc?.setupRowDrag(eBodyViewport, this); this.setupRowAnimationCssClass(); this.addEventListeners(); this.addFocusListeners([eTop, eBodyViewport, eBottom, eStickyTop, eStickyBottom]); this.setGridRootRole(); this.onGridColumnsChanged(); this.addBodyViewportListener(); this.setFloatingHeights(); this.disableBrowserDragging(); this.addStopEditingWhenGridLosesFocus(); this.updateScrollingClasses(); this.filterManager?.setupAdvFilterHeaderComp(eTop); this.ctrlsSvc.register("gridBodyCtrl", this); } addEventListeners() { const setFloatingHeights = this.setFloatingHeights.bind(this); const setGridRootRole = this.setGridRootRole.bind(this); const toggleRowResizeStyle = this.toggleRowResizeStyles.bind(this); this.addManagedEventListeners({ gridColumnsChanged: this.onGridColumnsChanged.bind(this), scrollVisibilityChanged: this.onScrollVisibilityChanged.bind(this), scrollGapChanged: this.updateScrollingClasses.bind(this), pinnedRowDataChanged: setFloatingHeights, pinnedHeightChanged: setFloatingHeights, pinnedRowsChanged: setFloatingHeights, headerHeightChanged: this.setStickyTopOffsetTop.bind(this), columnRowGroupChanged: setGridRootRole, columnPivotChanged: setGridRootRole, rowResizeStarted: toggleRowResizeStyle, rowResizeEnded: toggleRowResizeStyle }); this.addManagedPropertyListener("treeData", setGridRootRole); } toggleRowResizeStyles(params) { const isResizingRow = params.type === "rowResizeStarted"; this.eBodyViewport.classList.toggle("ag-prevent-animation", isResizingRow); } onGridColumnsChanged() { const columns = this.beans.colModel.getCols(); this.comp.setColumnCount(columns.length); } onScrollVisibilityChanged() { const { scrollVisibleSvc } = this; const visible = scrollVisibleSvc.verticalScrollShowing; this.setVerticalScrollPaddingVisible(visible); this.setStickyWidth(visible); this.setStickyBottomOffsetBottom(); const scrollbarWidth = visible ? scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const pad = _isInvisibleScrollbar() ? 16 : 0; const width = `calc(100% + ${scrollbarWidth + pad}px)`; _requestAnimationFrame(this.beans, () => this.comp.setBodyViewportWidth(width)); this.updateScrollingClasses(); } setGridRootRole() { const { rowGroupColsSvc, colModel, gos } = this; let isTreeGrid = gos.get("treeData"); if (!isTreeGrid) { const isPivotActive = colModel.isPivotMode(); const rowGroupColumnLen = !rowGroupColsSvc ? 0 : rowGroupColsSvc.columns.length; const columnsNeededForGrouping = isPivotActive ? 2 : 1; isTreeGrid = rowGroupColumnLen >= columnsNeededForGrouping; } this.comp.setGridRootRole(isTreeGrid ? "treegrid" : "grid"); } addFocusListeners(elements) { for (const element of elements) { this.addManagedElementListeners(element, { focusin: (e) => { const { target } = e; const isFocusedElementNested = _isElementChildOfClass(target, "ag-root", element); element.classList.toggle("ag-has-focus", !isFocusedElementNested); }, focusout: (e) => { const { target, relatedTarget } = e; const gridContainRelatedTarget = element.contains(relatedTarget); const isNestedRelatedTarget = _isElementChildOfClass(relatedTarget, "ag-root", element); const isNestedTarget = _isElementChildOfClass(target, "ag-root", element); if (isNestedTarget) { return; } if (!gridContainRelatedTarget || isNestedRelatedTarget) { element.classList.remove("ag-has-focus"); } } }); } } setColumnMovingCss(moving) { this.comp.setColumnMovingCss(CSS_CLASS_COLUMN_MOVING, moving); } setCellTextSelection(selectable = false) { this.comp.setCellSelectableCss(CSS_CLASS_CELL_SELECTABLE, selectable); } updateScrollingClasses() { const { eGridBody: { classList }, scrollVisibleSvc } = this; classList.toggle("ag-body-vertical-content-no-gap", !scrollVisibleSvc.verticalScrollGap); classList.toggle("ag-body-horizontal-content-no-gap", !scrollVisibleSvc.horizontalScrollGap); } disableBrowserDragging() { this.addManagedElementListeners(this.eGridBody, { dragstart: (event) => { if (event.target instanceof HTMLImageElement) { event.preventDefault(); return false; } } }); } addStopEditingWhenGridLosesFocus() { this.beans.editSvc?.addStopEditingWhenGridLosesFocus([ this.eBodyViewport, this.eBottom, this.eTop, this.eStickyTop, this.eStickyBottom ]); } updateRowCount() { const headerCount = (this.ctrlsSvc.getHeaderRowContainerCtrl()?.getRowCount() ?? 0) + (this.filterManager?.getHeaderRowCount() ?? 0); const { rowModel } = this.beans; const rowCount = rowModel.isLastRowIndexKnown() ? rowModel.getRowCount() : -1; const total = rowCount === -1 ? -1 : headerCount + rowCount; this.comp.setRowCount(total); } registerBodyViewportResizeListener(listener) { this.comp.registerBodyViewportResizeListener(listener); } setVerticalScrollPaddingVisible(visible) { const overflowY = visible ? "scroll" : "hidden"; this.comp.setPinnedTopBottomOverflowY(overflowY); } isVerticalScrollShowing() { const { gos, comp, ctrlsSvc } = this; const show = gos.get("alwaysShowVerticalScroll"); const cssClass = show ? CSS_CLASS_FORCE_VERTICAL_SCROLL : null; const allowVerticalScroll = _isDomLayout(gos, "normal"); comp.setAlwaysVerticalScrollClass(cssClass, show); const horizontalScrollElement = ctrlsSvc.get("center")?.eViewport; const hScrollEl = ctrlsSvc.get("fakeHScrollComp")?.getGui(); const vScrollEl = ctrlsSvc.get("fakeVScrollComp")?.getGui(); return show || allowVerticalScroll && _shouldShowVerticalScroll(this.eBodyViewport, horizontalScrollElement, undefined, vScrollEl, hScrollEl); } setupRowAnimationCssClass() { const { rowContainerHeight, environment } = this.beans; let initialSizeMeasurementComplete = environment.sizesMeasured; const updateAnimationClass = () => { const animateRows = initialSizeMeasurementComplete && _isAnimateRows(this.gos) && !rowContainerHeight.stretching; const animateRowsCssClass = animateRows ? "ag-row-animation" : "ag-row-no-animation"; this.comp.setRowAnimationCssOnBodyViewport(animateRowsCssClass, animateRows); }; updateAnimationClass(); this.addManagedEventListeners({ heightScaleChanged: updateAnimationClass }); this.addManagedPropertyListener("animateRows", updateAnimationClass); this.addManagedEventListeners({ stylesChanged: () => { if (!initialSizeMeasurementComplete && environment.sizesMeasured) { initialSizeMeasurementComplete = true; updateAnimationClass(); } } }); } addBodyViewportListener() { const { eBodyViewport, eStickyTop, eStickyBottom, eTop, eBottom, beans: { popupSvc, touchSvc } } = this; const listener = this.onBodyViewportContextMenu.bind(this); this.addManagedElementListeners(eBodyViewport, { contextmenu: listener }); touchSvc?.mockBodyContextMenu(this, listener); this.addManagedElementListeners(eBodyViewport, { wheel: this.onBodyViewportWheel.bind(this, popupSvc) }); const onStickyWheel = this.onStickyWheel.bind(this); for (const container of [eStickyTop, eStickyBottom, eTop, eBottom]) { this.addManagedElementListeners(container, { wheel: onStickyWheel }); } const onHorizontalWheel = this.onHorizontalWheel.bind(this); for (const container of ["left", "right", "topLeft", "topRight", "bottomLeft", "bottomRight"]) { this.addManagedElementListeners(this.ctrlsSvc.get(container).eContainer, { wheel: onHorizontalWheel }); } this.addFullWidthContainerWheelListener(); } addFullWidthContainerWheelListener() { this.addManagedElementListeners(this.eFullWidthContainer, { wheel: (e) => this.onFullWidthContainerWheel(e) }); } onFullWidthContainerWheel(e) { const { deltaX, deltaY, shiftKey } = e; const isHorizontalScroll = shiftKey || Math.abs(deltaX) > Math.abs(deltaY); if (isHorizontalScroll && _isEventFromThisInstance(this.beans, e)) { this.scrollGridBodyToMatchEvent(e); } } onStickyWheel(e) { const { deltaY } = e; const scrolled = this.scrollVertically(deltaY); if (scrolled > 0) { e.preventDefault(); } } onHorizontalWheel(e) { const { deltaX, deltaY, shiftKey } = e; const isHorizontalScroll = shiftKey || Math.abs(deltaX) > Math.abs(deltaY); if (!isHorizontalScroll) { return; } this.scrollGridBodyToMatchEvent(e); } scrollGridBodyToMatchEvent(e) { const { deltaX, deltaY } = e; e.preventDefault(); this.eCenterColsViewport.scrollBy({ left: deltaX || deltaY }); } onBodyViewportContextMenu(mouseEvent, touch, touchEvent) { if (!mouseEvent && !touchEvent) { return; } if (this.gos.get("preventDefaultOnContextMenu")) { const event = mouseEvent || touchEvent; event.preventDefault(); } const { target } = mouseEvent || touch; if (target === this.eBodyViewport || target === this.ctrlsSvc.get("center").eViewport) { this.beans.contextMenuSvc?.showContextMenu({ mouseEvent, touchEvent, value: null, anchorToElement: this.eGridBody, source: "ui" }); } } onBodyViewportWheel(popupSvc, e) { if (!this.gos.get("suppressScrollWhenPopupsAreOpen")) { return; } if (popupSvc?.hasAnchoredPopup()) { e.preventDefault(); } } scrollVertically(pixels) { const oldScrollPosition = this.eBodyViewport.scrollTop; this.scrollFeature.setVerticalScrollPosition(oldScrollPosition + pixels); return this.eBodyViewport.scrollTop - oldScrollPosition; } setFloatingHeights() { const { pinnedRowModel, beans: { environment } } = this; const floatingTopHeight = pinnedRowModel?.getPinnedTopTotalHeight(); const floatingBottomHeight = pinnedRowModel?.getPinnedBottomTotalHeight(); const pinnedBorderWidth = environment.getPinnedRowBorderWidth(); const rowBorderWidth = environment.getRowBorderWidth(); const additionalHeight = pinnedBorderWidth - rowBorderWidth; const normalisedFloatingTopHeight = !floatingTopHeight ? 0 : additionalHeight + floatingTopHeight; const normalisedFloatingBottomHeight = !floatingBottomHeight ? 0 : additionalHeight + floatingBottomHeight; this.comp.setTopHeight(normalisedFloatingTopHeight); this.comp.setBottomHeight(normalisedFloatingBottomHeight); this.comp.setTopInvisible(normalisedFloatingTopHeight <= 0); this.comp.setBottomInvisible(normalisedFloatingBottomHeight <= 0); this.setStickyTopOffsetTop(); this.setStickyBottomOffsetBottom(); } setStickyTopHeight(height = 0) { this.comp.setStickyTopHeight(`${height}px`); this.stickyTopHeight = height; } setStickyBottomHeight(height = 0) { this.comp.setStickyBottomHeight(`${height}px`); this.stickyBottomHeight = height; } setStickyWidth(vScrollVisible) { if (!vScrollVisible) { this.comp.setStickyTopWidth("100%"); this.comp.setStickyBottomWidth("100%"); } else { const scrollbarWidth = this.scrollVisibleSvc.getScrollbarWidth(); this.comp.setStickyTopWidth(`calc(100% - ${scrollbarWidth}px)`); this.comp.setStickyBottomWidth(`calc(100% - ${scrollbarWidth}px)`); } } setStickyTopOffsetTop() { const headerCtrl = this.ctrlsSvc.get("gridHeaderCtrl"); const headerHeight = headerCtrl.headerHeight + (this.filterManager?.getHeaderHeight() ?? 0); const pinnedTopHeight = this.pinnedRowModel?.getPinnedTopTotalHeight() ?? 0; let height = 0; if (headerHeight > 0) { height += headerHeight; } if (pinnedTopHeight > 0) { height += pinnedTopHeight; } if (height > 0) { height += 1; } this.comp.setStickyTopTop(`${height}px`); } setStickyBottomOffsetBottom() { const { pinnedRowModel, scrollVisibleSvc, comp } = this; const pinnedBottomHeight = pinnedRowModel?.getPinnedBottomTotalHeight() ?? 0; const hScrollShowing = scrollVisibleSvc.horizontalScrollShowing; const scrollbarWidth = hScrollShowing ? scrollVisibleSvc.getScrollbarWidth() || 0 : 0; const height = pinnedBottomHeight + scrollbarWidth; comp.setStickyBottomBottom(`${height}px`); } }; function _createElement(params) { return _createAgElement(params); } var CellComp = class extends Component { constructor(beans, cellCtrl, printLayout, eRow, editingCell) { super(); this.cellCtrl = cellCtrl; this.rowResizerElement = null; this.rendererVersion = 0; this.editorVersion = 0; this.beans = beans; this.gos = beans.gos; this.column = cellCtrl.column; this.rowNode = cellCtrl.rowNode; this.eRow = eRow; const cellDiv = _createElement({ tag: "div", role: cellCtrl.getCellAriaRole(), attrs: { "comp-id": `${this.getCompId()}`, "col-id": cellCtrl.column.colIdSanitised } }); this.eCell = cellDiv; let wrapperDiv; if (cellCtrl.isCellSpanning()) { wrapperDiv = _createElement({ tag: "div", cls: "ag-spanned-cell-wrapper", role: "presentation" }); wrapperDiv.appendChild(cellDiv); this.setTemplateFromElement(wrapperDiv); } else { this.setTemplateFromElement(cellDiv); } this.cellCssManager = new CssClassManager(() => cellDiv); this.forceWrapper = cellCtrl.isForceWrapper(); this.refreshWrapper(false); const compProxy = { toggleCss: (cssClassName, on) => this.cellCssManager.toggleCss(cssClassName, on), setUserStyles: (styles) => _addStylesToElement(cellDiv, styles), getFocusableElement: () => cellDiv, setIncludeSelection: (include) => this.includeSelection = include, setIncludeRowDrag: (include) => this.includeRowDrag = include, setIncludeDndSource: (include) => this.includeDndSource = include, setRowResizerElement: (element) => this.setRowResizerElement(element), setRenderDetails: (compDetails, valueToDisplay, force) => this.setRenderDetails(compDetails, valueToDisplay, force), setEditDetails: (compDetails, popup, position) => this.setEditDetails(compDetails, popup, position), getCellEditor: () => this.cellEditor || null, getCellRenderer: () => this.cellRenderer || null, getParentOfValue: () => this.getParentOfValue(), refreshEditStyles: (editing, isPopup) => this.refreshEditStyles(editing, isPopup) }; cellCtrl.setComp(compProxy, cellDiv, wrapperDiv, this.eCellWrapper, printLayout, editingCell, undefined); } getParentOfValue() { return this.eCellValue ?? this.eCellWrapper ?? this.eCell; } setRowResizerElement(element) { if (this.rowResizerElement) { _removeFromParent(this.rowResizerElement); } this.rowResizerElement = element; if (element) { this.eCell.appendChild(element); } } setRenderDetails(compDetails, valueToDisplay, forceNewCellRendererInstance) { const isInlineEditing = this.cellEditor && !this.cellEditorPopupWrapper; if (isInlineEditing) { return; } this.firstRender = this.firstRender == null; const controlWrapperChanged = this.refreshWrapper(false); this.refreshEditStyles(false); if (compDetails) { const neverRefresh = forceNewCellRendererInstance || controlWrapperChanged; const cellRendererRefreshSuccessful = neverRefresh ? false : this.refreshCellRenderer(compDetails); if (!cellRendererRefreshSuccessful) { this.destroyRenderer(); this.createCellRendererInstance(compDetails); } } else { this.destroyRenderer(); this.insertValueWithoutCellRenderer(valueToDisplay); } this.rowDraggingComp?.refreshVisibility(); if (this.rowResizerElement && !this.rowResizerElement.parentElement) { this.eCell.appendChild(this.rowResizerElement); } } setEditDetails(compDetails, popup, position) { if (compDetails) { this.createCellEditorInstance(compDetails, popup, position); } else { this.destroyEditor(); } } removeControls() { const context = this.beans.context; this.checkboxSelectionComp = context.destroyBean(this.checkboxSelectionComp); this.dndSourceComp = context.destroyBean(this.dndSourceComp); this.rowDraggingComp = context.destroyBean(this.rowDraggingComp); } refreshWrapper(editing) { const providingControls = this.includeRowDrag || this.includeDndSource || this.includeSelection; const usingWrapper = providingControls || this.forceWrapper; const putWrapperIn = usingWrapper && this.eCellWrapper == null; if (putWrapperIn) { this.eCellWrapper = _createElement({ tag: "div", cls: "ag-cell-wrapper", role: "presentation" }); this.eCell.appendChild(this.eCellWrapper); } const takeWrapperOut = !usingWrapper && this.eCellWrapper != null; if (takeWrapperOut) { _removeFromParent(this.eCellWrapper); this.eCellWrapper = undefined; } this.cellCssManager.toggleCss("ag-cell-value", !usingWrapper); const usingCellValue = !editing && usingWrapper; const putCellValueIn = usingCellValue && this.eCellValue == null; if (putCellValueIn) { const cls = this.cellCtrl.getCellValueClass(); this.eCellValue = _createElement({ tag: "span", cls, role: "presentation" }); this.eCellWrapper.appendChild(this.eCellValue); } const takeCellValueOut = !usingCellValue && this.eCellValue != null; if (takeCellValueOut) { _removeFromParent(this.eCellValue); this.eCellValue = undefined; } const templateChanged = putWrapperIn || takeWrapperOut || putCellValueIn || takeCellValueOut; if (templateChanged) { this.removeControls(); } if (!editing && providingControls) { this.addControls(); } return templateChanged; } addControls() { const { cellCtrl, eCellWrapper, eCellValue, includeRowDrag, includeDndSource, includeSelection } = this; const insertBefore = (comp) => { if (comp) { eCellWrapper.insertBefore(comp.getGui(), eCellValue); } }; if (includeRowDrag && this.rowDraggingComp == null) { this.rowDraggingComp = cellCtrl.createRowDragComp(); insertBefore(this.rowDraggingComp); } if (includeDndSource && this.dndSourceComp == null) { this.dndSourceComp = cellCtrl.createDndSource(); insertBefore(this.dndSourceComp); } if (includeSelection && this.checkboxSelectionComp == null) { this.checkboxSelectionComp = cellCtrl.createSelectionCheckbox(); insertBefore(this.checkboxSelectionComp); } } createCellEditorInstance(compDetails, popup, position) { const versionCopy = this.editorVersion; const cellEditorPromise = compDetails.newAgStackInstance(); const { params } = compDetails; cellEditorPromise.then((c) => this.afterCellEditorCreated(versionCopy, c, params, popup, position)); const cellEditorAsync = _missing(this.cellEditor); if (cellEditorAsync && params.cellStartedEdit) { this.cellCtrl.focusCell(true); } } insertValueWithoutCellRenderer(valueToDisplay) { const eParent = this.getParentOfValue(); _clearElement(eParent); const escapedValue = _toString(valueToDisplay); if (escapedValue != null) { eParent.textContent = escapedValue; } } destroyRenderer() { const { context } = this.beans; this.cellRenderer = context.destroyBean(this.cellRenderer); _removeFromParent(this.cellRendererGui); this.cellRendererGui = null; this.rendererVersion++; } destroyEditor() { const { context } = this.beans; const recoverFocus = this.cellEditorPopupWrapper?.getGui().contains(_getActiveDomElement(this.beans)) || this.cellCtrl.hasBrowserFocus(); if (recoverFocus) { this.eCell.focus({ preventScroll: true }); } this.hideEditorPopup?.(); this.hideEditorPopup = undefined; this.cellEditor = context.destroyBean(this.cellEditor); this.cellEditorPopupWrapper = context.destroyBean(this.cellEditorPopupWrapper); _removeFromParent(this.cellEditorGui); this.cellCtrl.disableEditorTooltipFeature(); this.cellEditorGui = null; this.editorVersion++; } refreshCellRenderer(compClassAndParams) { if (this.cellRenderer?.refresh == null) { return false; } if (this.cellRendererClass !== compClassAndParams.componentClass) { return false; } const result = this.cellRenderer.refresh(compClassAndParams.params); return result === true || result === undefined; } createCellRendererInstance(compDetails) { const displayComponentVersionCopy = this.rendererVersion; const createCellRendererFunc = (details) => (_) => { const staleTask = this.rendererVersion !== displayComponentVersionCopy || !this.isAlive(); if (staleTask) { return; } const componentPromise = details.newAgStackInstance(); const callback = this.afterCellRendererCreated.bind(this, displayComponentVersionCopy, details.componentClass); componentPromise?.then(callback); }; const { animationFrameSvc } = this.beans; let createTask; if (animationFrameSvc?.active && this.firstRender) { createTask = (details, isDeferred = false) => { animationFrameSvc.createTask(createCellRendererFunc(details), this.rowNode.rowIndex, "p2", details.componentFromFramework, isDeferred); }; } else { createTask = (details) => createCellRendererFunc(details)(); } if (compDetails.params?.deferRender && !this.cellCtrl.rowNode.group) { const { loadingComp, onReady } = this.cellCtrl.getDeferLoadingCellRenderer(); if (loadingComp) { createTask(loadingComp); onReady.then(() => createTask(compDetails, true)); } } else { createTask(compDetails); } } afterCellRendererCreated(cellRendererVersion, cellRendererClass, cellRenderer) { const staleTask = !this.isAlive() || cellRendererVersion !== this.rendererVersion; if (staleTask) { this.beans.context.destroyBean(cellRenderer); return; } this.cellRenderer = cellRenderer; this.cellRendererClass = cellRendererClass; const cellGui = cellRenderer.getGui(); this.cellRendererGui = cellGui; if (cellGui != null) { const eParent = this.getParentOfValue(); _clearElement(eParent); eParent.appendChild(cellGui); } } afterCellEditorCreated(requestVersion, cellEditor, params, popup, position) { const staleComp = requestVersion !== this.editorVersion; const { context } = this.beans; if (staleComp) { context.destroyBean(cellEditor); return; } const editingCancelledByUserComp = cellEditor.isCancelBeforeStart?.(); if (editingCancelledByUserComp) { context.destroyBean(cellEditor); this.cellCtrl.stopEditing(true); return; } if (!cellEditor.getGui) { _warn(97, { colId: this.column.getId() }); context.destroyBean(cellEditor); return; } this.cellEditor = cellEditor; this.cellEditorGui = cellEditor.getGui(); const cellEditorInPopup = popup || cellEditor.isPopup?.(); if (cellEditorInPopup) { this.addPopupCellEditor(params, position); } else { this.addInCellEditor(); } this.refreshEditStyles(true, cellEditorInPopup); cellEditor.afterGuiAttached?.(); this.cellCtrl.enableEditorTooltipFeature(cellEditor); this.cellCtrl.cellEditorAttached(); } refreshEditStyles(editing, isPopup) { const { cellCssManager } = this; cellCssManager.toggleCss("ag-cell-inline-editing", editing && !isPopup); cellCssManager.toggleCss("ag-cell-popup-editing", editing && !!isPopup); cellCssManager.toggleCss("ag-cell-not-inline-editing", !editing || !!isPopup); } addInCellEditor() { const { eCell } = this; if (eCell.contains(_getActiveDomElement(this.beans))) { eCell.focus(); } this.destroyRenderer(); this.refreshWrapper(true); _clearElement(this.getParentOfValue()); if (this.cellEditorGui) { const eParent = this.getParentOfValue(); eParent.appendChild(this.cellEditorGui); } } addPopupCellEditor(params, position) { const { gos, context, popupSvc, editSvc } = this.beans; if (gos.get("editType") === "fullRow") { _warn(98); } const cellEditorPopupWrapper = this.cellEditorPopupWrapper = context.createBean(editSvc.createPopupEditorWrapper(params)); const { cellEditor, cellEditorGui, eCell, rowNode, column, cellCtrl } = this; const ePopupGui = cellEditorPopupWrapper.getGui(); if (cellEditorGui) { ePopupGui.appendChild(cellEditorGui); } const useModelPopup = gos.get("stopEditingWhenCellsLoseFocus"); const positionToUse = position != null ? position : cellEditor.getPopupPosition?.() ?? "over"; const isRtl = gos.get("enableRtl"); const positionParams = { ePopup: ePopupGui, additionalParams: { column, rowNode }, type: "popupCellEditor", eventSource: eCell, position: positionToUse, alignSide: isRtl ? "right" : "left", keepWithinBounds: true }; const positionCallback = popupSvc.positionPopupByComponent.bind(popupSvc, positionParams); const addPopupRes = popupSvc.addPopup({ modal: useModelPopup, eChild: ePopupGui, closeOnEsc: true, closedCallback: (e) => { cellCtrl.onPopupEditorClosed(e); }, anchorToElement: eCell, positionCallback, ariaOwns: eCell }); if (addPopupRes) { this.hideEditorPopup = addPopupRes.hideFunc; } } detach() { this.getGui().remove(); } destroy() { this.destroyRenderer(); this.destroyEditor(); this.removeControls(); super.destroy(); } }; var RowComp = class extends Component { constructor(ctrl, beans, containerType) { super(); this.cellComps = /* @__PURE__ */ new Map; this.beans = beans; this.rowCtrl = ctrl; const rowDiv = _createElement({ tag: "div", role: "row", attrs: { "comp-id": `${this.getCompId()}` } }); this.setInitialStyle(rowDiv, containerType); this.setTemplateFromElement(rowDiv); const style = rowDiv.style; this.domOrder = this.rowCtrl.getDomOrder(); const compProxy = { setDomOrder: (domOrder) => this.domOrder = domOrder, setCellCtrls: (cellCtrls) => this.setCellCtrls(cellCtrls), showFullWidth: (compDetails) => this.showFullWidth(compDetails), getFullWidthCellRenderer: () => this.fullWidthCellRenderer, getFullWidthCellRendererParams: () => this.fullWidthCellRendererParams, toggleCss: (name, on) => this.toggleCss(name, on), setUserStyles: (styles) => _addStylesToElement(rowDiv, styles), setTop: (top) => style.top = top, setTransform: (transform) => style.transform = transform, setRowIndex: (rowIndex) => rowDiv.setAttribute("row-index", rowIndex), setRowId: (rowId) => rowDiv.setAttribute("row-id", rowId), setRowBusinessKey: (businessKey) => rowDiv.setAttribute("row-business-key", businessKey), refreshFullWidth: (getUpdatedParams) => { const params = getUpdatedParams(); this.fullWidthCellRendererParams = params; return this.fullWidthCellRenderer?.refresh?.(params) ?? false; } }; ctrl.setComp(compProxy, this.getGui(), containerType, undefined); this.addDestroyFunc(() => { ctrl.unsetComp(containerType); }); } setInitialStyle(container, containerType) { const transform = this.rowCtrl.getInitialTransform(containerType); if (transform) { container.style.setProperty("transform", transform); } else { const top = this.rowCtrl.getInitialRowTop(containerType); if (top) { container.style.setProperty("top", top); } } } showFullWidth(compDetails) { const callback = (cellRenderer) => { if (this.isAlive()) { const eGui = cellRenderer.getGui(); this.getGui().appendChild(eGui); this.rowCtrl.setupDetailRowAutoHeight(eGui); this.setFullWidthRowComp(cellRenderer, compDetails.params); } else { this.beans.context.destroyBean(cellRenderer); } }; const res = compDetails.newAgStackInstance(); res.then(callback); } setCellCtrls(cellCtrls) { const cellsToRemove = new Map(this.cellComps); for (const cellCtrl of cellCtrls) { const key = cellCtrl.instanceId; if (!this.cellComps.has(key)) { this.newCellComp(cellCtrl); } else { cellsToRemove.delete(key); } } this.destroyCells(cellsToRemove); this.ensureDomOrder(cellCtrls); } ensureDomOrder(cellCtrls) { if (!this.domOrder) { return; } const elementsInOrder = []; for (const cellCtrl of cellCtrls) { const cellComp = this.cellComps.get(cellCtrl.instanceId); if (cellComp) { elementsInOrder.push(cellComp.getGui()); } } _setDomChildOrder(this.getGui(), elementsInOrder); } newCellComp(cellCtrl) { const editing = this.beans.editSvc?.isEditing(cellCtrl, { withOpenEditor: true }) ?? false; const cellComp = new CellComp(this.beans, cellCtrl, this.rowCtrl.printLayout, this.getGui(), editing); this.cellComps.set(cellCtrl.instanceId, cellComp); this.getGui().appendChild(cellComp.getGui()); } destroy() { super.destroy(); this.destroyCells(this.cellComps); } setFullWidthRowComp(fullWidthRowComponent, params) { this.fullWidthCellRenderer = fullWidthRowComponent; this.fullWidthCellRendererParams = params; this.addDestroyFunc(() => { this.fullWidthCellRenderer = this.beans.context.destroyBean(this.fullWidthCellRenderer); this.fullWidthCellRendererParams = undefined; }); } destroyCells(cellComps) { for (const cellComp of cellComps.values()) { if (!cellComp) { continue; } const instanceId = cellComp.cellCtrl.instanceId; if (this.cellComps.get(instanceId) !== cellComp) { continue; } cellComp.detach(); cellComp.destroy(); this.cellComps.delete(instanceId); } } }; function getElementParams(name, options, beans) { const isCellSpanning = !!beans.gos.get("enableCellSpan") && !!options.getSpannedRowCtrls; const eContainerElement = { tag: "div", ref: "eContainer", cls: _getRowContainerClass(name), role: "rowgroup" }; if (options.type === "center" || isCellSpanning) { const eSpannedContainerElement = { tag: "div", ref: "eSpannedContainer", cls: `ag-spanning-container ${_getRowSpanContainerClass(name)}`, role: "presentation" }; eContainerElement.role = "presentation"; return { tag: "div", ref: "eViewport", cls: `ag-viewport ${_getRowViewportClass(name)}`, role: "rowgroup", children: [eContainerElement, isCellSpanning ? eSpannedContainerElement : null] }; } return eContainerElement; } var RowContainerComp = class extends Component { constructor(params) { super(); this.eViewport = RefPlaceholder; this.eContainer = RefPlaceholder; this.eSpannedContainer = RefPlaceholder; this.rowCompsNoSpan = {}; this.rowCompsWithSpan = {}; this.name = params?.name; this.options = _getRowContainerOptions(this.name); } postConstruct() { this.setTemplate(getElementParams(this.name, this.options, this.beans)); const compProxy = { setHorizontalScroll: (offset) => this.eViewport.scrollLeft = offset, setViewportHeight: (height) => this.eViewport.style.height = height, setRowCtrls: ({ rowCtrls }) => this.setRowCtrls(rowCtrls), setSpannedRowCtrls: (rowCtrls) => this.setRowCtrls(rowCtrls, true), setDomOrder: (domOrder) => { this.domOrder = domOrder; }, setContainerWidth: (width) => { this.eContainer.style.width = width; if (this.eSpannedContainer) { this.eSpannedContainer.style.width = width; } }, setOffsetTop: (offset) => { const top = `translateY(${offset})`; this.eContainer.style.transform = top; if (this.eSpannedContainer) { this.eSpannedContainer.style.transform = top; } } }; const ctrl = this.createManagedBean(new RowContainerCtrl(this.name)); ctrl.setComp(compProxy, this.eContainer, this.eSpannedContainer, this.eViewport); } destroy() { this.setRowCtrls([]); this.setRowCtrls([], true); super.destroy(); this.lastPlacedElement = null; } setRowCtrls(rowCtrls, spanContainer) { const { beans, options } = this; const container = spanContainer ? this.eSpannedContainer : this.eContainer; const oldRows = spanContainer ? { ...this.rowCompsWithSpan } : { ...this.rowCompsNoSpan }; const newComps = {}; if (spanContainer) { this.rowCompsWithSpan = newComps; } else { this.rowCompsNoSpan = newComps; } this.lastPlacedElement = null; const orderedRows = []; for (const rowCtrl of rowCtrls) { const instanceId = rowCtrl.instanceId; const existingRowComp = oldRows[instanceId]; let rowComp; if (existingRowComp) { rowComp = existingRowComp; delete oldRows[instanceId]; } else { if (!rowCtrl.rowNode.displayed) { continue; } rowComp = new RowComp(rowCtrl, beans, options.type); } newComps[instanceId] = rowComp; orderedRows.push([rowComp, !existingRowComp]); } this.removeOldRows(Object.values(oldRows)); this.addRowNodes(orderedRows, container); } addRowNodes(rows, container) { const { domOrder } = this; for (const [rowComp, isNew] of rows) { const eGui = rowComp.getGui(); if (!domOrder) { if (isNew) { container.appendChild(eGui); } } else { this.ensureDomOrder(eGui, container); } } } removeOldRows(rowComps) { for (const oldRowComp of rowComps) { oldRowComp.getGui().remove(); oldRowComp.destroy(); } } ensureDomOrder(eRow, container) { _ensureDomOrder(container, eRow, this.lastPlacedElement); this.lastPlacedElement = eRow; } }; var RowContainerSelector = { selector: "AG-ROW-CONTAINER", component: RowContainerComp }; function makeRowContainers(paramsMap, names) { return names.map((name) => { const refName = `e${name[0].toUpperCase() + name.substring(1)}RowContainer`; paramsMap[refName] = { name }; return { tag: "ag-row-container", ref: refName, attrs: { name } }; }); } function getGridBodyTemplate(includeOverlay) { const paramsMap = {}; const elementParams = { tag: "div", ref: "eGridRoot", cls: "ag-root ag-unselectable", children: [ { tag: "ag-header-root" }, { tag: "div", ref: "eTop", cls: "ag-floating-top", role: "presentation", children: makeRowContainers(paramsMap, ["topLeft", "topCenter", "topRight", "topFullWidth"]) }, { tag: "div", ref: "eBody", cls: "ag-body", role: "presentation", children: [ { tag: "div", ref: "eBodyViewport", cls: "ag-body-viewport", role: "presentation", children: makeRowContainers(paramsMap, ["left", "center", "right", "fullWidth"]) }, { tag: "ag-fake-vertical-scroll" } ] }, { tag: "div", ref: "eStickyTop", cls: "ag-sticky-top", role: "presentation", children: makeRowContainers(paramsMap, [ "stickyTopLeft", "stickyTopCenter", "stickyTopRight", "stickyTopFullWidth" ]) }, { tag: "div", ref: "eStickyBottom", cls: "ag-sticky-bottom", role: "presentation", children: makeRowContainers(paramsMap, [ "stickyBottomLeft", "stickyBottomCenter", "stickyBottomRight", "stickyBottomFullWidth" ]) }, { tag: "div", ref: "eBottom", cls: "ag-floating-bottom", role: "presentation", children: makeRowContainers(paramsMap, [ "bottomLeft", "bottomCenter", "bottomRight", "bottomFullWidth" ]) }, { tag: "ag-fake-horizontal-scroll" }, includeOverlay ? { tag: "ag-overlay-wrapper" } : null ] }; return { paramsMap, elementParams }; } var GridBodyComp = class extends Component { constructor() { super(...arguments); this.eGridRoot = RefPlaceholder; this.eBodyViewport = RefPlaceholder; this.eStickyTop = RefPlaceholder; this.eStickyBottom = RefPlaceholder; this.eTop = RefPlaceholder; this.eBottom = RefPlaceholder; this.eBody = RefPlaceholder; } postConstruct() { const { overlays, rangeSvc } = this.beans; const overlaySelector = overlays?.getOverlayWrapperSelector(); const { paramsMap, elementParams } = getGridBodyTemplate(!!overlaySelector); this.setTemplate(elementParams, [ ...overlaySelector ? [overlaySelector] : [], FakeHScrollSelector, FakeVScrollSelector, GridHeaderSelector, RowContainerSelector ], paramsMap); const setHeight = (height, element) => { const heightString = `${height}px`; element.style.minHeight = heightString; element.style.height = heightString; }; const compProxy = { setRowAnimationCssOnBodyViewport: (cssClass, animate) => this.setRowAnimationCssOnBodyViewport(cssClass, animate), setColumnCount: (count) => _setAriaColCount(this.getGui(), count), setRowCount: (count) => _setAriaRowCount(this.getGui(), count), setTopHeight: (height) => setHeight(height, this.eTop), setBottomHeight: (height) => setHeight(height, this.eBottom), setTopInvisible: (invisible) => this.eTop.classList.toggle("ag-invisible", invisible), setBottomInvisible: (invisible) => this.eBottom.classList.toggle("ag-invisible", invisible), setStickyTopHeight: (height) => this.eStickyTop.style.height = height, setStickyTopTop: (top) => this.eStickyTop.style.top = top, setStickyTopWidth: (width) => this.eStickyTop.style.width = width, setStickyBottomHeight: (height) => { this.eStickyBottom.style.height = height; this.eStickyBottom.classList.toggle("ag-invisible", height === "0px"); }, setStickyBottomBottom: (bottom) => this.eStickyBottom.style.bottom = bottom, setStickyBottomWidth: (width) => this.eStickyBottom.style.width = width, setColumnMovingCss: (cssClass, flag) => this.toggleCss(cssClass, flag), updateLayoutClasses: (cssClass, params) => { const classLists = [this.eBodyViewport.classList, this.eBody.classList]; for (const classList of classLists) { classList.toggle(LayoutCssClasses.AUTO_HEIGHT, params.autoHeight); classList.toggle(LayoutCssClasses.NORMAL, params.normal); classList.toggle(LayoutCssClasses.PRINT, params.print); } this.toggleCss(LayoutCssClasses.AUTO_HEIGHT, params.autoHeight); this.toggleCss(LayoutCssClasses.NORMAL, params.normal); this.toggleCss(LayoutCssClasses.PRINT, params.print); }, setAlwaysVerticalScrollClass: (cssClass, on) => this.eBodyViewport.classList.toggle(CSS_CLASS_FORCE_VERTICAL_SCROLL, on), registerBodyViewportResizeListener: (listener) => { const unsubscribeFromResize = _observeResize(this.beans, this.eBodyViewport, listener); this.addDestroyFunc(() => unsubscribeFromResize()); }, setPinnedTopBottomOverflowY: (overflow) => this.eTop.style.overflowY = this.eBottom.style.overflowY = overflow, setCellSelectableCss: (cssClass, selectable) => { for (const ct of [this.eTop, this.eBodyViewport, this.eBottom]) { ct.classList.toggle(cssClass, selectable); } }, setBodyViewportWidth: (width) => this.eBodyViewport.style.width = width, setGridRootRole: (role) => _setAriaRole(this.eGridRoot, role) }; this.ctrl = this.createManagedBean(new GridBodyCtrl); this.ctrl.setComp(compProxy, this.getGui(), this.eBodyViewport, this.eTop, this.eBottom, this.eStickyTop, this.eStickyBottom); if (rangeSvc && _isCellSelectionEnabled(this.gos) || _isMultiRowSelection(this.gos)) { _setAriaMultiSelectable(this.getGui(), true); } } setRowAnimationCssOnBodyViewport(cssClass, animateRows) { const bodyViewportClassList = this.eBodyViewport.classList; bodyViewportClassList.toggle("ag-row-animation", animateRows); bodyViewportClassList.toggle("ag-row-no-animation", !animateRows); } getFocusableContainerName() { return "gridBody"; } }; var GridBodySelector = { selector: "AG-GRID-BODY", component: GridBodyComp }; var TabGuardClassNames = { TAB_GUARD: "ag-tab-guard", TAB_GUARD_TOP: "ag-tab-guard-top", TAB_GUARD_BOTTOM: "ag-tab-guard-bottom" }; var AgTabGuardCtrl = class extends AgBeanStub { constructor(params, stopPropagationCallbacks) { super(); this.stopPropagationCallbacks = stopPropagationCallbacks; this.skipTabGuardFocus = false; this.forcingFocusOut = false; this.allowFocus = false; const { comp, eTopGuard, eBottomGuard, focusTrapActive, forceFocusOutWhenTabGuardsAreEmpty, isFocusableContainer, focusInnerElement, onFocusIn, onFocusOut, shouldStopEventPropagation, onTabKeyDown, handleKeyDown, isEmpty, eFocusableElement } = params; this.comp = comp; this.eTopGuard = eTopGuard; this.eBottomGuard = eBottomGuard; this.providedFocusInnerElement = focusInnerElement; this.eFocusableElement = eFocusableElement; this.focusTrapActive = !!focusTrapActive; this.forceFocusOutWhenTabGuardsAreEmpty = !!forceFocusOutWhenTabGuardsAreEmpty; this.isFocusableContainer = !!isFocusableContainer; this.providedFocusIn = onFocusIn; this.providedFocusOut = onFocusOut; this.providedShouldStopEventPropagation = shouldStopEventPropagation; this.providedOnTabKeyDown = onTabKeyDown; this.providedHandleKeyDown = handleKeyDown; this.providedIsEmpty = isEmpty; } postConstruct() { this.createManagedBean(new AgManagedFocusFeature(this.eFocusableElement, this.stopPropagationCallbacks, { shouldStopEventPropagation: () => this.shouldStopEventPropagation(), onTabKeyDown: (e) => this.onTabKeyDown(e), handleKeyDown: (e) => this.handleKeyDown(e), onFocusIn: (e) => this.onFocusIn(e), onFocusOut: (e) => this.onFocusOut(e) })); this.activateTabGuards(); for (const guard of [this.eTopGuard, this.eBottomGuard]) { this.addManagedElementListeners(guard, { focus: this.onFocus.bind(this) }); } } handleKeyDown(e) { if (this.providedHandleKeyDown) { this.providedHandleKeyDown(e); } } tabGuardsAreActive() { return !!this.eTopGuard && this.eTopGuard.hasAttribute("tabIndex"); } shouldStopEventPropagation() { if (this.providedShouldStopEventPropagation) { return this.providedShouldStopEventPropagation(); } return false; } activateTabGuards() { if (this.forcingFocusOut) { return; } const tabIndex = this.gos.get("tabIndex"); this.comp.setTabIndex(tabIndex.toString()); } deactivateTabGuards() { this.comp.setTabIndex(); } onFocus(e) { if (this.isFocusableContainer && !this.eFocusableElement.contains(e.relatedTarget)) { if (!this.allowFocus) { this.findNextElementOutsideAndFocus(e.target === this.eBottomGuard); return; } } if (this.skipTabGuardFocus) { this.skipTabGuardFocus = false; return; } if (this.forceFocusOutWhenTabGuardsAreEmpty) { const isEmpty = this.providedIsEmpty ? this.providedIsEmpty() : _findFocusableElements(this.eFocusableElement, ".ag-tab-guard").length === 0; if (isEmpty) { this.findNextElementOutsideAndFocus(e.target === this.eBottomGuard); return; } } if (this.isFocusableContainer && this.eFocusableElement.contains(e.relatedTarget)) { return; } const fromBottom = e.target === this.eBottomGuard; const hasFocusedInnerElement = this.providedFocusInnerElement ? this.providedFocusInnerElement(fromBottom) : this.focusInnerElement(fromBottom); if (!hasFocusedInnerElement && this.forceFocusOutWhenTabGuardsAreEmpty) { this.findNextElementOutsideAndFocus(e.target === this.eBottomGuard); } } findNextElementOutsideAndFocus(up) { const eDocument = _getDocument(this.beans); const focusableEls = _findFocusableElements(eDocument.body, null, true); const index = focusableEls.indexOf(up ? this.eTopGuard : this.eBottomGuard); if (index === -1) { return; } let start; let end; if (up) { start = 0; end = index; } else { start = index + 1; end = focusableEls.length; } const focusableRange = focusableEls.slice(start, end); const targetTabIndex = this.gos.get("tabIndex"); focusableRange.sort((a, b) => { const indexA = Number.parseInt(a.getAttribute("tabindex") || "0"); const indexB = Number.parseInt(b.getAttribute("tabindex") || "0"); if (indexB === targetTabIndex) { return 1; } if (indexA === targetTabIndex) { return -1; } if (indexA === 0) { return 1; } if (indexB === 0) { return -1; } return indexA - indexB; }); focusableRange[up ? focusableRange.length - 1 : 0]?.focus(); } onFocusIn(e) { if (this.focusTrapActive || this.forcingFocusOut) { return; } if (this.providedFocusIn) { this.providedFocusIn(e); } if (!this.isFocusableContainer) { this.deactivateTabGuards(); } } onFocusOut(e) { if (this.focusTrapActive) { return; } if (this.providedFocusOut) { this.providedFocusOut(e); } if (!this.eFocusableElement.contains(e.relatedTarget)) { this.activateTabGuards(); } } onTabKeyDown(e) { if (this.providedOnTabKeyDown) { this.providedOnTabKeyDown(e); return; } if (this.focusTrapActive) { return; } if (e.defaultPrevented) { return; } const tabGuardsAreActive = this.tabGuardsAreActive(); if (tabGuardsAreActive) { this.deactivateTabGuards(); } const nextRoot = this.getNextFocusableElement(e.shiftKey); if (tabGuardsAreActive) { setTimeout(() => this.activateTabGuards(), 0); } if (!nextRoot) { return; } nextRoot.focus(); e.preventDefault(); } focusInnerElement(fromBottom = false) { const focusable = _findFocusableElements(this.eFocusableElement); if (this.tabGuardsAreActive()) { focusable.splice(0, 1); focusable.splice(-1, 1); } if (!focusable.length) { return false; } focusable[fromBottom ? focusable.length - 1 : 0].focus({ preventScroll: true }); return true; } getNextFocusableElement(backwards) { return _findNextFocusableElement(this.beans, this.eFocusableElement, false, backwards); } forceFocusOutOfContainer(up = false) { if (this.forcingFocusOut) { return; } const tabGuardToFocus = up ? this.eTopGuard : this.eBottomGuard; this.activateTabGuards(); this.skipTabGuardFocus = true; this.forcingFocusOut = true; tabGuardToFocus.focus(); window.setTimeout(() => { this.forcingFocusOut = false; this.activateTabGuards(); }); } isTabGuard(element, bottom) { return element === this.eTopGuard && !bottom || element === this.eBottomGuard && (bottom ?? true); } setAllowFocus(allowFocus) { this.allowFocus = allowFocus; } }; var AgTabGuardFeature = class extends AgBeanStub { constructor(comp, stopPropagationCallbacks) { super(); this.comp = comp; this.stopPropagationCallbacks = stopPropagationCallbacks; } initialiseTabGuard(params) { this.eTopGuard = this.createTabGuard("top"); this.eBottomGuard = this.createTabGuard("bottom"); this.eFocusableElement = this.comp.getFocusableElement(); const { eTopGuard, eBottomGuard, eFocusableElement, stopPropagationCallbacks } = this; const tabGuards = [eTopGuard, eBottomGuard]; const compProxy = { setTabIndex: (tabIndex) => { for (const tabGuard of tabGuards) { if (tabIndex == null) { tabGuard.removeAttribute("tabindex"); } else { tabGuard.setAttribute("tabindex", tabIndex); } } } }; this.addTabGuards(eTopGuard, eBottomGuard); const { focusTrapActive = false, onFocusIn, onFocusOut, focusInnerElement, handleKeyDown, onTabKeyDown, shouldStopEventPropagation, isEmpty, forceFocusOutWhenTabGuardsAreEmpty, isFocusableContainer } = params; this.tabGuardCtrl = this.createManagedBean(new AgTabGuardCtrl({ comp: compProxy, focusTrapActive, eTopGuard, eBottomGuard, eFocusableElement, onFocusIn, onFocusOut, focusInnerElement, handleKeyDown, onTabKeyDown, shouldStopEventPropagation, isEmpty, forceFocusOutWhenTabGuardsAreEmpty, isFocusableContainer }, stopPropagationCallbacks)); } getTabGuardCtrl() { return this.tabGuardCtrl; } createTabGuard(side) { const tabGuard = _getDocument(this.beans).createElement("div"); const cls = side === "top" ? TabGuardClassNames.TAB_GUARD_TOP : TabGuardClassNames.TAB_GUARD_BOTTOM; tabGuard.classList.add(TabGuardClassNames.TAB_GUARD, cls); _setAriaRole(tabGuard, "presentation"); return tabGuard; } addTabGuards(topTabGuard, bottomTabGuard) { const eFocusableElement = this.eFocusableElement; eFocusableElement.prepend(topTabGuard); eFocusableElement.append(bottomTabGuard); } removeAllChildrenExceptTabGuards() { const tabGuards = [this.eTopGuard, this.eBottomGuard]; _clearElement(this.comp.getFocusableElement()); this.addTabGuards(...tabGuards); } forceFocusOutOfContainer(up = false) { this.tabGuardCtrl.forceFocusOutOfContainer(up); } appendChild(appendChild, newChild, container) { if (!_isNodeOrElement(newChild)) { newChild = newChild.getGui(); } const { eBottomGuard: bottomTabGuard } = this; if (bottomTabGuard) { bottomTabGuard.before(newChild); } else { appendChild(newChild, container); } } destroy() { const { eTopGuard, eBottomGuard } = this; _removeFromParent(eTopGuard); _removeFromParent(eBottomGuard); super.destroy(); } }; var AgTabGuardComp = class extends AgComponentStub { initialiseTabGuard(params, stopPropagationCallbacks) { this.tabGuardFeature = this.createManagedBean(new AgTabGuardFeature(this, stopPropagationCallbacks)); this.tabGuardFeature.initialiseTabGuard(params); } forceFocusOutOfContainer(up = false) { this.tabGuardFeature.forceFocusOutOfContainer(up); } appendChild(newChild, container) { this.tabGuardFeature.appendChild(super.appendChild.bind(this), newChild, container); } }; var TabGuardComp = class extends AgTabGuardComp { initialiseTabGuard(params) { super.initialiseTabGuard(params, STOP_PROPAGATION_CALLBACKS); } }; var focusContainer = (comp, up) => { return _runWithContainerFocusAllowed(comp, () => _focusInto(comp.getGui(), up, false, true)); }; var getGridContainerName = (container) => { return container?.getFocusableContainerName() ?? "external"; }; var getDefaultTabToNextGridContainerTargetName = (target) => { if (target == null) { return "external"; } return typeof target === "string" ? target : "gridBody"; }; var GridCtrl = class extends BeanStub { constructor() { super(...arguments); this.additionalFocusableContainers = /* @__PURE__ */ new Set; } setComp(view, eGridDiv, eGui) { this.view = view; this.eGridHostDiv = eGridDiv; this.eGui = eGui; this.eGui.setAttribute("grid-id", this.beans.context.getId()); const { dragAndDrop, ctrlsSvc } = this.beans; dragAndDrop?.registerGridDropTarget(() => this.eGui, this); this.createManagedBean(new LayoutFeature(this.view)); this.view.setRtlClass(this.gos.get("enableRtl") ? "ag-rtl" : "ag-ltr"); const unsubscribeFromResize = _observeResize(this.beans, this.eGridHostDiv, this.onGridSizeChanged.bind(this)); this.addDestroyFunc(() => unsubscribeFromResize()); ctrlsSvc.register("gridCtrl", this); } isDetailGrid() { const el = _findTabbableParent(this.getGui()); return el?.getAttribute("row-id")?.startsWith("detail") || false; } getOptionalSelectors() { const beans = this.beans; return { paginationSelector: beans.pagination?.getPaginationSelector(), gridHeaderDropZonesSelector: beans.registry?.getSelector("AG-GRID-HEADER-DROP-ZONES"), sideBarSelector: beans.sideBar?.getSelector(), statusBarSelector: beans.registry?.getSelector("AG-STATUS-BAR"), watermarkSelector: beans.licenseManager?.getWatermarkSelector() }; } onGridSizeChanged() { this.eventSvc.dispatchEvent({ type: "gridSizeChanged", clientWidth: this.eGridHostDiv.clientWidth, clientHeight: this.eGridHostDiv.clientHeight }); } destroyGridUi() { this.view.destroyGridUi(); } getGui() { return this.eGui; } setResizeCursor(direction) { const { view } = this; if (direction === false) { view.setCursor(null); } else { view.setCursor(direction === 1 ? "ew-resize" : "ns-resize"); } } disableUserSelect(on) { this.view.setUserSelect(on ? "none" : null); } focusNextInnerContainer(backwards) { const focusableContainers = this.getFocusableContainers(); const { indexWithFocus, nextIndex } = this.getNextFocusableIndex(focusableContainers, backwards); const resolvedNextIndex = indexWithFocus === -1 ? backwards ? focusableContainers.length - 1 : 0 : nextIndex; const { gos, beans: { focusSvc, navigation } } = this; const userCallbackFunction = gos.getCallback("tabToNextGridContainer"); if (userCallbackFunction) { const defaultTarget = focusSvc.getDefaultTabToNextGridContainerTarget({ backwards, focusableContainers, nextIndex: resolvedNextIndex }); const nextContainerName = getGridContainerName(focusableContainers[resolvedNextIndex]); const nextContainer = defaultTarget == null && nextContainerName === "gridBody" ? "gridBody" : getDefaultTabToNextGridContainerTargetName(defaultTarget); const userResult = userCallbackFunction({ backwards, previousContainer: getGridContainerName(focusableContainers[indexWithFocus]), nextContainer, defaultTarget }); if (userResult !== undefined) { if (typeof userResult === "boolean") { return userResult; } if (typeof userResult === "string") { if (userResult === "gridBody") { return this.focusGridBodyDefault(backwards) || undefined; } const targetContainer = focusableContainers.find((container) => container.getFocusableContainerName() === userResult); if (!targetContainer) { _consoleWarn(`tabToNextGridContainer - ${userResult} container not found`); return; } return focusContainer(targetContainer, backwards) ? true : undefined; } if (isHeaderPosition(userResult)) { return focusSvc.focusHeaderPosition({ headerPosition: userResult }) || undefined; } navigation?.ensureCellVisible(userResult); focusSvc.setFocusedCell({ ...userResult, forceBrowserFocus: true }); return focusSvc.isCellFocused(userResult) || undefined; } } return this.focusNextInnerContainerDefault({ backwards, focusableContainers, indexWithFocus, nextIndex: resolvedNextIndex }) || undefined; } focusInnerElement(fromBottom) { const { gos, beans, beans: { focusSvc, visibleCols } } = this; const userCallbackFunction = gos.getCallback("focusGridInnerElement"); if (userCallbackFunction?.({ fromBottom: !!fromBottom })) { return true; } const focusableContainers = this.getFocusableContainers(); if (fromBottom) { if (this.focusNextInnerContainerDefault({ backwards: true, focusableContainers, indexWithFocus: focusableContainers.length, nextIndex: focusableContainers.length - 1 })) { return true; } return focusSvc.focusGridView({ column: _last(visibleCols.allCols), backwards: true }); } const allColumns = visibleCols.allCols; if (gos.get("headerHeight") === 0 || _isHeaderFocusSuppressed(beans)) { if (focusSvc.focusGridView({ column: allColumns[0], backwards: fromBottom })) { return true; } for (let i = 1;i < focusableContainers.length; i++) { if (_focusInto(focusableContainers[i].getGui(), fromBottom)) { return true; } } return false; } return focusSvc.focusFirstHeader(); } forceFocusOutOfContainer(up = false) { this.view.forceFocusOutOfContainer(up); } isFocusInsideGridBody() { const focusableContainers = this.getFocusableContainers(); const { indexWithFocus } = this.getNextFocusableIndex(focusableContainers); return focusableContainers[indexWithFocus]?.getFocusableContainerName() === "gridBody"; } addFocusableContainer(container) { this.additionalFocusableContainers.add(container); } removeFocusableContainer(container) { this.additionalFocusableContainers.delete(container); } allowFocusForNextCoreContainer(up) { const coreContainers = this.view.getFocusableContainers(); const { indexWithFocus, nextIndex } = this.getNextFocusableIndex(coreContainers, up); if (!this.focusNextInnerContainerDefault({ backwards: !!up, focusableContainers: coreContainers, indexWithFocus, nextIndex })) { this.forceFocusOutOfContainer(up); } } isFocusable() { const beans = this.beans; return !_isCellFocusSuppressed(beans) || !_isHeaderFocusSuppressed(beans) || !!beans.sideBar?.comp?.isDisplayed(); } getNextFocusableIndex(focusableContainers, backwards) { const activeEl = _getActiveDomElement(this.beans); const indexWithFocus = focusableContainers.findIndex((container) => container.getGui().contains(activeEl)); return { indexWithFocus, nextIndex: indexWithFocus + (backwards ? -1 : 1) }; } focusGridBodyDefault(backwards) { const { gos, beans, beans: { focusSvc, visibleCols: { allCols } } } = this; if (backwards) { return focusSvc.focusGridView({ column: _last(allCols), backwards: true }); } if (gos.get("headerHeight") === 0 || _isHeaderFocusSuppressed(beans)) { return focusSvc.focusGridView({ column: allCols[0] }); } return focusSvc.focusFirstHeader(); } focusNextInnerContainerDefault(params) { const { backwards, focusableContainers, indexWithFocus } = params; const step = backwards ? -1 : 1; for (let index = params.nextIndex;index >= 0 && index < focusableContainers.length; index += step) { const container = focusableContainers[index]; const containerName = container.getFocusableContainerName(); if (containerName === "gridBody") { const enteringGridBody = indexWithFocus === -1 || (backwards ? indexWithFocus > index : indexWithFocus < index); if (enteringGridBody) { if (this.focusGridBodyDefault(backwards)) { return true; } continue; } } if (focusContainer(container, backwards)) { return true; } } return false; } getFocusableContainers() { return [...this.view.getFocusableContainers(), ...this.additionalFocusableContainers]; } destroy() { this.additionalFocusableContainers.clear(); super.destroy(); } }; var GridComp = class extends TabGuardComp { constructor(eGridDiv) { super(); this.gridBody = RefPlaceholder; this.gridHeaderDropZones = RefPlaceholder; this.sideBar = RefPlaceholder; this.statusBar = RefPlaceholder; this.pagination = RefPlaceholder; this.rootWrapperBody = RefPlaceholder; this.eGridDiv = eGridDiv; } postConstruct() { const compProxy = { destroyGridUi: () => this.destroyBean(this), setRtlClass: (cssClass) => this.addCss(cssClass), forceFocusOutOfContainer: this.forceFocusOutOfContainer.bind(this), updateLayoutClasses: this.updateLayoutClasses.bind(this), getFocusableContainers: this.getFocusableContainers.bind(this), setUserSelect: (value) => { this.getGui().style.userSelect = value != null ? value : ""; this.getGui().style.webkitUserSelect = value != null ? value : ""; }, setCursor: (value) => { this.getGui().style.cursor = value != null ? value : ""; } }; const ctrl = this.createManagedBean(new GridCtrl); const comps = ctrl.getOptionalSelectors(); const template = this.createTemplate(comps); const requiredComps = [GridBodySelector, ...Object.values(comps).filter((c) => !!c)]; this.setTemplate(template, requiredComps); ctrl.setComp(compProxy, this.eGridDiv, this.getGui()); this.insertGridIntoDom(); this.initialiseTabGuard({ onTabKeyDown: () => { return; }, focusInnerElement: (fromBottom) => ctrl.focusInnerElement(fromBottom), forceFocusOutWhenTabGuardsAreEmpty: true, isEmpty: () => !ctrl.isFocusable() }); } insertGridIntoDom() { const eGui = this.getGui(); this.eGridDiv.appendChild(eGui); this.addDestroyFunc(() => { eGui.remove(); _logIfDebug(this.gos, "Grid removed from DOM"); }); } updateLayoutClasses(cssClass, params) { const eRootWrapperBodyClassList = this.rootWrapperBody.classList; const { AUTO_HEIGHT, NORMAL, PRINT } = LayoutCssClasses; const { autoHeight, normal, print } = params; eRootWrapperBodyClassList.toggle(AUTO_HEIGHT, autoHeight); eRootWrapperBodyClassList.toggle(NORMAL, normal); eRootWrapperBodyClassList.toggle(PRINT, print); this.toggleCss(AUTO_HEIGHT, autoHeight); this.toggleCss(NORMAL, normal); this.toggleCss(PRINT, print); } createTemplate(params) { const dropZones = params.gridHeaderDropZonesSelector ? { tag: "ag-grid-header-drop-zones", ref: "gridHeaderDropZones" } : null; const sideBar = params.sideBarSelector ? { tag: "ag-side-bar", ref: "sideBar" } : null; const statusBar = params.statusBarSelector ? { tag: "ag-status-bar", ref: "statusBar" } : null; const watermark = params.watermarkSelector ? { tag: "ag-watermark" } : null; const pagination = params.paginationSelector ? { tag: "ag-pagination", ref: "pagination" } : null; return { tag: "div", cls: "ag-root-wrapper", role: "presentation", children: [ dropZones, { tag: "div", ref: "rootWrapperBody", cls: "ag-root-wrapper-body", role: "presentation", children: [{ tag: "ag-grid-body", ref: "gridBody" }, sideBar] }, statusBar, pagination, watermark ] }; } getFocusableElement() { return this.rootWrapperBody; } forceFocusOutOfContainer(up = false) { if (!up && this.pagination?.isDisplayed()) { this.pagination.forceFocusOutOfContainer(up); return; } super.forceFocusOutOfContainer(up); } getFocusableContainers() { const focusableContainers = [ ...this.gridHeaderDropZones?.getFocusableContainers?.() ?? [], this.gridBody ]; for (const comp of [this.sideBar, this.statusBar, this.pagination]) { if (comp) { focusableContainers.push(comp); } } return focusableContainers.filter((el) => _isVisible(el.getGui())); } }; var mod = (moduleName, input) => { for (const key of Object.keys(input)) { input[key] = moduleName; } return input; }; var gridApiFunctionsMap = { dispatchEvent: "CommunityCore", ...mod("CommunityCore", { destroy: 0, getGridId: 0, getGridOption: 0, isDestroyed: 0, setGridOption: 0, updateGridOptions: 0, isModuleRegistered: 0 }), ...mod("GridState", { getState: 0, setState: 0 }), ...mod("SharedRowSelection", { setNodesSelected: 0, selectAll: 0, deselectAll: 0, selectAllFiltered: 0, deselectAllFiltered: 0, selectAllOnCurrentPage: 0, deselectAllOnCurrentPage: 0, getSelectedNodes: 0, getSelectedRows: 0 }), ...mod("RowApi", { redrawRows: 0, setRowNodeExpanded: 0, getRowNode: 0, addRenderedRowListener: 0, getRenderedNodes: 0, forEachNode: 0, getFirstDisplayedRowIndex: 0, getLastDisplayedRowIndex: 0, getDisplayedRowAtIndex: 0, getDisplayedRowCount: 0 }), ...mod("ScrollApi", { getVerticalPixelRange: 0, getHorizontalPixelRange: 0, ensureColumnVisible: 0, ensureIndexVisible: 0, ensureNodeVisible: 0 }), ...mod("KeyboardNavigation", { getFocusedCell: 0, clearFocusedCell: 0, setFocusedCell: 0, tabToNextCell: 0, tabToPreviousCell: 0, setFocusedHeader: 0 }), ...mod("EventApi", { addEventListener: 0, addGlobalListener: 0, removeEventListener: 0, removeGlobalListener: 0 }), ...mod("ValueCache", { expireValueCache: 0 }), ...mod("CellApi", { getCellValue: 0 }), ...mod("SharedMenu", { showColumnMenu: 0, hidePopupMenu: 0 }), ...mod("Sort", { onSortChanged: 0 }), ...mod("PinnedRow", { getPinnedTopRowCount: 0, getPinnedBottomRowCount: 0, getPinnedTopRow: 0, getPinnedBottomRow: 0, forEachPinnedRow: 0 }), ...mod("Overlay", { showLoadingOverlay: 0, showNoRowsOverlay: 0, hideOverlay: 0 }), ...mod("RenderApi", { setGridAriaProperty: 0, refreshCells: 0, refreshHeader: 0, isAnimationFrameQueueEmpty: 0, flushAllAnimationFrames: 0, getSizesForCurrentTheme: 0, getCellRendererInstances: 0 }), ...mod("HighlightChanges", { flashCells: 0 }), ...mod("RowDrag", { addRowDropZone: 0, removeRowDropZone: 0, getRowDropZoneParams: 0, getRowDropPositionIndicator: 0, setRowDropPositionIndicator: 0 }), ...mod("ColumnApi", { getColumnDefs: 0, getColumnDef: 0, getDisplayNameForColumn: 0, getColumn: 0, getColumns: 0, applyColumnState: 0, getColumnState: 0, resetColumnState: 0, isPinning: 0, isPinningLeft: 0, isPinningRight: 0, getDisplayedColAfter: 0, getDisplayedColBefore: 0, setColumnsVisible: 0, setColumnsPinned: 0, getAllGridColumns: 0, getDisplayedLeftColumns: 0, getDisplayedCenterColumns: 0, getDisplayedRightColumns: 0, getAllDisplayedColumns: 0, getAllDisplayedVirtualColumns: 0 }), ...mod("ColumnAutoSize", { sizeColumnsToFit: 0, autoSizeColumns: 0, autoSizeAllColumns: 0 }), ...mod("ColumnGroup", { setColumnGroupOpened: 0, getColumnGroup: 0, getProvidedColumnGroup: 0, getDisplayNameForColumnGroup: 0, getColumnGroupState: 0, setColumnGroupState: 0, resetColumnGroupState: 0, getLeftDisplayedColumnGroups: 0, getCenterDisplayedColumnGroups: 0, getRightDisplayedColumnGroups: 0, getAllDisplayedColumnGroups: 0 }), ...mod("ColumnMove", { moveColumnByIndex: 0, moveColumns: 0 }), ...mod("ColumnResize", { setColumnWidths: 0 }), ...mod("ColumnHover", { isColumnHovered: 0 }), ...mod("EditCore", { getCellEditorInstances: 0, getEditingCells: 0, getEditRowValues: 0, stopEditing: 0, startEditingCell: 0, isEditing: 0, validateEdit: 0 }), ...mod("BatchEdit", { startBatchEdit: 0, cancelBatchEdit: 0, commitBatchEdit: 0, isBatchEditing: 0 }), ...mod("UndoRedoEdit", { undoCellEditing: 0, redoCellEditing: 0, getCurrentUndoSize: 0, getCurrentRedoSize: 0 }), ...mod("FilterCore", { isAnyFilterPresent: 0, onFilterChanged: 0 }), ...mod("ColumnFilter", { isColumnFilterPresent: 0, getColumnFilterInstance: 0, destroyFilter: 0, setFilterModel: 0, getFilterModel: 0, getColumnFilterModel: 0, setColumnFilterModel: 0, showColumnFilter: 0, hideColumnFilter: 0, getColumnFilterHandler: 0, doFilterAction: 0 }), ...mod("QuickFilter", { isQuickFilterPresent: 0, getQuickFilter: 0, resetQuickFilter: 0 }), ...mod("Find", { findGetActiveMatch: 0, findGetTotalMatches: 0, findGoTo: 0, findNext: 0, findPrevious: 0, findGetNumMatches: 0, findGetParts: 0, findClearActive: 0, findRefresh: 0 }), ...mod("Pagination", { paginationIsLastPageFound: 0, paginationGetPageSize: 0, paginationGetCurrentPage: 0, paginationGetTotalPages: 0, paginationGetRowCount: 0, paginationGoToNextPage: 0, paginationGoToPreviousPage: 0, paginationGoToFirstPage: 0, paginationGoToLastPage: 0, paginationGoToPage: 0 }), ...mod("CsrmSsrmSharedApi", { expandAll: 0, collapseAll: 0, resetRowGroupExpansion: 0 }), ...mod("SsrmInfiniteSharedApi", { setRowCount: 0, getCacheBlockState: 0, isLastRowIndexKnown: 0 }), ...mod("ClientSideRowModelApi", { onGroupExpandedOrCollapsed: 0, refreshClientSideRowModel: 0, isRowDataEmpty: 0, forEachLeafNode: 0, forEachNodeAfterFilter: 0, forEachNodeAfterFilterAndSort: 0, applyTransaction: 0, applyTransactionAsync: 0, flushAsyncTransactions: 0, getBestCostNodeSelection: 0, onRowHeightChanged: 0, resetRowHeights: 0 }), ...mod("CsvExport", { getDataAsCsv: 0, exportDataAsCsv: 0 }), ...mod("InfiniteRowModel", { refreshInfiniteCache: 0, purgeInfiniteCache: 0, getInfiniteRowCount: 0 }), ...mod("AdvancedFilter", { getAdvancedFilterModel: 0, setAdvancedFilterModel: 0, showAdvancedFilterBuilder: 0, hideAdvancedFilterBuilder: 0 }), ...mod("IntegratedCharts", { getChartModels: 0, getChartRef: 0, getChartImageDataURL: 0, downloadChart: 0, openChartToolPanel: 0, closeChartToolPanel: 0, createRangeChart: 0, createPivotChart: 0, createCrossFilterChart: 0, updateChart: 0, restoreChart: 0 }), ...mod("Clipboard", { copyToClipboard: 0, cutToClipboard: 0, copySelectedRowsToClipboard: 0, copySelectedRangeToClipboard: 0, copySelectedRangeDown: 0, pasteFromClipboard: 0 }), ...mod("ExcelExport", { getDataAsExcel: 0, exportDataAsExcel: 0, getSheetDataForExcel: 0, getMultipleSheetsAsExcel: 0, exportMultipleSheetsAsExcel: 0 }), ...mod("SharedMasterDetail", { addDetailGridInfo: 0, removeDetailGridInfo: 0, getDetailGridInfo: 0, forEachDetailGridInfo: 0 }), ...mod("ContextMenu", { showContextMenu: 0 }), ...mod("ColumnMenu", { showColumnChooser: 0, hideColumnChooser: 0 }), ...mod("CellSelection", { getCellRanges: 0, addCellRange: 0, clearRangeSelection: 0, clearCellSelection: 0 }), ...mod("SharedRowGrouping", { setRowGroupColumns: 0, removeRowGroupColumns: 0, addRowGroupColumns: 0, getRowGroupColumns: 0, moveRowGroupColumn: 0 }), ...mod("SharedAggregation", { addAggFuncs: 0, clearAggFuncs: 0, setColumnAggFunc: 0 }), ...mod("SharedPivot", { isPivotMode: 0, getPivotResultColumn: 0, setValueColumns: 0, getValueColumns: 0, removeValueColumns: 0, addValueColumns: 0, setPivotColumns: 0, removePivotColumns: 0, addPivotColumns: 0, getPivotColumns: 0, setPivotResultColumns: 0, getPivotResultColumns: 0 }), ...mod("ServerSideRowModelApi", { getServerSideSelectionState: 0, setServerSideSelectionState: 0, applyServerSideTransaction: 0, applyServerSideTransactionAsync: 0, applyServerSideRowData: 0, retryServerSideLoads: 0, flushServerSideAsyncTransactions: 0, refreshServerSide: 0, getServerSideGroupLevelState: 0, onRowHeightChanged: 0, resetRowHeights: 0 }), ...mod("SideBar", { isSideBarVisible: 0, setSideBarVisible: 0, setSideBarPosition: 0, openToolPanel: 0, closeToolPanel: 0, getOpenedToolPanel: 0, refreshToolPanel: 0, isToolPanelShowing: 0, getToolPanelInstance: 0, getSideBar: 0 }), ...mod("StatusBar", { getStatusPanel: 0 }), ...mod("AiToolkit", { getStructuredSchema: 0 }) }; var defaultFns = { isDestroyed: () => true, destroy() {}, preConstruct() {}, postConstruct() {}, preWireBeans() {}, wireBeans() {} }; var dispatchEvent = (beans, event) => beans.eventSvc.dispatchEvent(event); var GridApiClass = class { }; Reflect.defineProperty(GridApiClass, "name", { value: "GridApi" }); var ApiFunctionService = class extends BeanStub { constructor() { super(); this.beanName = "apiFunctionSvc"; this.api = new GridApiClass; this.fns = { ...defaultFns, dispatchEvent }; this.preDestroyLink = ""; const { api } = this; for (const key of Object.keys(gridApiFunctionsMap)) { api[key] = this.makeApi(key)[key]; } } postConstruct() { this.preDestroyLink = this.beans.frameworkOverrides.getDocLink("grid-lifecycle/#grid-pre-destroyed"); } addFunction(functionName, func) { const { fns, beans } = this; if (fns !== defaultFns) { fns[functionName] = beans?.validation?.validateApiFunction(functionName, func) ?? func; } } makeApi(apiName) { return { [apiName]: (...args) => { const { beans, fns: { [apiName]: fn } } = this; return fn ? fn(beans, ...args) : this.apiNotFound(apiName); } }; } apiNotFound(fnName) { const { beans, gos, preDestroyLink } = this; if (!beans) { _warn(26, { fnName, preDestroyLink }); } else { const module = gridApiFunctionsMap[fnName]; if (gos.assertModuleRegistered(module, `api.${fnName}`)) { _warn(27, { fnName, module }); } } } destroy() { super.destroy(); this.fns = defaultFns; this.beans = null; } }; function getGridId(beans) { return beans.context.getId(); } function destroy(beans) { beans.gridDestroySvc.destroy(); } function isDestroyed(beans) { return beans.gridDestroySvc.destroyCalled; } function getGridOption(beans, key) { return beans.gos.get(key); } function setGridOption(beans, key, value) { updateGridOptions(beans, { [key]: value }); } function updateGridOptions(beans, options) { beans.gos.updateGridOptions({ options }); } function isModuleRegistered(beans, moduleName) { const withoutSuffix = moduleName.replace(/Module$/, ""); return beans.gos.isModuleRegistered(withoutSuffix); } function _createIcon(iconName, beans, column) { const iconContents = _createIconNoSpan(iconName, beans, column); if (iconContents) { const { className } = iconContents; if (typeof className === "string" && className.includes("ag-icon") || typeof className === "object" && className["ag-icon"]) { return iconContents; } } const eResult = _createElement({ tag: "span" }); eResult.appendChild(iconContents); return eResult; } function _createIconNoSpan(iconName, beans, column) { let userProvidedIcon = null; if (iconName === "smallDown") { _warn(262); } else if (iconName === "smallLeft") { _warn(263); } else if (iconName === "smallRight") { _warn(264); } const icons = column?.getColDef().icons; if (icons) { userProvidedIcon = icons[iconName]; } if (beans.gos && !userProvidedIcon) { const optionsIcons = beans.gos.get("icons"); if (optionsIcons) { userProvidedIcon = optionsIcons[iconName]; } } if (userProvidedIcon) { let rendererResult; if (typeof userProvidedIcon === "function") { rendererResult = userProvidedIcon(); } else if (typeof userProvidedIcon === "string") { rendererResult = userProvidedIcon; } else { _warn(38, { iconName }); return; } if (typeof rendererResult === "string") { return _loadTemplate(rendererResult); } if (_isNodeOrElement(rendererResult)) { return rendererResult; } _warn(133, { iconName }); return; } else { const iconValue = beans.registry.getIcon(iconName); if (!iconValue) { beans.validation?.validateIcon(iconName); } return _createElement({ tag: "span", cls: `ag-icon ag-icon-${iconValue ?? iconName}`, role: "presentation", attrs: { unselectable: "on" } }); } } var dragAndDropImageComponent_default = ".ag-dnd-ghost{align-items:center;background-color:var(--ag-drag-and-drop-image-background-color);border:var(--ag-drag-and-drop-image-border);border-radius:var(--ag-border-radius);box-shadow:var(--ag-drag-and-drop-image-shadow);color:var(--ag-text-color);cursor:move;display:flex;font-weight:500;gap:var(--ag-cell-widget-spacing);height:var(--ag-header-height);overflow:hidden;padding-left:var(--ag-cell-horizontal-padding);padding-right:var(--ag-cell-horizontal-padding);text-overflow:ellipsis;transform:translateY(calc(var(--ag-spacing)*2));white-space:nowrap}.ag-dnd-ghost-not-allowed{border:var(--ag-drag-and-drop-image-not-allowed-border)}"; var DragAndDropElement = { tag: "div", children: [ { tag: "div", ref: "eGhost", cls: "ag-dnd-ghost ag-unselectable", children: [ { tag: "span", ref: "eIcon", cls: "ag-dnd-ghost-icon ag-shake-left-to-right" }, { tag: "div", ref: "eLabel", cls: "ag-dnd-ghost-label" } ] } ] }; var DragAndDropImageComponent2 = class extends Component { constructor() { super(); this.dragSource = null; this.eIcon = RefPlaceholder; this.eLabel = RefPlaceholder; this.eGhost = RefPlaceholder; this.registerCSS(dragAndDropImageComponent_default); } postConstruct() { const create = (iconName) => _createIcon(iconName, this.beans, null); this.dropIconMap = { pinned: create("columnMovePin"), hide: create("columnMoveHide"), move: create("columnMoveMove"), left: create("columnMoveLeft"), right: create("columnMoveRight"), group: create("columnMoveGroup"), aggregate: create("columnMoveValue"), pivot: create("columnMovePivot"), notAllowed: create("dropNotAllowed") }; } init(params) { this.dragSource = params.dragSource; this.setTemplate(DragAndDropElement); this.beans.environment.applyThemeClasses(this.eGhost); } destroy() { this.dragSource = null; super.destroy(); } setIcon(iconName, shake) { const { eGhost, eIcon, dragSource, dropIconMap, gos } = this; _clearElement(eIcon); let eIconChild = null; if (!iconName) { iconName = dragSource?.getDefaultIconName ? dragSource.getDefaultIconName() : "notAllowed"; } eIconChild = dropIconMap[iconName]; eGhost.classList.toggle("ag-dnd-ghost-not-allowed", iconName === "notAllowed"); eIcon.classList.toggle("ag-shake-left-to-right", shake); if (eIconChild === dropIconMap["hide"] && gos.get("suppressDragLeaveHidesColumns")) { return; } if (eIconChild) { eIcon.appendChild(eIconChild); } } setLabel(label) { this.eLabel.textContent = label; } }; var tryPointerCapture = (eElement, pointerId) => { if (pointerId != null && eElement?.setPointerCapture) { try { eElement.setPointerCapture(pointerId); return eElement.hasPointerCapture(pointerId); } catch {} } return false; }; var capturePointer = (eElement, mouseEvent) => { if (typeof PointerEvent === "undefined" || !(mouseEvent instanceof PointerEvent)) { return null; } const pointerId = mouseEvent.pointerId; if (!tryPointerCapture(eElement, pointerId)) { return null; } const capture = { eElement, pointerId, onLost(pointerEvent) { pointerLostHandler(capture, pointerEvent); } }; eElement.addEventListener("lostpointercapture", capture.onLost); return capture; }; var releasePointerCapture = (capture) => { if (!capture) { return; } removeLostHandler(capture); const { eElement, pointerId } = capture; if (!eElement) { return; } try { eElement.releasePointerCapture(pointerId); } catch {} capture.eElement = null; }; var removeLostHandler = (capture) => { const { eElement, onLost } = capture; if (eElement && onLost) { eElement.removeEventListener("lostpointercapture", onLost); capture.onLost = null; } }; var pointerLostHandler = (capture, pointerEvent) => { removeLostHandler(capture); const { eElement, pointerId } = capture; if (eElement && pointerEvent.pointerId === pointerId) { tryPointerCapture(eElement, pointerId); } }; var activePointerDrags; var handledDragEvents; var PASSIVE_TRUE = { passive: true }; var PASSIVE_FALSE = { passive: false }; var addHandledDragEvent = (event) => { if (!handledDragEvents) { handledDragEvents = /* @__PURE__ */ new WeakSet; } else if (handledDragEvents.has(event)) { return false; } handledDragEvents.add(event); return true; }; var BaseDragService = class extends AgBeanStub { constructor() { super(...arguments); this.beanName = "dragSvc"; this.dragging = false; this.drag = null; this.dragSources = []; } get startTarget() { return this.drag?.start.target ?? null; } isPointer() { return !!activePointerDrags?.has(_getRootNode(this.beans)); } hasPointerCapture() { const capture = this.drag?.pointerCapture; return !!(capture && this.beans.eRootDiv.hasPointerCapture?.(capture.pointerId)); } destroy() { if (this.drag) { this.cancelDrag(); } const dragSources = this.dragSources; for (const entry of dragSources) { destroyDragSourceEntry(entry); } dragSources.length = 0; super.destroy(); } removeDragSource(params) { const dragSources = this.dragSources; for (let i = 0, len = dragSources.length;i < len; ++i) { const entry = dragSources[i]; if (entry.params === params) { dragSources.splice(i, 1); destroyDragSourceEntry(entry); break; } } } addDragSource(params) { if (!this.isAlive()) { return; } const { eElement, includeTouch } = params; const handlers = []; let oldTouchAction; if (includeTouch) { const style = eElement.style; if (style) { oldTouchAction = style.touchAction; style.touchAction = "none"; } } const dragSource = { handlers, params, oldTouchAction }; this.dragSources.push(dragSource); const pointerDownListener = (event) => this.onPointerDown(params, event); const mouseListener = (event) => this.onMouseDown(params, event); addTempEventHandlers(handlers, [eElement, "pointerdown", pointerDownListener, PASSIVE_FALSE], [eElement, "mousedown", mouseListener]); const suppressTouch = this.gos.get("suppressTouch"); if (includeTouch && !suppressTouch) { const touchListener = (touchEvent) => this.onTouchStart(params, touchEvent); addTempEventHandlers(handlers, [eElement, "touchstart", touchListener, PASSIVE_FALSE]); } } cancelDrag(eElement) { const drag = this.drag; eElement ?? (eElement = drag?.eElement); if (eElement) { this.eventSvc.dispatchEvent({ type: "dragCancelled", target: eElement }); } drag?.params.onDragCancel?.(); this.destroyDrag(); } shouldPreventMouseEvent(mouseEvent) { const type = mouseEvent.type; const isMouseMove = type === "mousemove" || type === "pointermove"; return isMouseMove && mouseEvent.cancelable && _isEventFromThisInstance(this.beans, mouseEvent) && !_isFocusableFormField(getEventTargetElement(mouseEvent)); } initDrag(drag, ...handlers) { this.drag = drag; const beans = this.beans; const onScroll = (event) => this.onScroll(event); const keydownEvent = (ev) => this.onKeyDown(ev); const rootEl = _getRootNode(beans); const eDocument = _getDocument(beans); addTempEventHandlers(drag.handlers, [rootEl, "contextmenu", preventEventDefault], [rootEl, "keydown", keydownEvent], [eDocument, "scroll", onScroll, { capture: true }], [eDocument.defaultView || window, "scroll", onScroll], ...handlers); } destroyDrag() { this.dragging = false; const drag = this.drag; if (drag) { const rootEl = drag.rootEl; if (activePointerDrags?.get(rootEl) === drag) { activePointerDrags.delete(rootEl); } this.drag = null; releasePointerCapture(drag.pointerCapture); clearTempEventHandlers(drag.handlers); } } onPointerDown(params, pointerEvent) { if (this.isPointer()) { return; } const beans = this.beans; if (handledDragEvents?.has(pointerEvent)) { return; } const pointerType = pointerEvent.pointerType; if (pointerType === "touch") { if (beans.gos.get("suppressTouch") || !params.includeTouch) { return; } if (params.stopPropagationForTouch) { pointerEvent.stopPropagation(); } if (_isFocusableFormField(getEventTargetElement(pointerEvent))) { return; } } if (!pointerEvent.isPrimary) { return; } if (pointerType === "mouse" && pointerEvent.button !== 0) { return; } this.destroyDrag(); const rootEl = _getRootNode(beans); const eElement = params.eElement; const pointerId = pointerEvent.pointerId; const pointerDrag = new Dragging(rootEl, params, pointerEvent, pointerId); activePointerDrags ?? (activePointerDrags = /* @__PURE__ */ new WeakMap); activePointerDrags.set(rootEl, pointerDrag); const onPointerMove = (ev) => { if (ev.pointerId === pointerId) { this.onMouseOrPointerMove(ev); } }; const onUp = (ev) => { if (ev.pointerId === pointerId) { this.onMouseOrPointerUp(ev); } }; const onCancel = (ev) => { if (ev.pointerId === pointerId && addHandledDragEvent(ev)) { this.cancelDrag(); } }; const dragPreventEventDefault = (e) => this.draggingPreventDefault(e); this.initDrag(pointerDrag, [rootEl, "pointerup", onUp], [rootEl, "pointercancel", onCancel], [rootEl, "pointermove", onPointerMove, PASSIVE_FALSE], [rootEl, "touchmove", dragPreventEventDefault, PASSIVE_FALSE], [eElement, "mousemove", dragPreventEventDefault, PASSIVE_FALSE]); if (params.dragStartPixels === 0) { this.onMouseOrPointerMove(pointerEvent); } else { addHandledDragEvent(pointerEvent); } } onTouchStart(params, touchEvent) { const suppressTouch = this.gos.get("suppressTouch"); if (suppressTouch || !params.includeTouch) { return; } if (!addHandledDragEvent(touchEvent)) { return; } if (_isFocusableFormField(getEventTargetElement(touchEvent))) { return; } if (params.stopPropagationForTouch) { touchEvent.stopPropagation(); } if (this.isPointer()) { if (this.dragging) { preventEventDefault(touchEvent); } return; } this.destroyDrag(); const beans = this.beans; const rootEl = _getRootNode(beans); const touchDrag = new Dragging(rootEl, params, touchEvent.touches[0]); const touchMoveEvent = (e) => this.onTouchMove(e); const touchEndEvent = (e) => this.onTouchUp(e); const touchCancelEvent = (e) => this.onTouchCancel(e); const dragPreventEventDefault = (e) => this.draggingPreventDefault(e); const rootNode = _getRootNode(beans); const target = touchEvent.target ?? params.eElement; this.initDrag(touchDrag, [target, "touchmove", touchMoveEvent, PASSIVE_TRUE], [target, "touchend", touchEndEvent, PASSIVE_TRUE], [target, "touchcancel", touchCancelEvent, PASSIVE_TRUE], [rootNode, "touchmove", dragPreventEventDefault, PASSIVE_FALSE], [rootNode, "touchend", touchEndEvent, PASSIVE_FALSE], [rootNode, "touchcancel", touchCancelEvent, PASSIVE_FALSE]); if (params.dragStartPixels === 0) { this.onMove(touchDrag.start); } } draggingPreventDefault(e) { if (this.dragging) { preventEventDefault(e); } } onMouseDown(params, mouseEvent) { if (mouseEvent.button !== 0) { return; } if (handledDragEvents?.has(mouseEvent)) { return; } if (this.isPointer()) { return; } const beans = this.beans; this.destroyDrag(); const mouseDrag = new Dragging(_getRootNode(beans), params, mouseEvent); const mouseMoveEvent = (event) => this.onMouseOrPointerMove(event); const mouseUpEvent = (event) => this.onMouseOrPointerUp(event); const target = _getRootNode(beans); this.initDrag(mouseDrag, [target, "mousemove", mouseMoveEvent], [target, "mouseup", mouseUpEvent]); if (params.dragStartPixels === 0) { this.onMouseOrPointerMove(mouseEvent); } else { addHandledDragEvent(mouseEvent); } } onScroll(event) { if (!addHandledDragEvent(event)) { return; } const drag = this.drag; const lastDrag = drag?.lastDrag; if (lastDrag && this.dragging) { drag.params?.onDragging?.(lastDrag); } } onMouseOrPointerMove(mouseEvent) { if (!addHandledDragEvent(mouseEvent)) { return; } if (_isBrowserSafari()) { _getDocument(this.beans).getSelection()?.removeAllRanges(); } if (this.shouldPreventMouseEvent(mouseEvent)) { preventEventDefault(mouseEvent); } this.onMove(mouseEvent); } onTouchCancel(touchEvent) { const drag = this.drag; if (!drag || !addHandledDragEvent(touchEvent)) { return; } if (!_getFirstActiveTouch(drag.start, touchEvent.changedTouches)) { return; } this.cancelDrag(); } onTouchMove(touchEvent) { const drag = this.drag; if (!drag || !addHandledDragEvent(touchEvent)) { return; } const touch = _getFirstActiveTouch(drag.start, touchEvent.touches); if (touch) { this.onMove(touch); this.draggingPreventDefault(touchEvent); } } onMove(currentEvent) { const drag = this.drag; if (!drag) { return; } drag.lastDrag = currentEvent; const dragSource = drag.params; if (!this.dragging) { const start = drag.start; const dragStartPixels = dragSource.dragStartPixels; const requiredPixelDiff = dragStartPixels ?? 4; if (_areEventsNear(currentEvent, start, requiredPixelDiff)) { return; } this.dragging = true; if (dragSource.capturePointer) { drag.pointerCapture = capturePointer(this.beans.eRootDiv, currentEvent); } this.eventSvc.dispatchEvent({ type: "dragStarted", target: dragSource.eElement }); dragSource.onDragStart?.(start); if (this.drag !== drag) { return; } dragSource.onDragging?.(start); if (this.drag !== drag) { return; } } dragSource.onDragging?.(currentEvent); } onTouchUp(touchEvent) { const drag = this.drag; if (drag && addHandledDragEvent(touchEvent)) { this.onUp(_getFirstActiveTouch(drag.start, touchEvent.changedTouches)); } } onMouseOrPointerUp(mouseEvent) { if (addHandledDragEvent(mouseEvent)) { this.onUp(mouseEvent); } } onUp(eventOrTouch) { const drag = this.drag; if (!drag) { return; } if (!eventOrTouch) { eventOrTouch = drag.lastDrag; } if (eventOrTouch && this.dragging) { this.dragging = false; drag.params.onDragStop?.(eventOrTouch); this.eventSvc.dispatchEvent({ type: "dragStopped", target: drag.params.eElement }); } this.destroyDrag(); } onKeyDown(event) { if (event.key === KeyCode.ESCAPE) { this.cancelDrag(); } } }; var destroyDragSourceEntry = (dragSource) => { clearTempEventHandlers(dragSource.handlers); const oldTouchAction = dragSource.oldTouchAction; if (oldTouchAction != null) { const style = dragSource.params.eElement.style; if (style) { style.touchAction = oldTouchAction; } } }; var Dragging = class { constructor(rootEl, params, start, pointerId = null) { this.rootEl = rootEl; this.params = params; this.start = start; this.pointerId = pointerId; this.handlers = []; this.lastDrag = null; this.pointerCapture = null; this.eElement = params.eElement; } }; var getEventTargetElement = (event) => { const target = event.target; return target instanceof Element ? target : null; }; var DragService = class extends BaseDragService { shouldPreventMouseEvent(mouseEvent) { const isEnableCellTextSelect = this.gos.get("enableCellTextSelection"); return isEnableCellTextSelect && super.shouldPreventMouseEvent(mouseEvent); } }; var HorizontalResizeService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "horizontalResizeSvc"; } addResizeBar(params) { const dragSource = { dragStartPixels: params.dragStartPixels || 0, eElement: params.eResizeBar, onDragStart: this.onDragStart.bind(this, params), onDragStop: this.onDragStop.bind(this, params), onDragging: this.onDragging.bind(this, params), onDragCancel: this.onDragStop.bind(this, params), includeTouch: true, stopPropagationForTouch: true }; const { dragSvc } = this.beans; dragSvc.addDragSource(dragSource); const finishedWithResizeFunc = () => dragSvc.removeDragSource(dragSource); return finishedWithResizeFunc; } onDragStart(params, mouseEvent) { this.dragStartX = mouseEvent.clientX; this.setResizeIcons(); const shiftKey = mouseEvent instanceof MouseEvent && mouseEvent.shiftKey === true; params.onResizeStart(shiftKey); } setResizeIcons() { const ctrl = this.beans.ctrlsSvc.get("gridCtrl"); ctrl.setResizeCursor(1); ctrl.disableUserSelect(true); } onDragStop(params) { params.onResizeEnd(this.resizeAmount); this.resetIcons(); } resetIcons() { const ctrl = this.beans.ctrlsSvc.get("gridCtrl"); ctrl.setResizeCursor(false); ctrl.disableUserSelect(false); } onDragging(params, mouseEvent) { this.resizeAmount = mouseEvent.clientX - this.dragStartX; params.onResizing(this.resizeAmount); } }; var AutoScrollService = class { constructor(params) { this.tickingInterval = null; this.onScrollCallback = null; this.scrollContainer = params.scrollContainer; this.scrollHorizontally = params.scrollAxis.includes("x"); this.scrollVertically = params.scrollAxis.includes("y"); this.scrollByTick = params.scrollByTick ?? 20; if (params.onScrollCallback) { this.onScrollCallback = params.onScrollCallback; } if (this.scrollVertically) { this.getVerticalPosition = params.getVerticalPosition; this.setVerticalPosition = params.setVerticalPosition; } if (this.scrollHorizontally) { this.getHorizontalPosition = params.getHorizontalPosition; this.setHorizontalPosition = params.setHorizontalPosition; } this.shouldSkipVerticalScroll = params.shouldSkipVerticalScroll || (() => false); this.shouldSkipHorizontalScroll = params.shouldSkipHorizontalScroll || (() => false); } get scrolling() { return this.tickingInterval !== null; } check(mouseEvent, forceSkipVerticalScroll = false) { const skipVerticalScroll = !this.scrollVertically || forceSkipVerticalScroll || this.shouldSkipVerticalScroll(); const skipHorizontalScroll = !this.scrollHorizontally || this.shouldSkipHorizontalScroll(); if (skipVerticalScroll && skipHorizontalScroll) { return; } const rect = this.scrollContainer.getBoundingClientRect(); const scrollTick = this.scrollByTick; this.tickLeft = !skipHorizontalScroll && mouseEvent.clientX < rect.left + scrollTick; this.tickRight = !skipHorizontalScroll && mouseEvent.clientX > rect.right - scrollTick; this.tickUp = !skipVerticalScroll && mouseEvent.clientY < rect.top + scrollTick; this.tickDown = !skipVerticalScroll && mouseEvent.clientY > rect.bottom - scrollTick; if (this.tickLeft || this.tickRight || this.tickUp || this.tickDown) { this.ensureTickingStarted(); } else { this.ensureCleared(); } } ensureTickingStarted() { if (this.tickingInterval === null) { this.tickingInterval = window.setInterval(this.doTick.bind(this), 100); this.tickCount = 0; } } doTick() { this.tickCount++; const tickAmount = this.tickCount > 20 ? 200 : this.tickCount > 10 ? 80 : 40; if (this.scrollVertically) { const vScrollPosition = this.getVerticalPosition(); if (this.tickUp) { this.setVerticalPosition(vScrollPosition - tickAmount); } if (this.tickDown) { this.setVerticalPosition(vScrollPosition + tickAmount); } } if (this.scrollHorizontally) { const hScrollPosition = this.getHorizontalPosition(); if (this.tickLeft) { this.setHorizontalPosition(hScrollPosition - tickAmount); } if (this.tickRight) { this.setHorizontalPosition(hScrollPosition + tickAmount); } } if (this.onScrollCallback) { this.onScrollCallback(); } } ensureCleared() { if (this.tickingInterval) { window.clearInterval(this.tickingInterval); this.tickingInterval = null; } } }; var ChangedRowNodes = class { constructor() { this.reordered = false; this.removals = []; this.updates = /* @__PURE__ */ new Set; this.adds = /* @__PURE__ */ new Set; } }; var _csrmFirstLeaf = (node) => { let childrenAfterGroup = node.childrenAfterGroup; while (childrenAfterGroup?.length) { const child = childrenAfterGroup[0]; if (child.sourceRowIndex >= 0) { return child; } childrenAfterGroup = child.childrenAfterGroup; } }; var _csrmReorderAllLeafs = (allLeafs, leafsToMove, target, above) => { if (!leafsToMove.size || !allLeafs) { return false; } let orderChanged = false; const allLeafsLen = allLeafs.length ?? 0; let targetPositionIdx = -1; if (target) { targetPositionIdx = target.sourceRowIndex; target = targetPositionIdx < 0 ? _csrmFirstLeaf(target) : null; if (target) { targetPositionIdx = target.sourceRowIndex; } } if (targetPositionIdx < 0 || targetPositionIdx >= allLeafsLen) { targetPositionIdx = allLeafsLen; } else if (!above) { ++targetPositionIdx; } let firstAffectedLeafIdx = targetPositionIdx; let lastAffectedLeafIndex = Math.min(targetPositionIdx, allLeafsLen - 1); for (const row of leafsToMove) { const sourceRowIndex = row.sourceRowIndex; if (sourceRowIndex < firstAffectedLeafIdx) { firstAffectedLeafIdx = sourceRowIndex; } if (sourceRowIndex > lastAffectedLeafIndex) { lastAffectedLeafIndex = sourceRowIndex; } } let writeIdxLeft = firstAffectedLeafIdx; for (let readIdx = firstAffectedLeafIdx;readIdx < targetPositionIdx; ++readIdx) { const row = allLeafs[readIdx]; if (leafsToMove.has(row)) { continue; } if (row.sourceRowIndex !== writeIdxLeft) { row.sourceRowIndex = writeIdxLeft; allLeafs[writeIdxLeft] = row; orderChanged = true; } ++writeIdxLeft; } let writeIdxRight = lastAffectedLeafIndex; for (let readIdx = lastAffectedLeafIndex;readIdx >= targetPositionIdx; --readIdx) { const row = allLeafs[readIdx]; if (leafsToMove.has(row)) { continue; } if (row.sourceRowIndex !== writeIdxRight) { row.sourceRowIndex = writeIdxRight; allLeafs[writeIdxRight] = row; orderChanged = true; } --writeIdxRight; } for (const row of leafsToMove) { if (row.sourceRowIndex !== writeIdxLeft) { row.sourceRowIndex = writeIdxLeft; allLeafs[writeIdxLeft] = row; orderChanged = true; } ++writeIdxLeft; } return orderChanged; }; function _getCellPositionForEvent(gos, event) { return _getCellCtrlForEventTarget(gos, event.target)?.getFocusedCellPosition() ?? null; } function _getNormalisedMousePosition(beans, event) { const gridPanelHasScrolls = _isDomLayout(beans.gos, "normal"); const e = event; let x; let y; if (e.clientX != null || e.clientY != null) { x = e.clientX; y = e.clientY; } else { x = e.x; y = e.y; } const { pageFirstPixel } = beans.pageBounds.getCurrentPagePixelRange(); y += pageFirstPixel; if (gridPanelHasScrolls) { const scrollFeature = beans.ctrlsSvc.getScrollFeature(); const vRange = scrollFeature.getVScrollPosition(); const hRange = scrollFeature.getHScrollPosition(); x += hRange.left; y += vRange.top; } return { x, y }; } var DragModule = { moduleName: "Drag", version: VERSION, beans: [DragService] }; var SharedDragAndDropModule = { moduleName: "SharedDragAndDrop", version: VERSION, beans: [DragAndDropService], dependsOn: [DragModule], userComponents: { agDragAndDropImage: DragAndDropImageComponent2 }, icons: { columnMovePin: "pin", columnMoveHide: "eye-slash", columnMoveMove: "arrows", columnMoveLeft: "left", columnMoveRight: "right", columnMoveGroup: "group", columnMoveValue: "aggregation", columnMovePivot: "pivot", dropNotAllowed: "not-allowed", rowDrag: "grip" } }; var HorizontalResizeModule = { moduleName: "HorizontalResize", version: VERSION, beans: [HorizontalResizeService], dependsOn: [DragModule] }; var column_moving_default = ":where(.ag-ltr) :where(.ag-column-moving){.ag-cell,.ag-header-cell,.ag-spanned-cell-wrapper{transition:left .2s}.ag-header-group-cell{transition:left .2s,width .2s}}:where(.ag-rtl) :where(.ag-column-moving){.ag-cell,.ag-header-cell,.ag-spanned-cell-wrapper{transition:right .2s}.ag-header-group-cell{transition:right .2s,width .2s}}"; var ColumnAnimationService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colAnimation"; this.executeNextFuncs = []; this.executeLaterFuncs = []; this.active = false; this.activeNext = false; this.suppressAnimation = false; this.animationThreadCount = 0; } postConstruct() { this.beans.ctrlsSvc.whenReady(this, (p) => this.gridBodyCtrl = p.gridBodyCtrl); } isActive() { return this.active && !this.suppressAnimation; } setSuppressAnimation(suppress) { this.suppressAnimation = suppress; } start() { if (this.active) { return; } const { gos } = this; if (gos.get("suppressColumnMoveAnimation")) { return; } if (gos.get("enableRtl")) { return; } this.ensureAnimationCssClassPresent(); this.active = true; this.activeNext = true; } finish() { if (!this.active) { return; } this.flush(() => this.activeNext = false, () => this.active = false); } executeNextVMTurn(func) { if (this.activeNext) { this.executeNextFuncs.push(func); } else { func(); } } executeLaterVMTurn(func) { if (this.active) { this.executeLaterFuncs.push(func); } else { func(); } } ensureAnimationCssClassPresent() { this.animationThreadCount++; const animationThreadCountCopy = this.animationThreadCount; const { gridBodyCtrl } = this; gridBodyCtrl.setColumnMovingCss(true); this.executeLaterFuncs.push(() => { if (this.animationThreadCount === animationThreadCountCopy) { gridBodyCtrl.setColumnMovingCss(false); } }); } flush(callbackNext, callbackLater) { const { executeNextFuncs, executeLaterFuncs } = this; if (executeNextFuncs.length === 0 && executeLaterFuncs.length === 0) { callbackNext(); callbackLater(); return; } const runFuncs = (queue) => { while (queue.length) { const func = queue.pop(); if (func) { func(); } } }; this.beans.frameworkOverrides.wrapIncoming(() => { window.setTimeout(() => { callbackNext(); runFuncs(executeNextFuncs); }, 0); window.setTimeout(() => { callbackLater(); runFuncs(executeLaterFuncs); }, 200); }); } }; function moveColumnByIndex(beans, fromIndex, toIndex) { beans.colMoves?.moveColumnByIndex(fromIndex, toIndex, "api"); } function moveColumns(beans, columnsToMoveKeys, toIndex) { beans.colMoves?.moveColumns(columnsToMoveKeys, toIndex, "api"); } var BodyDropPivotTarget = class extends BeanStub { constructor(pinned) { super(); this.pinned = pinned; this.columnsToAggregate = []; this.columnsToGroup = []; this.columnsToPivot = []; } onDragEnter(draggingEvent) { this.clearColumnsList(); if (this.gos.get("functionsReadOnly")) { return; } const dragColumns = draggingEvent.dragItem.columns; if (!dragColumns) { return; } for (const column of dragColumns) { if (!column.isPrimary()) { continue; } if (column.isAnyFunctionActive()) { continue; } if (column.isAllowValue()) { this.columnsToAggregate.push(column); } else if (column.isAllowRowGroup()) { this.columnsToGroup.push(column); } else if (column.isAllowPivot()) { this.columnsToPivot.push(column); } } } getIconName() { const totalColumns = this.columnsToAggregate.length + this.columnsToGroup.length + this.columnsToPivot.length; if (totalColumns > 0) { return this.pinned ? "pinned" : "move"; } return null; } onDragLeave(draggingEvent) { this.clearColumnsList(); } clearColumnsList() { this.columnsToAggregate.length = 0; this.columnsToGroup.length = 0; this.columnsToPivot.length = 0; } onDragging(draggingEvent) {} onDragStop(draggingEvent) { const { valueColsSvc, rowGroupColsSvc, pivotColsSvc } = this.beans; if (this.columnsToAggregate.length > 0) { valueColsSvc?.addColumns(this.columnsToAggregate, "toolPanelDragAndDrop"); } if (this.columnsToGroup.length > 0) { rowGroupColsSvc?.addColumns(this.columnsToGroup, "toolPanelDragAndDrop"); } if (this.columnsToPivot.length > 0) { pivotColsSvc?.addColumns(this.columnsToPivot, "toolPanelDragAndDrop"); } } onDragCancel() { this.clearColumnsList(); } }; function sortColsLikeCols(colsList, cols) { if (!cols || cols.length <= 1) { return; } const notAllColsPresent = cols.filter((c) => colsList.indexOf(c) < 0).length > 0; if (notAllColsPresent) { return; } cols.sort((a, b) => { const indexA = colsList.indexOf(a); const indexB = colsList.indexOf(b); return indexA - indexB; }); } function getColsToMove(allMovingColumns) { const newCols = [...allMovingColumns]; for (const col of allMovingColumns) { let movingGroup = null; let parent = col.getParent(); while (parent != null && parent.getDisplayedLeafColumns().length === 1) { movingGroup = parent; parent = parent.getParent(); } if (movingGroup != null) { const isMarryChildren = !!movingGroup.getColGroupDef()?.marryChildren; const columnsToMove = isMarryChildren ? movingGroup.getProvidedColumnGroup().getLeafColumns() : movingGroup.getLeafColumns(); for (const newCol of columnsToMove) { if (!newCols.includes(newCol)) { newCols.push(newCol); } } } } return newCols; } function getLowestFragMove(validMoves, allMovingColumnsOrdered, colMoves, visibleCols) { const displayedCols = visibleCols.allCols; let lowestFragMove = null; let targetOrder = null; for (let i = 0;i < validMoves.length; i++) { const move = validMoves[i]; const order = colMoves.getProposedColumnOrder(allMovingColumnsOrdered, move); if (!colMoves.doesOrderPassRules(order)) { continue; } const displayedOrder = order.filter((col) => displayedCols.includes(col)); if (targetOrder === null) { targetOrder = displayedOrder; } else if (!_areEqual(displayedOrder, targetOrder)) { break; } const fragCount = groupFragCount(order); if (lowestFragMove === null || fragCount < lowestFragMove.fragCount) { lowestFragMove = { move, fragCount }; } } return lowestFragMove; } function getBestColumnMoveIndexFromXPosition(params) { const { isFromHeader, fromLeft, xPosition, fromEnter, fakeEvent, pinned, gos, colModel, colMoves, visibleCols } = params; let { allMovingColumns } = params; if (isFromHeader) { allMovingColumns = getColsToMove(allMovingColumns); } const allMovingColumnsOrdered = allMovingColumns.slice(); sortColsLikeCols(colModel.getCols(), allMovingColumnsOrdered); const validMoves = calculateValidMoves({ movingCols: allMovingColumnsOrdered, draggingRight: fromLeft, xPosition, pinned, gos, colModel, visibleCols }); const oldIndex = calculateOldIndex(allMovingColumnsOrdered, colModel); if (validMoves.length === 0) { return; } const firstValidMove = validMoves[0]; const constrainDirection = oldIndex !== null && (isFromHeader || !fromEnter); if (constrainDirection && !fakeEvent) { if (!fromLeft && firstValidMove >= oldIndex) { return; } if (fromLeft && firstValidMove <= oldIndex) { return; } } const lowestFragMove = getLowestFragMove(validMoves, allMovingColumnsOrdered, colMoves, visibleCols); if (!lowestFragMove) { return; } const toIndex = lowestFragMove.move; if (toIndex > colModel.getCols().length - allMovingColumnsOrdered.length) { return; } return { columns: allMovingColumnsOrdered, toIndex }; } function attemptMoveColumns(params) { const { columns, toIndex } = getBestColumnMoveIndexFromXPosition(params) || {}; const { finished, colMoves } = params; if (!columns || toIndex == null) { return null; } colMoves.moveColumns(columns, toIndex, "uiColumnMoved", finished); return finished ? null : { columns, toIndex }; } function calculateOldIndex(movingCols, colModel) { const gridCols = colModel.getCols(); const indexes = movingCols.map((col) => gridCols.indexOf(col)).sort((a, b) => a - b); const firstIndex = indexes[0]; const lastIndex = _last(indexes); const spread = lastIndex - firstIndex; const gapsExist = spread !== indexes.length - 1; return gapsExist ? null : firstIndex; } function groupFragCount(columns) { function parents(col) { const result = []; let parent = col.getOriginalParent(); while (parent != null) { result.push(parent); parent = parent.getOriginalParent(); } return result; } let count = 0; for (let i = 0;i < columns.length - 1; i++) { let a = parents(columns[i]); let b = parents(columns[i + 1]); [a, b] = a.length > b.length ? [a, b] : [b, a]; for (const parent of a) { if (b.indexOf(parent) === -1) { count++; } } } return count; } function getDisplayedColumns(visibleCols, type) { switch (type) { case "left": return visibleCols.leftCols; case "right": return visibleCols.rightCols; default: return visibleCols.centerCols; } } function calculateValidMoves(params) { const { movingCols, draggingRight, xPosition, pinned, gos, colModel, visibleCols } = params; const isMoveBlocked = gos.get("suppressMovableColumns") || movingCols.some((col) => col.getColDef().suppressMovable); if (isMoveBlocked) { return []; } const allDisplayedCols = getDisplayedColumns(visibleCols, pinned); const allGridCols = colModel.getCols(); const movingDisplayedCols = allDisplayedCols.filter((col) => movingCols.includes(col)); const otherDisplayedCols = allDisplayedCols.filter((col) => !movingCols.includes(col)); const otherGridCols = allGridCols.filter((col) => !movingCols.includes(col)); let displayIndex = 0; let availableWidth = xPosition; if (draggingRight) { let widthOfMovingDisplayedCols = 0; for (const col of movingDisplayedCols) { widthOfMovingDisplayedCols += col.getActualWidth(); } availableWidth -= widthOfMovingDisplayedCols; } if (availableWidth > 0) { for (let i = 0;i < otherDisplayedCols.length; i++) { const col = otherDisplayedCols[i]; availableWidth -= col.getActualWidth(); if (availableWidth < 0) { break; } displayIndex++; } if (draggingRight) { displayIndex++; } } let firstValidMove; if (displayIndex > 0) { const leftColumn = otherDisplayedCols[displayIndex - 1]; firstValidMove = otherGridCols.indexOf(leftColumn) + 1; } else { firstValidMove = otherGridCols.indexOf(otherDisplayedCols[0]); if (firstValidMove === -1) { firstValidMove = 0; } } const validMoves = [firstValidMove]; const numberComparator = (a, b) => a - b; if (draggingRight) { let pointer = firstValidMove + 1; const lastIndex = allGridCols.length - 1; while (pointer <= lastIndex) { validMoves.push(pointer); pointer++; } validMoves.sort(numberComparator); } else { let pointer = firstValidMove; const lastIndex = allGridCols.length - 1; let displacedCol = allGridCols[pointer]; while (pointer <= lastIndex && allDisplayedCols.indexOf(displacedCol) < 0) { pointer++; validMoves.push(pointer); displacedCol = allGridCols[pointer]; } pointer = firstValidMove - 1; const firstDisplayIndex = 0; while (pointer >= firstDisplayIndex) { validMoves.push(pointer); pointer--; } validMoves.sort(numberComparator).reverse(); } return validMoves; } function normaliseX(params) { const { pinned, fromKeyboard, gos, ctrlsSvc, useHeaderRow, skipScrollPadding } = params; let eViewport = ctrlsSvc.getHeaderRowContainerCtrl(pinned)?.eViewport; let { x } = params; if (!eViewport) { return 0; } if (fromKeyboard) { x -= eViewport.getBoundingClientRect().left; } if (gos.get("enableRtl")) { if (useHeaderRow) { eViewport = eViewport.querySelector(".ag-header-row"); } x = eViewport.clientWidth - x; } if (pinned == null && !skipScrollPadding) { x += ctrlsSvc.get("center").getCenterViewportScrollLeft(); } return x; } function setColumnsMoving(columns, isMoving) { for (const column of columns) { column.moving = isMoving; column.dispatchColEvent("movingChanged", "uiColumnMoved"); } } var MOVE_FAIL_THRESHOLD = 7; var SCROLL_MOVE_WIDTH = 100; var SCROLL_GAP_NEEDED_BEFORE_MOVE = SCROLL_MOVE_WIDTH / 2; var SCROLL_ACCELERATION_RATE = 5; var SCROLL_TIME_INTERVAL = 100; var MoveColumnFeature = class extends BeanStub { constructor(pinned) { super(); this.pinned = pinned; this.needToMoveLeft = false; this.needToMoveRight = false; this.lastMovedInfo = null; this.isCenterContainer = !_exists(pinned); } postConstruct() { this.beans.ctrlsSvc.whenReady(this, (p) => { this.gridBodyCon = p.gridBodyCtrl; }); } getIconName() { const { pinned, lastDraggingEvent } = this; const { dragItem } = lastDraggingEvent || {}; const columns = dragItem?.columns ?? []; for (const col of columns) { const colPinned = col.getPinned(); if (col.getColDef().lockPinned) { if (colPinned == pinned) { return "move"; } continue; } const initialPinnedState = dragItem?.containerType; if (initialPinnedState === pinned || !pinned) { return "move"; } if (pinned && (!colPinned || initialPinnedState !== pinned)) { return "pinned"; } } return "notAllowed"; } onDragEnter(draggingEvent) { const dragItem = draggingEvent.dragItem; const columns = dragItem.columns; const dragCameFromToolPanel = draggingEvent.dragSource.type === 0; if (dragCameFromToolPanel) { this.setColumnsVisible(columns, true, "uiColumnDragged"); } else { const visibleState = dragItem.visibleState; const visibleColumns = (columns || []).filter((column) => visibleState[column.getId()] && !column.isVisible()); this.setColumnsVisible(visibleColumns, true, "uiColumnDragged"); } if (!this.gos.get("suppressMoveWhenColumnDragging")) { this.attemptToPinColumns(columns, this.pinned); } this.onDragging(draggingEvent, true, true); } onDragging(draggingEvent = this.lastDraggingEvent, fromEnter = false, fakeEvent = false, finished = false) { const { gos, ctrlsSvc } = this.beans; const isSuppressMoveWhenDragging = gos.get("suppressMoveWhenColumnDragging"); if (finished && !isSuppressMoveWhenDragging) { this.finishColumnMoving(); return; } this.lastDraggingEvent = draggingEvent; if (!draggingEvent || !finished && _missing(draggingEvent.hDirection)) { return; } const mouseX = normaliseX({ x: draggingEvent.x, pinned: this.pinned, gos, ctrlsSvc }); if (!fromEnter) { this.checkCenterForScrolling(mouseX); } if (isSuppressMoveWhenDragging) { this.handleColumnDragWhileSuppressingMovement(draggingEvent, fromEnter, fakeEvent, mouseX, finished); } else { this.handleColumnDragWhileAllowingMovement(draggingEvent, fromEnter, fakeEvent, mouseX, finished); } } onDragLeave() { this.ensureIntervalCleared(); this.clearHighlighted(); this.updateDragItemContainerType(); this.lastMovedInfo = null; } onDragStop() { this.onDragging(this.lastDraggingEvent, false, true, true); this.ensureIntervalCleared(); this.lastMovedInfo = null; } onDragCancel() { this.clearHighlighted(); this.ensureIntervalCleared(); this.lastMovedInfo = null; } setColumnsVisible(columns, visible, source) { if (!columns?.length) { return; } const allowedCols = columns.filter((c) => !c.getColDef().lockVisible); if (!allowedCols.length) { return; } this.beans.colModel.setColsVisible(allowedCols, visible, source); } finishColumnMoving() { this.clearHighlighted(); const lastMovedInfo = this.lastMovedInfo; if (!lastMovedInfo) { return; } const { columns, toIndex } = lastMovedInfo; this.beans.colMoves.moveColumns(columns, toIndex, "uiColumnMoved", true); } updateDragItemContainerType() { const { lastDraggingEvent } = this; if (this.gos.get("suppressMoveWhenColumnDragging") || !lastDraggingEvent) { return; } const dragItem = lastDraggingEvent.dragItem; if (!dragItem) { return; } dragItem.containerType = this.pinned; } handleColumnDragWhileSuppressingMovement(draggingEvent, fromEnter, fakeEvent, mouseX, finished) { const allMovingColumns = this.getAllMovingColumns(draggingEvent, true); if (finished) { const isAttemptingToPin = this.isAttemptingToPin(allMovingColumns); if (isAttemptingToPin) { this.attemptToPinColumns(allMovingColumns, undefined, true); } const { fromLeft, xPosition } = this.getNormalisedXPositionInfo(allMovingColumns, isAttemptingToPin) || {}; if (fromLeft == null || xPosition == null) { this.finishColumnMoving(); return; } this.moveColumnsAfterHighlight({ allMovingColumns, xPosition, fromEnter, fakeEvent, fromLeft }); } else { if (!this.beans.dragAndDrop.isDropZoneWithinThisGrid(draggingEvent)) { return; } this.highlightHoveredColumn(allMovingColumns, mouseX); } } handleColumnDragWhileAllowingMovement(draggingEvent, fromEnter, fakeEvent, mouseX, finished) { const allMovingColumns = this.getAllMovingColumns(draggingEvent); const fromLeft = this.normaliseDirection(draggingEvent.hDirection) === "right"; const isFromHeader = draggingEvent.dragSource.type === 1; const params = this.getMoveColumnParams({ allMovingColumns, isFromHeader, xPosition: mouseX, fromLeft, fromEnter, fakeEvent }); const lastMovedInfo = attemptMoveColumns({ ...params, finished }); if (lastMovedInfo) { this.lastMovedInfo = lastMovedInfo; } } getAllMovingColumns(draggingEvent, useSplit = false) { const dragItem = draggingEvent.dragSource.getDragItem(); let columns = null; if (useSplit) { columns = dragItem.columnsInSplit; if (!columns) { columns = dragItem.columns; } } else { columns = dragItem.columns; } const conditionCallback = (col) => col.getColDef().lockPinned ? col.getPinned() == this.pinned : true; if (!columns) { return []; } return columns.filter(conditionCallback); } getMoveColumnParams(params) { const { allMovingColumns, isFromHeader, xPosition, fromLeft, fromEnter, fakeEvent } = params; const { gos, colModel, colMoves, visibleCols } = this.beans; return { allMovingColumns, isFromHeader, fromLeft, xPosition, pinned: this.pinned, fromEnter, fakeEvent, gos, colModel, colMoves, visibleCols }; } highlightHoveredColumn(movingColumns, mouseX) { const { gos, colModel } = this.beans; const isRtl = gos.get("enableRtl"); const consideredColumns = colModel.getCols().filter((col) => col.isVisible() && col.getPinned() === this.pinned); let start = null; let width = null; let targetColumn = null; for (const col of consideredColumns) { width = col.getActualWidth(); start = this.getNormalisedColumnLeft(col, 0, isRtl); if (start != null) { const end = start + width; if (start <= mouseX && end >= mouseX) { targetColumn = col; break; } } start = null; width = null; } if (!targetColumn) { for (let i = consideredColumns.length - 1;i >= 0; i--) { const currentColumn = consideredColumns[i]; const parent = consideredColumns[i].getParent(); if (!parent) { targetColumn = currentColumn; break; } const leafDisplayedCols = parent?.getDisplayedLeafColumns(); if (leafDisplayedCols.length) { targetColumn = _last(leafDisplayedCols); break; } } if (!targetColumn) { return; } start = this.getNormalisedColumnLeft(targetColumn, 0, isRtl); width = targetColumn.getActualWidth(); } else if (movingColumns.indexOf(targetColumn) !== -1) { targetColumn = null; } if (targetColumn == null || start == null || width == null) { if (this.lastHighlightedColumn?.column !== targetColumn) { this.clearHighlighted(); } return; } let position; if (mouseX - start < width / 2) { const targetIndex = consideredColumns.indexOf(targetColumn); if (targetIndex === 0) { position = 0; } else { position = 1; targetColumn = consideredColumns[targetIndex - 1]; } } else { position = 1; } if (this.lastHighlightedColumn?.column !== targetColumn || this.lastHighlightedColumn?.position !== position) { this.clearHighlighted(); } setColumnHighlighted(targetColumn, position); this.lastHighlightedColumn = { column: targetColumn, position }; } getNormalisedXPositionInfo(allMovingColumns, isAttemptingToPin) { const { gos, visibleCols } = this.beans; const isRtl = gos.get("enableRtl"); const { firstMovingCol, column, position } = this.getColumnMoveAndTargetInfo(allMovingColumns, isAttemptingToPin, isRtl); if (!firstMovingCol || !column || position == null) { return; } const visibleColumns = visibleCols.allCols; const movingColIndex = visibleColumns.indexOf(firstMovingCol); const targetIndex = visibleColumns.indexOf(column); const isBefore = position === 0; const fromLeft = movingColIndex < targetIndex || movingColIndex === targetIndex && !isBefore; let diff = 0; if (isBefore) { if (fromLeft) { diff -= 1; } } else if (!fromLeft) { diff += 1; } if (targetIndex + diff === movingColIndex) { return; } const targetColumn = visibleColumns[targetIndex + diff]; if (!targetColumn) { return; } const xPosition = this.getNormalisedColumnLeft(targetColumn, 20, isRtl); return { fromLeft, xPosition }; } getColumnMoveAndTargetInfo(allMovingColumns, isAttemptingToPin, isRtl) { const lastHighlightedColumn = this.lastHighlightedColumn || {}; const { firstMovingCol, lastMovingCol } = findFirstAndLastMovingColumns(allMovingColumns); if (!firstMovingCol || !lastMovingCol || lastHighlightedColumn.column || !isAttemptingToPin) { return { firstMovingCol, ...lastHighlightedColumn }; } const pinned = this.getPinDirection(); const isLeft = pinned === "left"; return { firstMovingCol, position: isLeft ? 1 : 0, column: isLeft !== isRtl ? firstMovingCol : lastMovingCol }; } normaliseDirection(hDirection) { if (this.gos.get("enableRtl")) { switch (hDirection) { case "left": return "right"; case "right": return "left"; } } return hDirection; } getNormalisedColumnLeft(col, padding, isRtl) { const { gos, ctrlsSvc } = this.beans; const left = col.getLeft(); if (left == null) { return null; } const width = col.getActualWidth(); return normaliseX({ x: isRtl ? left + width - padding : left + padding, pinned: col.getPinned(), useHeaderRow: isRtl, skipScrollPadding: true, gos, ctrlsSvc }); } isAttemptingToPin(columns) { const isMovingHorizontally = this.needToMoveLeft || this.needToMoveRight; const isFailedMoreThanThreshold = this.failedMoveAttempts > MOVE_FAIL_THRESHOLD; return isMovingHorizontally && isFailedMoreThanThreshold || columns.some((col) => col.getPinned() !== this.pinned); } moveColumnsAfterHighlight(params) { const { allMovingColumns, xPosition, fromEnter, fakeEvent, fromLeft } = params; const columnMoveParams = this.getMoveColumnParams({ allMovingColumns, isFromHeader: true, xPosition, fromLeft, fromEnter, fakeEvent }); const { columns, toIndex } = getBestColumnMoveIndexFromXPosition(columnMoveParams) || {}; if (columns && toIndex != null) { this.lastMovedInfo = { columns, toIndex }; } this.finishColumnMoving(); } clearHighlighted() { const { lastHighlightedColumn } = this; if (!lastHighlightedColumn) { return; } setColumnHighlighted(lastHighlightedColumn.column, null); this.lastHighlightedColumn = null; } checkCenterForScrolling(xAdjustedForScroll) { if (!this.isCenterContainer) { return; } const centerCtrl = this.beans.ctrlsSvc.get("center"); const firstVisiblePixel = centerCtrl.getCenterViewportScrollLeft(); const lastVisiblePixel = firstVisiblePixel + centerCtrl.getCenterWidth(); let needToMoveRight; let needToMoveLeft; if (this.gos.get("enableRtl")) { needToMoveRight = xAdjustedForScroll < firstVisiblePixel + SCROLL_GAP_NEEDED_BEFORE_MOVE; needToMoveLeft = xAdjustedForScroll > lastVisiblePixel - SCROLL_GAP_NEEDED_BEFORE_MOVE; } else { needToMoveLeft = xAdjustedForScroll < firstVisiblePixel + SCROLL_GAP_NEEDED_BEFORE_MOVE; needToMoveRight = xAdjustedForScroll > lastVisiblePixel - SCROLL_GAP_NEEDED_BEFORE_MOVE; } this.needToMoveRight = needToMoveRight; this.needToMoveLeft = needToMoveLeft; if (needToMoveLeft || needToMoveRight) { this.ensureIntervalStarted(); } else { this.ensureIntervalCleared(); } } ensureIntervalStarted() { if (this.movingIntervalId) { return; } this.intervalCount = 0; this.failedMoveAttempts = 0; this.movingIntervalId = window.setInterval(this.moveInterval.bind(this), SCROLL_TIME_INTERVAL); this.beans.dragAndDrop.setDragImageCompIcon(this.needToMoveLeft ? "left" : "right", true); } ensureIntervalCleared() { if (!this.movingIntervalId) { return; } window.clearInterval(this.movingIntervalId); this.movingIntervalId = null; this.failedMoveAttempts = 0; this.beans.dragAndDrop.setDragImageCompIcon(this.getIconName()); } moveInterval() { let pixelsToMove; this.intervalCount++; pixelsToMove = 10 + this.intervalCount * SCROLL_ACCELERATION_RATE; if (pixelsToMove > SCROLL_MOVE_WIDTH) { pixelsToMove = SCROLL_MOVE_WIDTH; } let pixelsMoved = null; const scrollFeature = this.gridBodyCon.scrollFeature; if (this.needToMoveLeft) { pixelsMoved = scrollFeature.scrollHorizontally(-pixelsToMove); } else if (this.needToMoveRight) { pixelsMoved = scrollFeature.scrollHorizontally(pixelsToMove); } if (pixelsMoved !== 0) { this.onDragging(this.lastDraggingEvent); this.failedMoveAttempts = 0; } else { this.failedMoveAttempts++; const { pinnedCols, dragAndDrop, gos } = this.beans; if (this.failedMoveAttempts <= MOVE_FAIL_THRESHOLD + 1 || !pinnedCols) { return; } dragAndDrop.setDragImageCompIcon("pinned"); if (!gos.get("suppressMoveWhenColumnDragging")) { const columns = this.lastDraggingEvent?.dragItem.columns; this.attemptToPinColumns(columns, undefined, true); } } } getPinDirection() { if (this.needToMoveLeft || this.pinned === "left") { return "left"; } if (this.needToMoveRight || this.pinned === "right") { return "right"; } } attemptToPinColumns(columns, pinned, fromMoving = false) { const allowedCols = (columns || []).filter((c) => !c.getColDef().lockPinned); if (!allowedCols.length) { return 0; } if (fromMoving) { pinned = this.getPinDirection(); } const { pinnedCols, dragAndDrop } = this.beans; pinnedCols?.setColsPinned(allowedCols, pinned, "uiColumnDragged"); if (fromMoving) { dragAndDrop.nudge(); } return allowedCols.length; } destroy() { super.destroy(); this.lastDraggingEvent = null; this.clearHighlighted(); this.lastMovedInfo = null; } }; function setColumnHighlighted(column, highlighted) { if (column.highlighted === highlighted) { return; } column.highlighted = highlighted; column.dispatchColEvent("headerHighlightChanged", "uiColumnMoved"); } function findFirstAndLastMovingColumns(allMovingColumns) { const moveLen = allMovingColumns.length; let firstMovingCol; let lastMovingCol; for (let i = 0;i < moveLen; i++) { if (!firstMovingCol) { const leftCol = allMovingColumns[i]; if (leftCol.getLeft() != null) { firstMovingCol = leftCol; } } if (!lastMovingCol) { const rightCol = allMovingColumns[moveLen - 1 - i]; if (rightCol.getLeft() != null) { lastMovingCol = rightCol; } } if (firstMovingCol && lastMovingCol) { break; } } return { firstMovingCol, lastMovingCol }; } var BodyDropTarget = class extends BeanStub { constructor(pinned, eContainer) { super(); this.pinned = pinned; this.eContainer = eContainer; } postConstruct() { const { ctrlsSvc, dragAndDrop } = this.beans; const pinned = this.pinned; ctrlsSvc.whenReady(this, (p) => { let eSecondaryContainers; const eBodyViewport = p.gridBodyCtrl.eBodyViewport; switch (pinned) { case "left": eSecondaryContainers = [ [eBodyViewport, p.left.eContainer], [p.bottomLeft.eContainer], [p.topLeft.eContainer] ]; break; case "right": eSecondaryContainers = [ [eBodyViewport, p.right.eContainer], [p.bottomRight.eContainer], [p.topRight.eContainer] ]; break; default: eSecondaryContainers = [ [eBodyViewport, p.center.eViewport], [p.bottomCenter.eViewport], [p.topCenter.eViewport] ]; break; } this.eSecondaryContainers = eSecondaryContainers; }); this.moveColumnFeature = this.createManagedBean(new MoveColumnFeature(pinned)); this.bodyDropPivotTarget = this.createManagedBean(new BodyDropPivotTarget(pinned)); dragAndDrop.addDropTarget(this); this.addDestroyFunc(() => dragAndDrop.removeDropTarget(this)); } isInterestedIn(type) { return type === 1 || type === 0 && this.gos.get("allowDragFromColumnsToolPanel"); } getSecondaryContainers() { return this.eSecondaryContainers; } getContainer() { return this.eContainer; } getIconName() { return this.currentDropListener.getIconName(); } isDropColumnInPivotMode(draggingEvent) { return this.beans.colModel.isPivotMode() && draggingEvent.dragSource.type === 0; } onDragEnter(draggingEvent) { this.currentDropListener = this.isDropColumnInPivotMode(draggingEvent) ? this.bodyDropPivotTarget : this.moveColumnFeature; this.currentDropListener.onDragEnter(draggingEvent); } onDragLeave(params) { this.currentDropListener.onDragLeave(params); } onDragging(params) { this.currentDropListener.onDragging(params); } onDragStop(params) { this.currentDropListener.onDragStop(params); } onDragCancel() { this.currentDropListener.onDragCancel(); } }; function placeLockedColumns(cols, gos) { const left = []; const normal = []; const right = []; cols.forEach((col) => { const position = col.getColDef().lockPosition; if (position === "right") { right.push(col); } else if (position === "left" || position === true) { left.push(col); } else { normal.push(col); } }); const isRtl = gos.get("enableRtl"); if (isRtl) { return [...right, ...normal, ...left]; } return [...left, ...normal, ...right]; } function doesMovePassMarryChildren(allColumnsCopy, gridBalancedTree) { let rulePassed = true; depthFirstOriginalTreeSearch(null, gridBalancedTree, (child) => { if (!isProvidedColumnGroup(child)) { return; } const columnGroup = child; const colGroupDef = columnGroup.getColGroupDef(); const marryChildren = colGroupDef?.marryChildren; if (!marryChildren) { return; } const newIndexes = []; for (const col of columnGroup.getLeafColumns()) { const newColIndex = allColumnsCopy.indexOf(col); newIndexes.push(newColIndex); } const maxIndex = Math.max.apply(Math, newIndexes); const minIndex = Math.min.apply(Math, newIndexes); const spread = maxIndex - minIndex; const maxSpread = columnGroup.getLeafColumns().length - 1; if (spread > maxSpread) { rulePassed = false; } }); return rulePassed; } var ColumnMoveService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colMoves"; } moveColumnByIndex(fromIndex, toIndex, source) { const gridColumns = this.beans.colModel.getCols(); if (!gridColumns) { return; } const column = gridColumns[fromIndex]; this.moveColumns([column], toIndex, source); } moveColumns(columnsToMoveKeys, toIndex, source, finished = true) { const { colModel, colAnimation, visibleCols, eventSvc } = this.beans; const gridColumns = colModel.getCols(); if (!gridColumns) { return; } if (toIndex > gridColumns.length - columnsToMoveKeys.length) { _warn(30, { toIndex }); return; } colAnimation?.start(); const movedColumns = colModel.getColsForKeys(columnsToMoveKeys); if (this.doesMovePassRules(movedColumns, toIndex)) { _moveInArray(colModel.getCols(), movedColumns, toIndex); visibleCols.refresh(source); eventSvc.dispatchEvent({ type: "columnMoved", columns: movedColumns, column: movedColumns.length === 1 ? movedColumns[0] : null, toIndex, finished, source }); } colAnimation?.finish(); } doesMovePassRules(columnsToMove, toIndex) { const proposedColumnOrder = this.getProposedColumnOrder(columnsToMove, toIndex); return this.doesOrderPassRules(proposedColumnOrder); } doesOrderPassRules(gridOrder) { const { colModel, gos } = this.beans; if (!doesMovePassMarryChildren(gridOrder, colModel.getColTree())) { return false; } const doesMovePassLockedPositions = (proposedColumnOrder) => { const lockPositionToPlacement = (position) => { if (!position) { return 0; } return position === "left" || position === true ? -1 : 1; }; const isRtl = gos.get("enableRtl"); let lastPlacement = isRtl ? 1 : -1; let rulePassed = true; for (const col of proposedColumnOrder) { const placement = lockPositionToPlacement(col.getColDef().lockPosition); if (isRtl) { if (placement > lastPlacement) { rulePassed = false; } } else if (placement < lastPlacement) { rulePassed = false; } lastPlacement = placement; } return rulePassed; }; if (!doesMovePassLockedPositions(gridOrder)) { return false; } return true; } getProposedColumnOrder(columnsToMove, toIndex) { const gridColumns = this.beans.colModel.getCols(); const proposedColumnOrder = gridColumns.slice(); _moveInArray(proposedColumnOrder, columnsToMove, toIndex); return proposedColumnOrder; } createBodyDropTarget(pinned, dropContainer) { return new BodyDropTarget(pinned, dropContainer); } moveHeader(hDirection, eGui, column, pinned, bean) { const { ctrlsSvc, gos, colModel, visibleCols, focusSvc } = this.beans; const rect = eGui.getBoundingClientRect(); const left = rect.left; const isGroup = isColumnGroup(column); const width = isGroup ? rect.width : column.getActualWidth(); const isLeft = hDirection === "left" !== gos.get("enableRtl"); const xPosition = normaliseX({ x: isLeft ? left - 20 : left + width + 20, pinned, fromKeyboard: true, gos, ctrlsSvc }); const headerPosition = focusSvc.focusedHeader; attemptMoveColumns({ allMovingColumns: isGroup ? column.getLeafColumns() : [column], isFromHeader: true, fromLeft: hDirection === "right", xPosition, pinned, fromEnter: false, fakeEvent: false, gos, colModel, colMoves: this, visibleCols, finished: true }); let targetColumn; if (isGroup) { const displayedLeafColumns = column.getDisplayedLeafColumns(); targetColumn = isLeft ? displayedLeafColumns[0] : _last(displayedLeafColumns); } else { targetColumn = column; } ctrlsSvc.getScrollFeature().ensureColumnVisible(targetColumn, "auto"); if ((!bean.isAlive() || gos.get("ensureDomOrder")) && headerPosition) { let restoreFocusColumn; if (isGroup) { const groupId = column.getGroupId(); const leafCols = column.getLeafColumns(); if (!leafCols.length) { return; } const parent = leafCols[0].getParent(); if (!parent) { return; } restoreFocusColumn = findGroupWidthId(parent, groupId); } else { restoreFocusColumn = column; } if (restoreFocusColumn) { focusSvc.focusHeaderPosition({ headerPosition: { ...headerPosition, column: restoreFocusColumn } }); } } } setDragSourceForHeader(eSource, column, displayName) { const { gos, colModel, dragAndDrop, visibleCols } = this.beans; let hideColumnOnExit = !gos.get("suppressDragLeaveHidesColumns"); const isGroup = isColumnGroup(column); const columns = isGroup ? column.getProvidedColumnGroup().getLeafColumns() : [column]; const getDragItem = isGroup ? () => createDragItemForGroup(column, visibleCols.allCols) : () => createDragItem(column); const dragSource = { type: 1, eElement: eSource, getDefaultIconName: () => hideColumnOnExit ? "hide" : "notAllowed", getDragItem, dragItemName: displayName, onDragStarted: () => { hideColumnOnExit = !gos.get("suppressDragLeaveHidesColumns"); setColumnsMoving(columns, true); }, onDragStopped: () => setColumnsMoving(columns, false), onDragCancelled: () => setColumnsMoving(columns, false), onGridEnter: (dragItem) => { if (hideColumnOnExit) { const { columns: columns2 = [], visibleState } = dragItem ?? {}; const hasVisibleState = isGroup ? (col) => !visibleState || visibleState[col.getColId()] : () => true; const unlockedColumns = columns2.filter((col) => !col.getColDef().lockVisible && hasVisibleState(col)); colModel.setColsVisible(unlockedColumns, true, "uiColumnMoved"); } }, onGridExit: (dragItem) => { if (hideColumnOnExit) { const unlockedColumns = dragItem?.columns?.filter((col) => !col.getColDef().lockVisible) || []; colModel.setColsVisible(unlockedColumns, false, "uiColumnMoved"); } } }; dragAndDrop.addDragSource(dragSource, true); return dragSource; } }; function findGroupWidthId(columnGroup, id) { while (columnGroup) { if (columnGroup.getGroupId() === id) { return columnGroup; } columnGroup = columnGroup.getParent(); } return; } function createDragItem(column) { const visibleState = {}; visibleState[column.getId()] = column.isVisible(); return { columns: [column], visibleState, containerType: column.pinned }; } function createDragItemForGroup(columnGroup, allCols) { const allColumnsOriginalOrder = columnGroup.getProvidedColumnGroup().getLeafColumns(); const visibleState = {}; for (const column of allColumnsOriginalOrder) { visibleState[column.getId()] = column.isVisible(); } const allColumnsCurrentOrder = []; for (const column of allCols) { if (allColumnsOriginalOrder.indexOf(column) >= 0) { allColumnsCurrentOrder.push(column); _removeFromArray(allColumnsOriginalOrder, column); } } for (const column of allColumnsOriginalOrder) { allColumnsCurrentOrder.push(column); } const columnsInSplit = []; const columnGroupColumns = columnGroup.getLeafColumns(); for (const col of allColumnsCurrentOrder) { if (columnGroupColumns.indexOf(col) !== -1) { columnsInSplit.push(col); } } return { columns: allColumnsCurrentOrder, columnsInSplit, visibleState, containerType: columnsInSplit[0]?.pinned }; } var ColumnMoveModule = { moduleName: "ColumnMove", version: VERSION, beans: [ColumnMoveService, ColumnAnimationService], apiFunctions: { moveColumnByIndex, moveColumns }, dependsOn: [SharedDragAndDropModule], css: [column_moving_default] }; var AutoWidthCalculator = class extends BeanStub { constructor() { super(...arguments); this.beanName = "autoWidthCalc"; } postConstruct() { this.beans.ctrlsSvc.whenReady(this, (p) => { this.centerRowContainerCtrl = p.center; }); } getPreferredWidthForColumn(column, skipHeader) { const eHeaderCell = this.getHeaderCellForColumn(column); if (!eHeaderCell) { return -1; } const elements = this.beans.rowRenderer.getAllCellsNotSpanningForColumn(column); if (!skipHeader) { elements.push(eHeaderCell); } return this.getPreferredWidthForElements(elements); } getPreferredWidthForColumnGroup(columnGroup) { const eHeaderCell = this.getHeaderCellForColumn(columnGroup); if (!eHeaderCell) { return -1; } return this.getPreferredWidthForElements([eHeaderCell]); } getPreferredWidthForElements(elements, extraPadding) { const eDummyContainer = document.createElement("form"); eDummyContainer.style.position = "fixed"; const eBodyContainer = this.centerRowContainerCtrl.eContainer; for (const el of elements) { this.cloneItemIntoDummy(el, eDummyContainer); } eBodyContainer.appendChild(eDummyContainer); const dummyContainerWidth = Math.ceil(eDummyContainer.getBoundingClientRect().width); eDummyContainer.remove(); extraPadding = extraPadding ?? this.gos.get("autoSizePadding"); return dummyContainerWidth + extraPadding; } getHeaderCellForColumn(column) { let element = null; for (const container of this.beans.ctrlsSvc.getHeaderRowContainerCtrls()) { const res = container.getHtmlElementForColumnHeader(column); if (res != null) { element = res; } } return element; } cloneItemIntoDummy(eCell, eDummyContainer) { const eCellClone = eCell.cloneNode(true); eCellClone.style.width = ""; eCellClone.style.position = "static"; eCellClone.style.left = ""; const eCloneParent = document.createElement("div"); const eCloneParentClassList = eCloneParent.classList; const isHeader = ["ag-header-cell", "ag-header-group-cell"].some((cls) => eCellClone.classList.contains(cls)); if (isHeader) { eCloneParentClassList.add("ag-header", "ag-header-row"); eCloneParent.style.position = "static"; } else { eCloneParentClassList.add("ag-row"); } let pointer = eCell.parentElement; while (pointer) { const isRow = ["ag-header-row", "ag-row"].some((cls) => pointer.classList.contains(cls)); if (isRow) { for (let i = 0;i < pointer.classList.length; i++) { const item = pointer.classList[i]; if (item != "ag-row-position-absolute") { eCloneParentClassList.add(item); } } break; } pointer = pointer.parentElement; } eCloneParent.appendChild(eCellClone); eDummyContainer.appendChild(eCloneParent); } }; var AutoWidthModule = { moduleName: "AutoWidth", version: VERSION, beans: [AutoWidthCalculator] }; function setColumnWidths(beans, columnWidths, finished = true, source = "api") { beans.colResize?.setColumnWidths(columnWidths, false, finished, source); } function getCommonValue(cols, valueGetter) { if (!cols || cols.length == 0) { return; } const firstValue = valueGetter(cols[0]); for (let i = 1;i < cols.length; i++) { if (firstValue !== valueGetter(cols[i])) { return; } } return firstValue; } function dispatchColumnPinnedEvent(eventSvc, changedColumns, source) { if (!changedColumns.length) { return; } const column = changedColumns.length === 1 ? changedColumns[0] : null; const pinned = getCommonValue(changedColumns, (col) => col.getPinned()); eventSvc.dispatchEvent({ type: "columnPinned", pinned: pinned != null ? pinned : null, columns: changedColumns, column, source }); } function dispatchColumnVisibleEvent(eventSvc, changedColumns, source) { if (!changedColumns.length) { return; } const column = changedColumns.length === 1 ? changedColumns[0] : null; const visible = getCommonValue(changedColumns, (col) => col.isVisible()); eventSvc.dispatchEvent({ type: "columnVisible", visible, columns: changedColumns, column, source }); } function dispatchColumnChangedEvent(eventSvc, type, columns, source) { eventSvc.dispatchEvent({ type, columns, column: columns && columns.length == 1 ? columns[0] : null, source }); } function dispatchColumnResizedEvent(eventSvc, columns, finished, source, flexColumns = null) { if (columns?.length) { eventSvc.dispatchEvent({ type: "columnResized", columns, column: columns.length === 1 ? columns[0] : null, flexColumns, finished, source }); } } var GroupResizeFeature = class extends BeanStub { constructor(comp, eResize, pinned, columnGroup) { super(); this.comp = comp; this.eResize = eResize; this.pinned = pinned; this.columnGroup = columnGroup; } postConstruct() { if (!this.columnGroup.isResizable()) { this.comp.setResizableDisplayed(false); return; } const { horizontalResizeSvc, gos, colAutosize } = this.beans; const finishedWithResizeFunc = horizontalResizeSvc.addResizeBar({ eResizeBar: this.eResize, onResizeStart: this.onResizeStart.bind(this), onResizing: this.onResizing.bind(this, false), onResizeEnd: this.onResizing.bind(this, true) }); this.addDestroyFunc(finishedWithResizeFunc); if (!gos.get("suppressAutoSize") && colAutosize) { this.addDestroyFunc(colAutosize.addColumnGroupResize(this.eResize, this.columnGroup, () => this.resizeLeafColumnsToFit("uiColumnResized"))); } } onResizeStart(shiftKey) { const { columnsToResize, resizeStartWidth, resizeRatios, groupAfterColumns, groupAfterStartWidth, groupAfterRatios } = this.getInitialValues(shiftKey); this.resizeCols = columnsToResize; this.resizeStartWidth = resizeStartWidth; this.resizeRatios = resizeRatios; this.resizeTakeFromCols = groupAfterColumns; this.resizeTakeFromStartWidth = groupAfterStartWidth; this.resizeTakeFromRatios = groupAfterRatios; this.toggleColumnResizing(true); } onResizing(finished, resizeAmount, source = "uiColumnResized") { const resizeAmountNormalised = this.normaliseDragChange(resizeAmount); const width = this.resizeStartWidth + resizeAmountNormalised; this.resizeColumnsFromLocalValues(width, source, finished); } getInitialValues(shiftKey) { const getInitialSizeOfColumns = (columns) => columns.reduce((totalWidth, column) => totalWidth + column.getActualWidth(), 0); const getSizeRatiosOfColumns = (columns, initialSizeOfColumns) => columns.map((column) => column.getActualWidth() / initialSizeOfColumns); const columnsToResize = this.getColumnsToResize(); const resizeStartWidth = getInitialSizeOfColumns(columnsToResize); const resizeRatios = getSizeRatiosOfColumns(columnsToResize, resizeStartWidth); const columnSizeAndRatios = { columnsToResize, resizeStartWidth, resizeRatios }; let groupAfter = null; if (shiftKey) { groupAfter = this.beans.colGroupSvc?.getGroupAtDirection(this.columnGroup, "After") ?? null; } if (groupAfter) { const takeFromLeafCols = groupAfter.getDisplayedLeafColumns(); const groupAfterColumns = columnSizeAndRatios.groupAfterColumns = takeFromLeafCols.filter((col) => col.isResizable()); const groupAfterStartWidth = columnSizeAndRatios.groupAfterStartWidth = getInitialSizeOfColumns(groupAfterColumns); columnSizeAndRatios.groupAfterRatios = getSizeRatiosOfColumns(groupAfterColumns, groupAfterStartWidth); } else { columnSizeAndRatios.groupAfterColumns = undefined; columnSizeAndRatios.groupAfterStartWidth = undefined; columnSizeAndRatios.groupAfterRatios = undefined; } return columnSizeAndRatios; } resizeLeafColumnsToFit(source) { const preferredSize = this.beans.autoWidthCalc.getPreferredWidthForColumnGroup(this.columnGroup); const initialValues = this.getInitialValues(); if (preferredSize > initialValues.resizeStartWidth) { this.resizeColumns(initialValues, preferredSize, source, true); } } resizeColumnsFromLocalValues(totalWidth, source, finished = true) { if (!this.resizeCols || !this.resizeRatios) { return; } const initialValues = { columnsToResize: this.resizeCols, resizeStartWidth: this.resizeStartWidth, resizeRatios: this.resizeRatios, groupAfterColumns: this.resizeTakeFromCols, groupAfterStartWidth: this.resizeTakeFromStartWidth, groupAfterRatios: this.resizeTakeFromRatios }; this.resizeColumns(initialValues, totalWidth, source, finished); } resizeColumns(initialValues, totalWidth, source, finished = true) { const { columnsToResize, resizeStartWidth, resizeRatios, groupAfterColumns, groupAfterStartWidth, groupAfterRatios } = initialValues; const resizeSets = []; resizeSets.push({ columns: columnsToResize, ratios: resizeRatios, width: totalWidth }); if (groupAfterColumns) { const diff = totalWidth - resizeStartWidth; resizeSets.push({ columns: groupAfterColumns, ratios: groupAfterRatios, width: groupAfterStartWidth - diff }); } this.beans.colResize?.resizeColumnSets({ resizeSets, finished, source }); if (finished) { this.toggleColumnResizing(false); } } toggleColumnResizing(resizing) { this.comp.toggleCss("ag-column-resizing", resizing); } getColumnsToResize() { const leafCols = this.columnGroup.getDisplayedLeafColumns(); return leafCols.filter((col) => col.isResizable()); } normaliseDragChange(dragChange) { let result = dragChange; if (this.gos.get("enableRtl")) { if (this.pinned !== "left") { result *= -1; } } else if (this.pinned === "right") { result *= -1; } return result; } destroy() { super.destroy(); this.resizeCols = undefined; this.resizeRatios = undefined; this.resizeTakeFromCols = undefined; this.resizeTakeFromRatios = undefined; } }; var ResizeFeature = class extends BeanStub { constructor(pinned, column, eResize, comp, ctrl) { super(); this.pinned = pinned; this.column = column; this.eResize = eResize; this.comp = comp; this.ctrl = ctrl; } postConstruct() { const destroyResizeFuncs = []; let canResize; let canAutosize; const addResize = () => { _setDisplayed(this.eResize, canResize); if (!canResize) { return; } const { horizontalResizeSvc, colAutosize } = this.beans; const finishedWithResizeFunc = horizontalResizeSvc.addResizeBar({ eResizeBar: this.eResize, onResizeStart: this.onResizeStart.bind(this), onResizing: this.onResizing.bind(this, false), onResizeEnd: this.onResizing.bind(this, true) }); destroyResizeFuncs.push(finishedWithResizeFunc); if (canAutosize && colAutosize) { destroyResizeFuncs.push(colAutosize.addColumnAutosizeListeners(this.eResize, this.column)); } }; const removeResize = () => { for (const f of destroyResizeFuncs) { f(); } destroyResizeFuncs.length = 0; }; const refresh = () => { const resize = this.column.isResizable(); const autoSize = !this.gos.get("suppressAutoSize") && !this.column.getColDef().suppressAutoSize; const propertyChange = resize !== canResize || autoSize !== canAutosize; if (propertyChange) { canResize = resize; canAutosize = autoSize; removeResize(); addResize(); } }; refresh(); this.addDestroyFunc(removeResize); this.ctrl.setRefreshFunction("resize", refresh); } onResizing(finished, resizeAmount) { const { column: key, lastResizeAmount, resizeStartWidth, beans } = this; const resizeAmountNormalised = this.normaliseResizeAmount(resizeAmount); const newWidth = resizeStartWidth + resizeAmountNormalised; const columnWidths = [{ key, newWidth }]; const { pinnedCols, ctrlsSvc, colResize } = beans; if (this.column.getPinned()) { const leftWidth = pinnedCols?.leftWidth ?? 0; const rightWidth = pinnedCols?.rightWidth ?? 0; const bodyWidth = _getInnerWidth(ctrlsSvc.getGridBodyCtrl().eBodyViewport) - 50; if (leftWidth + rightWidth + (resizeAmountNormalised - lastResizeAmount) > bodyWidth) { return; } } this.lastResizeAmount = resizeAmountNormalised; colResize?.setColumnWidths(columnWidths, this.resizeWithShiftKey, finished, "uiColumnResized"); if (finished) { this.toggleColumnResizing(false); } } onResizeStart(shiftKey) { this.resizeStartWidth = this.column.getActualWidth(); this.lastResizeAmount = 0; this.resizeWithShiftKey = shiftKey; this.toggleColumnResizing(true); } toggleColumnResizing(resizing) { this.column.resizing = resizing; this.comp.toggleCss("ag-column-resizing", resizing); } normaliseResizeAmount(dragChange) { let result = dragChange; const notPinningLeft = this.pinned !== "left"; const pinningRight = this.pinned === "right"; if (this.gos.get("enableRtl")) { if (notPinningLeft) { result *= -1; } } else if (pinningRight) { result *= -1; } return result; } }; var ColumnResizeService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colResize"; } setColumnWidths(columnWidths, shiftKey, finished, source) { const sets = []; const { colModel, gos, visibleCols } = this.beans; for (const columnWidth of columnWidths) { const col = colModel.getColDefCol(columnWidth.key) || colModel.getCol(columnWidth.key); if (!col) { continue; } sets.push({ width: columnWidth.newWidth, ratios: [1], columns: [col] }); const defaultIsShift = gos.get("colResizeDefault") === "shift"; if (defaultIsShift) { shiftKey = !shiftKey; } if (shiftKey) { const otherCol = visibleCols.getColAfter(col); if (!otherCol) { continue; } const widthDiff = col.getActualWidth() - columnWidth.newWidth; const otherColWidth = otherCol.getActualWidth() + widthDiff; sets.push({ width: otherColWidth, ratios: [1], columns: [otherCol] }); } } if (sets.length === 0) { return; } this.resizeColumnSets({ resizeSets: sets, finished, source }); } resizeColumnSets(params) { const { resizeSets, finished, source } = params; const passMinMaxCheck = !resizeSets || resizeSets.every((columnResizeSet) => checkMinAndMaxWidthsForSet(columnResizeSet)); if (!passMinMaxCheck) { if (finished) { const columns = resizeSets && resizeSets.length > 0 ? resizeSets[0].columns : null; dispatchColumnResizedEvent(this.eventSvc, columns, finished, source); } return; } const changedCols = []; const allResizedCols = []; for (const set of resizeSets) { const { width, columns, ratios } = set; const newWidths = {}; const finishedCols = {}; for (const col of columns) { allResizedCols.push(col); } let finishedColsGrew = true; let loopCount = 0; while (finishedColsGrew) { loopCount++; if (loopCount > 1000) { _error(31); break; } finishedColsGrew = false; const subsetCols = []; let subsetRatioTotal = 0; let pixelsToDistribute = width; columns.forEach((col, index) => { const thisColFinished = finishedCols[col.getId()]; if (thisColFinished) { pixelsToDistribute -= newWidths[col.getId()]; } else { subsetCols.push(col); const ratioThisCol = ratios[index]; subsetRatioTotal += ratioThisCol; } }); const ratioScale = 1 / subsetRatioTotal; subsetCols.forEach((col, index) => { const lastCol = index === subsetCols.length - 1; let colNewWidth; if (lastCol) { colNewWidth = pixelsToDistribute; } else { colNewWidth = Math.round(ratios[index] * width * ratioScale); pixelsToDistribute -= colNewWidth; } const minWidth = col.getMinWidth(); const maxWidth = col.getMaxWidth(); if (colNewWidth < minWidth) { colNewWidth = minWidth; finishedCols[col.getId()] = true; finishedColsGrew = true; } else if (maxWidth > 0 && colNewWidth > maxWidth) { colNewWidth = maxWidth; finishedCols[col.getId()] = true; finishedColsGrew = true; } newWidths[col.getId()] = colNewWidth; }); } for (const col of columns) { const newWidth = newWidths[col.getId()]; const actualWidth = col.getActualWidth(); if (actualWidth !== newWidth) { col.setActualWidth(newWidth, source); changedCols.push(col); } } } const atLeastOneColChanged = changedCols.length > 0; let flexedCols = []; if (atLeastOneColChanged) { const { colFlex, visibleCols, colViewport } = this.beans; flexedCols = colFlex?.refreshFlexedColumns({ resizingCols: allResizedCols, skipSetLeft: true }) ?? []; visibleCols.setLeftValues(source); visibleCols.updateBodyWidths(); colViewport.checkViewportColumns(); } const colsForEvent = allResizedCols.concat(flexedCols); if (atLeastOneColChanged || finished) { dispatchColumnResizedEvent(this.eventSvc, colsForEvent, finished, source, flexedCols); } } resizeHeader(column, delta, shiftKey) { if (!column.isResizable()) { return; } const actualWidth = column.getActualWidth(); const minWidth = column.getMinWidth(); const maxWidth = column.getMaxWidth(); const newWidth = Math.min(Math.max(actualWidth + delta, minWidth), maxWidth); this.setColumnWidths([{ key: column, newWidth }], shiftKey, true, "uiColumnResized"); } createResizeFeature(pinned, column, eResize, comp, ctrl) { return new ResizeFeature(pinned, column, eResize, comp, ctrl); } createGroupResizeFeature(comp, eResize, pinned, columnGroup) { return new GroupResizeFeature(comp, eResize, pinned, columnGroup); } }; function checkMinAndMaxWidthsForSet(columnResizeSet) { const { columns, width } = columnResizeSet; let minWidthAccumulated = 0; let maxWidthAccumulated = 0; let maxWidthActive = true; for (const col of columns) { const minWidth = col.getMinWidth(); minWidthAccumulated += minWidth || 0; const maxWidth = col.getMaxWidth(); if (maxWidth > 0) { maxWidthAccumulated += maxWidth; } else { maxWidthActive = false; } } const minWidthPasses = width >= minWidthAccumulated; const maxWidthPasses = !maxWidthActive || width <= maxWidthAccumulated; return minWidthPasses && maxWidthPasses; } var ColumnResizeModule = { moduleName: "ColumnResize", version: VERSION, beans: [ColumnResizeService], apiFunctions: { setColumnWidths }, dependsOn: [HorizontalResizeModule, AutoWidthModule] }; var GroupWidthFeature = class extends BeanStub { constructor(comp, columnGroup) { super(); this.removeChildListenersFuncs = []; this.columnGroup = columnGroup; this.comp = comp; } postConstruct() { this.addListenersToChildrenColumns(); this.addManagedListeners(this.columnGroup, { displayedChildrenChanged: this.onDisplayedChildrenChanged.bind(this) }); this.onWidthChanged(); this.addDestroyFunc(this.removeListenersOnChildrenColumns.bind(this)); } addListenersToChildrenColumns() { this.removeListenersOnChildrenColumns(); const widthChangedListener = this.onWidthChanged.bind(this); for (const column of this.columnGroup.getLeafColumns()) { column.__addEventListener("widthChanged", widthChangedListener); column.__addEventListener("visibleChanged", widthChangedListener); this.removeChildListenersFuncs.push(() => { column.__removeEventListener("widthChanged", widthChangedListener); column.__removeEventListener("visibleChanged", widthChangedListener); }); } } removeListenersOnChildrenColumns() { for (const func of this.removeChildListenersFuncs) { func(); } this.removeChildListenersFuncs = []; } onDisplayedChildrenChanged() { this.addListenersToChildrenColumns(); this.onWidthChanged(); } onWidthChanged() { const columnWidth = this.columnGroup.getActualWidth(); this.comp.setWidth(`${columnWidth}px`); this.comp.toggleCss("ag-hidden", columnWidth === 0); } }; var HeaderGroupCellCtrl = class extends AbstractHeaderCellCtrl { constructor() { super(...arguments); this.onSuppressColMoveChange = () => { if (!this.isAlive() || this.isSuppressMoving()) { this.removeDragSource(); } else if (!this.dragSource) { this.setDragSource(this.eGui); } }; } wireComp(comp, eGui, eResize, eHeaderCompWrapper, compBean) { const { column, beans } = this; const { context, colNames, colHover, rangeSvc, colResize } = beans; this.comp = comp; compBean = setupCompBean(this, context, compBean); this.setGui(eGui, compBean); this.displayName = colNames.getDisplayNameForColumnGroup(column, "header"); this.refreshHeaderStyles(); this.addClasses(); this.setupMovingCss(compBean); this.setupExpandable(compBean); this.setupTooltip(); this.refreshAnnouncement(); this.setupAutoHeight({ wrapperElement: eHeaderCompWrapper, compBean }); this.setupUserComp(); this.addHeaderMouseListeners(compBean, eHeaderCompWrapper); this.addManagedPropertyListener("groupHeaderHeight", this.refreshMaxHeaderHeight.bind(this)); this.refreshMaxHeaderHeight(); const pinned = this.rowCtrl.pinned; const leafCols = column.getProvidedColumnGroup().getLeafColumns(); colHover?.createHoverFeature(compBean, leafCols, eGui); rangeSvc?.createRangeHighlightFeature(compBean, column, comp); compBean.createManagedBean(new SetLeftFeature(column, eGui, beans)); compBean.createManagedBean(new GroupWidthFeature(comp, column)); if (colResize) { this.resizeFeature = compBean.createManagedBean(colResize.createGroupResizeFeature(comp, eResize, pinned, column)); } else { comp.setResizableDisplayed(false); } compBean.createManagedBean(new ManagedFocusFeature(eGui, { shouldStopEventPropagation: this.shouldStopEventPropagation.bind(this), onTabKeyDown: () => { return; }, handleKeyDown: this.handleKeyDown.bind(this), onFocusIn: this.onFocusIn.bind(this) })); this.addHighlightListeners(compBean, leafCols); this.addManagedEventListeners({ cellSelectionChanged: () => this.refreshAnnouncement() }); compBean.addManagedPropertyListener("suppressMovableColumns", this.onSuppressColMoveChange); this.addResizeAndMoveKeyboardListeners(compBean); compBean.addDestroyFunc(() => this.clearComponent()); } getHeaderClassParams() { const { column, beans } = this; const colDef = column.getDefinition(); return _addGridCommonParams(beans.gos, { colDef, columnGroup: column, floatingFilter: false }); } refreshMaxHeaderHeight() { const { gos, comp } = this; const groupHeaderHeight = gos.get("groupHeaderHeight"); if (groupHeaderHeight != null) { if (groupHeaderHeight === 0) { comp.setHeaderWrapperHidden(true); } else { comp.setHeaderWrapperMaxHeight(groupHeaderHeight); } } else { comp.setHeaderWrapperHidden(false); comp.setHeaderWrapperMaxHeight(null); } } addHighlightListeners(compBean, columns) { if (!this.beans.gos.get("suppressMoveWhenColumnDragging")) { return; } for (const column of columns) { compBean.addManagedListeners(column, { headerHighlightChanged: this.onLeafColumnHighlightChanged.bind(this, column) }); } } onLeafColumnHighlightChanged(column) { const displayedColumns = this.column.getDisplayedLeafColumns(); const isFirst = displayedColumns[0] === column; const isLast = _last(displayedColumns) === column; if (!isFirst && !isLast) { return; } const highlighted = column.getHighlighted(); const isColumnMoveAtThisLevel = !!this.rowCtrl.getHeaderCellCtrls().find((ctrl) => { return ctrl.column.isMoving(); }); let beforeOn = false; let afterOn = false; if (isColumnMoveAtThisLevel) { const isRtl = this.beans.gos.get("enableRtl"); const isHighlightAfter = highlighted === 1; const isHighlightBefore = highlighted === 0; if (isFirst) { if (isRtl) { afterOn = isHighlightAfter; } else { beforeOn = isHighlightBefore; } } if (isLast) { if (isRtl) { beforeOn = isHighlightBefore; } else { afterOn = isHighlightAfter; } } } this.comp.toggleCss("ag-header-highlight-before", beforeOn); this.comp.toggleCss("ag-header-highlight-after", afterOn); } resizeHeader(delta, shiftKey) { const { resizeFeature } = this; if (!resizeFeature) { return; } const initialValues = resizeFeature.getInitialValues(shiftKey); resizeFeature.resizeColumns(initialValues, initialValues.resizeStartWidth + delta, "uiColumnResized", true); } resizeLeafColumnsToFit(source) { this.resizeFeature?.resizeLeafColumnsToFit(source); } setupUserComp() { const { colGroupSvc, userCompFactory, gos, enterpriseMenuFactory } = this.beans; const columnGroup = this.column; const providedColumnGroup = columnGroup.getProvidedColumnGroup(); const params = _addGridCommonParams(gos, { displayName: this.displayName, columnGroup, setExpanded: (expanded) => { colGroupSvc.setColumnGroupOpened(providedColumnGroup, expanded, "gridInitializing"); }, setTooltip: (value, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); this.setupTooltip(value, shouldDisplayTooltip); }, showColumnMenu: (buttonElement, onClosedCallback) => enterpriseMenuFactory?.showMenuAfterButtonClick(providedColumnGroup, buttonElement, "columnMenu", onClosedCallback), showColumnMenuAfterMouseClick: (mouseEvent, onClosedCallback) => enterpriseMenuFactory?.showMenuAfterMouseEvent(providedColumnGroup, mouseEvent, "columnMenu", onClosedCallback), eGridHeader: this.eGui }); const compDetails = _getHeaderGroupCompDetails(userCompFactory, params); if (compDetails) { this.comp.setUserCompDetails(compDetails); } } addHeaderMouseListeners(compBean, eHeaderCompWrapper) { const { column, comp, beans: { rangeSvc }, gos } = this; const listener = (e) => this.handleMouseOverChange(e.type === "mouseenter"); const clickListener = () => this.dispatchColumnMouseEvent("columnHeaderClicked", column.getProvidedColumnGroup()); const contextMenuListener = (event) => this.handleContextMenuMouseEvent(event, undefined, column.getProvidedColumnGroup()); compBean.addManagedListeners(this.eGui, { mouseenter: listener, mouseleave: listener, click: clickListener, contextmenu: contextMenuListener }); comp.toggleCss("ag-header-group-cell-selectable", _getEnableColumnSelection(gos)); const mouseListener = rangeSvc?.createHeaderGroupCellMouseListenerFeature(this.column, eHeaderCompWrapper); if (mouseListener) { this.createManagedBean(mouseListener); } } handleMouseOverChange(isMouseOver) { this.eventSvc.dispatchEvent({ type: isMouseOver ? "columnHeaderMouseOver" : "columnHeaderMouseLeave", column: this.column.getProvidedColumnGroup() }); } setupTooltip(value, shouldDisplayTooltip) { this.tooltipFeature = this.beans.tooltipSvc?.setupHeaderGroupTooltip(this.tooltipFeature, this, value, shouldDisplayTooltip); } setupExpandable(compBean) { const providedColGroup = this.column.getProvidedColumnGroup(); this.refreshExpanded(); const listener = this.refreshExpanded.bind(this); compBean.addManagedListeners(providedColGroup, { expandedChanged: listener, expandableChanged: listener }); } refreshExpanded() { const { column } = this; this.expandable = column.isExpandable(); const expanded = column.isExpanded(); if (this.expandable) { this.comp.setAriaExpanded(expanded ? "true" : "false"); } else { this.comp.setAriaExpanded(undefined); } this.refreshHeaderStyles(); } addClasses() { const { column } = this; const colGroupDef = column.getColGroupDef(); const classes = _getHeaderClassesFromColDef(colGroupDef, this.gos, null, column); if (column.isPadding()) { classes.push("ag-header-group-cell-no-group"); const leafCols = column.getLeafColumns(); if (leafCols.every((col) => col.isSpanHeaderHeight())) { classes.push("ag-header-span-height"); } } else { classes.push("ag-header-group-cell-with-group"); if (colGroupDef?.wrapHeaderText) { classes.push("ag-header-cell-wrap-text"); } } for (const c of classes) { this.comp.toggleCss(c, true); } } setupMovingCss(compBean) { const { column } = this; const providedColumnGroup = column.getProvidedColumnGroup(); const leafColumns = providedColumnGroup.getLeafColumns(); const listener = () => this.comp.toggleCss("ag-header-cell-moving", column.isMoving()); for (const col of leafColumns) { compBean.addManagedListeners(col, { movingChanged: listener }); } listener(); } onFocusIn(e) { if (!this.eGui.contains(e.relatedTarget)) { this.focusThis(); this.announceAriaDescription(); } } handleKeyDown(e) { super.handleKeyDown(e); const wrapperHasFocus = this.getWrapperHasFocus(); if (!wrapperHasFocus) { return; } const { column, expandable, gos, beans } = this; const enableColumnSelection = _getEnableColumnSelection(gos); if (e.key != KeyCode.ENTER) { return; } if (enableColumnSelection && !e.altKey) { beans.rangeSvc?.handleColumnSelection(column, e); } else if (expandable) { const newExpandedValue = !column.isExpanded(); beans.colGroupSvc.setColumnGroupOpened(column.getProvidedColumnGroup(), newExpandedValue, "uiColumnExpanded"); } } refreshAnnouncement() { let description; const { gos } = this; const enableColumnSelection = _getEnableColumnSelection(gos); if (enableColumnSelection) { const translate = this.getLocaleTextFunc(); description = translate("ariaColumnGroupCellSelection", "Press Enter to toggle selection for all visible cells in this column group"); } this.ariaAnnouncement = description; } announceAriaDescription() { const { beans, eGui, ariaAnnouncement } = this; if (!ariaAnnouncement || !eGui.contains(_getActiveDomElement(beans))) { return; } beans.ariaAnnounce?.announceValue(ariaAnnouncement, "columnHeader"); } setDragSource(eHeaderGroup) { if (!this.isAlive() || this.isSuppressMoving()) { return; } this.removeDragSource(); if (!eHeaderGroup) { return; } this.dragSource = this.beans.colMoves?.setDragSourceForHeader(eHeaderGroup, this.column, this.displayName) ?? null; } isSuppressMoving() { return this.gos.get("suppressMovableColumns") || this.column.getLeafColumns().some((column) => column.getColDef().suppressMovable || column.getColDef().lockPosition); } destroy() { this.tooltipFeature = this.destroyBean(this.tooltipFeature); super.destroy(); } }; function setColumnGroupOpened(beans, group, newValue) { beans.colGroupSvc?.setColumnGroupOpened(group, newValue, "api"); } function getColumnGroup(beans, name, instanceId) { return beans.colGroupSvc?.getColumnGroup(name, instanceId) ?? null; } function getProvidedColumnGroup(beans, name) { return beans.colGroupSvc?.getProvidedColGroup(name) ?? null; } function getDisplayNameForColumnGroup(beans, columnGroup, location) { return beans.colNames.getDisplayNameForColumnGroup(columnGroup, location) || ""; } function getColumnGroupState(beans) { return beans.colGroupSvc?.getColumnGroupState() ?? []; } function setColumnGroupState(beans, stateItems) { beans.colGroupSvc?.setColumnGroupState(stateItems, "api"); } function resetColumnGroupState(beans) { beans.colGroupSvc?.resetColumnGroupState("api"); } function getLeftDisplayedColumnGroups(beans) { return beans.visibleCols.treeLeft; } function getCenterDisplayedColumnGroups(beans) { return beans.visibleCols.treeCenter; } function getRightDisplayedColumnGroups(beans) { return beans.visibleCols.treeRight; } function getAllDisplayedColumnGroups(beans) { return beans.visibleCols.getAllTrees(); } var GroupInstanceIdCreator = class { constructor() { this.existingIds = {}; } getInstanceIdForKey(key) { const lastResult = this.existingIds[key]; let result; if (typeof lastResult !== "number") { result = 0; } else { result = lastResult + 1; } this.existingIds[key] = result; return result; } }; function _removeAllFromUnorderedArray(array, toRemove) { for (let i = 0;i < toRemove.length; i++) { const index = array.indexOf(toRemove[i]); if (index >= 0) { array[index] = array[array.length - 1]; array.pop(); } } } var VisibleColsService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "visibleCols"; this.colsAndGroupsMap = {}; this.leftCols = []; this.rightCols = []; this.centerCols = []; this.allCols = []; this.headerGroupRowCount = 0; this.bodyWidth = 0; this.leftWidth = 0; this.rightWidth = 0; this.isBodyWidthDirty = true; } refresh(source, skipTreeBuild = false) { const { colFlex, colModel, colGroupSvc, colViewport, selectionColSvc } = this.beans; if (!skipTreeBuild) { this.buildTrees(colModel, colGroupSvc); } colGroupSvc?.updateOpenClosedVisibility(); this.leftCols = pickDisplayedCols(this.treeLeft); this.centerCols = pickDisplayedCols(this.treeCenter); this.rightCols = pickDisplayedCols(this.treeRight); selectionColSvc?.refreshVisibility(this.leftCols, this.centerCols, this.rightCols); this.joinColsAriaOrder(colModel); this.joinCols(); this.headerGroupRowCount = this.getHeaderRowCount(); this.setLeftValues(source); this.autoHeightCols = this.allCols.filter((col) => col.isAutoHeight()); colFlex?.refreshFlexedColumns(); this.updateBodyWidths(); this.setFirstRightAndLastLeftPinned(colModel, this.leftCols, this.rightCols, source); colViewport.checkViewportColumns(false); this.eventSvc.dispatchEvent({ type: "displayedColumnsChanged", source }); } getHeaderRowCount() { if (!this.gos.get("hidePaddedHeaderRows")) { return this.beans.colModel.cols.treeDepth; } let headerGroupRowCount = 0; for (const col of this.allCols) { let parent = col.getParent(); while (parent) { if (!parent.isPadding()) { const level = parent.getProvidedColumnGroup().getLevel() + 1; if (level > headerGroupRowCount) { headerGroupRowCount = level; } break; } parent = parent.getParent(); } } return headerGroupRowCount; } updateBodyWidths() { const newBodyWidth = getWidthOfColsInList(this.centerCols); const newLeftWidth = getWidthOfColsInList(this.leftCols); const newRightWidth = getWidthOfColsInList(this.rightCols); this.isBodyWidthDirty = this.bodyWidth !== newBodyWidth; const atLeastOneChanged = this.bodyWidth !== newBodyWidth || this.leftWidth !== newLeftWidth || this.rightWidth !== newRightWidth; if (atLeastOneChanged) { this.bodyWidth = newBodyWidth; this.leftWidth = newLeftWidth; this.rightWidth = newRightWidth; this.eventSvc.dispatchEvent({ type: "columnContainerWidthChanged" }); this.eventSvc.dispatchEvent({ type: "displayedColumnsWidthChanged" }); } } setLeftValues(source) { this.setLeftValuesOfCols(source); this.setLeftValuesOfGroups(); } setFirstRightAndLastLeftPinned(colModel, leftCols, rightCols, source) { let lastLeft; let firstRight; if (this.gos.get("enableRtl")) { lastLeft = leftCols ? leftCols[0] : null; firstRight = rightCols ? _last(rightCols) : null; } else { lastLeft = leftCols ? _last(leftCols) : null; firstRight = rightCols ? rightCols[0] : null; } for (const col of colModel.getCols()) { col.setLastLeftPinned(col === lastLeft, source); col.setFirstRightPinned(col === firstRight, source); } } buildTrees(colModel, columnGroupSvc) { const cols = colModel.getColsToShow(); const leftCols = cols.filter((col) => col.getPinned() == "left"); const rightCols = cols.filter((col) => col.getPinned() == "right"); const centerCols = cols.filter((col) => col.getPinned() != "left" && col.getPinned() != "right"); const idCreator = new GroupInstanceIdCreator; const createGroups = (params) => { return columnGroupSvc ? columnGroupSvc.createColumnGroups(params) : params.columns; }; this.treeLeft = createGroups({ columns: leftCols, idCreator, pinned: "left", oldDisplayedGroups: this.treeLeft }); this.treeRight = createGroups({ columns: rightCols, idCreator, pinned: "right", oldDisplayedGroups: this.treeRight }); this.treeCenter = createGroups({ columns: centerCols, idCreator, pinned: null, oldDisplayedGroups: this.treeCenter }); this.updateColsAndGroupsMap(); } clear() { this.leftCols = []; this.rightCols = []; this.centerCols = []; this.allCols = []; this.ariaOrderColumns = []; } joinColsAriaOrder(colModel) { const allColumns = colModel.getCols(); const pinnedLeft = []; const center = []; const pinnedRight = []; for (const col of allColumns) { const pinned = col.getPinned(); if (!pinned) { center.push(col); } else if (pinned === true || pinned === "left") { pinnedLeft.push(col); } else { pinnedRight.push(col); } } this.ariaOrderColumns = pinnedLeft.concat(center).concat(pinnedRight); } getAriaColIndex(colOrGroup) { let col; if (isColumnGroup(colOrGroup)) { col = colOrGroup.getLeafColumns()[0]; } else { col = colOrGroup; } return this.ariaOrderColumns.indexOf(col) + 1; } setLeftValuesOfGroups() { for (const columns of [this.treeLeft, this.treeRight, this.treeCenter]) { for (const column of columns) { if (isColumnGroup(column)) { const columnGroup = column; columnGroup.checkLeft(); } } } } setLeftValuesOfCols(source) { const { colModel } = this.beans; const primaryCols = colModel.getColDefCols(); if (!primaryCols) { return; } const allColumns = colModel.getCols().slice(0); const doingRtl = this.gos.get("enableRtl"); for (const columns of [this.leftCols, this.rightCols, this.centerCols]) { if (doingRtl) { let left = getWidthOfColsInList(columns); for (const column of columns) { left -= column.getActualWidth(); column.setLeft(left, source); } } else { let left = 0; for (const column of columns) { column.setLeft(left, source); left += column.getActualWidth(); } } _removeAllFromUnorderedArray(allColumns, columns); } for (const column of allColumns) { column.setLeft(null, source); } } joinCols() { if (this.gos.get("enableRtl")) { this.allCols = this.rightCols.concat(this.centerCols).concat(this.leftCols); } else { this.allCols = this.leftCols.concat(this.centerCols).concat(this.rightCols); } } getAllTrees() { if (this.treeLeft && this.treeRight && this.treeCenter) { return this.treeLeft.concat(this.treeCenter).concat(this.treeRight); } return null; } isColDisplayed(column) { return this.allCols.indexOf(column) >= 0; } getLeftColsForRow(rowNode) { const { leftCols, beans: { colModel } } = this; const colSpanActive = colModel.colSpanActive; if (!colSpanActive) { return leftCols; } return this.getColsForRow(rowNode, leftCols); } getRightColsForRow(rowNode) { const { rightCols, beans: { colModel } } = this; const colSpanActive = colModel.colSpanActive; if (!colSpanActive) { return rightCols; } return this.getColsForRow(rowNode, rightCols); } getColsForRow(rowNode, displayedColumns, filterCallback, emptySpaceBeforeColumn) { const result = []; let lastConsideredCol = null; for (let i = 0;i < displayedColumns.length; i++) { const col = displayedColumns[i]; const maxAllowedColSpan = displayedColumns.length - i; const colSpan = Math.min(col.getColSpan(rowNode), maxAllowedColSpan); const columnsToCheckFilter = [col]; if (colSpan > 1) { const colsToRemove = colSpan - 1; for (let j = 1;j <= colsToRemove; j++) { columnsToCheckFilter.push(displayedColumns[i + j]); } i += colsToRemove; } let filterPasses; if (filterCallback) { filterPasses = false; for (const colForFilter of columnsToCheckFilter) { if (filterCallback(colForFilter)) { filterPasses = true; } } } else { filterPasses = true; } if (filterPasses) { if (result.length === 0 && lastConsideredCol) { const gapBeforeColumn = emptySpaceBeforeColumn ? emptySpaceBeforeColumn(col) : false; if (gapBeforeColumn) { result.push(lastConsideredCol); } } result.push(col); } lastConsideredCol = col; } return result; } getContainerWidth(pinned) { switch (pinned) { case "left": return this.leftWidth; case "right": return this.rightWidth; default: return this.bodyWidth; } } getColBefore(col) { const allDisplayedColumns = this.allCols; const oldIndex = allDisplayedColumns.indexOf(col); if (oldIndex > 0) { return allDisplayedColumns[oldIndex - 1]; } return null; } isPinningLeft() { return this.leftCols.length > 0; } isPinningRight() { return this.rightCols.length > 0; } updateColsAndGroupsMap() { this.colsAndGroupsMap = {}; const func = (child) => { this.colsAndGroupsMap[child.getUniqueId()] = child; }; depthFirstAllColumnTreeSearch(this.treeCenter, false, func); depthFirstAllColumnTreeSearch(this.treeLeft, false, func); depthFirstAllColumnTreeSearch(this.treeRight, false, func); } isVisible(item) { const fromMap = this.colsAndGroupsMap[item.getUniqueId()]; return fromMap === item; } getFirstColumn() { const isRtl = this.gos.get("enableRtl"); const queryOrder = ["leftCols", "centerCols", "rightCols"]; if (isRtl) { queryOrder.reverse(); } for (let i = 0;i < queryOrder.length; i++) { const container = this[queryOrder[i]]; if (container.length) { return isRtl ? _last(container) : container[0]; } } return null; } getColAfter(col) { const allDisplayedColumns = this.allCols; const oldIndex = allDisplayedColumns.indexOf(col); if (oldIndex < allDisplayedColumns.length - 1) { return allDisplayedColumns[oldIndex + 1]; } return null; } getColsLeftWidth() { return getWidthOfColsInList(this.leftCols); } getDisplayedColumnsRightWidth() { return getWidthOfColsInList(this.rightCols); } isColAtEdge(col, edge) { const allColumns = this.allCols; if (!allColumns.length) { return false; } const isFirst = edge === "first"; let columnToCompare; if (isColumnGroup(col)) { const leafColumns = col.getDisplayedLeafColumns(); if (!leafColumns.length) { return false; } columnToCompare = isFirst ? leafColumns[0] : _last(leafColumns); } else { columnToCompare = col; } return (isFirst ? allColumns[0] : _last(allColumns)) === columnToCompare; } }; function depthFirstAllColumnTreeSearch(tree, useDisplayedChildren, callback) { if (!tree) { return; } for (let i = 0;i < tree.length; i++) { const child = tree[i]; if (isColumnGroup(child)) { const childTree = useDisplayedChildren ? child.getDisplayedChildren() : child.getChildren(); depthFirstAllColumnTreeSearch(childTree, useDisplayedChildren, callback); } callback(child); } } function pickDisplayedCols(tree) { const res = []; depthFirstAllColumnTreeSearch(tree, true, (child) => { if (isColumn(child)) { res.push(child); } }); return res; } var ColumnGroupService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colGroupSvc"; } getColumnGroupState() { const columnGroupState = []; const gridBalancedTree = this.beans.colModel.getColTree(); depthFirstOriginalTreeSearch(null, gridBalancedTree, (node) => { if (isProvidedColumnGroup(node)) { columnGroupState.push({ groupId: node.getGroupId(), open: node.isExpanded() }); } }); return columnGroupState; } resetColumnGroupState(source) { const primaryColumnTree = this.beans.colModel.getColDefColTree(); if (!primaryColumnTree) { return; } const stateItems = []; depthFirstOriginalTreeSearch(null, primaryColumnTree, (child) => { if (isProvidedColumnGroup(child)) { const colGroupDef = child.getColGroupDef(); const groupState = { groupId: child.getGroupId(), open: !colGroupDef ? undefined : colGroupDef.openByDefault }; stateItems.push(groupState); } }); this.setColumnGroupState(stateItems, source); } setColumnGroupState(stateItems, source) { const { colModel, colAnimation, visibleCols, eventSvc } = this.beans; const gridBalancedTree = colModel.getColTree(); if (!gridBalancedTree.length) { return; } colAnimation?.start(); const impactedGroups = []; for (const stateItem of stateItems) { const groupKey = stateItem.groupId; const newValue = stateItem.open; const providedColumnGroup = this.getProvidedColGroup(groupKey); if (!providedColumnGroup) { continue; } if (providedColumnGroup.isExpanded() === newValue) { continue; } providedColumnGroup.setExpanded(newValue); impactedGroups.push(providedColumnGroup); } visibleCols.refresh(source, true); if (impactedGroups.length) { eventSvc.dispatchEvent({ type: "columnGroupOpened", columnGroup: impactedGroups.length === 1 ? impactedGroups[0] : undefined, columnGroups: impactedGroups }); } colAnimation?.finish(); } setColumnGroupOpened(key, newValue, source) { let keyAsString; if (isProvidedColumnGroup(key)) { keyAsString = key.getId(); } else { keyAsString = key || ""; } this.setColumnGroupState([{ groupId: keyAsString, open: newValue }], source); } getProvidedColGroup(key) { let res = null; depthFirstOriginalTreeSearch(null, this.beans.colModel.getColTree(), (node) => { if (isProvidedColumnGroup(node)) { if (node.getId() === key) { res = node; } } }); return res; } getGroupAtDirection(columnGroup, direction) { const requiredLevel = columnGroup.getProvidedColumnGroup().getLevel() + columnGroup.getPaddingLevel(); const colGroupLeafColumns = columnGroup.getDisplayedLeafColumns(); const col = direction === "After" ? _last(colGroupLeafColumns) : colGroupLeafColumns[0]; const getDisplayColMethod = `getCol${direction}`; while (true) { const column = this.beans.visibleCols[getDisplayColMethod](col); if (!column) { return null; } const groupPointer = this.getColGroupAtLevel(column, requiredLevel); if (groupPointer !== columnGroup) { return groupPointer; } } } getColGroupAtLevel(column, level) { let groupPointer = column.getParent(); let originalGroupLevel; let groupPointerLevel; while (true) { const groupPointerProvidedColumnGroup = groupPointer.getProvidedColumnGroup(); originalGroupLevel = groupPointerProvidedColumnGroup.getLevel(); groupPointerLevel = groupPointer.getPaddingLevel(); if (originalGroupLevel + groupPointerLevel <= level) { break; } groupPointer = groupPointer.getParent(); } return groupPointer; } updateOpenClosedVisibility() { const allColumnGroups = this.beans.visibleCols.getAllTrees(); depthFirstAllColumnTreeSearch(allColumnGroups, false, (child) => { if (isColumnGroup(child)) { child.calculateDisplayedColumns(); } }); } getColumnGroup(colId, partId) { if (!colId) { return null; } if (isColumnGroup(colId)) { return colId; } const allColumnGroups = this.beans.visibleCols.getAllTrees(); const checkPartId = typeof partId === "number"; let result = null; depthFirstAllColumnTreeSearch(allColumnGroups, false, (child) => { if (isColumnGroup(child)) { const columnGroup = child; let matched; if (checkPartId) { matched = colId === columnGroup.getGroupId() && partId === columnGroup.getPartId(); } else { matched = colId === columnGroup.getGroupId(); } if (matched) { result = columnGroup; } } }); return result; } createColumnGroups(params) { const { columns, idCreator, pinned, oldDisplayedGroups, isStandaloneStructure } = params; const oldColumnsMapped = this.mapOldGroupsById(oldDisplayedGroups); const topLevelResultCols = []; let groupsOrColsAtCurrentLevel = columns; while (groupsOrColsAtCurrentLevel.length) { const currentlyIterating = groupsOrColsAtCurrentLevel; groupsOrColsAtCurrentLevel = []; let lastGroupedColIdx = 0; const createGroupToIndex = (to) => { const from = lastGroupedColIdx; lastGroupedColIdx = to; const previousNode = currentlyIterating[from]; const previousNodeProvided = isColumnGroup(previousNode) ? previousNode.getProvidedColumnGroup() : previousNode; const previousNodeParent = previousNodeProvided.getOriginalParent(); if (previousNodeParent == null) { for (let i = from;i < to; i++) { topLevelResultCols.push(currentlyIterating[i]); } return; } const newGroup = this.createColumnGroup(previousNodeParent, idCreator, oldColumnsMapped, pinned, isStandaloneStructure); for (let i = from;i < to; i++) { newGroup.addChild(currentlyIterating[i]); } groupsOrColsAtCurrentLevel.push(newGroup); }; for (let i = 1;i < currentlyIterating.length; i++) { const thisNode = currentlyIterating[i]; const thisNodeProvided = isColumnGroup(thisNode) ? thisNode.getProvidedColumnGroup() : thisNode; const thisNodeParent = thisNodeProvided.getOriginalParent(); const previousNode = currentlyIterating[lastGroupedColIdx]; const previousNodeProvided = isColumnGroup(previousNode) ? previousNode.getProvidedColumnGroup() : previousNode; const previousNodeParent = previousNodeProvided.getOriginalParent(); if (thisNodeParent !== previousNodeParent) { createGroupToIndex(i); } } if (lastGroupedColIdx < currentlyIterating.length) { createGroupToIndex(currentlyIterating.length); } } if (!isStandaloneStructure) { this.setupParentsIntoCols(topLevelResultCols, null); } return topLevelResultCols; } createProvidedColumnGroup(primaryColumns, colGroupDef, level, existingColumns, columnKeyCreator, existingGroups, source) { const groupId = columnKeyCreator.getUniqueKey(colGroupDef.groupId || null, null); const colGroupDefMerged = createMergedColGroupDef(this.beans, colGroupDef, groupId); const providedGroup = new AgProvidedColumnGroup(colGroupDefMerged, groupId, false, level); this.createBean(providedGroup); const existingGroupAndIndex = this.findExistingGroup(colGroupDef, existingGroups); if (existingGroupAndIndex) { existingGroups.splice(existingGroupAndIndex.idx, 1); } const existingGroup = existingGroupAndIndex?.group; if (existingGroup) { providedGroup.setExpanded(existingGroup.isExpanded()); } const children = _recursivelyCreateColumns(this.beans, colGroupDefMerged.children, level + 1, primaryColumns, existingColumns, columnKeyCreator, existingGroups, source); providedGroup.setChildren(children); return providedGroup; } balanceColumnTree(unbalancedTree, currentDepth, columnDepth, columnKeyCreator) { const result = []; for (let i = 0;i < unbalancedTree.length; i++) { const child = unbalancedTree[i]; if (isProvidedColumnGroup(child)) { const originalGroup = child; const newChildren = this.balanceColumnTree(originalGroup.getChildren(), currentDepth + 1, columnDepth, columnKeyCreator); originalGroup.setChildren(newChildren); result.push(originalGroup); } else { let firstPaddedGroup; let currentPaddedGroup; for (let j = currentDepth;j < columnDepth; j++) { const newColId = columnKeyCreator.getUniqueKey(null, null); const colGroupDefMerged = createMergedColGroupDef(this.beans, null, newColId); const paddedGroup = new AgProvidedColumnGroup(colGroupDefMerged, newColId, true, j); this.createBean(paddedGroup); if (currentPaddedGroup) { currentPaddedGroup.setChildren([paddedGroup]); } currentPaddedGroup = paddedGroup; if (!firstPaddedGroup) { firstPaddedGroup = currentPaddedGroup; } } if (firstPaddedGroup && currentPaddedGroup) { result.push(firstPaddedGroup); const hasGroups = unbalancedTree.some((leaf) => isProvidedColumnGroup(leaf)); if (hasGroups) { currentPaddedGroup.setChildren([child]); continue; } else { currentPaddedGroup.setChildren(unbalancedTree); break; } } result.push(child); } } return result; } findDepth(balancedColumnTree) { let depth = 0; let pointer = balancedColumnTree; while (pointer?.[0] && isProvidedColumnGroup(pointer[0])) { depth++; pointer = pointer[0].getChildren(); } return depth; } findMaxDepth(treeChildren, depth) { let maxDepthThisLevel = depth; for (let i = 0;i < treeChildren.length; i++) { const abstractColumn = treeChildren[i]; if (isProvidedColumnGroup(abstractColumn)) { const originalGroup = abstractColumn; const newDepth = this.findMaxDepth(originalGroup.getChildren(), depth + 1); if (maxDepthThisLevel < newDepth) { maxDepthThisLevel = newDepth; } } } return maxDepthThisLevel; } balanceTreeForAutoCols(autoCols, depth) { const tree = []; for (const col of autoCols) { let nextChild = col; for (let i = depth - 1;i >= 0; i--) { const autoGroup = new AgProvidedColumnGroup(null, `FAKE_PATH_${col.getId()}_${i}`, true, i); this.createBean(autoGroup); autoGroup.setChildren([nextChild]); nextChild.originalParent = autoGroup; nextChild = autoGroup; } if (depth === 0) { col.originalParent = null; } tree.push(nextChild); } return tree; } findExistingGroup(newGroupDef, existingGroups) { const newHasId = newGroupDef.groupId != null; if (!newHasId) { return; } for (let i = 0;i < existingGroups.length; i++) { const existingGroup = existingGroups[i]; const existingDef = existingGroup.getColGroupDef(); if (!existingDef) { continue; } if (existingGroup.getId() === newGroupDef.groupId) { return { idx: i, group: existingGroup }; } } return; } createColumnGroup(providedGroup, groupInstanceIdCreator, oldColumnsMapped, pinned, isStandaloneStructure) { const groupId = providedGroup.getGroupId(); const instanceId = groupInstanceIdCreator.getInstanceIdForKey(groupId); const uniqueId = createUniqueColumnGroupId(groupId, instanceId); let columnGroup = oldColumnsMapped[uniqueId]; if (columnGroup && columnGroup.getProvidedColumnGroup() !== providedGroup) { columnGroup = null; } if (_exists(columnGroup)) { columnGroup.reset(); } else { columnGroup = new AgColumnGroup(providedGroup, groupId, instanceId, pinned); if (!isStandaloneStructure) { this.createBean(columnGroup); } } return columnGroup; } mapOldGroupsById(displayedGroups) { const result = {}; const recursive = (columnsOrGroups) => { for (const columnOrGroup of columnsOrGroups) { if (isColumnGroup(columnOrGroup)) { const columnGroup = columnOrGroup; result[columnOrGroup.getUniqueId()] = columnGroup; recursive(columnGroup.getChildren()); } } }; if (displayedGroups) { recursive(displayedGroups); } return result; } setupParentsIntoCols(columnsOrGroups, parent) { for (const columnsOrGroup of columnsOrGroups ?? []) { if (columnsOrGroup.parent !== parent) { this.beans.colViewport.colsWithinViewportHash = ""; } columnsOrGroup.parent = parent; if (isColumnGroup(columnsOrGroup)) { const columnGroup = columnsOrGroup; this.setupParentsIntoCols(columnGroup.getChildren(), columnGroup); } } } }; var ColumnGroupModule = { moduleName: "ColumnGroup", version: VERSION, dynamicBeans: { headerGroupCellCtrl: HeaderGroupCellCtrl }, beans: [ColumnGroupService], apiFunctions: { getAllDisplayedColumnGroups, getCenterDisplayedColumnGroups, getColumnGroup, getColumnGroupState, getDisplayNameForColumnGroup, getLeftDisplayedColumnGroups, getProvidedColumnGroup, getRightDisplayedColumnGroups, resetColumnGroupState, setColumnGroupOpened, setColumnGroupState } }; function _applyColumnState(beans, params, source) { const { colModel, rowGroupColsSvc, pivotColsSvc, autoColSvc, selectionColSvc, colAnimation, visibleCols, pivotResultCols, environment, valueColsSvc, eventSvc, gos } = beans; const providedCols = colModel.getColDefCols() ?? []; const selectionCols = selectionColSvc?.getColumns(); if (!providedCols.length && !selectionCols?.length) { return false; } if (params?.state && !params.state.forEach) { _warn(32); return false; } const syncColumnWithStateItem = (column, stateItem, rowGroupIndexes, pivotIndexes, autoCol) => { if (!column) { return; } const getValue = getValueFactory(stateItem, params.defaultState); const flex = getValue("flex").value1; const maybeSortDirection = getValue("sort").value1; const maybeSortType = getValue("sortType").value1; const isSortUpdate = _isSortDirectionValid(maybeSortDirection) || _isSortTypeValid(maybeSortType); const type = _normalizeSortType(maybeSortType); const direction = _normalizeSortDirection(maybeSortDirection); const newSortDef = isSortUpdate ? { type, direction } : undefined; updateSomeColumnState(beans, column, getValue("hide").value1, newSortDef, getValue("sortIndex").value1, getValue("pinned").value1, flex, source); if (flex == null) { const width = getValue("width").value1; if (width != null) { const minColWidth = column.getColDef().minWidth ?? environment.getDefaultColumnMinWidth(); if (minColWidth != null && width >= minColWidth) { column.setActualWidth(width, source); } } } if (autoCol || !column.isPrimary()) { return; } valueColsSvc?.syncColumnWithState(column, source, getValue); rowGroupColsSvc?.syncColumnWithState(column, source, getValue, rowGroupIndexes); pivotColsSvc?.syncColumnWithState(column, source, getValue, pivotIndexes); }; const applyStates = (states, existingColumns, getById2) => { const dispatchEventsFunc = _compareColumnStatesAndDispatchEvents(beans, source); const columnsWithNoState = existingColumns.slice(); const rowGroupIndexes = {}; const pivotIndexes = {}; const autoColStates = []; const selectionColStates = []; const unmatchedAndAutoStates2 = []; let unmatchedCount2 = 0; const previousRowGroupCols = rowGroupColsSvc?.columns.slice() ?? []; const previousPivotCols = pivotColsSvc?.columns.slice() ?? []; for (const state of states) { const colId = state.colId; const isAutoGroupColumn = colId.startsWith(GROUP_AUTO_COLUMN_ID); if (isAutoGroupColumn) { autoColStates.push(state); unmatchedAndAutoStates2.push(state); continue; } if (isColumnSelectionCol(colId)) { selectionColStates.push(state); unmatchedAndAutoStates2.push(state); continue; } const column = getById2(colId); if (!column) { unmatchedAndAutoStates2.push(state); unmatchedCount2 += 1; } else { syncColumnWithStateItem(column, state, rowGroupIndexes, pivotIndexes, false); _removeFromArray(columnsWithNoState, column); } } const applyDefaultsFunc = (col) => syncColumnWithStateItem(col, null, rowGroupIndexes, pivotIndexes, false); columnsWithNoState.forEach(applyDefaultsFunc); rowGroupColsSvc?.sortColumns(comparatorByIndex.bind(rowGroupColsSvc, rowGroupIndexes, previousRowGroupCols)); pivotColsSvc?.sortColumns(comparatorByIndex.bind(pivotColsSvc, pivotIndexes, previousPivotCols)); colModel.refreshCols(false, source); const syncColStates = (getCol, colStates, columns = []) => { for (const stateItem of colStates) { const col = getCol(stateItem.colId); _removeFromArray(columns, col); syncColumnWithStateItem(col, stateItem, null, null, true); } columns.forEach(applyDefaultsFunc); }; syncColStates((colId) => autoColSvc?.getColumn(colId) ?? null, autoColStates, autoColSvc?.getColumns()?.slice()); syncColStates((colId) => selectionColSvc?.getColumn(colId) ?? null, selectionColStates, selectionColSvc?.getColumns()?.slice()); orderLiveColsLikeState(params, colModel, gos); visibleCols.refresh(source); eventSvc.dispatchEvent({ type: "columnEverythingChanged", source }); dispatchEventsFunc(); return { unmatchedAndAutoStates: unmatchedAndAutoStates2, unmatchedCount: unmatchedCount2 }; }; colAnimation?.start(); let { unmatchedAndAutoStates, unmatchedCount } = applyStates(params.state || [], providedCols, (id) => colModel.getColDefCol(id)); if (unmatchedAndAutoStates.length > 0 || _exists(params.defaultState)) { const pivotResultColsList = pivotResultCols?.getPivotResultCols()?.list ?? []; unmatchedCount = applyStates(unmatchedAndAutoStates, pivotResultColsList, (id) => pivotResultCols?.getPivotResultCol(id) ?? null).unmatchedCount; } colAnimation?.finish(); return unmatchedCount === 0; } function _resetColumnState(beans, source) { const { colModel, autoColSvc, selectionColSvc, eventSvc, gos } = beans; const primaryCols = colModel.getColDefCols(); if (!primaryCols?.length) { return; } const primaryColumnTree = colModel.getColDefColTree(); const primaryColumns = _getColumnsFromTree(primaryColumnTree); const columnStates = []; let letRowGroupIndex = 1000; let letPivotIndex = 1000; const addColState = (col) => { const stateItem = getColumnStateFromColDef(col); if (_missing(stateItem.rowGroupIndex) && stateItem.rowGroup) { stateItem.rowGroupIndex = letRowGroupIndex++; } if (_missing(stateItem.pivotIndex) && stateItem.pivot) { stateItem.pivotIndex = letPivotIndex++; } columnStates.push(stateItem); }; autoColSvc?.getColumns()?.forEach(addColState); selectionColSvc?.getColumns()?.forEach(addColState); primaryColumns?.forEach(addColState); _applyColumnState(beans, { state: columnStates }, source); const autoCols = autoColSvc?.getColumns() ?? []; const selectionCols = selectionColSvc?.getColumns() ?? []; const orderedCols = [...selectionCols, ...autoCols, ...primaryCols]; const orderedColState = orderedCols.map((col) => ({ colId: col.colId })); _applyColumnState(beans, { state: orderedColState, applyOrder: true }, source); eventSvc.dispatchEvent(_addGridCommonParams(gos, { type: "columnsReset", source })); } function _compareColumnStatesAndDispatchEvents(beans, source) { const { rowGroupColsSvc, pivotColsSvc, valueColsSvc, colModel, sortSvc, eventSvc } = beans; const startState = { rowGroupColumns: rowGroupColsSvc?.columns.slice() ?? [], pivotColumns: pivotColsSvc?.columns.slice() ?? [], valueColumns: valueColsSvc?.columns.slice() ?? [] }; const columnStateBefore = _getColumnState(beans); const columnStateBeforeMap = {}; for (const col of columnStateBefore) { columnStateBeforeMap[col.colId] = col; } return () => { const dispatchWhenListsDifferent = (eventType, colsBefore, colsAfter, idMapper) => { const beforeList = colsBefore.map(idMapper); const afterList = colsAfter.map(idMapper); const unchanged = _areEqual(beforeList, afterList); if (unchanged) { return; } const changes = new Set(colsBefore); for (const id of colsAfter) { if (!changes.delete(id)) { changes.add(id); } } const changesArr = [...changes]; eventSvc.dispatchEvent({ type: eventType, columns: changesArr, column: changesArr.length === 1 ? changesArr[0] : null, source }); }; const getChangedColumns = (changedPredicate) => { const changedColumns2 = []; colModel.forAllCols((column) => { const colStateBefore = columnStateBeforeMap[column.getColId()]; if (colStateBefore && changedPredicate(colStateBefore, column)) { changedColumns2.push(column); } }); return changedColumns2; }; const columnIdMapper = (c) => c.getColId(); dispatchWhenListsDifferent("columnRowGroupChanged", startState.rowGroupColumns, rowGroupColsSvc?.columns ?? [], columnIdMapper); dispatchWhenListsDifferent("columnPivotChanged", startState.pivotColumns, pivotColsSvc?.columns ?? [], columnIdMapper); const valueChangePredicate = (cs, c) => { const oldActive = cs.aggFunc != null; const activeChanged = oldActive != c.isValueActive(); const aggFuncChanged = oldActive && cs.aggFunc != c.getAggFunc(); return activeChanged || aggFuncChanged; }; const changedValues = getChangedColumns(valueChangePredicate); if (changedValues.length > 0) { dispatchColumnChangedEvent(eventSvc, "columnValueChanged", changedValues, source); } const resizeChangePredicate = (cs, c) => cs.width != c.getActualWidth(); dispatchColumnResizedEvent(eventSvc, getChangedColumns(resizeChangePredicate), true, source); const pinnedChangePredicate = (cs, c) => cs.pinned != c.getPinned(); dispatchColumnPinnedEvent(eventSvc, getChangedColumns(pinnedChangePredicate), source); const visibilityChangePredicate = (cs, c) => cs.hide == c.isVisible(); dispatchColumnVisibleEvent(eventSvc, getChangedColumns(visibilityChangePredicate), source); const sortChangePredicate = (cs, c) => !_areSortDefsEqual(c.getSortDef(), { type: _normalizeSortType(cs.sortType), direction: _normalizeSortDirection(cs.sort) }) || cs.sortIndex != c.getSortIndex(); const changedColumns = getChangedColumns(sortChangePredicate); if (changedColumns.length > 0) { sortSvc?.dispatchSortChangedEvents(source, changedColumns); } const colStateAfter = _getColumnState(beans); normaliseColumnMovedEventForColumnState(columnStateBefore, colStateAfter, source, colModel, eventSvc); }; } function _getColumnState(beans) { const { colModel, rowGroupColsSvc, pivotColsSvc } = beans; const primaryCols = colModel.getColDefCols(); if (_missing(primaryCols) || !colModel.isAlive()) { return []; } const rowGroupColumns = rowGroupColsSvc?.columns; const pivotColumns = pivotColsSvc?.columns; const res = []; const createStateItemFromColumn = (column) => { const rowGroupIndex = column.isRowGroupActive() && rowGroupColumns ? rowGroupColumns.indexOf(column) : null; const pivotIndex = column.isPivotActive() && pivotColumns ? pivotColumns.indexOf(column) : null; const aggFunc = column.isValueActive() ? column.getAggFunc() : null; const sortIndex = column.getSortIndex() != null ? column.getSortIndex() : null; res.push({ colId: column.getColId(), width: column.getActualWidth(), hide: !column.isVisible(), pinned: column.getPinned(), sort: column.getSort(), sortType: column.getSortDef()?.type, sortIndex, aggFunc, rowGroup: column.isRowGroupActive(), rowGroupIndex, pivot: column.isPivotActive(), pivotIndex, flex: column.getFlex() ?? null }); }; colModel.forAllCols((col) => createStateItemFromColumn(col)); const colIdToGridIndexMap = new Map(colModel.getCols().map((col, index) => [col.getColId(), index])); res.sort((itemA, itemB) => { const posA = colIdToGridIndexMap.has(itemA.colId) ? colIdToGridIndexMap.get(itemA.colId) : -1; const posB = colIdToGridIndexMap.has(itemB.colId) ? colIdToGridIndexMap.get(itemB.colId) : -1; return posA - posB; }); return res; } function getColumnStateFromColDef(column) { const getValueOrNull = (a, b) => a != null ? a : b != null ? b : null; const colDef = column.getColDef(); const sortDefFromColDef = _getSortDefFromInput(getValueOrNull(colDef.sort, colDef.initialSort)); const sort = sortDefFromColDef.direction; const sortType = sortDefFromColDef.type; const sortIndex = getValueOrNull(colDef.sortIndex, colDef.initialSortIndex); const hide = getValueOrNull(colDef.hide, colDef.initialHide); const pinned = getValueOrNull(colDef.pinned, colDef.initialPinned); const width = getValueOrNull(colDef.width, colDef.initialWidth); const flex = getValueOrNull(colDef.flex, colDef.initialFlex); let rowGroupIndex = getValueOrNull(colDef.rowGroupIndex, colDef.initialRowGroupIndex); let rowGroup = getValueOrNull(colDef.rowGroup, colDef.initialRowGroup); if (rowGroupIndex == null && !rowGroup) { rowGroupIndex = null; rowGroup = null; } let pivotIndex = getValueOrNull(colDef.pivotIndex, colDef.initialPivotIndex); let pivot = getValueOrNull(colDef.pivot, colDef.initialPivot); if (pivotIndex == null && !pivot) { pivotIndex = null; pivot = null; } const aggFunc = getValueOrNull(colDef.aggFunc, colDef.initialAggFunc); return { colId: column.getColId(), sort, sortType, sortIndex, hide, pinned, width, flex, rowGroup, rowGroupIndex, pivot, pivotIndex, aggFunc }; } function orderLiveColsLikeState(params, colModel, gos) { if (!params.applyOrder || !params.state) { return; } const colIds = []; for (const item of params.state) { if (item.colId != null) { colIds.push(item.colId); } } sortColsLikeKeys(colModel.cols, colIds, colModel, gos); } function sortColsLikeKeys(cols, colIds, colModel, gos) { if (cols == null) { return; } let newOrder = []; const processedColIds = {}; for (const colId of colIds) { if (processedColIds[colId]) { continue; } const col = cols.map[colId]; if (col) { newOrder.push(col); processedColIds[colId] = true; } } let autoGroupInsertIndex = 0; for (const col of cols.list) { const colId = col.getColId(); const alreadyProcessed = processedColIds[colId] != null; if (alreadyProcessed) { continue; } const isAutoGroupCol = colId.startsWith(GROUP_AUTO_COLUMN_ID); if (isAutoGroupCol) { newOrder.splice(autoGroupInsertIndex++, 0, col); } else { newOrder.push(col); } } newOrder = placeLockedColumns(newOrder, gos); if (!doesMovePassMarryChildren(newOrder, colModel.getColTree())) { _warn(39); return; } cols.list = newOrder; } function normaliseColumnMovedEventForColumnState(colStateBefore, colStateAfter, source, colModel, eventSvc) { const colStateAfterMapped = {}; for (const s of colStateAfter) { colStateAfterMapped[s.colId] = s; } const colsIntersectIds = {}; for (const s of colStateBefore) { if (colStateAfterMapped[s.colId]) { colsIntersectIds[s.colId] = true; } } const beforeFiltered = colStateBefore.filter((c) => colsIntersectIds[c.colId]); const afterFiltered = colStateAfter.filter((c) => colsIntersectIds[c.colId]); const movedColumns = []; afterFiltered.forEach((csAfter, index) => { const csBefore = beforeFiltered?.[index]; if (csBefore && csBefore.colId !== csAfter.colId) { const gridCol = colModel.getCol(csBefore.colId); if (gridCol) { movedColumns.push(gridCol); } } }); if (!movedColumns.length) { return; } eventSvc.dispatchEvent({ type: "columnMoved", columns: movedColumns, column: movedColumns.length === 1 ? movedColumns[0] : null, finished: true, source }); } var comparatorByIndex = (indexes, oldList, colA, colB) => { const indexA = indexes[colA.getId()]; const indexB = indexes[colB.getId()]; const aHasIndex = indexA != null; const bHasIndex = indexB != null; if (aHasIndex && bHasIndex) { return indexA - indexB; } if (aHasIndex) { return -1; } if (bHasIndex) { return 1; } const oldIndexA = oldList.indexOf(colA); const oldIndexB = oldList.indexOf(colB); const aHasOldIndex = oldIndexA >= 0; const bHasOldIndex = oldIndexB >= 0; if (aHasOldIndex && bHasOldIndex) { return oldIndexA - oldIndexB; } if (aHasOldIndex) { return -1; } return 1; }; var ColumnModel = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colModel"; this.pivotMode = false; this.ready = false; this.changeEventsDispatching = false; } postConstruct() { this.pivotMode = this.gos.get("pivotMode"); this.addManagedPropertyListeners([ "groupDisplayType", "treeData", "treeDataDisplayType", "groupHideOpenParents", "groupHideColumnsUntilExpanded", "rowNumbers", "hidePaddedHeaderRows" ], (event) => this.refreshAll(_convertColumnEventSourceType(event.source))); this.addManagedPropertyListeners(["defaultColDef", "defaultColGroupDef", "columnTypes", "suppressFieldDotNotation"], this.recreateColumnDefs.bind(this)); this.addManagedPropertyListener("pivotMode", (event) => this.setPivotMode(this.gos.get("pivotMode"), _convertColumnEventSourceType(event.source))); } createColsFromColDefs(source) { const { beans } = this; const { valueCache, colAutosize, rowGroupColsSvc, pivotColsSvc, valueColsSvc, visibleCols, eventSvc, groupHierarchyColSvc } = beans; const dispatchEventsFunc = this.colDefs ? _compareColumnStatesAndDispatchEvents(beans, source) : undefined; valueCache?.expire(); const oldCols = this.colDefCols?.list; const oldTree = this.colDefCols?.tree; const newTree = _createColumnTree(beans, this.colDefs, true, oldTree, source); _destroyColumnTree(beans, this.colDefCols?.tree, newTree.columnTree); const tree = newTree.columnTree; const treeDepth = newTree.treeDepth; const list = _getColumnsFromTree(tree); const map = {}; for (const col of list) { map[col.getId()] = col; } this.colDefCols = { tree, treeDepth, list, map }; this.createColumnsForService([groupHierarchyColSvc], this.colDefCols, source); rowGroupColsSvc?.extractCols(source, oldCols); pivotColsSvc?.extractCols(source, oldCols); valueColsSvc?.extractCols(source, oldCols); this.ready = true; this.changeEventsDispatching = true; this.refreshCols(true, source); this.changeEventsDispatching = false; visibleCols.refresh(source); eventSvc.dispatchEvent({ type: "columnEverythingChanged", source }); if (dispatchEventsFunc) { this.changeEventsDispatching = true; dispatchEventsFunc(); this.changeEventsDispatching = false; } eventSvc.dispatchEvent({ type: "newColumnsLoaded", source }); if (source === "gridInitializing") { colAutosize?.applyAutosizeStrategy(); } } refreshCols(newColDefs, source) { if (!this.colDefCols) { return; } const prevColTree = this.cols?.tree; this.saveColOrder(); const { autoColSvc, selectionColSvc, rowNumbersSvc, quickFilter, pivotResultCols, showRowGroupCols, rowAutoHeight, visibleCols, colViewport, eventSvc, formula } = this.beans; const cols = this.selectCols(pivotResultCols, this.colDefCols); formula?.setFormulasActive(cols); this.createColumnsForService([autoColSvc, selectionColSvc, rowNumbersSvc], cols, source); const shouldSortNewColDefs = _shouldMaintainColumnOrder(this.gos, this.showingPivotResult); if (!newColDefs || shouldSortNewColDefs) { this.restoreColOrder(cols); } this.positionLockedCols(cols); showRowGroupCols?.refresh(); quickFilter?.refreshCols(); this.setColSpanActive(); rowAutoHeight?.setAutoHeightActive(cols); visibleCols.clear(); colViewport.clear(); if (!_areEqual(prevColTree, this.cols.tree)) { eventSvc.dispatchEvent({ type: "gridColumnsChanged" }); } } createColumnsForService(services, cols, source) { for (const service of services) { if (!service) { continue; } service.createColumns(cols, (updateOrder) => { this.lastOrder = updateOrder(this.lastOrder); this.lastPivotOrder = updateOrder(this.lastPivotOrder); }, source); service.addColumns(cols); } } selectCols(pivotResultColsSvc, colDefCols) { const pivotResultCols = pivotResultColsSvc?.getPivotResultCols() ?? null; this.showingPivotResult = pivotResultCols != null; const { map, list, tree, treeDepth } = pivotResultCols ?? colDefCols; this.cols = { list: list.slice(), map: { ...map }, tree: tree.slice(), treeDepth }; if (pivotResultCols) { const hasSameColumns = pivotResultCols.list.some((col) => this.cols?.map[col.getColId()] !== undefined); if (!hasSameColumns) { this.lastPivotOrder = null; } } return this.cols; } getColsToShow() { if (!this.cols) { return []; } const { beans, showingPivotResult, cols } = this; const { valueColsSvc, selectionColSvc, gos } = beans; const showAutoGroupAndValuesOnly = this.isPivotMode() && !showingPivotResult; const showSelectionColumn = selectionColSvc?.isSelectionColumnEnabled(); const showRowNumbers = _isRowNumbers(beans); const valueColumns = valueColsSvc?.columns; const hideEmptyAutoColGroups = _isGroupHideColumnsUntilExpanded(gos); const res = cols.list.filter((col) => { const isAutoGroupCol = isColumnGroupAutoCol(col); if (showAutoGroupAndValuesOnly) { const isValueCol = valueColumns?.includes(col); return isValueCol || isAutoGroupCol && (!hideEmptyAutoColGroups || col.isVisible()) || showSelectionColumn && isColumnSelectionCol(col) || showRowNumbers && isRowNumberCol(col); } else { return isAutoGroupCol && !hideEmptyAutoColGroups || col.isVisible(); } }); return res; } refreshAll(source) { if (!this.ready) { return; } this.refreshCols(false, source); this.beans.visibleCols.refresh(source); } setColsVisible(keys, visible = false, source) { _applyColumnState(this.beans, { state: keys.map((key) => ({ colId: typeof key === "string" ? key : key.getColId(), hide: !visible })) }, source); } restoreColOrder(cols) { const lastOrder = this.showingPivotResult ? this.lastPivotOrder : this.lastOrder; if (!lastOrder) { return; } const preservedOrder = lastOrder.filter((col) => cols.map[col.getId()] != null); if (preservedOrder.length === 0) { return; } if (preservedOrder.length === cols.list.length) { cols.list = preservedOrder; return; } const hasSiblings = (col) => { const ancestor = col.getOriginalParent(); if (!ancestor) { return false; } const children = ancestor.getChildren(); if (children.length > 1) { return true; } return hasSiblings(ancestor); }; if (!preservedOrder.some((col) => hasSiblings(col))) { const preservedOrderSet = new Set(preservedOrder); for (const col of cols.list) { if (!preservedOrderSet.has(col)) { preservedOrder.push(col); } } cols.list = preservedOrder; return; } const colPositionMap = /* @__PURE__ */ new Map; for (let i = 0;i < preservedOrder.length; i++) { const col = preservedOrder[i]; colPositionMap.set(col, i); } const additionalCols = cols.list.filter((col) => !colPositionMap.has(col)); if (additionalCols.length === 0) { cols.list = preservedOrder; return; } const getPreviousSibling = (col, group) => { const parent = group ? group.getOriginalParent() : col.getOriginalParent(); if (!parent) { return null; } let highestIdx = null; let highestSibling = null; for (const child of parent.getChildren()) { if (child === group || child === col) { continue; } if (child instanceof AgColumn) { const colIdx = colPositionMap.get(child); if (colIdx == null) { continue; } if (highestIdx == null || highestIdx < colIdx) { highestIdx = colIdx; highestSibling = child; } continue; } child.forEachLeafColumn((leafCol) => { const colIdx = colPositionMap.get(leafCol); if (colIdx == null) { return; } if (highestIdx == null || highestIdx < colIdx) { highestIdx = colIdx; highestSibling = leafCol; } }); } if (highestSibling == null) { return getPreviousSibling(col, parent); } return highestSibling; }; const noSiblingsAvailable = []; const previousSiblingPosMap = /* @__PURE__ */ new Map; for (const col of additionalCols) { const prevSiblingIdx = getPreviousSibling(col, null); if (prevSiblingIdx == null) { noSiblingsAvailable.push(col); continue; } const prev = previousSiblingPosMap.get(prevSiblingIdx); if (prev === undefined) { previousSiblingPosMap.set(prevSiblingIdx, col); } else if (Array.isArray(prev)) { prev.push(col); } else { previousSiblingPosMap.set(prevSiblingIdx, [prev, col]); } } const result = new Array(cols.list.length); let resultPointer = result.length - 1; for (let i = noSiblingsAvailable.length - 1;i >= 0; i--) { result[resultPointer--] = noSiblingsAvailable[i]; } for (let i = preservedOrder.length - 1;i >= 0; i--) { const nextCol = preservedOrder[i]; const extraCols = previousSiblingPosMap.get(nextCol); if (extraCols) { if (Array.isArray(extraCols)) { for (let x = extraCols.length - 1;x >= 0; x--) { const col = extraCols[x]; result[resultPointer--] = col; } } else { result[resultPointer--] = extraCols; } } result[resultPointer--] = nextCol; } cols.list = result; } positionLockedCols(cols) { cols.list = placeLockedColumns(cols.list, this.gos); } saveColOrder() { if (this.showingPivotResult) { this.lastPivotOrder = this.cols?.list ?? null; } else { this.lastOrder = this.cols?.list ?? null; } } getColumnDefs(sorted) { return this.colDefCols && this.beans.colDefFactory?.getColumnDefs(this.colDefCols.list, this.showingPivotResult, this.lastOrder, this.cols?.list ?? [], sorted); } setColSpanActive() { this.colSpanActive = !!this.cols?.list.some((col) => col.getColDef().colSpan != null); } isPivotMode() { return this.pivotMode; } setPivotMode(pivotMode, source) { if (pivotMode === this.pivotMode) { return; } this.pivotMode = pivotMode; if (!this.ready) { return; } this.refreshCols(false, source); const { visibleCols, eventSvc } = this.beans; visibleCols.refresh(source); eventSvc.dispatchEvent({ type: "columnPivotModeChanged" }); } isPivotActive() { const pivotColumns = this.beans.pivotColsSvc?.columns; return this.pivotMode && !!pivotColumns?.length; } recreateColumnDefs(e) { if (!this.cols) { return; } this.beans.autoColSvc?.updateColumns(e); const source = _convertColumnEventSourceType(e.source); this.createColsFromColDefs(source); } setColumnDefs(columnDefs, source) { this.colDefs = columnDefs; this.createColsFromColDefs(source); } destroy() { _destroyColumnTree(this.beans, this.colDefCols?.tree); super.destroy(); } getColTree() { return this.cols?.tree ?? []; } getColDefColTree() { return this.colDefCols?.tree ?? []; } getColDefCols() { return this.colDefCols?.list ?? null; } getCols() { return this.cols?.list ?? []; } forAllCols(callback) { const { pivotResultCols, autoColSvc, selectionColSvc, groupHierarchyColSvc } = this.beans; if (_forAll(this.colDefCols?.list, callback)) { return; } if (_forAll(autoColSvc?.columns?.list, callback)) { return; } if (_forAll(selectionColSvc?.columns?.list, callback)) { return; } if (_forAll(groupHierarchyColSvc?.columns?.list, callback)) { return; } if (_forAll(pivotResultCols?.getPivotResultCols()?.list, callback)) { return; } } getColsForKeys(keys) { if (!keys) { return []; } return keys.map((key) => this.getCol(key)).filter((col) => col != null); } getColDefCol(key) { if (!this.colDefCols?.list) { return null; } return this.getColFromCollection(key, this.colDefCols); } getCol(key) { if (key == null) { return null; } return this.getColFromCollection(key, this.cols); } getColById(key) { return this.cols?.map[key] ?? null; } getColFromCollection(key, cols) { if (cols == null) { return null; } const { map, list } = cols; if (typeof key == "string" && map[key]) { return map[key]; } for (let i = 0;i < list.length; i++) { if (_columnsMatch(list[i], key)) { return list[i]; } } const { autoColSvc, selectionColSvc, groupHierarchyColSvc } = this.beans; return autoColSvc?.getColumn(key) ?? selectionColSvc?.getColumn(key) ?? groupHierarchyColSvc?.getColumn(key) ?? null; } }; var agAbstractLabel_default = ".ag-label{white-space:nowrap}:where(.ag-ltr) .ag-label{margin-right:var(--ag-spacing)}:where(.ag-rtl) .ag-label{margin-left:var(--ag-spacing)}:where(.ag-label-align-right) .ag-label{order:1}:where(.ag-ltr) :where(.ag-label-align-right) .ag-label{margin-left:var(--ag-spacing)}:where(.ag-rtl) :where(.ag-label-align-right) .ag-label{margin-right:var(--ag-spacing)}:where(.ag-label-align-right){.ag-label,.ag-wrapper{flex:none}}.ag-label-align-top{align-items:flex-start;flex-direction:column}:where(.ag-label-align-top){.ag-label,.ag-wrapper{align-self:stretch}}.ag-label-ellipsis{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:where(.ag-label-align-top) .ag-label{margin-bottom:calc(var(--ag-spacing)*.5)}"; var AgAbstractLabel = class extends AgComponentStub { constructor(config, template, components) { super(template, components); this.labelSeparator = ""; this.labelAlignment = "left"; this.disabled = false; this.label = ""; this.config = config || {}; this.registerCSS(agAbstractLabel_default); } postConstruct() { this.addCss("ag-labeled"); this.eLabel.classList.add("ag-label"); const { labelSeparator, label, labelWidth, labelAlignment, disabled, labelEllipsis } = this.config; if (disabled != null) { this.setDisabled(disabled); } if (labelSeparator != null) { this.setLabelSeparator(labelSeparator); } if (label != null) { this.setLabel(label); } if (labelWidth != null) { this.setLabelWidth(labelWidth); } if (labelEllipsis != null) { this.setLabelEllipsis(labelEllipsis); } this.setLabelAlignment(labelAlignment || this.labelAlignment); this.refreshLabel(); } refreshLabel() { const { label, eLabel } = this; _clearElement(eLabel); if (typeof label === "string") { eLabel.innerText = label + this.labelSeparator; } else if (label) { eLabel.appendChild(label); } if (label === "") { _setDisplayed(eLabel, false); _setAriaRole(eLabel, "presentation"); } else { _setDisplayed(eLabel, true); _setAriaRole(eLabel, null); } } setLabelSeparator(labelSeparator) { if (this.labelSeparator === labelSeparator) { return this; } this.labelSeparator = labelSeparator; if (this.label != null) { this.refreshLabel(); } return this; } getLabelId() { const eLabel = this.eLabel; eLabel.id = eLabel.id || `ag-${this.getCompId()}-label`; return eLabel.id; } getLabel() { return this.label; } setLabel(label) { if (this.label === label) { return this; } this.label = label; this.refreshLabel(); return this; } setLabelAlignment(alignment) { const eGui = this.getGui(); const eGuiClassList = eGui.classList; eGuiClassList.toggle("ag-label-align-left", alignment === "left"); eGuiClassList.toggle("ag-label-align-right", alignment === "right"); eGuiClassList.toggle("ag-label-align-top", alignment === "top"); return this; } setLabelEllipsis(hasEllipsis) { this.eLabel.classList.toggle("ag-label-ellipsis", hasEllipsis); return this; } setLabelWidth(width) { if (this.label == null) { return this; } _setElementWidth(this.eLabel, width); return this; } setDisabled(disabled) { disabled = !!disabled; const element = this.getGui(); _setDisabled(element, disabled); element.classList.toggle("ag-disabled", disabled); this.disabled = disabled; return this; } isDisabled() { return !!this.disabled; } }; var AgAbstractField = class extends AgAbstractLabel { constructor(config, template, components, className) { super(config, template, components); this.className = className; } postConstruct() { super.postConstruct(); const { width, value, onValueChange, ariaLabel } = this.config; if (width != null) { this.setWidth(width); } if (value != null) { this.setValue(value); } if (onValueChange != null) { this.onValueChange(onValueChange); } if (ariaLabel != null) { this.setAriaLabel(ariaLabel); } if (this.className) { this.addCss(this.className); } this.refreshAriaLabelledBy(); } setLabel(label) { super.setLabel(label); this.refreshAriaLabelledBy(); return this; } refreshAriaLabelledBy() { const ariaEl = this.getAriaElement(); const labelId = this.getLabelId(); const label = this.getLabel(); if (label == null || label == "" || _getAriaLabel(ariaEl) !== null) { _setAriaLabelledBy(ariaEl, ""); } else { _setAriaLabelledBy(ariaEl, labelId ?? ""); } } setAriaLabel(label) { _setAriaLabel(this.getAriaElement(), label); this.refreshAriaLabelledBy(); return this; } onValueChange(callbackFn) { this.addManagedListeners(this, { fieldValueChanged: () => callbackFn(this.getValue()) }); return this; } getWidth() { return this.getGui().clientWidth; } setWidth(width) { _setFixedWidth(this.getGui(), width); return this; } getPreviousValue() { return this.previousValue; } getValue() { return this.value; } setValue(value, silent) { if (this.value === value) { return this; } this.previousValue = this.value; this.value = value; if (!silent) { this.dispatchLocalEvent({ type: "fieldValueChanged" }); } return this; } }; function buildTemplate(displayFieldTag) { return { tag: "div", role: "presentation", children: [ { tag: "div", ref: "eLabel", cls: "ag-input-field-label" }, { tag: "div", ref: "eWrapper", cls: "ag-wrapper ag-input-wrapper", role: "presentation", children: [{ tag: displayFieldTag, ref: "eInput", cls: "ag-input-field-input" }] } ] }; } var AgAbstractInputField = class extends AgAbstractField { constructor(config, className, inputType = "text", displayFieldTag = "input") { super(config, config?.template ?? buildTemplate(displayFieldTag), [], className); this.inputType = inputType; this.displayFieldTag = displayFieldTag; this.eLabel = RefPlaceholder; this.eWrapper = RefPlaceholder; this.eInput = RefPlaceholder; } postConstruct() { super.postConstruct(); this.setInputType(this.inputType); const { eLabel, eWrapper, eInput, className } = this; eLabel.classList.add(`${className}-label`); eWrapper.classList.add(`${className}-input-wrapper`); eInput.classList.add(`${className}-input`); this.addCss("ag-input-field"); eInput.id = eInput.id || `ag-${this.getCompId()}-input`; const { inputName, inputWidth, inputPlaceholder, autoComplete, tabIndex } = this.config; if (inputName != null) { this.setInputName(inputName); } if (inputWidth != null) { this.setInputWidth(inputWidth); } if (inputPlaceholder != null) { this.setInputPlaceholder(inputPlaceholder); } if (autoComplete != null) { this.setAutoComplete(autoComplete); } this.addInputListeners(); this.activateTabIndex([eInput], tabIndex); } addInputListeners() { this.addManagedElementListeners(this.eInput, { input: (e) => this.setValue(e.target.value) }); } setInputType(inputType) { if (this.displayFieldTag === "input") { this.inputType = inputType; _addOrRemoveAttribute(this.eInput, "type", inputType); } } getInputElement() { return this.eInput; } getWrapperElement() { return this.eWrapper; } setInputWidth(width) { _setElementWidth(this.eWrapper, width); return this; } setInputName(name) { this.getInputElement().setAttribute("name", name); return this; } getFocusableElement() { return this.eInput; } setMaxLength(length) { const eInput = this.eInput; eInput.maxLength = length; return this; } setInputPlaceholder(placeholder) { _addOrRemoveAttribute(this.eInput, "placeholder", placeholder); return this; } setInputAriaLabel(label) { _setAriaLabel(this.eInput, label); this.refreshAriaLabelledBy(); return this; } setDisabled(disabled) { _setDisabled(this.eInput, disabled); return super.setDisabled(disabled); } setAutoComplete(value) { if (value === true) { _addOrRemoveAttribute(this.eInput, "autocomplete", null); } else { const autoCompleteValue = typeof value === "string" ? value : "off"; _addOrRemoveAttribute(this.eInput, "autocomplete", autoCompleteValue); } return this; } }; var AgCheckbox = class extends AgAbstractInputField { constructor(config, className = "ag-checkbox", inputType = "checkbox") { super(config, className, inputType); this.labelAlignment = "right"; this.selected = false; this.readOnly = false; this.passive = false; } postConstruct() { super.postConstruct(); const { readOnly, passive, name } = this.config; if (typeof readOnly === "boolean") { this.setReadOnly(readOnly); } if (typeof passive === "boolean") { this.setPassive(passive); } if (name != null) { this.setName(name); } } addInputListeners() { this.addManagedElementListeners(this.eInput, { click: this.onCheckboxClick.bind(this) }); this.addManagedElementListeners(this.eLabel, { click: this.toggle.bind(this) }); } getNextValue() { return this.selected === undefined ? true : !this.selected; } setPassive(passive) { this.passive = passive; } isReadOnly() { return this.readOnly; } setReadOnly(readOnly) { this.eWrapper.classList.toggle("ag-disabled", readOnly); this.eInput.disabled = readOnly; this.readOnly = readOnly; } setDisabled(disabled) { this.eWrapper.classList.toggle("ag-disabled", disabled); return super.setDisabled(disabled); } toggle() { if (this.eInput.disabled) { return; } const previousValue = this.isSelected(); const nextValue = this.getNextValue(); if (this.passive) { this.dispatchChange(nextValue, previousValue); } else { this.setValue(nextValue); } } getValue() { return this.isSelected(); } setValue(value, silent) { this.refreshSelectedClass(value); this.setSelected(value, silent); return this; } setName(name) { const input = this.getInputElement(); input.name = name; return this; } isSelected() { return this.selected; } setSelected(selected, silent) { if (this.isSelected() === selected) { return; } this.previousValue = this.isSelected(); selected = this.selected = typeof selected === "boolean" ? selected : undefined; const eInput = this.eInput; eInput.checked = selected; eInput.indeterminate = selected === undefined; if (!silent) { this.dispatchChange(this.selected, this.previousValue); } } dispatchChange(selected, previousValue, event) { this.dispatchLocalEvent({ type: "fieldValueChanged", selected, previousValue, event }); const input = this.getInputElement(); this.eventSvc.dispatchEvent({ type: "checkboxChanged", id: input.id, name: input.name, selected, previousValue }); } onCheckboxClick(e) { if (this.passive || this.eInput.disabled) { return; } const previousValue = this.isSelected(); const selected = this.selected = e.target.checked; this.refreshSelectedClass(selected); this.dispatchChange(selected, previousValue, e); } refreshSelectedClass(value) { const classList = this.eWrapper.classList; classList.toggle("ag-checked", value === true); classList.toggle("ag-indeterminate", value == null); } }; var AgCheckboxSelector = { selector: "AG-CHECKBOX", component: AgCheckbox }; var checkboxCellRenderer_default = ".ag-checkbox-cell{height:100%}"; var CheckboxCellRendererElement = { tag: "div", cls: "ag-cell-wrapper ag-checkbox-cell", role: "presentation", children: [ { tag: "ag-checkbox", ref: "eCheckbox", role: "presentation" } ] }; var CheckboxCellRenderer = class extends Component { constructor() { super(CheckboxCellRendererElement, [AgCheckboxSelector]); this.eCheckbox = RefPlaceholder; this.registerCSS(checkboxCellRenderer_default); } init(params) { this.refresh(params); const { eCheckbox, beans } = this; const inputEl = eCheckbox.getInputElement(); inputEl.setAttribute("tabindex", "-1"); _setAriaLive(inputEl, "polite"); this.addManagedListeners(inputEl, { click: (event) => { _stopPropagationForAgGrid(event); if (eCheckbox.isDisabled()) { return; } const isSelected = eCheckbox.getValue(); this.onCheckboxChanged(isSelected); }, dblclick: (event) => { _stopPropagationForAgGrid(event); } }); this.addManagedElementListeners(params.eGridCell, { keydown: (event) => { if (event.key === KeyCode.SPACE && !eCheckbox.isDisabled()) { if (params.eGridCell === _getActiveDomElement(beans)) { eCheckbox.toggle(); } const isSelected = eCheckbox.getValue(); this.onCheckboxChanged(isSelected); event.preventDefault(); } } }); } refresh(params) { this.params = params; this.updateCheckbox(params); return true; } updateCheckbox(params) { let isSelected; let displayed = true; const { value, column, node } = params; if (node.group && column) { if (typeof value === "boolean") { isSelected = value; } else { const colId = column.getColId(); if (colId.startsWith(GROUP_AUTO_COLUMN_ID)) { isSelected = value == null || value === "" ? undefined : value === "true"; } else if (node.aggData && node.aggData[colId] !== undefined) { isSelected = value ?? undefined; } else if (node.sourceRowIndex >= 0) { isSelected = value ?? undefined; } else { displayed = false; } } } else { isSelected = value ?? undefined; } const { eCheckbox } = this; if (!displayed) { eCheckbox.setDisplayed(false); return; } eCheckbox.setValue(isSelected); const disabled = params.disabled ?? !column?.isCellEditable(node); eCheckbox.setDisabled(disabled); const translate = this.getLocaleTextFunc(); const stateName = _getAriaCheckboxStateName(translate, isSelected); const ariaLabel = disabled ? stateName : `${translate("ariaToggleCellValue", "Press SPACE to toggle cell value")} (${stateName})`; eCheckbox.setInputAriaLabel(ariaLabel); } onCheckboxChanged(isSelected) { const { params } = this; const { column, node, value: oldValue } = params; const { editSvc } = this.beans; if (!column) { return; } const position = { rowNode: node, column }; editSvc?.dispatchCellEvent(position, null, "cellEditingStarted", { value: oldValue }); const valueChanged = node.setDataValue(column, isSelected, "ui"); editSvc?.dispatchCellEvent(position, null, "cellEditingStopped", { oldValue, newValue: isSelected, valueChanged }); if (!valueChanged) { this.updateCheckbox(params); } } }; var SkeletonCellRendererElement = { tag: "div", cls: "ag-skeleton-container" }; var SkeletonCellRenderer = class extends Component { constructor() { super(SkeletonCellRendererElement); } init(params) { const id = `ag-cell-skeleton-renderer-${this.getCompId()}`; this.getGui().setAttribute("id", id); this.addDestroyFunc(() => _setAriaLabelledBy(params.eParentOfValue)); _setAriaLabelledBy(params.eParentOfValue, id); if (params.deferRender) { this.setupLoading(params); } else if (params.node.failedLoad) { this.setupFailed(); } else { this.setupLoading(params); } } setupFailed() { const localeTextFunc = this.getLocaleTextFunc(); this.getGui().textContent = localeTextFunc("loadingError", "ERR"); const ariaFailed = localeTextFunc("ariaSkeletonCellLoadingFailed", "Row failed to load"); _setAriaLabel(this.getGui(), ariaFailed); } setupLoading(params) { const skeletonEffect = _createElement({ tag: "div", cls: "ag-skeleton-effect" }); const rowIndex = params.node.rowIndex; if (rowIndex != null) { const width = 75 + 25 * (rowIndex % 2 === 0 ? Math.sin(rowIndex) : Math.cos(rowIndex)); skeletonEffect.style.width = `${width}%`; } this.getGui().appendChild(skeletonEffect); const localeTextFunc = this.getLocaleTextFunc(); const ariaLoading = params.deferRender ? localeTextFunc("ariaDeferSkeletonCellLoading", "Cell is loading") : localeTextFunc("ariaSkeletonCellLoading", "Row data is loading"); _setAriaLabel(this.getGui(), ariaLoading); } refresh(_params) { return false; } }; var CheckboxCellRendererModule = { moduleName: "CheckboxCellRenderer", version: VERSION, userComponents: { agCheckboxCellRenderer: CheckboxCellRenderer } }; var SkeletonCellRendererModule = { moduleName: "SkeletonCellRenderer", version: VERSION, userComponents: { agSkeletonCellRenderer: SkeletonCellRenderer } }; var ColumnFlexService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colFlex"; this.columnsHidden = false; } refreshFlexedColumns(params = {}) { const source = params.source ?? "flex"; if (params.viewportWidth != null) { this.flexViewportWidth = params.viewportWidth; } const totalSpace = this.flexViewportWidth; const { visibleCols, colDelayRenderSvc } = this.beans; const visibleCenterCols = visibleCols.centerCols; let flexAfterDisplayIndex = -1; if (params.resizingCols) { const allResizingCols = new Set(params.resizingCols); for (let i = visibleCenterCols.length - 1;i >= 0; i--) { if (allResizingCols.has(visibleCenterCols[i])) { flexAfterDisplayIndex = i; break; } } } let hasFlexItems = false; const items = visibleCenterCols.map((col, i) => { const flex = col.getFlex(); const isFlex = flex != null && flex > 0 && i > flexAfterDisplayIndex; hasFlexItems || (hasFlexItems = isFlex); return { col, isFlex, flex: Math.max(0, flex ?? 0), initialSize: col.getActualWidth(), min: col.getMinWidth(), max: col.getMaxWidth(), targetSize: 0 }; }); if (hasFlexItems) { colDelayRenderSvc?.hideColumns("colFlex"); this.columnsHidden = true; } else if (this.columnsHidden) { this.revealColumns(colDelayRenderSvc); } if (!totalSpace || !hasFlexItems) { return []; } let unfrozenItemCount = items.length; let unfrozenFlex = items.reduce((acc, item) => acc + item.flex, 0); let unfrozenSpace = totalSpace; const freeze = (item, width) => { item.frozenSize = width; item.col.setActualWidth(width, source); unfrozenSpace -= width; unfrozenFlex -= item.flex; unfrozenItemCount -= 1; }; const isFrozen = (item) => item.frozenSize != null; for (const item of items) { if (!item.isFlex) { freeze(item, item.initialSize); } } while (unfrozenItemCount > 0) { const spaceToFill = Math.round(unfrozenFlex < 1 ? unfrozenSpace * unfrozenFlex : unfrozenSpace); let lastUnfrozenItem; let actualLeft = 0; let idealRight = 0; for (const item of items) { if (isFrozen(item)) { continue; } lastUnfrozenItem = item; idealRight += spaceToFill * (item.flex / unfrozenFlex); const idealSize = idealRight - actualLeft; const roundedSize = Math.round(idealSize); item.targetSize = roundedSize; actualLeft += roundedSize; } if (lastUnfrozenItem) { lastUnfrozenItem.targetSize += spaceToFill - actualLeft; } let totalViolation = 0; for (const item of items) { if (isFrozen(item)) { continue; } const unclampedSize = item.targetSize; const clampedSize = Math.min(Math.max(unclampedSize, item.min), item.max); totalViolation += clampedSize - unclampedSize; item.violationType = clampedSize === unclampedSize ? undefined : clampedSize < unclampedSize ? "max" : "min"; item.targetSize = clampedSize; } const freezeType = totalViolation === 0 ? "all" : totalViolation > 0 ? "min" : "max"; for (const item of items) { if (isFrozen(item)) { continue; } if (freezeType === "all" || item.violationType === freezeType) { freeze(item, item.targetSize); } } } if (!params.skipSetLeft) { visibleCols.setLeftValues(source); } if (params.updateBodyWidths) { visibleCols.updateBodyWidths(); } const unconstrainedFlexColumns = items.filter((item) => item.isFlex && !item.violationType).map((item) => item.col); if (params.fireResizedEvent) { const changedColumns = items.filter((item) => item.initialSize !== item.frozenSize).map((item) => item.col); const flexingColumns = items.filter((item) => item.flex).map((item) => item.col); dispatchColumnResizedEvent(this.eventSvc, changedColumns, true, source, flexingColumns); } this.revealColumns(colDelayRenderSvc); return unconstrainedFlexColumns; } revealColumns(colDelayRenderSvc) { if (this.columnsHidden) { colDelayRenderSvc?.revealColumns("colFlex"); this.columnsHidden = false; } } initCol(column) { const { flex, initialFlex } = column.colDef; if (flex !== undefined) { column.flex = flex; } else if (initialFlex !== undefined) { column.flex = initialFlex; } } setColFlex(column, flex) { column.flex = flex ?? null; column.dispatchStateUpdatedEvent("flex"); } }; var _parseBigIntOrNull = (value) => { if (typeof value === "bigint") { return value; } let trimmed; if (typeof value === "number") { trimmed = value; } else if (typeof value === "string") { trimmed = value.trim(); if (trimmed === "") { return null; } if (trimmed.endsWith("n")) { trimmed = trimmed.slice(0, -1); } if (!/^[+-]?\d+$/.test(trimmed)) { return null; } } if (trimmed == null) { return null; } try { return BigInt(trimmed); } catch { return null; } }; var DATE_TIME_SEPARATOR = "T"; var DATE_TIME_SEPARATOR_REGEXP = new RegExp(`[${DATE_TIME_SEPARATOR} ]`); var DATE_TIME_REGEXP = new RegExp(`^\\d{4}-\\d{2}-\\d{2}(${DATE_TIME_SEPARATOR}\\d{2}:\\d{2}:\\d{2}\\D?)?`); function _padStartWidthZeros(value, totalStringSize) { return value.toString().padStart(totalStringSize, "0"); } function _serialiseDate(date, includeTime = true, separator = DATE_TIME_SEPARATOR) { if (!date) { return null; } let serialised = [date.getFullYear(), date.getMonth() + 1, date.getDate()].map((part) => _padStartWidthZeros(part, 2)).join("-"); if (includeTime) { serialised += separator + [date.getHours(), date.getMinutes(), date.getSeconds()].map((part) => _padStartWidthZeros(part, 2)).join(":"); } return serialised; } function _getDateParts(d, includeTime = true) { if (!d) { return null; } if (includeTime) { return [ String(d.getFullYear()), String(d.getMonth() + 1), _padStartWidthZeros(d.getDate(), 2), _padStartWidthZeros(d.getHours(), 2), `:${_padStartWidthZeros(d.getMinutes(), 2)}`, `:${_padStartWidthZeros(d.getSeconds(), 2)}` ]; } return [d.getFullYear(), d.getMonth() + 1, _padStartWidthZeros(d.getDate(), 2)].map(String); } var calculateOrdinal = (value) => { if (value > 3 && value < 21) { return "th"; } const remainder = value % 10; switch (remainder) { case 1: return "st"; case 2: return "nd"; case 3: return "rd"; } return "th"; }; var MONTHS = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; var DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; function _dateToFormattedString(date, format) { if (format == null) { return _serialiseDate(date, false); } const fullYear = _padStartWidthZeros(date.getFullYear(), 4); const replace = { YYYY: () => fullYear.slice(fullYear.length - 4, fullYear.length), YY: () => fullYear.slice(fullYear.length - 2, fullYear.length), Y: () => `${date.getFullYear()}`, MMMM: () => MONTHS[date.getMonth()], MMM: () => MONTHS[date.getMonth()].slice(0, 3), MM: () => _padStartWidthZeros(date.getMonth() + 1, 2), Mo: () => `${date.getMonth() + 1}${calculateOrdinal(date.getMonth() + 1)}`, M: () => `${date.getMonth() + 1}`, Do: () => `${date.getDate()}${calculateOrdinal(date.getDate())}`, DD: () => _padStartWidthZeros(date.getDate(), 2), D: () => `${date.getDate()}`, dddd: () => DAYS[date.getDay()], ddd: () => DAYS[date.getDay()].slice(0, 3), dd: () => DAYS[date.getDay()].slice(0, 2), do: () => `${date.getDay()}${calculateOrdinal(date.getDay())}`, d: () => `${date.getDay()}` }; const regexp = new RegExp(Object.keys(replace).join("|"), "g"); return format.replace(regexp, (match) => { if (match in replace) { return replace[match](); } return match; }); } function _isValidDate(value, bailIfInvalidTime = false) { return !!_parseDateTimeFromString(value, bailIfInvalidTime); } function _isValidDateTime(value) { return _isValidDate(value, true); } function _parseDateTimeFromString(value, bailIfInvalidTime = false, skipValidation) { if (!value) { return null; } if (!skipValidation && !DATE_TIME_REGEXP.test(value)) { return null; } const [dateStr, timeStr] = value.split(DATE_TIME_SEPARATOR_REGEXP); if (!dateStr) { return null; } const fields = dateStr.split("-").map((f) => Number.parseInt(f, 10)); if (fields.filter((f) => !isNaN(f)).length !== 3) { return null; } const [year, month, day] = fields; const date = new Date(year, month - 1, day); if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) { return null; } if (!timeStr && bailIfInvalidTime) { return null; } if (!timeStr || timeStr === "00:00:00") { return date; } const [hours, minutes, seconds] = timeStr.split(":").map((part) => Number.parseInt(part, 10)); if (hours >= 0 && hours < 24) { date.setHours(hours); } else if (bailIfInvalidTime) { return null; } if (minutes >= 0 && minutes < 60) { date.setMinutes(minutes); } else if (bailIfInvalidTime) { return null; } if (seconds >= 0 && seconds < 60) { date.setSeconds(seconds); } else if (bailIfInvalidTime) { return null; } return date; } function _getValueUsingField(data, field, fieldContainsDots) { if (!field || !data) { return; } if (!fieldContainsDots) { return data[field]; } const fields = field.split("."); let currentObject = data; for (let i = 0;i < fields.length; i++) { if (currentObject == null) { return; } currentObject = currentObject[fields[i]]; } return currentObject; } var SORTED_CELL_DATA_TYPES_FOR_MATCHING = [ "dateTimeString", "dateString", "text", "number", "bigint", "boolean", "date" ]; var DataTypeService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "dataTypeSvc"; this.dataTypeDefinitions = {}; this.isPendingInference = false; this.isColumnTypeOverrideInDataTypeDefinitions = false; this.columnStateUpdatesPendingInference = {}; this.columnStateUpdateListenerDestroyFuncs = []; this.columnDefinitionPropsPerDataType = { number() { return { cellEditor: "agNumberCellEditor" }; }, bigint({ filterModuleBean }) { if (filterModuleBean) { return { cellEditor: "agTextCellEditor" }; } return { cellEditor: "agTextCellEditor", comparator: { default: bigintComparator, absolute: bigintAbsoluteComparator } }; }, boolean() { return { cellEditor: "agCheckboxCellEditor", cellRenderer: "agCheckboxCellRenderer", getFindText: () => null, suppressKeyboardEvent: ({ node, event, column }) => event.key === KeyCode.SPACE && column.isCellEditable(node) }; }, date({ formatValue }) { return { cellEditor: "agDateCellEditor", keyCreator: formatValue }; }, dateString({ formatValue }) { return { cellEditor: "agDateStringCellEditor", keyCreator: formatValue }; }, dateTime(args) { return this.date(args); }, dateTimeString(args) { return this.dateString(args); }, object({ formatValue, colModel, colId }) { return { cellEditorParams: { useFormatter: true }, comparator: (a, b) => { const column = colModel.getColDefCol(colId); const colDef = column?.getColDef(); if (!column || !colDef) { return 0; } const valA = a == null ? "" : formatValue({ column, node: null, value: a }); const valB = b == null ? "" : formatValue({ column, node: null, value: b }); if (valA === valB) { return 0; } return valA > valB ? 1 : -1; }, keyCreator: formatValue }; }, text() { return {}; } }; } wireBeans(beans) { this.colModel = beans.colModel; } postConstruct() { this.processDataTypeDefinitions(); this.addManagedPropertyListener("dataTypeDefinitions", (event) => { this.processDataTypeDefinitions(); this.colModel.recreateColumnDefs(event); }); } processDataTypeDefinitions() { const defaultDataTypes = this.getDefaultDataTypes(); const newDataTypeDefinitions = {}; const newFormatValueFuncs = {}; const generateFormatValueFunc = (dataTypeDefinition) => { return (params) => { const { column, node, value } = params; let valueFormatter = column.getColDef().valueFormatter; if (valueFormatter === dataTypeDefinition.groupSafeValueFormatter) { valueFormatter = dataTypeDefinition.valueFormatter; } return this.beans.valueSvc.formatValue(column, node, value, valueFormatter); }; }; for (const cellDataType of Object.keys(defaultDataTypes)) { const defaultDataTypeDef = defaultDataTypes[cellDataType]; const mergedDataTypeDefinition = { ...defaultDataTypeDef, groupSafeValueFormatter: createGroupSafeValueFormatter(defaultDataTypeDef, this.gos) }; newDataTypeDefinitions[cellDataType] = mergedDataTypeDefinition; newFormatValueFuncs[cellDataType] = generateFormatValueFunc(mergedDataTypeDefinition); } const userDataTypeDefs = this.gos.get("dataTypeDefinitions") ?? {}; const newDataTypeMatchers = {}; for (const cellDataType of Object.keys(userDataTypeDefs)) { const userDataTypeDef = userDataTypeDefs[cellDataType]; const mergedDataTypeDefinition = this.processDataTypeDefinition(userDataTypeDef, userDataTypeDefs, [cellDataType], defaultDataTypes); if (mergedDataTypeDefinition) { newDataTypeDefinitions[cellDataType] = mergedDataTypeDefinition; if (userDataTypeDef.dataTypeMatcher) { newDataTypeMatchers[cellDataType] = userDataTypeDef.dataTypeMatcher; } newFormatValueFuncs[cellDataType] = generateFormatValueFunc(mergedDataTypeDefinition); } } const { valueParser: defaultValueParser, valueFormatter: defaultValueFormatter } = defaultDataTypes.object; const { valueParser: userValueParser, valueFormatter: userValueFormatter } = newDataTypeDefinitions.object; this.hasObjectValueParser = userValueParser !== defaultValueParser; this.hasObjectValueFormatter = userValueFormatter !== defaultValueFormatter; this.formatValueFuncs = newFormatValueFuncs; this.dataTypeDefinitions = newDataTypeDefinitions; this.dataTypeMatchers = this.sortKeysInMatchers(newDataTypeMatchers, defaultDataTypes); } sortKeysInMatchers(matchers, dataTypes) { const sortedMatchers = { ...matchers }; for (const cellDataType of SORTED_CELL_DATA_TYPES_FOR_MATCHING) { delete sortedMatchers[cellDataType]; sortedMatchers[cellDataType] = matchers[cellDataType] ?? dataTypes[cellDataType].dataTypeMatcher; } return sortedMatchers; } processDataTypeDefinition(userDataTypeDef, userDataTypeDefs, alreadyProcessedDataTypes, defaultDataTypes) { let mergedDataTypeDefinition; const extendsCellDataType = userDataTypeDef.extendsDataType; if (userDataTypeDef.columnTypes) { this.isColumnTypeOverrideInDataTypeDefinitions = true; } if (userDataTypeDef.extendsDataType === userDataTypeDef.baseDataType) { let baseDataTypeDefinition = defaultDataTypes[extendsCellDataType]; const overriddenBaseDataTypeDefinition = userDataTypeDefs[extendsCellDataType]; if (baseDataTypeDefinition && overriddenBaseDataTypeDefinition) { baseDataTypeDefinition = overriddenBaseDataTypeDefinition; } if (!validateDataTypeDefinition(userDataTypeDef, baseDataTypeDefinition, extendsCellDataType)) { return; } mergedDataTypeDefinition = mergeDataTypeDefinitions(baseDataTypeDefinition, userDataTypeDef); } else { if (alreadyProcessedDataTypes.includes(extendsCellDataType)) { _warn(44); return; } const extendedDataTypeDefinition = userDataTypeDefs[extendsCellDataType]; if (!validateDataTypeDefinition(userDataTypeDef, extendedDataTypeDefinition, extendsCellDataType)) { return; } const mergedExtendedDataTypeDefinition = this.processDataTypeDefinition(extendedDataTypeDefinition, userDataTypeDefs, [...alreadyProcessedDataTypes, extendsCellDataType], defaultDataTypes); if (!mergedExtendedDataTypeDefinition) { return; } mergedDataTypeDefinition = mergeDataTypeDefinitions(mergedExtendedDataTypeDefinition, userDataTypeDef); } return { ...mergedDataTypeDefinition, groupSafeValueFormatter: createGroupSafeValueFormatter(mergedDataTypeDefinition, this.gos) }; } updateColDefAndGetColumnType(colDef, userColDef, colId) { let { cellDataType } = userColDef; if (cellDataType === undefined) { cellDataType = colDef.cellDataType; } const { field } = userColDef; if (cellDataType == null || cellDataType === true) { cellDataType = this.canInferCellDataType(colDef, userColDef) ? this.inferCellDataType(field, colId) : false; } this.addFormulaCellEditorToColDef(colDef, userColDef); if (!cellDataType) { colDef.cellDataType = false; return; } const dataTypeDefinition = this.dataTypeDefinitions[cellDataType]; if (!dataTypeDefinition) { _warn(47, { cellDataType }); return; } colDef.cellDataType = cellDataType; if (dataTypeDefinition.groupSafeValueFormatter) { colDef.valueFormatter = dataTypeDefinition.groupSafeValueFormatter; } if (dataTypeDefinition.valueParser) { colDef.valueParser = dataTypeDefinition.valueParser; } if (!dataTypeDefinition.suppressDefaultProperties) { this.setColDefPropertiesForBaseDataType(colDef, cellDataType, dataTypeDefinition, colId); } return dataTypeDefinition.columnTypes; } addFormulaCellEditorToColDef(colDef, userColDef) { const allowFormula = userColDef.allowFormula ?? colDef.allowFormula; if (!allowFormula || userColDef.cellEditor) { return; } colDef.cellEditor = "agFormulaCellEditor"; } addColumnListeners(column) { if (!this.isPendingInference) { return; } const columnStateUpdates = this.columnStateUpdatesPendingInference[column.getColId()]; if (!columnStateUpdates) { return; } const columnListener = (event) => { columnStateUpdates.add(event.key); }; column.__addEventListener("columnStateUpdated", columnListener); this.columnStateUpdateListenerDestroyFuncs.push(() => column.__removeEventListener("columnStateUpdated", columnListener)); } canInferCellDataType(colDef, userColDef) { const { gos } = this; if (!_isClientSideRowModel(gos)) { return false; } const propsToCheckForInference = { cellRenderer: true, valueGetter: true, valueParser: true, refData: true }; if (doColDefPropsPreventInference(userColDef, propsToCheckForInference)) { return false; } const columnTypes = userColDef.type === null ? colDef.type : userColDef.type; if (columnTypes) { const columnTypeDefs = gos.get("columnTypes") ?? {}; const hasPropsPreventingInference = convertColumnTypes(columnTypes).some((columnType) => { const columnTypeDef = columnTypeDefs[columnType.trim()]; return columnTypeDef && doColDefPropsPreventInference(columnTypeDef, propsToCheckForInference); }); if (hasPropsPreventingInference) { return false; } } return !doColDefPropsPreventInference(colDef, propsToCheckForInference); } inferCellDataType(field, colId) { if (!field) { return; } let value; const initialData = this.getInitialData(); if (initialData) { const fieldContainsDots = field.includes(".") && !this.gos.get("suppressFieldDotNotation"); value = _getValueUsingField(initialData, field, fieldContainsDots); } else { this.initWaitForRowData(colId); } if (value == null) { return; } const matchedType = Object.keys(this.dataTypeMatchers).find((_cellDataType) => this.dataTypeMatchers[_cellDataType](value)); return matchedType ?? "object"; } getInitialData() { const rowData = this.gos.get("rowData"); if (rowData?.length) { return rowData[0]; } else if (this.initialData) { return this.initialData; } else { const rowNodes = this.beans.rowModel.rootNode?._leafs; if (rowNodes?.length) { return rowNodes[0].data; } } return null; } initWaitForRowData(colId) { this.columnStateUpdatesPendingInference[colId] = /* @__PURE__ */ new Set; if (this.isPendingInference) { return; } this.isPendingInference = true; const columnTypeOverridesExist = this.isColumnTypeOverrideInDataTypeDefinitions; const { colAutosize, eventSvc } = this.beans; if (columnTypeOverridesExist && colAutosize) { colAutosize.shouldQueueResizeOperations = true; } const [destroyFunc] = this.addManagedEventListeners({ rowDataUpdateStarted: (event) => { const { firstRowData } = event; if (!firstRowData) { return; } destroyFunc?.(); this.isPendingInference = false; this.processColumnsPendingInference(firstRowData, columnTypeOverridesExist); this.columnStateUpdatesPendingInference = {}; if (columnTypeOverridesExist) { colAutosize?.processResizeOperations(); } eventSvc.dispatchEvent({ type: "dataTypesInferred" }); } }); } processColumnsPendingInference(firstRowData, columnTypeOverridesExist) { this.initialData = firstRowData; const state = []; this.destroyColumnStateUpdateListeners(); const newRowGroupColumnStateWithoutIndex = {}; const newPivotColumnStateWithoutIndex = {}; for (const colId of Object.keys(this.columnStateUpdatesPendingInference)) { const columnStateUpdates = this.columnStateUpdatesPendingInference[colId]; const column = this.colModel.getCol(colId); if (!column) { continue; } const oldColDef = column.getColDef(); if (!this.resetColDefIntoCol(column, "cellDataTypeInferred")) { continue; } const newColDef = column.getColDef(); if (columnTypeOverridesExist && newColDef.type && newColDef.type !== oldColDef.type) { const updatedColumnState = getUpdatedColumnState(column, columnStateUpdates); if (updatedColumnState.rowGroup && updatedColumnState.rowGroupIndex == null) { newRowGroupColumnStateWithoutIndex[colId] = updatedColumnState; } if (updatedColumnState.pivot && updatedColumnState.pivotIndex == null) { newPivotColumnStateWithoutIndex[colId] = updatedColumnState; } state.push(updatedColumnState); } } if (columnTypeOverridesExist) { state.push(...this.generateColumnStateForRowGroupAndPivotIndexes(newRowGroupColumnStateWithoutIndex, newPivotColumnStateWithoutIndex)); } if (state.length) { _applyColumnState(this.beans, { state }, "cellDataTypeInferred"); } this.initialData = null; } generateColumnStateForRowGroupAndPivotIndexes(updatedRowGroupColumnState, updatedPivotColumnState) { const existingColumnStateUpdates = {}; const { rowGroupColsSvc, pivotColsSvc } = this.beans; rowGroupColsSvc?.restoreColumnOrder(existingColumnStateUpdates, updatedRowGroupColumnState); pivotColsSvc?.restoreColumnOrder(existingColumnStateUpdates, updatedPivotColumnState); return Object.values(existingColumnStateUpdates); } resetColDefIntoCol(column, source) { const userColDef = column.getUserProvidedColDef(); if (!userColDef) { return false; } const newColDef = _addColumnDefaultAndTypes(this.beans, userColDef, column.getColId()); column.setColDef(newColDef, userColDef, source); return true; } getDateStringTypeDefinition(column) { const { dateString } = this.dataTypeDefinitions; if (!column) { return dateString; } return this.getDataTypeDefinition(column) ?? dateString; } getDateParserFunction(column) { return this.getDateStringTypeDefinition(column).dateParser; } getDateFormatterFunction(column) { return this.getDateStringTypeDefinition(column).dateFormatter; } getDateIncludesTimeFlag(cellDataType) { return cellDataType === "dateTime" || cellDataType === "dateTimeString"; } getDataTypeDefinition(column) { const colDef = column.getColDef(); if (!colDef.cellDataType) { return; } return this.dataTypeDefinitions[colDef.cellDataType]; } getBaseDataType(column) { return this.getDataTypeDefinition(column)?.baseDataType; } checkType(column, value) { if (value == null) { return true; } const dataTypeMatcher = this.getDataTypeDefinition(column)?.dataTypeMatcher; if (!dataTypeMatcher) { return true; } if (column.getColDef().allowFormula && this.beans.formula?.isFormula(value)) { return true; } return dataTypeMatcher(value); } validateColDef(colDef, userColDef, defaultColDef, colId) { if (colDef.cellDataType === "object") { const wasInferred = (colDef2) => { return colDef2?.cellDataType == null || colDef2?.cellDataType === true; }; const inferred = wasInferred(userColDef) && wasInferred(defaultColDef); const warning = (property) => _warn(48, { property, inferred, colId }); const { object } = this.dataTypeDefinitions; if (colDef.valueFormatter === object.groupSafeValueFormatter && !this.hasObjectValueFormatter) { warning("Formatter"); } if (colDef.editable && colDef.valueParser === object.valueParser && !this.hasObjectValueParser) { warning("Parser"); } } } postProcess(colDef) { const cellDataType = colDef.cellDataType; if (!cellDataType || typeof cellDataType !== "string") { return; } const { dataTypeDefinitions, beans, formatValueFuncs } = this; const dataTypeDefinition = dataTypeDefinitions[cellDataType]; if (!dataTypeDefinition) { return; } beans.colFilter?.setColDefPropsForDataType(colDef, dataTypeDefinition, formatValueFuncs[cellDataType]); } getFormatValue(cellDataType) { return this.formatValueFuncs[cellDataType]; } isColPendingInference(colId) { return this.isPendingInference && !!this.columnStateUpdatesPendingInference[colId]; } setColDefPropertiesForBaseDataType(colDef, cellDataType, dataTypeDefinition, colId) { const formatValue = this.formatValueFuncs[cellDataType]; const partialColDef = this.columnDefinitionPropsPerDataType[dataTypeDefinition.baseDataType]({ colDef, cellDataType, colModel: this.colModel, dataTypeDefinition, colId, formatValue, filterModuleBean: this.beans.filterManager }); if (colDef.cellEditor === "agFormulaCellEditor" && partialColDef.cellEditor !== colDef.cellEditor) { partialColDef.cellEditor = colDef.cellEditor; } Object.assign(colDef, partialColDef); } getDateObjectTypeDef(baseDataType) { const translate = this.getLocaleTextFunc(); const includeTime = this.getDateIncludesTimeFlag(baseDataType); return { baseDataType, valueParser: (params) => _parseDateTimeFromString(params.newValue && String(params.newValue)), valueFormatter: (params) => { if (params.value == null) { return ""; } if (!(params.value instanceof Date) || isNaN(params.value.getTime())) { return translate("invalidDate", "Invalid Date"); } return _serialiseDate(params.value, includeTime) ?? ""; }, dataTypeMatcher: (value) => value instanceof Date }; } getDateStringTypeDef(baseDataType) { const includeTime = this.getDateIncludesTimeFlag(baseDataType); return { baseDataType, dateParser: (value) => _parseDateTimeFromString(value) ?? undefined, dateFormatter: (value) => _serialiseDate(value ?? null, includeTime) ?? undefined, valueParser: (params) => _isValidDate(String(params.newValue)) ? params.newValue : null, valueFormatter: (params) => _isValidDate(String(params.value)) ? String(params.value) : "", dataTypeMatcher: (value) => typeof value === "string" && _isValidDate(value) }; } getDefaultDataTypes() { const translate = this.getLocaleTextFunc(); return { number: { baseDataType: "number", valueParser: (params) => params.newValue?.trim?.() === "" ? null : Number(params.newValue), valueFormatter: (params) => { if (params.value == null) { return ""; } if (typeof params.value !== "number" || isNaN(params.value)) { return translate("invalidNumber", "Invalid Number"); } return String(params.value); }, dataTypeMatcher: (value) => typeof value === "number" }, bigint: { baseDataType: "bigint", valueParser: (params) => { const { newValue } = params; if (newValue == null) { return null; } if (typeof newValue === "string" && newValue.trim() === "") { return null; } return _parseBigIntOrNull(newValue); }, valueFormatter: (params) => { if (params.value == null) { return ""; } if (typeof params.value !== "bigint") { return translate("invalidBigInt", "Invalid BigInt"); } return String(params.value); }, dataTypeMatcher: (value) => typeof value === "bigint" }, text: { baseDataType: "text", valueParser: (params) => params.newValue === "" ? null : _toStringOrNull(params.newValue), dataTypeMatcher: (value) => typeof value === "string" }, boolean: { baseDataType: "boolean", valueParser: (params) => { if (params.newValue == null) { return params.newValue; } return params.newValue?.trim?.() === "" ? null : String(params.newValue).toLowerCase() === "true"; }, valueFormatter: (params) => params.value == null ? "" : String(params.value), dataTypeMatcher: (value) => typeof value === "boolean" }, date: this.getDateObjectTypeDef("date"), dateString: this.getDateStringTypeDef("dateString"), dateTime: this.getDateObjectTypeDef("dateTime"), dateTimeString: { ...this.getDateStringTypeDef("dateTimeString"), dataTypeMatcher: (value) => typeof value === "string" && _isValidDateTime(value) }, object: { baseDataType: "object", valueParser: () => null, valueFormatter: (params) => _toStringOrNull(params.value) ?? "" } }; } destroyColumnStateUpdateListeners() { for (const destroyFunc of this.columnStateUpdateListenerDestroyFuncs) { destroyFunc(); } this.columnStateUpdateListenerDestroyFuncs = []; } destroy() { this.dataTypeDefinitions = {}; this.dataTypeMatchers = {}; this.formatValueFuncs = {}; this.columnStateUpdatesPendingInference = {}; this.destroyColumnStateUpdateListeners(); super.destroy(); } }; function mergeDataTypeDefinitions(parentDataTypeDefinition, childDataTypeDefinition) { const mergedDataTypeDefinition = { ...parentDataTypeDefinition, ...childDataTypeDefinition }; if (parentDataTypeDefinition.columnTypes && childDataTypeDefinition.columnTypes && childDataTypeDefinition.appendColumnTypes) { mergedDataTypeDefinition.columnTypes = [ ...convertColumnTypes(parentDataTypeDefinition.columnTypes), ...convertColumnTypes(childDataTypeDefinition.columnTypes) ]; } return mergedDataTypeDefinition; } function validateDataTypeDefinition(dataTypeDefinition, parentDataTypeDefinition, parentCellDataType) { if (!parentDataTypeDefinition) { _warn(45, { parentCellDataType }); return false; } if (parentDataTypeDefinition.baseDataType !== dataTypeDefinition.baseDataType) { _warn(46); return false; } return true; } var isNumberOrBigintType = (v) => typeof v === "bigint" || typeof v === "number"; var isNumberOrBigintBaseDataType = (v) => v === "number" || v === "bigint"; function createGroupSafeValueFormatter(dataTypeDefinition, gos) { if (!dataTypeDefinition.valueFormatter) { return; } return (params) => { const { node, colDef, column, value } = params; if (node?.group) { const aggFunc = (colDef.pivotValueColumn ?? column).getAggFunc(); if (aggFunc) { if (aggFunc === "first" || aggFunc === "last") { return dataTypeDefinition.valueFormatter(params); } const { baseDataType } = dataTypeDefinition; if (isNumberOrBigintBaseDataType(baseDataType) && aggFunc !== "count") { if (isNumberOrBigintType(value)) { return dataTypeDefinition.valueFormatter(params); } if (value == null) { return; } if (typeof value === "object") { if (typeof value.toNumber === "function") { return dataTypeDefinition.valueFormatter({ ...params, value: value.toNumber() }); } if ("value" in value) { return dataTypeDefinition.valueFormatter({ ...params, value: value.value }); } } } return; } } else if (gos.get("groupHideOpenParents") && params.column.isRowGroupActive()) { if (typeof params.value === "string" && !dataTypeDefinition.dataTypeMatcher?.(params.value)) { return; } } return dataTypeDefinition.valueFormatter(params); }; } function doesColDefPropPreventInference(colDef, checkProps, prop, comparisonValue) { if (!checkProps[prop]) { return false; } const value = colDef[prop]; if (value === null) { checkProps[prop] = false; return false; } else { return comparisonValue === undefined ? !!value : value === comparisonValue; } } function bigintComparator(valueA, valueB) { if (valueA == null) { return valueB == null ? 0 : -1; } if (valueB == null) { return 1; } const bigA = _parseBigIntOrNull(valueA); const bigB = _parseBigIntOrNull(valueB); if (bigA != null && bigB != null) { if (bigA === bigB) { return 0; } return bigA > bigB ? 1 : -1; } return 0; } function bigintAbsoluteComparator(valueA, valueB) { if (valueA == null) { return valueB == null ? 0 : -1; } if (valueB == null) { return 1; } const bigA = toAbsoluteBigInt(valueA); const bigB = toAbsoluteBigInt(valueB); if (bigA != null && bigB != null) { if (bigA === bigB) { return 0; } return bigA > bigB ? 1 : -1; } return 0; } function toAbsoluteBigInt(value) { const bigIntValue = _parseBigIntOrNull(value); if (bigIntValue == null) { return null; } return bigIntValue < 0n ? -bigIntValue : bigIntValue; } function doColDefPropsPreventInference(colDef, propsToCheckForInference) { return [ ["cellRenderer", "agSparklineCellRenderer"], ["valueGetter", undefined], ["valueParser", undefined], ["refData", undefined] ].some(([prop, comparisonValue]) => doesColDefPropPreventInference(colDef, propsToCheckForInference, prop, comparisonValue)); } function getUpdatedColumnState(column, columnStateUpdates) { const columnState = getColumnStateFromColDef(column); for (const key of columnStateUpdates) { delete columnState[key]; if (key === "rowGroup") { delete columnState.rowGroupIndex; } else if (key === "pivot") { delete columnState.pivotIndex; } } return columnState; } var DataTypeModule = { moduleName: "DataType", version: VERSION, beans: [DataTypeService], dependsOn: [CheckboxCellRendererModule] }; var ColumnFlexModule = { moduleName: "ColumnFlex", version: VERSION, beans: [ColumnFlexService] }; var ColumnNameService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colNames"; } getDisplayNameForColumn(column, location, includeAggFunc = false) { if (!column) { return null; } const headerName = this.getHeaderName(column.getColDef(), column, null, null, location); const { aggColNameSvc } = this.beans; if (includeAggFunc && aggColNameSvc) { return aggColNameSvc.getHeaderName(column, headerName); } return headerName; } getDisplayNameForProvidedColumnGroup(columnGroup, providedColumnGroup, location) { const colGroupDef = providedColumnGroup?.getColGroupDef(); if (colGroupDef) { return this.getHeaderName(colGroupDef, null, columnGroup, providedColumnGroup, location); } return null; } getDisplayNameForColumnGroup(columnGroup, location) { return this.getDisplayNameForProvidedColumnGroup(columnGroup, columnGroup.getProvidedColumnGroup(), location); } getHeaderName(colDef, column, columnGroup, providedColumnGroup, location) { const headerValueGetter = colDef.headerValueGetter; if (headerValueGetter) { const params = _addGridCommonParams(this.gos, { colDef, column, columnGroup, providedColumnGroup, location }); if (typeof headerValueGetter === "function") { return headerValueGetter(params); } else if (typeof headerValueGetter === "string") { return this.beans.expressionSvc?.evaluate(headerValueGetter, params) ?? null; } return ""; } else if (colDef.headerName != null) { return colDef.headerName; } else if (colDef.field) { return _camelCaseToHumanText(colDef.field); } return ""; } }; var ColumnViewportService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colViewport"; this.colsWithinViewport = []; this.headerColsWithinViewport = []; this.colsWithinViewportHash = ""; this.rowsOfHeadersToRenderLeft = {}; this.rowsOfHeadersToRenderRight = {}; this.rowsOfHeadersToRenderCenter = {}; this.columnsToRenderLeft = []; this.columnsToRenderRight = []; this.columnsToRenderCenter = []; } wireBeans(beans) { this.visibleCols = beans.visibleCols; this.colModel = beans.colModel; } postConstruct() { this.suppressColumnVirtualisation = this.gos.get("suppressColumnVirtualisation"); } getScrollPosition() { return this.scrollPosition; } setScrollPosition(scrollWidth, scrollPosition, afterScroll = false) { const { visibleCols } = this; const bodyWidthDirty = visibleCols.isBodyWidthDirty; const noChange = scrollWidth === this.scrollWidth && scrollPosition === this.scrollPosition && !bodyWidthDirty; if (noChange) { return; } this.scrollWidth = scrollWidth; this.scrollPosition = scrollPosition; visibleCols.isBodyWidthDirty = true; if (this.gos.get("enableRtl")) { const bodyWidth = visibleCols.bodyWidth; this.viewportLeft = bodyWidth - scrollPosition - scrollWidth; this.viewportRight = bodyWidth - scrollPosition; } else { this.viewportLeft = scrollPosition; this.viewportRight = scrollWidth + scrollPosition; } if (this.colModel.ready) { this.checkViewportColumns(afterScroll); } } getColumnHeadersToRender(type) { switch (type) { case "left": return this.columnsToRenderLeft; case "right": return this.columnsToRenderRight; default: return this.columnsToRenderCenter; } } getHeadersToRender(type, depth) { let result; switch (type) { case "left": result = this.rowsOfHeadersToRenderLeft[depth]; break; case "right": result = this.rowsOfHeadersToRenderRight[depth]; break; default: result = this.rowsOfHeadersToRenderCenter[depth]; break; } return result ?? []; } extractViewportColumns() { const displayedColumnsCenter = this.visibleCols.centerCols; if (this.isColumnVirtualisationSuppressed()) { this.colsWithinViewport = displayedColumnsCenter; this.headerColsWithinViewport = displayedColumnsCenter; } else { this.colsWithinViewport = displayedColumnsCenter.filter(this.isColumnInRowViewport.bind(this)); this.headerColsWithinViewport = displayedColumnsCenter.filter(this.isColumnInHeaderViewport.bind(this)); } } isColumnVirtualisationSuppressed() { return this.suppressColumnVirtualisation || this.viewportRight === 0; } clear() { this.rowsOfHeadersToRenderLeft = {}; this.rowsOfHeadersToRenderRight = {}; this.rowsOfHeadersToRenderCenter = {}; this.colsWithinViewportHash = ""; } isColumnInHeaderViewport(col) { if (col.isAutoHeaderHeight() || isAnyParentAutoHeaderHeight(col)) { return true; } return this.isColumnInRowViewport(col); } isColumnInRowViewport(col) { if (col.isAutoHeight()) { return true; } const columnLeft = col.getLeft() || 0; const columnRight = columnLeft + col.getActualWidth(); const leftBounds = this.viewportLeft - 200; const rightBounds = this.viewportRight + 200; const columnToMuchLeft = columnLeft < leftBounds && columnRight < leftBounds; const columnToMuchRight = columnLeft > rightBounds && columnRight > rightBounds; return !columnToMuchLeft && !columnToMuchRight; } getViewportColumns() { const { leftCols, rightCols } = this.visibleCols; const res = this.colsWithinViewport.concat(leftCols).concat(rightCols); return res; } getColsWithinViewport(rowNode) { if (!this.colModel.colSpanActive) { return this.colsWithinViewport; } const emptySpaceBeforeColumn = (col) => { const left = col.getLeft(); return _exists(left) && left > this.viewportLeft; }; const inViewportCallback = this.isColumnVirtualisationSuppressed() ? undefined : this.isColumnInRowViewport.bind(this); const { visibleCols } = this; const displayedColumnsCenter = visibleCols.centerCols; return visibleCols.getColsForRow(rowNode, displayedColumnsCenter, inViewportCallback, emptySpaceBeforeColumn); } checkViewportColumns(afterScroll = false) { const viewportColumnsChanged = this.extractViewport(); if (viewportColumnsChanged) { this.eventSvc.dispatchEvent({ type: "virtualColumnsChanged", afterScroll }); } } calculateHeaderRows() { const { leftCols, rightCols } = this.visibleCols; this.columnsToRenderLeft = leftCols; this.columnsToRenderRight = rightCols; this.columnsToRenderCenter = this.colsWithinViewport; const workOutGroupsToRender = (cols) => { const groupsToRenderSet = /* @__PURE__ */ new Set; const groupsToRender = {}; for (const col of cols) { let group = col.getParent(); const skipFillers = col.isSpanHeaderHeight(); while (group) { if (groupsToRenderSet.has(group)) { break; } const skipFillerGroup = skipFillers && group.isPadding(); if (skipFillerGroup) { group = group.getParent(); continue; } const level = group.getProvidedColumnGroup().getLevel(); groupsToRender[level] ?? (groupsToRender[level] = []); groupsToRender[level].push(group); groupsToRenderSet.add(group); group = group.getParent(); } } return groupsToRender; }; this.rowsOfHeadersToRenderLeft = workOutGroupsToRender(leftCols); this.rowsOfHeadersToRenderRight = workOutGroupsToRender(rightCols); this.rowsOfHeadersToRenderCenter = workOutGroupsToRender(this.headerColsWithinViewport); } extractViewport() { const hashColumn = (c) => `${c.getId()}-${c.getPinned() || "normal"}`; this.extractViewportColumns(); const newHash = this.getViewportColumns().map(hashColumn).join("#"); const changed = this.colsWithinViewportHash !== newHash; if (changed) { this.colsWithinViewportHash = newHash; this.calculateHeaderRows(); } return changed; } }; function isAnyParentAutoHeaderHeight(col) { while (col) { if (col.isAutoHeaderHeight()) { return true; } col = col.getParent(); } return false; } var AgComponentUtils = class extends BeanStub { constructor() { super(...arguments); this.beanName = "agCompUtils"; } adaptFunction(type, jsCompFunc) { if (!type.cellRenderer) { return null; } class Adapter { refresh() { return false; } getGui() { return this.eGui; } init(params) { const callbackResult = jsCompFunc(params); const type2 = typeof callbackResult; if (type2 === "string" || type2 === "number" || type2 === "boolean") { this.eGui = _loadTemplate("" + callbackResult + ""); return; } if (callbackResult == null) { this.eGui = _createElement({ tag: "span" }); return; } this.eGui = callbackResult; } } return Adapter; } }; var CellRendererFunctionModule = { moduleName: "CellRendererFunction", version: VERSION, beans: [AgComponentUtils] }; var BaseRegistry = class extends AgBeanStub { constructor() { super(...arguments); this.beanName = "registry"; } registerDynamicBeans(dynamicBeans) { if (dynamicBeans) { this.dynamicBeans ?? (this.dynamicBeans = {}); for (const name of Object.keys(dynamicBeans)) { this.dynamicBeans[name] = dynamicBeans[name]; } } } createDynamicBean(name, mandatory, ...args) { if (!this.dynamicBeans) { throw new Error(this.getDynamicError(name, true)); } const BeanClass = this.dynamicBeans[name]; if (BeanClass == null) { if (mandatory) { throw new Error(this.getDynamicError(name, false)); } return; } return new BeanClass(...args); } }; function isComponentMetaFunc(componentMeta) { return typeof componentMeta === "object" && !!componentMeta.getComp; } var Registry = class extends BaseRegistry { constructor() { super(...arguments); this.agGridDefaults = {}; this.agGridDefaultOverrides = {}; this.jsComps = {}; this.selectors = {}; this.icons = {}; } postConstruct() { const comps = this.gos.get("components"); if (comps != null) { for (const key of Object.keys(comps)) { this.jsComps[key] = comps[key]; } } } registerModule(module) { const { icons, userComponents, dynamicBeans, selectors } = module; if (userComponents) { const registerUserComponent = (name, component, params, processParams) => { this.agGridDefaults[name] = component; if (params || processParams) { this.agGridDefaultOverrides[name] = { params, processParams }; } }; for (const name of Object.keys(userComponents)) { let comp = userComponents[name]; if (isComponentMetaFunc(comp)) { comp = comp.getComp(this.beans); } if (typeof comp === "object") { const { classImp, params, processParams } = comp; registerUserComponent(name, classImp, params, processParams); } else { registerUserComponent(name, comp); } } } this.registerDynamicBeans(dynamicBeans); for (const selector of selectors ?? []) { this.selectors[selector.selector] = selector; } if (icons) { for (const name of Object.keys(icons)) { this.icons[name] = icons[name]; } } } getUserComponent(propertyName, name) { const createResult = (component, componentFromFramework, params, processParams) => ({ componentFromFramework, component, params, processParams }); const { frameworkOverrides } = this.beans; const registeredViaFrameworkComp = frameworkOverrides.frameworkComponent(name, this.gos.get("components")); if (registeredViaFrameworkComp != null) { return createResult(registeredViaFrameworkComp, true); } const jsComponent = this.jsComps[name]; if (jsComponent) { const isFwkComp = frameworkOverrides.isFrameworkComponent(jsComponent); return createResult(jsComponent, isFwkComp); } const defaultComponent = this.agGridDefaults[name]; if (defaultComponent) { const overrides = this.agGridDefaultOverrides[name]; return createResult(defaultComponent, false, overrides?.params, overrides?.processParams); } this.beans.validation?.missingUserComponent(propertyName, name, this.agGridDefaults, this.jsComps); return null; } getSelector(name) { return this.selectors[name]; } getIcon(name) { return this.icons[name]; } getDynamicError(name, init) { if (init) { return _errMsg(279, { name }); } return this.beans.validation?.missingDynamicBean(name) ?? _errMsg(256); } }; var NUM_CTRLS = 23; var CtrlsService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "ctrlsSvc"; this.params = {}; this.ready = false; this.readyCallbacks = []; } postConstruct() { this.addEventListener("ready", () => { this.updateReady(); if (this.ready) { for (const callback of this.readyCallbacks) { callback(this.params); } this.readyCallbacks.length = 0; } }, this.beans.frameworkOverrides.runWhenReadyAsync?.() ?? false); } updateReady() { const values = Object.values(this.params); this.ready = values.length === NUM_CTRLS && values.every((ctrl) => { return ctrl?.isAlive() ?? false; }); } whenReady(caller, callback) { if (this.ready) { callback(this.params); } else { this.readyCallbacks.push(callback); } caller.addDestroyFunc(() => { const index = this.readyCallbacks.indexOf(callback); if (index >= 0) { this.readyCallbacks.splice(index, 1); } }); } register(ctrlType, ctrl) { this.params[ctrlType] = ctrl; this.updateReady(); if (this.ready) { this.dispatchLocalEvent({ type: "ready" }); } ctrl.addDestroyFunc(() => { this.updateReady(); }); } get(ctrlType) { return this.params[ctrlType]; } getGridBodyCtrl() { return this.params.gridBodyCtrl; } getHeaderRowContainerCtrls() { const { leftHeader, centerHeader, rightHeader } = this.params; return [leftHeader, rightHeader, centerHeader]; } getHeaderRowContainerCtrl(pinned) { const params = this.params; switch (pinned) { case "left": return params.leftHeader; case "right": return params.rightHeader; default: return params.centerHeader; } } getScrollFeature() { return this.getGridBodyCtrl().scrollFeature; } }; var shared_default = ':where([class^=ag-]),:where([class^=ag-]):after,:where([class^=ag-]):before{box-sizing:border-box}:where([class^=ag-]):where(button){color:inherit}:where([class^=ag-]):where(div,span,label):focus-visible{box-shadow:inset var(--ag-focus-shadow);outline:none;&:where(.invalid){box-shadow:inset var(--ag-focus-error-shadow)}}:where([class^=ag-]) ::-ms-clear{display:none}.ag-hidden{display:none!important}.ag-invisible{visibility:hidden!important}.ag-tab-guard{display:block;height:0;position:absolute;width:0}.ag-tab-guard-top{top:1px}.ag-tab-guard-bottom{bottom:1px}.ag-measurement-container{height:0;overflow:hidden;visibility:hidden;width:0}.ag-measurement-element-border{display:inline-block}.ag-measurement-element-border:before{border-left:var(--ag-internal-measurement-border);content:"";display:block}.ag-popup-child{top:0;z-index:5}.ag-popup-child:where(:not(.ag-tooltip-custom)){box-shadow:var(--ag-popup-shadow)}.ag-input-wrapper,.ag-picker-field-wrapper{align-items:center;display:flex;flex:1 1 auto;line-height:normal;position:relative}.ag-input-field{align-items:center;display:flex;flex-direction:row}.ag-input-field-input:where(:not([type=checkbox],[type=radio])){flex:1 1 auto;min-width:0;width:100%}.ag-chart,.ag-dnd-ghost,.ag-external,.ag-popup,.ag-root-wrapper{cursor:default;line-height:normal;white-space:normal;-webkit-font-smoothing:antialiased;background-color:var(--ag-background-color);color:var(--ag-text-color);color-scheme:var(--ag-browser-color-scheme);font-family:var(--ag-font-family);font-size:var(--ag-font-size);font-weight:var(--ag-font-weight);--ag-indentation-level:0}:where(.ag-icon):before{align-items:center;background-color:currentcolor;color:inherit;content:"";display:flex;font-family:inherit;font-size:var(--ag-icon-size);font-style:normal;font-variant:normal;height:var(--ag-icon-size);justify-content:center;line-height:var(--ag-icon-size);-webkit-mask-size:contain;mask-size:contain;text-transform:none;width:var(--ag-icon-size)}.ag-icon{background-position:50%;background-repeat:no-repeat;background-size:contain;color:var(--ag-icon-color);display:block;height:var(--ag-icon-size);position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--ag-icon-size)}.ag-disabled .ag-icon,[disabled] .ag-icon{opacity:.5}.ag-icon-grip.ag-disabled,.ag-icon-grip[disabled]{opacity:.35}.ag-icon-loading{animation-duration:1s;animation-iteration-count:infinite;animation-name:spin;animation-timing-function:linear}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.ag-resizer{pointer-events:none;position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1}:where(.ag-resizer){&.ag-resizer-topLeft{cursor:nwse-resize;height:5px;left:0;top:0;width:5px}&.ag-resizer-top{cursor:ns-resize;height:5px;left:5px;right:5px;top:0}&.ag-resizer-topRight{cursor:nesw-resize;height:5px;right:0;top:0;width:5px}&.ag-resizer-right{bottom:5px;cursor:ew-resize;right:0;top:5px;width:5px}&.ag-resizer-bottomRight{bottom:0;cursor:nwse-resize;height:5px;right:0;width:5px}&.ag-resizer-bottom{bottom:0;cursor:ns-resize;height:5px;left:5px;right:5px}&.ag-resizer-bottomLeft{bottom:0;cursor:nesw-resize;height:5px;left:0;width:5px}&.ag-resizer-left{bottom:5px;cursor:ew-resize;left:0;top:5px;width:5px}}.ag-menu{background-color:var(--ag-menu-background-color);border:var(--ag-menu-border);border-radius:var(--ag-border-radius);box-shadow:var(--ag-menu-shadow);color:var(--ag-menu-text-color);max-height:100%;overflow-y:auto;position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none}'; var IS_SSR = typeof window !== "object" || !window?.document?.fonts?.forEach; var FORCE_LEGACY_THEMES = false; var _injectGlobalCSS = (rawCss, styleContainer, debugId, layer, priority, nonce, isParams = false) => { if (IS_SSR || FORCE_LEGACY_THEMES) { return; } let injectedCss = rawCss; if (layer) { injectedCss = `@layer ${CSS.escape(layer).replaceAll("\\.", ".")} { ${rawCss} }`; } let injections = injectionState.map.get(styleContainer); if (!injections) { injections = []; injectionState.map.set(styleContainer, injections); } if (injections.some((i) => i.injectedCss === injectedCss)) { return; } const el = document.createElement("style"); if (nonce) { el.setAttribute("nonce", nonce); } el.dataset.agCss = debugId; el.dataset.agCssVersion = VERSION; el.textContent = injectedCss; const newInjection = { rawCss, injectedCss, el, priority, isParams }; let insertAfter; for (const injection of injections) { if (injection.priority > priority) { break; } insertAfter = injection; } if (insertAfter) { insertAfter.el.after(el); const index = injections.indexOf(insertAfter); injections.splice(index + 1, 0, newInjection); } else { if (styleContainer.nodeName === "STYLE") { styleContainer.after(el); } else { styleContainer.insertBefore(el, styleContainer.querySelector(":not(title, meta)")); } injections.push(newInjection); } }; var _injectCoreAndModuleCSS = (styleContainer, layer, nonce, moduleCss) => { _injectGlobalCSS(shared_default, styleContainer, "shared", layer, 0, nonce); moduleCss?.forEach((css, debugId) => css.forEach((singleCss) => _injectGlobalCSS(singleCss, styleContainer, debugId, layer, 0, nonce))); }; var _useParamsCss = (environment, paramsCss, paramsDebugId, styleContainer, layer, nonce) => { if (IS_SSR || FORCE_LEGACY_THEMES) { return; } const gridState = injectionState.grids.get(environment); if (!gridState) { injectionState.grids.set(environment, { styleContainer, paramsCss }); } else { gridState.paramsCss = paramsCss; } removeStaleParamsCss(styleContainer); if (paramsCss && paramsDebugId) { _injectGlobalCSS(paramsCss, styleContainer, paramsDebugId, layer, 2, nonce, true); } }; var _unregisterInstanceUsingThemingAPI = (environment) => { const styleContainer = injectionState.grids.get(environment)?.styleContainer; if (!styleContainer) { return; } injectionState.grids.delete(environment); const containerStillInUse = Array.from(injectionState.grids.values()).some((gs) => gs.styleContainer === styleContainer); if (containerStillInUse) { removeStaleParamsCss(styleContainer); } else { removeStaleParamsCss(styleContainer, true); injectionState.map.delete(styleContainer); } }; var removeStaleParamsCss = (styleContainer, deleteAll = false) => { const neededCss = /* @__PURE__ */ new Set; for (const gs of injectionState.grids.values()) { if (gs.styleContainer === styleContainer) { neededCss.add(gs.paramsCss); } } const injections = injectionState.map.get(styleContainer) ?? []; for (let i = injections.length - 1;i >= 0; i--) { if (deleteAll || injections[i].isParams && !neededCss.has(injections[i].rawCss)) { injections[i].el.remove(); injections.splice(i, 1); } } }; var getInjectionState = () => { const versionMap = globalThis.agStyleInjectionVersions ?? (globalThis.agStyleInjectionVersions = /* @__PURE__ */ new Map); let state = versionMap.get(VERSION); if (!state) { state = { map: /* @__PURE__ */ new WeakMap, grids: /* @__PURE__ */ new Map, paramsId: 0 }; versionMap.set(VERSION, state); } return state; }; var injectionState = getInjectionState(); var createPart = (args) => { return new PartImpl(args); }; var defaultModeName = "$default"; var partCounter = 0; var PartImpl = class { constructor({ feature, params, modeParams = {}, css, cssImports }) { this.feature = feature; this.css = css; this.cssImports = cssImports; this.modeParams = { [defaultModeName]: { ...modeParams[defaultModeName] ?? {}, ...params ?? {} }, ...modeParams }; } use(styleContainer, layer, nonce) { let inject = this._inject; if (inject == null) { let { css } = this; if (css) { const className = `ag-theme-${this.feature ?? "part"}-${++partCounter}`; if (typeof css === "function") { css = css(); } css = `:where(.${className}) { ${css} } `; for (const cssImport of this.cssImports ?? []) { css = `@import url(${JSON.stringify(cssImport)}); ${css}`; } inject = { css, class: className }; } else { inject = false; } this._inject = inject; } if (inject && styleContainer) { _injectGlobalCSS(inject.css, styleContainer, inject.class, layer, 1, nonce); } return inject ? inject.class : false; } }; var kebabCase = (str) => str.replace(/[A-Z]|\d+/g, (m) => `-${m}`).toLowerCase(); var paramToVariableName = (paramName) => `--ag-${kebabCase(paramName)}`; var paramToVariableExpression = (paramName) => `var(${paramToVariableName(paramName)})`; var clamp = (value, min, max) => Math.max(min, Math.min(max, value)); var memoize = (fn) => { const values = /* @__PURE__ */ new Map; return (a) => { const key = a; if (!values.has(key)) { values.set(key, fn(a)); } return values.get(key); }; }; var accentMix = (mix) => ({ ref: "accentColor", mix }); var foregroundMix = (mix) => ({ ref: "foregroundColor", mix }); var foregroundBackgroundMix = (mix) => ({ ref: "foregroundColor", mix, onto: "backgroundColor" }); var foregroundHeaderBackgroundMix = (mix) => ({ ref: "foregroundColor", mix, onto: "headerBackgroundColor" }); var backgroundColor = { ref: "backgroundColor" }; var foregroundColor = { ref: "foregroundColor" }; var accentColor = { ref: "accentColor" }; var defaultLightColorSchemeParams = { backgroundColor: "#fff", foregroundColor: "#181d1f", borderColor: foregroundMix(0.15), chromeBackgroundColor: foregroundBackgroundMix(0.02), browserColorScheme: "light" }; var sharedDefaults = { ...defaultLightColorSchemeParams, textColor: foregroundColor, accentColor: "#2196f3", invalidColor: "#e02525", fontFamily: [ "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", "sans-serif" ], subtleTextColor: { ref: "textColor", mix: 0.5 }, borderWidth: 1, borderRadius: 4, spacing: 8, fontSize: 14, fontWeight: "inherit", focusShadow: { spread: 3, color: accentMix(0.5) }, focusErrorShadow: { spread: 3, color: { ref: "invalidColor", onto: "backgroundColor", mix: 0.5 } }, popupShadow: "0 0 16px #00000026", cardShadow: "0 1px 4px 1px #00000018", dropdownShadow: { ref: "cardShadow" }, listItemHeight: { calc: "max(iconSize, dataFontSize) + widgetVerticalSpacing" }, dragAndDropImageBackgroundColor: backgroundColor, dragAndDropImageBorder: true, dragAndDropImageNotAllowedBorder: { color: { ref: "invalidColor", onto: "dragAndDropImageBackgroundColor", mix: 0.5 } }, dragAndDropImageShadow: { ref: "popupShadow" }, iconSize: 16, iconColor: "inherit", toggleButtonWidth: 28, toggleButtonHeight: 18, toggleButtonOnBackgroundColor: accentColor, toggleButtonOffBackgroundColor: foregroundBackgroundMix(0.3), toggleButtonSwitchBackgroundColor: backgroundColor, toggleButtonSwitchInset: 2, tooltipBackgroundColor: { ref: "chromeBackgroundColor" }, tooltipErrorBackgroundColor: { ref: "invalidColor", onto: "backgroundColor", mix: 0.1 }, tooltipTextColor: { ref: "textColor" }, tooltipErrorTextColor: { ref: "invalidColor" }, tooltipBorder: true, tooltipErrorBorder: { color: { ref: "invalidColor", onto: "backgroundColor", mix: 0.25 } }, panelBackgroundColor: backgroundColor, panelTitleBarHeight: { ref: "headerHeight" }, panelTitleBarBackgroundColor: { ref: "headerBackgroundColor" }, panelTitleBarIconColor: { ref: "headerTextColor" }, panelTitleBarTextColor: { ref: "headerTextColor" }, panelTitleBarFontFamily: { ref: "headerFontFamily" }, panelTitleBarFontSize: { ref: "headerFontSize" }, panelTitleBarFontWeight: { ref: "headerFontWeight" }, panelTitleBarBorder: true, dialogShadow: { ref: "popupShadow" }, dialogBorder: { color: foregroundMix(0.2) }, widgetContainerHorizontalPadding: { calc: "spacing * 1.5" }, widgetContainerVerticalPadding: { calc: "spacing * 1.5" }, widgetHorizontalSpacing: { calc: "spacing * 1.5" }, widgetVerticalSpacing: { ref: "spacing" }, dataFontSize: { ref: "fontSize" }, headerBackgroundColor: { ref: "chromeBackgroundColor" }, headerFontFamily: { ref: "fontFamily" }, headerFontSize: { ref: "fontSize" }, headerFontWeight: 500, headerTextColor: { ref: "textColor" }, headerHeight: { calc: "max(iconSize, dataFontSize) + spacing * 4 * headerVerticalPaddingScale" }, headerVerticalPaddingScale: 1, menuBorder: { color: foregroundMix(0.2) }, menuBackgroundColor: foregroundBackgroundMix(0.03), menuTextColor: foregroundBackgroundMix(0.95), menuShadow: { ref: "popupShadow" }, menuSeparatorColor: { ref: "borderColor" } }; var paramTypes = [ "colorScheme", "color", "length", "scale", "borderStyle", "border", "shadow", "image", "fontFamily", "fontWeight", "duration" ]; var getParamType = memoize((param) => { param = param.toLowerCase(); return paramTypes.find((type) => param.endsWith(type.toLowerCase())) ?? "length"; }); var literalToCSS = (value) => { if (typeof value === "object" && value?.ref) { return paramToVariableExpression(value.ref); } if (typeof value === "string") { return value; } if (typeof value === "number") { return String(value); } return false; }; var colorValueToCss = (value) => { if (typeof value === "string") { return value; } if (typeof value === "object" && value && "ref" in value) { const colorExpr = paramToVariableExpression(value.ref); if (value.mix == null) { return colorExpr; } const backgroundExpr = value.onto ? paramToVariableExpression(value.onto) : "transparent"; return `color-mix(in srgb, ${backgroundExpr}, ${colorExpr} ${clamp(value.mix * 100, 0, 100)}%)`; } return false; }; var colorSchemeValueToCss = literalToCSS; var lengthValueToCss = (value) => { if (typeof value === "string") { return value; } if (typeof value === "number") { return `${value}px`; } if (typeof value === "object" && value && "calc" in value) { const valueWithSpaces = value.calc.replace(/ ?[*/+] ?/g, " $& "); return `calc(${valueWithSpaces.replace(/-?\b[a-z][a-z0-9]*\b(?![-(])/gi, (p) => p[0] === "-" ? p : " " + paramToVariableExpression(p) + " ")})`; } if (typeof value === "object" && value && "ref" in value) { return paramToVariableExpression(value.ref); } return false; }; var scaleValueToCss = literalToCSS; var borderValueToCss = (value, param) => { if (typeof value === "string") { return value; } if (value === true) { return borderValueToCss({}, param); } if (value === false) { return param === "columnBorder" ? borderValueToCss({ color: "transparent" }, param) : "none"; } if (typeof value === "object" && value && "ref" in value) { return paramToVariableExpression(value.ref); } return borderStyleValueToCss(value.style ?? "solid") + " " + lengthValueToCss(value.width ?? { ref: "borderWidth" }) + " " + colorValueToCss(value.color ?? { ref: "borderColor" }); }; var shadowValueParamsToCss = (value) => { return [ lengthValueToCss(value.offsetX ?? 0), lengthValueToCss(value.offsetY ?? 0), lengthValueToCss(value.radius ?? 0), lengthValueToCss(value.spread ?? 0), colorValueToCss(value.color ?? { ref: "foregroundColor" }), ...value.inset ? ["inset"] : [] ].join(" "); }; var shadowValueToCss = (value) => { if (typeof value === "string") { return value; } if (value === false) { return "none"; } if (typeof value === "object" && value && "ref" in value) { return paramToVariableExpression(value.ref); } if (Array.isArray(value)) { return value.map(shadowValueParamsToCss).join(", "); } return shadowValueParamsToCss(value); }; var borderStyleValueToCss = literalToCSS; var fontFamilyValueToCss = (value) => { if (typeof value === "string") { return value.includes(",") ? value : quoteUnsafeChars(value); } if (typeof value === "object" && value && "googleFont" in value) { return fontFamilyValueToCss(value.googleFont); } if (typeof value === "object" && value && "ref" in value) { return paramToVariableExpression(value.ref); } if (Array.isArray(value)) { return value.map((font) => { if (typeof font === "object" && "googleFont" in font) { font = font.googleFont; } return quoteUnsafeChars(font); }).join(", "); } return false; }; var quoteUnsafeChars = (font) => /^[\w-]+$|\w\(/.test(font) ? font : JSON.stringify(font); var fontWeightValueToCss = literalToCSS; var imageValueToCss = (value) => { if (typeof value === "string") { return value; } if (typeof value === "object" && value && "url" in value) { return `url(${JSON.stringify(value.url)})`; } if (typeof value === "object" && value && "svg" in value) { return imageValueToCss({ url: `data:image/svg+xml,${encodeURIComponent(value.svg)}` }); } if (typeof value === "object" && value && "ref" in value) { return paramToVariableExpression(value.ref); } return false; }; var durationValueToCss = (value, param, themeLogger) => { if (typeof value === "string") { return value; } if (typeof value === "number") { if (value >= 10) { themeLogger?.warn(104, { value, param }); } return `${value}s`; } if (typeof value === "object" && value && "ref" in value) { return paramToVariableExpression(value.ref); } return false; }; var paramValidators = { color: colorValueToCss, colorScheme: colorSchemeValueToCss, length: lengthValueToCss, scale: scaleValueToCss, border: borderValueToCss, borderStyle: borderStyleValueToCss, shadow: shadowValueToCss, image: imageValueToCss, fontFamily: fontFamilyValueToCss, fontWeight: fontWeightValueToCss, duration: durationValueToCss }; var paramValueToCss = (param, value, themeLogger) => { const type = getParamType(param); return paramValidators[type](value, param, themeLogger); }; var createSharedTheme = (themeLogger, overridePrefix) => new ThemeImpl({ themeLogger, overridePrefix }); var ThemeImpl = class _ThemeImpl { constructor(params, parts = []) { this.params = params; this.parts = parts; } withPart(part) { if (typeof part === "function") { part = part(); } if (!(part instanceof PartImpl)) { this.params.themeLogger.preInitErr(259, "Invalid part", { part }); return this; } return new _ThemeImpl(this.params, [...this.parts, part]); } withoutPart(feature) { return this.withPart(createPart({ feature })); } withParams(params, mode = defaultModeName) { return this.withPart(createPart({ modeParams: { [mode]: params } })); } _startUse({ styleContainer, cssLayer, nonce, loadThemeGoogleFonts, moduleCss }) { if (IS_SSR) { return; } if (FORCE_LEGACY_THEMES) { return; } uninstallLegacyCSS(); _injectCoreAndModuleCSS(styleContainer, cssLayer, nonce, moduleCss); const googleFontsUsed = getGoogleFontsUsed(this); if (googleFontsUsed.length > 0) { for (const googleFont of googleFontsUsed) { if (loadThemeGoogleFonts) { loadGoogleFont(googleFont, nonce); } } } for (const part of this.parts) { part.use(styleContainer, cssLayer, nonce); } } _getCssClass() { if (FORCE_LEGACY_THEMES) { return "ag-theme-quartz"; } return this._cssClassCache ?? (this._cssClassCache = deduplicatePartsByFeature(this.parts).map((part) => part.use(undefined, undefined, undefined)).filter(Boolean).concat(this._getParamsClassName()).join(" ")); } _getParamsClassName() { return this._paramsClassName ?? (this._paramsClassName = `ag-theme-params-${++getInjectionState().paramsId}`); } _getModeParams() { let paramsCache = this._paramsCache; if (!paramsCache) { const mergedModeParams = { [defaultModeName]: { ...sharedDefaults } }; for (const part of deduplicatePartsByFeature(this.parts)) { for (const partMode of Object.keys(part.modeParams)) { const partParams = part.modeParams[partMode]; if (partParams) { const mergedParams = mergedModeParams[partMode] ?? (mergedModeParams[partMode] = {}); const partParamNames = /* @__PURE__ */ new Set; for (const partParamName of Object.keys(partParams)) { const partParamValue = partParams[partParamName]; if (partParamValue !== undefined) { mergedParams[partParamName] = partParamValue; partParamNames.add(partParamName); } } if (partMode === defaultModeName) { for (const mergedMode of Object.keys(mergedModeParams)) { const mergedParams2 = mergedModeParams[mergedMode]; if (mergedMode !== defaultModeName) { for (const partParamName of partParamNames) { delete mergedParams2[partParamName]; } } } } } } } this._paramsCache = paramsCache = mergedModeParams; } return paramsCache; } _getParamsCss() { if (!this._paramsCssCache) { let variablesCss = ""; let inheritanceCss = ""; const modeParams = this._getModeParams(); const { overridePrefix, themeLogger } = this.params; const cssOverridePrefix = overridePrefix ? `--ag-${overridePrefix}-` : undefined; for (const mode of Object.keys(modeParams)) { const params = modeParams[mode]; if (mode !== defaultModeName) { const escapedMode = typeof CSS === "object" ? CSS.escape(mode) : mode; const wrapPrefix = `:where([data-ag-theme-mode="${escapedMode}"]) & { `; variablesCss += wrapPrefix; inheritanceCss += wrapPrefix; } for (const key of Object.keys(params).sort()) { const value = params[key]; const cssValue = paramValueToCss(key, value, themeLogger); if (cssValue === false) { themeLogger.error(107, { key, value }); } else { const cssName = paramToVariableName(key); const overrideName = cssOverridePrefix ? cssName.replace("--ag-", cssOverridePrefix) : cssName; const inheritedName = cssName.replace("--ag-", "--ag-inherited-"); variablesCss += ` ${cssName}: var(${inheritedName}, ${cssValue}); `; inheritanceCss += ` ${inheritedName}: var(${overrideName}); `; } } if (mode !== defaultModeName) { variablesCss += `} `; inheritanceCss += `} `; } } const selectorPlaceholder = `:where(.${this._getParamsClassName()})`; let css = `${selectorPlaceholder} { ${variablesCss}} `; css += `:has(> ${selectorPlaceholder}):not(${selectorPlaceholder}) { ${inheritanceCss}} `; this._paramsCssCache = css; } return this._paramsCssCache; } }; var deduplicatePartsByFeature = (parts) => { const lastPartByFeature = /* @__PURE__ */ new Map; for (const part of parts) { lastPartByFeature.set(part.feature, part); } const result = []; for (const part of parts) { if (!part.feature || lastPartByFeature.get(part.feature) === part) { result.push(part); } } return result; }; var getGoogleFontsUsed = (theme) => { const googleFontsUsed = /* @__PURE__ */ new Set; const visitParamValue = (paramValue) => { if (Array.isArray(paramValue)) { paramValue.forEach(visitParamValue); } else { const googleFont = paramValue?.googleFont; if (typeof googleFont === "string") { googleFontsUsed.add(googleFont); } } }; const allModeValues = Object.values(theme._getModeParams()); const allValues = allModeValues.flatMap((mv) => Object.values(mv)); allValues.forEach(visitParamValue); return Array.from(googleFontsUsed).sort(); }; var uninstalledLegacyCSS = false; var uninstallLegacyCSS = () => { if (uninstalledLegacyCSS) { return; } uninstalledLegacyCSS = true; for (const style of Array.from(document.head.querySelectorAll('style[data-ag-scope="legacy"]'))) { style.remove(); } }; var loadGoogleFont = async (font, nonce) => { const css = `@import url('https://${googleFontsDomain}/css2?family=${encodeURIComponent(font)}:wght@100;200;300;400;500;600;700;800;900&display=swap'); `; _injectGlobalCSS(css, document.head, `googleFont:${font}`, undefined, 0, nonce); }; var googleFontsDomain = "fonts.googleapis.com"; var LIST_ITEM_HEIGHT = { changeKey: "listItemHeight", type: "length", defaultValue: 24 }; var BaseEnvironment = class extends AgBeanStub { constructor() { super(...arguments); this.beanName = "environment"; this.sizeEls = /* @__PURE__ */ new Map; this.lastKnownValues = /* @__PURE__ */ new Map; this.sizesMeasured = false; this.globalCSS = []; } wireBeans(beans) { this.eRootDiv = beans.eRootDiv; } postConstruct() { const { gos, eRootDiv } = this; gos.setInstanceDomData(eRootDiv); const themeStyleContainer = gos.get("themeStyleContainer"); const hasShadowRootGlobal = typeof ShadowRoot !== "undefined"; const isShadowRoot = hasShadowRootGlobal && eRootDiv.getRootNode() instanceof ShadowRoot; this.eStyleContainer = (typeof themeStyleContainer === "function" ? themeStyleContainer() : themeStyleContainer) ?? (isShadowRoot ? eRootDiv : document.head); if (!themeStyleContainer && !isShadowRoot && hasShadowRootGlobal) { warnOnAttachToShadowRoot(eRootDiv, this.shadowRootError.bind(this), this.addDestroyFunc.bind(this)); } this.cssLayer = gos.get("themeCssLayer"); this.styleNonce = gos.get("styleNonce"); this.addManagedPropertyListener("theme", () => this.handleThemeChange()); this.handleThemeChange(); this.getSizeEl(LIST_ITEM_HEIGHT); this.initVariables(); this.addDestroyFunc(() => _unregisterInstanceUsingThemingAPI(this)); this.mutationObserver = new MutationObserver(() => { this.fireStylesChangedEvent("theme"); }); this.addDestroyFunc(() => this.mutationObserver.disconnect()); } applyThemeClasses(el, extraClasses = []) { const { theme } = this; const themeClass = theme ? theme._getCssClass() : this.applyLegacyThemeClasses(); for (const className of Array.from(el.classList)) { if (className.startsWith("ag-theme-")) { el.classList.remove(className); } } if (themeClass) { const oldClass = el.className; el.className = `${oldClass}${oldClass ? " " : ""}${themeClass}${extraClasses?.length ? " " + extraClasses.join(" ") : ""}`; } } applyLegacyThemeClasses() { let themeClass = ""; this.mutationObserver.disconnect(); let node = this.eRootDiv; while (node) { let isThemeEl = false; for (const className of Array.from(node.classList)) { if (className.startsWith("ag-theme-")) { isThemeEl = true; themeClass = themeClass ? `${themeClass} ${className}` : className; } } if (isThemeEl) { this.mutationObserver.observe(node, { attributes: true, attributeFilter: ["class"] }); } node = node.parentElement; } return themeClass; } addGlobalCSS(css, debugId) { if (this.theme) { _injectGlobalCSS(css, this.eStyleContainer, debugId, this.cssLayer, 0, this.styleNonce); } else { this.globalCSS.push([css, debugId]); } } getDefaultListItemHeight() { return this.getCSSVariablePixelValue(LIST_ITEM_HEIGHT); } getCSSVariablePixelValue(variable) { const cached = this.lastKnownValues.get(variable); if (cached != null) { return cached; } const measurement = this.measureSizeEl(variable); if (measurement === "detached" || measurement === "no-styles") { if (variable.cacheDefault) { this.lastKnownValues.set(variable, variable.defaultValue); } return variable.defaultValue; } this.lastKnownValues.set(variable, measurement); return measurement; } measureSizeEl(variable) { const sizeEl = this.getSizeEl(variable); if (sizeEl.offsetParent == null) { return "detached"; } const newSize = sizeEl.offsetWidth; if (newSize === NO_VALUE_SENTINEL) { return "no-styles"; } this.sizesMeasured = true; return newSize; } getMeasurementContainer() { let container = this.eMeasurementContainer; if (!container) { container = this.eMeasurementContainer = _createAgElement({ tag: "div", cls: "ag-measurement-container" }); this.eRootDiv.appendChild(container); } return container; } getSizeEl(variable) { let sizeEl = this.sizeEls.get(variable); if (sizeEl) { return sizeEl; } const container = this.getMeasurementContainer(); sizeEl = _createAgElement({ tag: "div" }); const cssName = this.setSizeElStyles(sizeEl, variable); container.appendChild(sizeEl); this.sizeEls.set(variable, sizeEl); const { type, noWarn } = variable; if (type !== "length" && type !== "border") { return sizeEl; } let lastMeasurement = this.measureSizeEl(variable); if (lastMeasurement === "no-styles" && !noWarn) { this.varError(cssName, variable.defaultValue); } const unsubscribe = _observeResize(this.beans, sizeEl, () => { const newMeasurement = this.measureSizeEl(variable); if (newMeasurement === "detached" || newMeasurement === "no-styles") { return; } this.lastKnownValues.set(variable, newMeasurement); if (newMeasurement !== lastMeasurement) { lastMeasurement = newMeasurement; this.fireStylesChangedEvent(variable.changeKey); } }); this.addDestroyFunc(() => unsubscribe()); return sizeEl; } setSizeElStyles(sizeEl, variable) { const { changeKey, type } = variable; let cssName = paramToVariableName(changeKey); if (type === "border") { if (cssName.endsWith("-width")) { cssName = cssName.slice(0, -6); } sizeEl.className = "ag-measurement-element-border"; sizeEl.style.setProperty("--ag-internal-measurement-border", `var(${cssName}, solid ${NO_VALUE_SENTINEL}px)`); } else { sizeEl.style.width = `var(${cssName}, ${NO_VALUE_SENTINEL}px)`; } return cssName; } handleThemeChange() { const { gos, theme: oldTheme } = this; const themeProperty = gos.get("theme"); let newTheme; if (themeProperty === "legacy") { newTheme = undefined; } else { const themeOrDefault = themeProperty ?? this.getDefaultTheme(); if (themeOrDefault instanceof ThemeImpl) { newTheme = themeOrDefault; } else { this.themeError(themeOrDefault); } } if (newTheme !== oldTheme) { this.handleNewTheme(newTheme); } this.postProcessThemeChange(newTheme, themeProperty); } handleNewTheme(newTheme) { const { gos, eRootDiv, globalCSS } = this; const additionalCss = this.getAdditionalCss(); if (newTheme) { _injectCoreAndModuleCSS(this.eStyleContainer, this.cssLayer, this.styleNonce, additionalCss); for (const [css, debugId] of globalCSS) { _injectGlobalCSS(css, this.eStyleContainer, debugId, this.cssLayer, 0, this.styleNonce); } globalCSS.length = 0; } this.theme = newTheme; newTheme?._startUse({ loadThemeGoogleFonts: gos.get("loadThemeGoogleFonts"), styleContainer: this.eStyleContainer, cssLayer: this.cssLayer, nonce: this.styleNonce, moduleCss: additionalCss }); _useParamsCss(this, newTheme?._getParamsCss() ?? null, newTheme?._getParamsClassName() ?? null, this.eStyleContainer, this.cssLayer, this.styleNonce); this.applyThemeClasses(eRootDiv); this.fireStylesChangedEvent("theme"); } fireStylesChangedEvent(change) { this.eventSvc.dispatchEvent({ type: "stylesChanged", [`${change}Changed`]: true }); } }; var NO_VALUE_SENTINEL = 15538; var warnOnAttachToShadowRoot = (el, errorCallback, onDestroy) => { let retries = 60; const interval = setInterval(() => { if (typeof ShadowRoot !== "undefined" && el.getRootNode() instanceof ShadowRoot) { errorCallback(); clearInterval(interval); } if (el.isConnected || --retries < 0) { clearInterval(interval); } }, 1000); onDestroy(() => clearInterval(interval)); }; var core_default = ".ag-aria-description-container{border:0;z-index:9999;clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.ag-unselectable{-webkit-user-select:none;-moz-user-select:none;user-select:none}.ag-selectable{-webkit-user-select:text;-moz-user-select:text;user-select:text}.ag-shake-left-to-right{animation-direction:alternate;animation-duration:.2s;animation-iteration-count:infinite;animation-name:ag-shake-left-to-right}@keyframes ag-shake-left-to-right{0%{padding-left:6px;padding-right:2px}to{padding-left:2px;padding-right:6px}}.ag-body-horizontal-scroll-viewport,.ag-body-vertical-scroll-viewport,.ag-body-viewport,.ag-center-cols-viewport,.ag-floating-bottom-viewport,.ag-floating-top-viewport,.ag-header-viewport,.ag-sticky-bottom-viewport,.ag-sticky-top-viewport{flex:1 1 auto;height:100%;min-width:0;overflow:hidden;position:relative}.ag-viewport{position:relative}.ag-spanning-container{position:absolute;top:0;z-index:1}.ag-body-viewport,.ag-center-cols-viewport,.ag-floating-bottom-viewport,.ag-floating-top-viewport,.ag-header-viewport,.ag-sticky-bottom-viewport,.ag-sticky-top-viewport{overflow-x:auto;-ms-overflow-style:none!important;scrollbar-width:none!important}.ag-body-viewport::-webkit-scrollbar,.ag-center-cols-viewport::-webkit-scrollbar,.ag-floating-bottom-viewport::-webkit-scrollbar,.ag-floating-top-viewport::-webkit-scrollbar,.ag-header-viewport::-webkit-scrollbar,.ag-sticky-bottom-viewport::-webkit-scrollbar,.ag-sticky-top-viewport::-webkit-scrollbar{display:none!important}.ag-body-viewport{display:flex;overflow-x:hidden;&:where(.ag-layout-normal){overflow-y:auto;-webkit-overflow-scrolling:touch}}.ag-floating-bottom-container,.ag-floating-top-container,.ag-sticky-bottom-container,.ag-sticky-top-container{min-height:1px}.ag-center-cols-viewport{min-height:100%;width:100%}.ag-body-horizontal-scroll-viewport{overflow-x:scroll}.ag-body-vertical-scroll-viewport{overflow-y:scroll}.ag-body-container,.ag-body-horizontal-scroll-container,.ag-body-vertical-scroll-container,.ag-center-cols-container,.ag-floating-bottom-container,.ag-floating-bottom-full-width-container,.ag-floating-top-container,.ag-full-width-container,.ag-header-container,.ag-pinned-left-cols-container,.ag-pinned-left-sticky-bottom,.ag-pinned-right-cols-container,.ag-pinned-right-sticky-bottom,.ag-sticky-bottom-container,.ag-sticky-top-container{position:relative}.ag-floating-bottom-container,.ag-floating-top-container,.ag-header-container,.ag-pinned-left-floating-bottom,.ag-pinned-left-floating-top,.ag-pinned-right-floating-bottom,.ag-pinned-right-floating-top,.ag-sticky-bottom-container,.ag-sticky-top-container{height:100%;white-space:nowrap}.ag-center-cols-container,.ag-pinned-right-cols-container{display:block}.ag-body-horizontal-scroll-container{height:100%}.ag-body-vertical-scroll-container{width:100%}.ag-floating-bottom-full-width-container,.ag-floating-top-full-width-container,.ag-full-width-container,.ag-sticky-bottom-full-width-container,.ag-sticky-top-full-width-container{pointer-events:none;position:absolute;top:0}:where(.ag-ltr) .ag-floating-bottom-full-width-container,:where(.ag-ltr) .ag-floating-top-full-width-container,:where(.ag-ltr) .ag-full-width-container,:where(.ag-ltr) .ag-sticky-bottom-full-width-container,:where(.ag-ltr) .ag-sticky-top-full-width-container{left:0}:where(.ag-rtl) .ag-floating-bottom-full-width-container,:where(.ag-rtl) .ag-floating-top-full-width-container,:where(.ag-rtl) .ag-full-width-container,:where(.ag-rtl) .ag-sticky-bottom-full-width-container,:where(.ag-rtl) .ag-sticky-top-full-width-container{right:0}.ag-full-width-container{width:100%}.ag-floating-bottom-full-width-container,.ag-floating-top-full-width-container{display:inline-block;height:100%;overflow:hidden;width:100%}.ag-body{display:flex;flex:1 1 auto;flex-direction:row!important;min-height:0;position:relative}.ag-body-horizontal-scroll,.ag-body-vertical-scroll{display:flex;min-height:0;min-width:0;position:relative;&:where(.ag-scrollbar-invisible){bottom:0;position:absolute;&:where(.ag-apple-scrollbar){opacity:0;transition:opacity .4s;visibility:hidden;&:where(.ag-scrollbar-active),&:where(.ag-scrollbar-scrolling){opacity:1;visibility:visible}}}}.ag-body-horizontal-scroll{width:100%;&:where(.ag-scrollbar-invisible){left:0;right:0}}.ag-body-vertical-scroll{height:100%;&:where(.ag-scrollbar-invisible){top:0;z-index:10}}:where(.ag-ltr) .ag-body-vertical-scroll{&:where(.ag-scrollbar-invisible){right:0}}:where(.ag-rtl) .ag-body-vertical-scroll{&:where(.ag-scrollbar-invisible){left:0}}.ag-force-vertical-scroll{overflow-y:scroll!important}.ag-horizontal-left-spacer,.ag-horizontal-right-spacer{height:100%;min-width:0;overflow-x:scroll;&:where(.ag-scroller-corner){overflow-x:hidden}}:where(.ag-row-animation) .ag-row{transition:transform .4s,top .4s,opacity .2s;&:where(.ag-after-created){transition:transform .4s,top .4s,height .4s,opacity .2s}}:where(.ag-row-animation.ag-prevent-animation) .ag-row{transition:none!important;&:where(.ag-row.ag-after-created){transition:none!important}}:where(.ag-row-no-animation) .ag-row{transition:none}.ag-row-loading{align-items:center;display:flex}.ag-row-position-absolute{position:absolute}.ag-row-position-relative{position:relative}.ag-full-width-row{overflow:hidden;pointer-events:all}.ag-row-inline-editing{z-index:1}.ag-row-dragging{z-index:2}.ag-stub-cell{align-items:center;display:flex}.ag-cell{display:inline-block;height:100%;position:absolute;white-space:nowrap;&:focus-visible{box-shadow:none}}.ag-cell-value{flex:1 1 auto}.ag-cell-value:not(.ag-allow-overflow),.ag-group-value{overflow:hidden;text-overflow:ellipsis}.ag-cell-wrap-text{white-space:normal;word-break:break-word}:where(.ag-cell) .ag-icon{display:inline-block;vertical-align:middle}.ag-floating-top{display:flex;overflow:hidden;position:relative;white-space:nowrap;width:100%}:where(.ag-floating-top:not(.ag-invisible)){border-bottom:var(--ag-pinned-row-border)}.ag-floating-bottom{display:flex;overflow:hidden;position:relative;white-space:nowrap;width:100%}:where(.ag-floating-bottom:not(.ag-invisible)){border-top:var(--ag-pinned-row-border)}.ag-sticky-bottom,.ag-sticky-top{background-color:var(--ag-data-background-color);display:flex;height:0;overflow:hidden;position:absolute;width:100%;z-index:1}.ag-sticky-bottom{box-sizing:content-box!important;:where(.ag-pinned-left-sticky-bottom),:where(.ag-pinned-right-sticky-bottom),:where(.ag-sticky-bottom-container){border-top:var(--ag-row-border);box-sizing:border-box}}.ag-opacity-zero{opacity:0!important}.ag-cell-label-container{align-items:center;display:flex;flex-direction:row-reverse;height:100%;justify-content:space-between;width:100%}:where(.ag-right-aligned-header){.ag-cell-label-container{flex-direction:row}.ag-header-cell-text{text-align:end}}.ag-column-group-icons{display:block;:where(.ag-column-group-closed-icon),:where(.ag-column-group-opened-icon){cursor:pointer}}:where(.ag-ltr){direction:ltr;.ag-body,.ag-body-horizontal-scroll,.ag-body-viewport,.ag-floating-bottom,.ag-floating-top,.ag-header,.ag-sticky-bottom,.ag-sticky-top{flex-direction:row}}:where(.ag-rtl){direction:rtl;text-align:right;.ag-body,.ag-body-horizontal-scroll,.ag-body-viewport,.ag-floating-bottom,.ag-floating-top,.ag-header,.ag-sticky-bottom,.ag-sticky-top{flex-direction:row-reverse}.ag-icon-contracted,.ag-icon-expanded,.ag-icon-tree-closed{display:block}}:where(.ag-rtl){.ag-icon-contracted,.ag-icon-expanded,.ag-icon-tree-closed{transform:rotate(180deg)}}:where(.ag-rtl){.ag-icon-contracted,.ag-icon-expanded,.ag-icon-tree-closed{transform:rotate(-180deg)}}:where(.ag-ltr) .ag-row:not(.ag-row-level-0) .ag-pivot-leaf-group{margin-left:var(--ag-row-group-indent-size)}:where(.ag-rtl) .ag-row:not(.ag-row-level-0) .ag-pivot-leaf-group{margin-right:var(--ag-row-group-indent-size)}:where(.ag-ltr) .ag-row-group-leaf-indent{margin-left:calc(var(--ag-cell-widget-spacing) + var(--ag-icon-size))}:where(.ag-rtl) .ag-row-group-leaf-indent{margin-right:calc(var(--ag-cell-widget-spacing) + var(--ag-icon-size))}.ag-value-change-delta{padding:0 2px}.ag-value-change-delta-up{color:var(--ag-value-change-delta-up-color)}.ag-value-change-delta-down{color:var(--ag-value-change-delta-down-color)}.ag-value-change-value{background-color:transparent;border-radius:1px;padding-left:1px;padding-right:1px;transition:background-color 1s}.ag-value-change-value-highlight{background-color:var(--ag-value-change-value-highlight-background-color);transition:background-color .1s}.ag-cell-data-changed{background-color:var(--ag-value-change-value-highlight-background-color)!important}.ag-cell-data-changed-animation{background-color:transparent}.ag-cell-highlight{background-color:var(--ag-range-selection-highlight-color)!important}.ag-row,.ag-spanned-row{color:var(--ag-cell-text-color);font-family:var(--ag-cell-font-family);font-size:var(--ag-cell-font-size);font-weight:var(--ag-cell-font-weight);white-space:nowrap;--ag-internal-content-line-height:calc(min(var(--ag-row-height), var(--ag-line-height, 1000px)) - var(--ag-internal-row-border-width, 1px) - 2px)}.ag-row{background-color:var(--ag-data-background-color);border-bottom:var(--ag-row-border);height:var(--ag-row-height);width:100%;&.ag-row-editing-invalid{background-color:var(--ag-full-row-edit-invalid-background-color)}}:where(.ag-body-vertical-content-no-gap>div>div>div,.ag-body-vertical-content-no-gap>div>div>div>div)>.ag-row-last{border-bottom-color:transparent}.ag-group-contracted,.ag-group-expanded{cursor:pointer}.ag-cell,.ag-full-width-row .ag-cell-wrapper.ag-row-group{border:1px solid transparent;line-height:var(--ag-internal-content-line-height);-webkit-font-smoothing:subpixel-antialiased}:where(.ag-ltr) .ag-cell{border-right:var(--ag-column-border)}:where(.ag-rtl) .ag-cell{border-left:var(--ag-column-border)}.ag-spanned-cell-wrapper{background-color:var(--ag-data-background-color);position:absolute}.ag-spanned-cell-wrapper>.ag-spanned-cell{display:block;position:relative}:where(.ag-ltr) :where(.ag-body-horizontal-content-no-gap) .ag-column-last{border-right-color:transparent}:where(.ag-rtl) :where(.ag-body-horizontal-content-no-gap) .ag-column-last{border-left-color:transparent}.ag-cell-wrapper{align-items:center;display:flex;>:where(:not(.ag-cell-value,.ag-group-value)){align-items:center;display:flex;height:var(--ag-internal-content-line-height)}&:where(.ag-row-group){align-items:flex-start}:where(.ag-full-width-row) &:where(.ag-row-group){align-items:center;height:100%}}:where(.ag-ltr) .ag-cell-wrapper{padding-left:calc(var(--ag-indentation-level)*var(--ag-row-group-indent-size))}:where(.ag-rtl) .ag-cell-wrapper{padding-right:calc(var(--ag-indentation-level)*var(--ag-row-group-indent-size))}:where(.ag-cell-wrap-text:not(.ag-cell-auto-height)) .ag-cell-wrapper{align-items:normal;height:100%;:where(.ag-cell-value){height:100%}}:where(.ag-ltr) .ag-row>.ag-cell-wrapper.ag-row-group{padding-left:calc(var(--ag-cell-horizontal-padding) + var(--ag-row-group-indent-size)*var(--ag-indentation-level))}:where(.ag-rtl) .ag-row>.ag-cell-wrapper.ag-row-group{padding-right:calc(var(--ag-cell-horizontal-padding) + var(--ag-row-group-indent-size)*var(--ag-indentation-level))}.ag-cell-focus:not(.ag-cell-range-selected):focus-within,.ag-cell-range-single-cell,.ag-cell-range-single-cell.ag-cell-range-handle,.ag-context-menu-open .ag-cell-focus:not(.ag-cell-range-selected),.ag-context-menu-open .ag-full-width-row.ag-row-focus .ag-cell-wrapper.ag-row-group,.ag-full-width-row.ag-row-focus:focus .ag-cell-wrapper.ag-row-group{border:1px solid;border-color:var(--ag-range-selection-border-color);border-style:var(--ag-range-selection-border-style);outline:initial}.ag-full-width-row.ag-row-focus:focus{box-shadow:none}:where(.ag-ltr) .ag-group-contracted,:where(.ag-ltr) .ag-group-expanded,:where(.ag-ltr) .ag-row-drag,:where(.ag-ltr) .ag-selection-checkbox{margin-right:var(--ag-cell-widget-spacing)}:where(.ag-rtl) .ag-group-contracted,:where(.ag-rtl) .ag-group-expanded,:where(.ag-rtl) .ag-row-drag,:where(.ag-rtl) .ag-selection-checkbox{margin-left:var(--ag-cell-widget-spacing)}.ag-drag-handle-disabled{opacity:.35;pointer-events:none}:where(.ag-ltr) .ag-group-child-count{margin-left:3px}:where(.ag-rtl) .ag-group-child-count{margin-right:3px}.ag-row-highlight-above:after,.ag-row-highlight-below:after,.ag-row-highlight-inside:after{background-color:var(--ag-row-drag-indicator-color);border-radius:calc(var(--ag-row-drag-indicator-width)/2);content:\"\";height:var(--ag-row-drag-indicator-width);pointer-events:none;position:absolute;width:calc(100% - 1px)}:where(.ag-ltr) .ag-row-highlight-above:after,:where(.ag-ltr) .ag-row-highlight-below:after,:where(.ag-ltr) .ag-row-highlight-inside:after{left:1px}:where(.ag-rtl) .ag-row-highlight-above:after,:where(.ag-rtl) .ag-row-highlight-below:after,:where(.ag-rtl) .ag-row-highlight-inside:after{right:1px}.ag-row-highlight-above:after{top:0}.ag-row-highlight-below:after{bottom:0}.ag-row-highlight-indent:after{display:block;width:auto}:where(.ag-ltr) .ag-row-highlight-indent:after{left:calc((var(--ag-cell-widget-spacing) + var(--ag-icon-size))*2 + var(--ag-cell-horizontal-padding) + var(--ag-row-highlight-level)*var(--ag-row-group-indent-size));right:1px}:where(.ag-rtl) .ag-row-highlight-indent:after{left:1px;right:calc((var(--ag-cell-widget-spacing) + var(--ag-icon-size))*2 + var(--ag-cell-horizontal-padding) + var(--ag-row-highlight-level)*var(--ag-row-group-indent-size))}.ag-row-highlight-inside:after{background-color:var(--ag-selected-row-background-color);border:1px solid var(--ag-range-selection-border-color);display:block;height:auto;inset:0;width:auto}.ag-body,.ag-floating-bottom,.ag-floating-top{background-color:var(--ag-data-background-color)}.ag-row-odd{background-color:var(--ag-odd-row-background-color)}.ag-row-selected:before{background-color:var(--ag-selected-row-background-color);content:\"\";display:block;inset:0;pointer-events:none;position:absolute}.ag-row-hover.ag-full-width-row.ag-row-group:before,.ag-row-hover:not(.ag-full-width-row):before{background-color:var(--ag-row-hover-color);content:\"\";display:block;inset:0;pointer-events:none;position:absolute}.ag-row-hover.ag-row-selected:before{background-color:var(--ag-row-hover-color);background-image:linear-gradient(var(--ag-selected-row-background-color),var(--ag-selected-row-background-color))}.ag-row.ag-full-width-row.ag-row-group>*{position:relative}.ag-column-hover{background-color:var(--ag-column-hover-color)}.ag-header-range-highlight{background-color:var(--ag-range-header-highlight-color)}.ag-right-aligned-cell{font-variant-numeric:tabular-nums}:where(.ag-ltr) .ag-right-aligned-cell{text-align:right}:where(.ag-rtl) .ag-right-aligned-cell{text-align:left}.ag-right-aligned-cell .ag-cell-value,.ag-right-aligned-cell .ag-group-value{margin-left:auto}:where(.ag-ltr) .ag-cell:not(.ag-cell-inline-editing),:where(.ag-ltr) .ag-full-width-row .ag-cell-wrapper.ag-row-group{padding-left:calc(var(--ag-cell-horizontal-padding) - 1px + var(--ag-row-group-indent-size)*var(--ag-indentation-level));padding-right:calc(var(--ag-cell-horizontal-padding) - 1px)}:where(.ag-rtl) .ag-cell:not(.ag-cell-inline-editing),:where(.ag-rtl) .ag-full-width-row .ag-cell-wrapper.ag-row-group{padding-left:calc(var(--ag-cell-horizontal-padding) - 1px);padding-right:calc(var(--ag-cell-horizontal-padding) - 1px + var(--ag-row-group-indent-size)*var(--ag-indentation-level))}.ag-row>.ag-cell-wrapper{padding-left:calc(var(--ag-cell-horizontal-padding) - 1px);padding-right:calc(var(--ag-cell-horizontal-padding) - 1px)}.ag-row-dragging{cursor:move;opacity:.5}.ag-details-row{background-color:var(--ag-data-background-color);padding:calc(var(--ag-spacing)*3.75)}.ag-layout-auto-height,.ag-layout-print{.ag-center-cols-container,.ag-center-cols-viewport{min-height:150px}}.ag-overlay-exporting-wrapper,.ag-overlay-loading-wrapper,.ag-overlay-modal-wrapper{background-color:var(--ag-modal-overlay-background-color)}.ag-skeleton-container{align-content:center;height:100%;width:100%}.ag-skeleton-effect{animation:ag-skeleton-loading 1.5s ease-in-out .5s infinite;background-color:var(--ag-row-loading-skeleton-effect-color);border-radius:.25rem;height:1em;width:100%}:where(.ag-ltr) .ag-right-aligned-cell .ag-skeleton-effect{margin-left:auto}:where(.ag-rtl) .ag-right-aligned-cell .ag-skeleton-effect{margin-right:auto}@keyframes ag-skeleton-loading{0%{background-color:var(--ag-row-loading-skeleton-effect-color)}50%{background-color:color-mix(in srgb,transparent,var(--ag-row-loading-skeleton-effect-color) 40%)}to{background-color:var(--ag-row-loading-skeleton-effect-color)}}.ag-loading{align-items:center;display:flex;height:100%}:where(.ag-ltr) .ag-loading{padding-left:var(--ag-cell-horizontal-padding)}:where(.ag-rtl) .ag-loading{padding-right:var(--ag-cell-horizontal-padding)}:where(.ag-ltr) .ag-loading-icon{padding-right:var(--ag-cell-widget-spacing)}:where(.ag-rtl) .ag-loading-icon{padding-left:var(--ag-cell-widget-spacing)}.ag-header{background-color:var(--ag-header-background-color);border-bottom:var(--ag-header-row-border);color:var(--ag-header-text-color);display:flex;font-family:var(--ag-header-font-family);font-size:var(--ag-header-font-size);font-weight:var(--ag-header-font-weight);overflow:hidden;white-space:nowrap;width:100%}.ag-header-row{height:var(--ag-header-height);position:absolute}.ag-floating-filter-button-button,.ag-header-cell-filter-button,.ag-header-cell-menu-button,.ag-header-expand-icon,.ag-panel-title-bar-button,:where(.ag-header-cell-sortable) .ag-header-cell-label,:where(.ag-header-group-cell-selectable) .ag-header-cell-comp-wrapper{cursor:pointer}:where(.ag-ltr) .ag-header-expand-icon{margin-left:4px}:where(.ag-rtl) .ag-header-expand-icon{margin-right:4px}.ag-header-row:where(:not(:first-child)){:where(.ag-header-cell:not(.ag-header-span-height.ag-header-span-total,.ag-header-parent-hidden)),:where(.ag-header-group-cell.ag-header-group-cell-with-group){border-top:var(--ag-header-row-border)}}.ag-header-row:where(:not(.ag-header-row-column-group)){overflow:hidden}:where(.ag-header.ag-header-allow-overflow) .ag-header-row{overflow:visible}.ag-header-cell{display:inline-flex;overflow:hidden}.ag-header-group-cell{contain:paint;display:flex}.ag-header-cell,.ag-header-group-cell{align-items:center;gap:var(--ag-cell-widget-spacing);height:100%;padding:0 var(--ag-cell-horizontal-padding);position:absolute}@property --ag-internal-moving-color{syntax:\"\";inherits:false;initial-value:transparent}@property --ag-internal-hover-color{syntax:\"\";inherits:false;initial-value:transparent}.ag-header-cell:where(:not(.ag-floating-filter)):before,.ag-header-group-cell:before{background-image:linear-gradient(var(--ag-internal-hover-color),var(--ag-internal-hover-color)),linear-gradient(var(--ag-internal-moving-color),var(--ag-internal-moving-color));content:\"\";inset:0;position:absolute;--ag-internal-moving-color:transparent;--ag-internal-hover-color:transparent;transition:--ag-internal-moving-color var(--ag-header-cell-background-transition-duration),--ag-internal-hover-color var(--ag-header-cell-background-transition-duration)}.ag-header-cell:where(:not(.ag-floating-filter)):where(:hover):before,.ag-header-group-cell:where(:hover):before{--ag-internal-hover-color:var(--ag-header-cell-hover-background-color)}.ag-header-cell:where(:not(.ag-floating-filter)):where(.ag-header-cell-moving):before,.ag-header-group-cell:where(.ag-header-cell-moving):before{--ag-internal-moving-color:var(--ag-header-cell-moving-background-color);--ag-internal-hover-color:var(--ag-header-cell-hover-background-color)}:where(.ag-header-cell:not(.ag-floating-filter)>*,.ag-header-group-cell>*){position:relative;z-index:1}.ag-header-cell-menu-button:where(:not(.ag-header-menu-always-show)){opacity:0;transition:opacity .2s}.ag-header-cell-filter-button,:where(.ag-header-cell.ag-header-active) .ag-header-cell-menu-button{opacity:1}.ag-header-cell-label,.ag-header-group-cell-label{align-items:center;align-self:stretch;display:flex;flex:1 1 auto;overflow:hidden;padding:5px 0}:where(.ag-ltr) .ag-sort-indicator-icon{padding-left:var(--ag-spacing)}:where(.ag-rtl) .ag-sort-indicator-icon{padding-right:var(--ag-spacing)}.ag-header-cell-label{text-overflow:ellipsis}.ag-header-group-cell-label.ag-sticky-label{flex:none;max-width:100%;overflow:visible;position:sticky}:where(.ag-ltr) .ag-header-group-cell-label.ag-sticky-label{left:var(--ag-cell-horizontal-padding)}:where(.ag-rtl) .ag-header-group-cell-label.ag-sticky-label{right:var(--ag-cell-horizontal-padding)}.ag-header-cell-text,.ag-header-group-text{overflow:hidden;text-overflow:ellipsis}.ag-header-cell-text{word-break:break-word}.ag-header-cell-comp-wrapper{width:100%}:where(.ag-header-group-cell) .ag-header-cell-comp-wrapper{display:flex}:where(.ag-header-cell:not(.ag-header-cell-auto-height)) .ag-header-cell-comp-wrapper{align-items:center;display:flex;height:100%}.ag-header-cell-wrap-text .ag-header-cell-comp-wrapper{white-space:normal}.ag-header-cell-comp-wrapper-limited-height>*{overflow:hidden}:where(.ag-right-aligned-header) .ag-header-cell-label{flex-direction:row-reverse}:where(.ag-header-cell:not(.ag-right-aligned-header)){.ag-header-col-ref{color:var(--ag-subtle-text-color)}}:where(.ag-ltr) :where(.ag-header-cell:not(.ag-right-aligned-header)){.ag-header-col-ref{margin-right:var(--ag-spacing)}.ag-header-label-icon,.ag-header-menu-icon{margin-left:var(--ag-spacing)}}:where(.ag-rtl) :where(.ag-header-cell:not(.ag-right-aligned-header)){.ag-header-col-ref{margin-left:var(--ag-spacing)}.ag-header-label-icon,.ag-header-menu-icon{margin-right:var(--ag-spacing)}}:where(.ag-header-cell.ag-right-aligned-header){.ag-header-col-ref{color:var(--ag-subtle-text-color)}}:where(.ag-ltr) :where(.ag-header-cell.ag-right-aligned-header){.ag-header-col-ref{margin-left:var(--ag-spacing)}.ag-header-label-icon,.ag-header-menu-icon{margin-right:var(--ag-spacing)}}:where(.ag-rtl) :where(.ag-header-cell.ag-right-aligned-header){.ag-header-col-ref{margin-right:var(--ag-spacing)}.ag-header-label-icon,.ag-header-menu-icon{margin-left:var(--ag-spacing)}}.ag-header-cell:after,.ag-header-group-cell:where(:not(.ag-header-span-height.ag-header-group-cell-no-group)):after{content:\"\";height:var(--ag-header-column-border-height);position:absolute;top:calc(50% - var(--ag-header-column-border-height)*.5);z-index:1}:where(.ag-ltr) .ag-header-cell:after,:where(.ag-ltr) .ag-header-group-cell:where(:not(.ag-header-span-height.ag-header-group-cell-no-group)):after{border-right:var(--ag-header-column-border);right:0}:where(.ag-rtl) .ag-header-cell:after,:where(.ag-rtl) .ag-header-group-cell:where(:not(.ag-header-span-height.ag-header-group-cell-no-group)):after{border-left:var(--ag-header-column-border);left:0}.ag-header-highlight-after:after,.ag-header-highlight-before:after{background-color:var(--ag-column-drag-indicator-color);border-radius:calc(var(--ag-column-drag-indicator-width)/2);content:\"\";height:100%;position:absolute;top:0;width:var(--ag-column-drag-indicator-width)}:where(.ag-ltr) .ag-header-highlight-before:after{left:0}:where(.ag-rtl) .ag-header-highlight-before:after{right:0}:where(.ag-ltr) .ag-header-highlight-after:after{right:0;:where(.ag-pinned-left-header) &{right:1px}}:where(.ag-rtl) .ag-header-highlight-after:after{left:0;:where(.ag-pinned-left-header) &{left:1px}}.ag-header-cell-resize{align-items:center;cursor:ew-resize;display:flex;height:100%;position:absolute;top:0;width:8px;z-index:2}:where(.ag-ltr) .ag-header-cell-resize{right:-3px}:where(.ag-rtl) .ag-header-cell-resize{left:-3px}.ag-header-cell-resize:after{background-color:var(--ag-header-column-resize-handle-color);content:\"\";height:var(--ag-header-column-resize-handle-height);position:absolute;top:calc(50% - var(--ag-header-column-resize-handle-height)*.5);width:var(--ag-header-column-resize-handle-width);z-index:1}:where(.ag-ltr) .ag-header-cell-resize:after{left:calc(50% - var(--ag-header-column-resize-handle-width))}:where(.ag-rtl) .ag-header-cell-resize:after{right:calc(50% - var(--ag-header-column-resize-handle-width))}:where(.ag-header-cell.ag-header-span-height) .ag-header-cell-resize:after{height:calc(100% - var(--ag-spacing)*4);top:calc(var(--ag-spacing)*2)}.ag-header-group-cell-no-group:where(.ag-header-span-height){display:none}.ag-sort-indicator-container{display:flex;gap:var(--ag-spacing)}.ag-layout-print{&.ag-body{display:block;height:unset}&.ag-root-wrapper{container-type:normal;display:inline-block}.ag-body-horizontal-scroll,.ag-body-vertical-scroll{display:none}&.ag-force-vertical-scroll{overflow-y:visible!important}}@media print{.ag-root-wrapper.ag-layout-print{container-type:normal;display:table;.ag-body-horizontal-scroll-viewport,.ag-body-viewport,.ag-center-cols-container,.ag-center-cols-viewport,.ag-root,.ag-root-wrapper-body,.ag-virtual-list-viewport{display:block!important;height:auto!important;overflow:hidden!important}.ag-cell,.ag-row{-moz-column-break-inside:avoid;break-inside:avoid}}}ag-grid,ag-grid-angular{display:block}.ag-root-wrapper{border:var(--ag-wrapper-border);border-radius:var(--ag-wrapper-border-radius);container-type:inline-size;display:flex;flex-direction:column;overflow:hidden;position:relative;&.ag-layout-normal{height:100%}}.ag-root-wrapper-body{display:flex;flex-direction:row;&.ag-layout-normal{flex:1 1 auto;height:0;min-height:0}}.ag-root{display:flex;flex-direction:column;position:relative;&.ag-layout-auto-height,&.ag-layout-normal{flex:1 1 auto;overflow:hidden;width:0}&.ag-layout-normal{height:100%}}.ag-drag-handle{color:var(--ag-drag-handle-color);cursor:grab;:where(.ag-icon){color:var(--ag-drag-handle-color)}}.ag-chart-menu-icon,.ag-chart-settings-next,.ag-chart-settings-prev,.ag-column-group-icons,.ag-column-select-header-icon,.ag-filter-toolpanel-expand,.ag-floating-filter-button-button,.ag-group-title-bar-icon,.ag-header-cell-filter-button,.ag-header-cell-menu-button,.ag-header-expand-icon,.ag-panel-title-bar-button,.ag-panel-title-bar-button-icon,.ag-set-filter-group-icons,:where(.ag-group-contracted) .ag-icon,:where(.ag-group-expanded) .ag-icon{background-color:var(--ag-icon-button-background-color);border-radius:var(--ag-icon-button-border-radius);box-shadow:0 0 0 var(--ag-icon-button-background-spread) var(--ag-icon-button-background-color);color:var(--ag-icon-button-color)}.ag-chart-menu-icon:hover,.ag-chart-settings-next:hover,.ag-chart-settings-prev:hover,.ag-column-group-icons:hover,.ag-column-select-header-icon:hover,.ag-filter-toolpanel-expand:hover,.ag-floating-filter-button-button:hover,.ag-group-title-bar-icon:hover,.ag-header-cell-filter-button:hover,.ag-header-cell-menu-button:hover,.ag-header-expand-icon:hover,.ag-panel-title-bar-button-icon:hover,.ag-panel-title-bar-button:hover,.ag-set-filter-group-icons:hover,:where(.ag-group-contracted) .ag-icon:hover,:where(.ag-group-expanded) .ag-icon:hover{background-color:var(--ag-icon-button-hover-background-color);box-shadow:0 0 0 var(--ag-icon-button-background-spread) var(--ag-icon-button-hover-background-color);color:var(--ag-icon-button-hover-color)}:where(.ag-filter-active),:where(.ag-filter-toolpanel-group-instance-header-icon),:where(.ag-filter-toolpanel-instance-header-icon){position:relative}:where(.ag-filter-active):after,:where(.ag-filter-toolpanel-group-instance-header-icon):after,:where(.ag-filter-toolpanel-instance-header-icon):after{background-color:var(--ag-icon-button-active-indicator-color);border-radius:50%;content:\"\";height:6px;position:absolute;top:-1px;width:6px}:where(.ag-ltr) :where(.ag-filter-active):after,:where(.ag-ltr) :where(.ag-filter-toolpanel-group-instance-header-icon):after,:where(.ag-ltr) :where(.ag-filter-toolpanel-instance-header-icon):after{right:-1px}:where(.ag-rtl) :where(.ag-filter-active):after,:where(.ag-rtl) :where(.ag-filter-toolpanel-group-instance-header-icon):after,:where(.ag-rtl) :where(.ag-filter-toolpanel-instance-header-icon):after{left:-1px}.ag-filter-active{background-image:linear-gradient(var(--ag-icon-button-active-background-color),var(--ag-icon-button-active-background-color));border-radius:1px;outline:solid var(--ag-icon-button-background-spread) var(--ag-icon-button-active-background-color);:where(.ag-icon-filter){clip-path:path(\"M8,0C8,4.415 11.585,8 16,8L16,16L0,16L0,0L8,0Z\");color:var(--ag-icon-button-active-color)}}"; var coreDefaults = { wrapperBorder: true, rowBorder: true, headerRowBorder: true, footerRowBorder: { ref: "rowBorder" }, columnBorder: { style: "solid", width: 1, color: "transparent" }, headerColumnBorder: false, headerColumnBorderHeight: "100%", pinnedColumnBorder: true, pinnedRowBorder: true, sidePanelBorder: true, sideBarPanelWidth: 250, sideBarPanelAnimationDuration: 0, sideBarBackgroundColor: { ref: "chromeBackgroundColor" }, sideButtonBarBackgroundColor: { ref: "sideBarBackgroundColor" }, sideButtonBarTopPadding: 0, sideButtonSelectedUnderlineWidth: 2, sideButtonSelectedUnderlineColor: "transparent", sideButtonSelectedUnderlineTransitionDuration: 0, sideButtonBackgroundColor: "transparent", sideButtonTextColor: { ref: "textColor" }, sideButtonHoverBackgroundColor: { ref: "sideButtonBackgroundColor" }, sideButtonHoverTextColor: { ref: "sideButtonTextColor" }, sideButtonSelectedBackgroundColor: backgroundColor, sideButtonSelectedTextColor: { ref: "sideButtonTextColor" }, sideButtonBorder: "solid 1px transparent", sideButtonSelectedBorder: true, sideButtonLeftPadding: { ref: "spacing" }, sideButtonRightPadding: { ref: "spacing" }, sideButtonVerticalPadding: { calc: "spacing * 3" }, cellFontFamily: { ref: "fontFamily" }, cellFontSize: { ref: "dataFontSize" }, cellFontWeight: { ref: "fontWeight" }, headerCellHoverBackgroundColor: "transparent", headerCellMovingBackgroundColor: { ref: "headerCellHoverBackgroundColor" }, headerCellBackgroundTransitionDuration: "0.2s", cellTextColor: { ref: "textColor" }, rangeSelectionBorderStyle: "solid", rangeSelectionBorderColor: accentColor, rangeSelectionBackgroundColor: accentMix(0.2), rangeSelectionChartBackgroundColor: "#0058FF1A", rangeSelectionChartCategoryBackgroundColor: "#00FF841A", rangeSelectionHighlightColor: accentMix(0.5), rangeHeaderHighlightColor: foregroundHeaderBackgroundMix(0.08), rowNumbersSelectedColor: accentMix(0.5), rowHoverColor: accentMix(0.08), columnHoverColor: accentMix(0.05), selectedRowBackgroundColor: accentMix(0.12), modalOverlayBackgroundColor: { ref: "backgroundColor", mix: 0.66 }, dataBackgroundColor: backgroundColor, oddRowBackgroundColor: { ref: "dataBackgroundColor" }, wrapperBorderRadius: 8, cellHorizontalPadding: { calc: "spacing * 2 * cellHorizontalPaddingScale" }, cellWidgetSpacing: { calc: "spacing * 1.5" }, cellHorizontalPaddingScale: 1, rowGroupIndentSize: { calc: "cellWidgetSpacing + iconSize" }, valueChangeDeltaUpColor: "#43a047", valueChangeDeltaDownColor: "#e53935", valueChangeValueHighlightBackgroundColor: "#16a08580", rowHeight: { calc: "max(iconSize, cellFontSize) + spacing * 3.25 * rowVerticalPaddingScale" }, rowVerticalPaddingScale: 1, paginationPanelHeight: { ref: "rowHeight", calc: "max(rowHeight, 22px)" }, dragHandleColor: foregroundMix(0.7), headerColumnResizeHandleHeight: "30%", headerColumnResizeHandleWidth: 2, headerColumnResizeHandleColor: { ref: "borderColor" }, iconButtonColor: { ref: "iconColor" }, iconButtonBackgroundColor: "transparent", iconButtonBackgroundSpread: 4, iconButtonBorderRadius: 1, iconButtonHoverColor: { ref: "iconButtonColor" }, iconButtonHoverBackgroundColor: foregroundMix(0.1), iconButtonActiveColor: accentColor, iconButtonActiveBackgroundColor: accentMix(0.28), iconButtonActiveIndicatorColor: accentColor, setFilterIndentSize: { ref: "iconSize" }, chartMenuPanelWidth: 260, chartMenuLabelColor: foregroundMix(0.8), cellEditingBorder: { color: accentColor }, cellEditingShadow: { ref: "cardShadow" }, fullRowEditInvalidBackgroundColor: { ref: "invalidColor", onto: "backgroundColor", mix: 0.25 }, columnSelectIndentSize: { ref: "iconSize" }, toolPanelSeparatorBorder: true, columnDropCellBackgroundColor: foregroundMix(0.07), columnDropCellTextColor: { ref: "textColor" }, columnDropCellDragHandleColor: { ref: "textColor" }, columnDropCellBorder: { color: foregroundMix(0.13) }, selectCellBackgroundColor: foregroundMix(0.07), selectCellBorder: { color: foregroundMix(0.13) }, advancedFilterBuilderButtonBarBorder: true, advancedFilterBuilderIndentSize: { calc: "spacing * 2 + iconSize" }, advancedFilterBuilderJoinPillColor: "#f08e8d", advancedFilterBuilderColumnPillColor: "#a6e194", advancedFilterBuilderOptionPillColor: "#f3c08b", advancedFilterBuilderValuePillColor: "#85c0e4", filterPanelApplyButtonColor: backgroundColor, filterPanelApplyButtonBackgroundColor: accentColor, columnPanelApplyButtonColor: backgroundColor, columnPanelApplyButtonBackgroundColor: accentColor, filterPanelCardSubtleColor: { ref: "textColor", mix: 0.7 }, filterPanelCardSubtleHoverColor: { ref: "textColor" }, findMatchColor: foregroundColor, findMatchBackgroundColor: "#ffff00", findActiveMatchColor: foregroundColor, findActiveMatchBackgroundColor: "#ffa500", filterToolPanelGroupIndent: { ref: "spacing" }, rowLoadingSkeletonEffectColor: foregroundMix(0.15), statusBarLabelColor: foregroundColor, statusBarLabelFontWeight: 500, statusBarValueColor: foregroundColor, statusBarValueFontWeight: 500, pinnedSourceRowTextColor: { ref: "textColor" }, pinnedSourceRowBackgroundColor: { ref: "dataBackgroundColor" }, pinnedSourceRowFontWeight: 600, pinnedRowFontWeight: 600, pinnedRowBackgroundColor: { ref: "dataBackgroundColor" }, pinnedRowTextColor: { ref: "textColor" }, rowDragIndicatorColor: { ref: "rangeSelectionBorderColor" }, rowDragIndicatorWidth: 2, columnDragIndicatorColor: { ref: "accentColor" }, columnDragIndicatorWidth: 2 }; var batch_edit_style_default_default = ".ag-cell-batch-edit{background-color:var(--ag-cell-batch-edit-background-color);color:var(--ag-cell-batch-edit-text-color);display:inherit}.ag-row-batch-edit{background-color:var(--ag-row-batch-edit-background-color);color:var(--ag-row-batch-edit-text-color)}"; var baseParams = { cellBatchEditBackgroundColor: "rgba(220 181 139 / 16%)", cellBatchEditTextColor: "#422f00", rowBatchEditBackgroundColor: { ref: "cellBatchEditBackgroundColor" }, rowBatchEditTextColor: { ref: "cellBatchEditTextColor" } }; var baseDarkBatchEditParams = { ...baseParams, cellBatchEditTextColor: "#f3d0b3" }; var makeBatchEditStyleBaseTreeShakeable = () => createPart({ feature: "batchEditStyle", params: baseParams, css: batch_edit_style_default_default }); var batchEditStyleBase = /* @__PURE__ */ makeBatchEditStyleBaseTreeShakeable(); var button_style_base_default = ":where(.ag-button){background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0;text-indent:inherit;text-shadow:inherit;text-transform:inherit;word-spacing:inherit;&:disabled{cursor:default}&:focus-visible{box-shadow:var(--ag-focus-shadow);outline:none}}.ag-standard-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--ag-button-background-color);border:var(--ag-button-border);border-radius:var(--ag-button-border-radius);color:var(--ag-button-text-color);cursor:pointer;font-weight:var(--ag-button-font-weight);padding:var(--ag-button-vertical-padding) var(--ag-button-horizontal-padding);&:active{background-color:var(--ag-button-active-background-color);border:var(--ag-button-active-border);color:var(--ag-button-active-text-color)}&:disabled{background-color:var(--ag-button-disabled-background-color);border:var(--ag-button-disabled-border);color:var(--ag-button-disabled-text-color)}}.ag-standard-button:hover{background-color:var(--ag-button-hover-background-color);border:var(--ag-button-hover-border);color:var(--ag-button-hover-text-color)}"; var baseParams2 = { buttonTextColor: "inherit", buttonFontWeight: "normal", buttonBackgroundColor: "transparent", buttonBorder: false, buttonBorderRadius: { ref: "borderRadius" }, buttonHorizontalPadding: { calc: "spacing * 2" }, buttonVerticalPadding: { ref: "spacing" }, buttonHoverTextColor: { ref: "buttonTextColor" }, buttonHoverBackgroundColor: { ref: "buttonBackgroundColor" }, buttonHoverBorder: { ref: "buttonBorder" }, buttonActiveTextColor: { ref: "buttonHoverTextColor" }, buttonActiveBackgroundColor: { ref: "buttonHoverBackgroundColor" }, buttonActiveBorder: { ref: "buttonHoverBorder" }, buttonDisabledTextColor: { ref: "inputDisabledTextColor" }, buttonDisabledBackgroundColor: { ref: "inputDisabledBackgroundColor" }, buttonDisabledBorder: { ref: "inputDisabledBorder" } }; var makeButtonStyleQuartzTreeShakeable = () => createPart({ feature: "buttonStyle", params: { ...baseParams2, buttonBackgroundColor: backgroundColor, buttonBorder: true, buttonHoverBackgroundColor: { ref: "rowHoverColor" }, buttonActiveBorder: { color: accentColor } }, css: button_style_base_default }); var buttonStyleQuartz = /* @__PURE__ */ makeButtonStyleQuartzTreeShakeable(); var column_drop_style_bordered_default = ".ag-column-drop-vertical-empty-message{align-items:center;border:dashed var(--ag-border-width);border-color:var(--ag-border-color);display:flex;inset:0;justify-content:center;margin:calc(var(--ag-spacing)*1.5) calc(var(--ag-spacing)*2);overflow:hidden;padding:calc(var(--ag-spacing)*2);position:absolute}"; var makeColumnDropStyleBorderedTreeShakeable = () => { return createPart({ feature: "columnDropStyle", css: column_drop_style_bordered_default }); }; var columnDropStyleBordered = /* @__PURE__ */ makeColumnDropStyleBorderedTreeShakeable(); var baseParams3 = { formulaToken1Color: "#3269c6", formulaToken1BackgroundColor: { ref: "formulaToken1Color", mix: 0.08 }, formulaToken1Border: { color: { ref: "formulaToken1Color" } }, formulaToken2Color: "#c0343f", formulaToken2BackgroundColor: { ref: "formulaToken2Color", mix: 0.06 }, formulaToken2Border: { color: { ref: "formulaToken2Color" } }, formulaToken3Color: "#8156b8", formulaToken3BackgroundColor: { ref: "formulaToken3Color", mix: 0.08 }, formulaToken3Border: { color: { ref: "formulaToken3Color" } }, formulaToken4Color: "#007c1f", formulaToken4BackgroundColor: { ref: "formulaToken4Color", mix: 0.06 }, formulaToken4Border: { color: { ref: "formulaToken4Color" } }, formulaToken5Color: "#b03e85", formulaToken5BackgroundColor: { ref: "formulaToken5Color", mix: 0.08 }, formulaToken5Border: { color: { ref: "formulaToken5Color" } }, formulaToken6Color: "#b74900", formulaToken6BackgroundColor: { ref: "formulaToken6Color", mix: 0.06 }, formulaToken6Border: { color: { ref: "formulaToken6Color" } }, formulaToken7Color: "#247492", formulaToken7BackgroundColor: { ref: "formulaToken7Color", mix: 0.08 }, formulaToken7Border: { color: { ref: "formulaToken7Color" } } }; var makeBatchEditStyleBaseTreeShakeable2 = () => createPart({ feature: "formulaStyle", params: baseParams3 }); var formulaStyleBase = /* @__PURE__ */ makeBatchEditStyleBaseTreeShakeable2(); var gridThemeLogger = { warn: (...args) => { _warn(args[0], args[1]); }, error: (...args) => { _error(args[0], args[1]); }, preInitErr: (...args) => { _logPreInitErr(args[0], args[2], args[1]); } }; var createTheme = () => createSharedTheme(gridThemeLogger).withParams(coreDefaults).withPart(buttonStyleQuartz).withPart(columnDropStyleBordered).withPart(batchEditStyleBase).withPart(formulaStyleBase); var checkbox_style_default_default = '.ag-checkbox-input-wrapper,.ag-radio-button-input-wrapper{background-color:var(--ag-checkbox-unchecked-background-color);border:solid var(--ag-checkbox-border-width) var(--ag-checkbox-unchecked-border-color);flex:none;height:var(--ag-icon-size);position:relative;width:var(--ag-icon-size);&:where(.ag-checked){background-color:var(--ag-checkbox-checked-background-color);border-color:var(--ag-checkbox-checked-border-color)}&:where(.ag-checked):after{background-color:var(--ag-checkbox-checked-shape-color)}&:where(.ag-disabled){filter:grayscale();opacity:.5}}.ag-checkbox-input,.ag-radio-button-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;display:block;height:var(--ag-icon-size);margin:0;opacity:0;width:var(--ag-icon-size)}.ag-checkbox-input-wrapper:after,.ag-radio-button-input-wrapper:after{content:"";display:block;inset:0;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;pointer-events:none;position:absolute}.ag-checkbox-input-wrapper:where(:focus-within,:active),.ag-radio-button-input-wrapper:where(:focus-within,:active){box-shadow:var(--ag-focus-shadow)}.ag-checkbox-input-wrapper{border-radius:var(--ag-checkbox-border-radius);&:where(.ag-checked):after{-webkit-mask-image:var(--ag-checkbox-checked-shape-image);mask-image:var(--ag-checkbox-checked-shape-image)}&:where(.ag-indeterminate){background-color:var(--ag-checkbox-indeterminate-background-color);border-color:var(--ag-checkbox-indeterminate-border-color)}&:where(.ag-indeterminate):after{background-color:var(--ag-checkbox-indeterminate-shape-color);-webkit-mask-image:var(--ag-checkbox-indeterminate-shape-image);mask-image:var(--ag-checkbox-indeterminate-shape-image)}}.ag-cell-editing-error .ag-checkbox-input-wrapper:focus-within{box-shadow:var(--ag-focus-error-shadow)}.ag-radio-button-input-wrapper{border-radius:100%;&:where(.ag-checked):after{-webkit-mask-image:var(--ag-radio-checked-shape-image);mask-image:var(--ag-radio-checked-shape-image)}}'; var makeCheckboxStyleDefaultTreeShakeable = () => createPart({ feature: "checkboxStyle", params: { checkboxBorderWidth: 1, checkboxBorderRadius: { ref: "borderRadius" }, checkboxUncheckedBackgroundColor: backgroundColor, checkboxUncheckedBorderColor: foregroundBackgroundMix(0.3), checkboxCheckedBackgroundColor: accentColor, checkboxCheckedBorderColor: { ref: "checkboxCheckedBackgroundColor" }, checkboxCheckedShapeImage: { svg: '' }, checkboxCheckedShapeColor: backgroundColor, checkboxIndeterminateBackgroundColor: foregroundBackgroundMix(0.3), checkboxIndeterminateBorderColor: { ref: "checkboxIndeterminateBackgroundColor" }, checkboxIndeterminateShapeImage: { svg: '' }, checkboxIndeterminateShapeColor: backgroundColor, radioCheckedShapeImage: { svg: '' } }, css: checkbox_style_default_default }); var checkboxStyleDefault = /* @__PURE__ */ makeCheckboxStyleDefaultTreeShakeable(); var darkParams = () => ({ ...defaultLightColorSchemeParams, ...baseDarkBatchEditParams, backgroundColor: "hsl(217, 0%, 17%)", foregroundColor: "#FFF", chromeBackgroundColor: foregroundBackgroundMix(0.05), rowHoverColor: accentMix(0.15), selectedRowBackgroundColor: accentMix(0.2), menuBackgroundColor: foregroundBackgroundMix(0.1), browserColorScheme: "dark", popupShadow: "0 0px 20px #000A", cardShadow: "0 1px 4px 1px #000A", advancedFilterBuilderJoinPillColor: "#7a3a37", advancedFilterBuilderColumnPillColor: "#355f2d", advancedFilterBuilderOptionPillColor: "#5a3168", advancedFilterBuilderValuePillColor: "#374c86", filterPanelApplyButtonColor: foregroundColor, columnPanelApplyButtonColor: foregroundColor, findMatchColor: backgroundColor, findActiveMatchColor: backgroundColor, checkboxUncheckedBorderColor: foregroundBackgroundMix(0.4), toggleButtonOffBackgroundColor: foregroundBackgroundMix(0.4), rowBatchEditBackgroundColor: foregroundBackgroundMix(0.1), formulaToken1Color: "#4da3e5", formulaToken2Color: "#f55864", formulaToken3Color: "#b688f2", formulaToken4Color: "#24bb4a", formulaToken5Color: "#e772ba", formulaToken6Color: "#f69b5f", formulaToken7Color: "#a3e6ff" }); var darkBlueParams = () => ({ ...darkParams(), backgroundColor: "#1f2836" }); var makeColorSchemeVariableTreeShakeable = () => createPart({ feature: "colorScheme", params: defaultLightColorSchemeParams, modeParams: { light: defaultLightColorSchemeParams, dark: darkParams(), "dark-blue": darkBlueParams() } }); var colorSchemeVariable = /* @__PURE__ */ makeColorSchemeVariableTreeShakeable(); var iconNameToSvgFragment = { aggregation: '', arrows: '', asc: '', cancel: '', chart: '', "color-picker": '', columns: '', contracted: '', copy: '', cross: '', csv: '', cut: '', desc: '', down: '', excel: '', expanded: '', eye: '', "eye-slash": '', filter: '', first: '', grip: '', group: '', last: '', left: '', linked: '', loading: '', maximize: '', menu: '', "menu-alt": '', minimize: '', minus: '', next: '', none: '', "not-allowed": '', paste: '', pin: '', pivot: '', plus: '', previous: '', right: '', save: '', settings: '', "small-left": '', "small-right": '', tick: '', "tree-closed": '', "tree-indeterminate": '', "tree-open": '', unlinked: '', up: '' }; var iconNameToFullSvg = { aasc: ``, adesc: ``, "chevron-down": '', "chevron-left": '', "chevron-right": '', "chevron-up": '', "column-arrow": '', edit: '', "filter-add": '', "pinned-bottom": '', "pinned-top": '', "small-down": '', "small-up": '', "un-pin": '' }; var getQuartzIconsCss = (args = {}) => { let result = ""; for (const iconName of [...Object.keys(iconNameToSvgFragment), ...Object.keys(iconNameToFullSvg)]) { const iconSvg = quartzIconSvg(iconName, args.strokeWidth); result += `.ag-icon-${iconName}::before { mask-image: url('data:image/svg+xml,${encodeURIComponent(iconSvg)}'); } `; } return result; }; var quartzIconSvg = (name, strokeWidth = 1.5) => { const fullSVG = iconNameToFullSvg[name]; if (fullSVG) { return fullSVG; } const svgFragment = iconNameToSvgFragment[name]; if (!svgFragment) { throw new Error(`Missing icon data for ${name}`); } return `` + svgFragment + ""; }; var iconSetQuartz = (args = {}) => { return createPart({ feature: "iconSet", css: () => getQuartzIconsCss(args) }); }; var iconSetQuartzRegular = /* @__PURE__ */ iconSetQuartz(); var input_style_base_default = ":where(.ag-input-field-input[type=number]:not(.ag-number-field-input-stepper)){-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;&::-webkit-inner-spin-button,&::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none;margin:0}}.ag-input-field-input:where(input:not([type]),input[type=text],input[type=number],input[type=tel],input[type=date],input[type=datetime-local],textarea){background-color:var(--ag-input-background-color);border:var(--ag-input-border);border-radius:var(--ag-input-border-radius);color:var(--ag-input-text-color);font-family:inherit;font-size:inherit;line-height:inherit;margin:0;min-height:var(--ag-input-height);padding:0;&:where(:disabled){background-color:var(--ag-input-disabled-background-color);border:var(--ag-input-disabled-border);color:var(--ag-input-disabled-text-color)}&:where(:focus){background-color:var(--ag-input-focus-background-color);border:var(--ag-input-focus-border);box-shadow:var(--ag-input-focus-shadow);color:var(--ag-input-focus-text-color);outline:none}&:where(:invalid){background-color:var(--ag-input-invalid-background-color);border:var(--ag-input-invalid-border);color:var(--ag-input-invalid-text-color)}&:where(.invalid){background-color:var(--ag-input-invalid-background-color);border:var(--ag-input-invalid-border);color:var(--ag-input-invalid-text-color)}&::-moz-placeholder{color:var(--ag-input-placeholder-text-color)}&::placeholder{color:var(--ag-input-placeholder-text-color)}}:where(.ag-ltr) .ag-input-field-input:where(input:not([type]),input[type=text],input[type=number],input[type=tel],input[type=date],input[type=datetime-local],textarea){padding-left:var(--ag-input-padding-start)}:where(.ag-rtl) .ag-input-field-input:where(input:not([type]),input[type=text],input[type=number],input[type=tel],input[type=date],input[type=datetime-local],textarea){padding-right:var(--ag-input-padding-start)}&:where(.ag-ltr,.ag-rtl) .ag-input-field-input:where(input:not([type]),input[type=text],input[type=number],input[type=tel],input[type=date],input[type=datetime-local],textarea){padding:0 var(--ag-input-padding-start)}:where(.ag-column-select-header-filter-wrapper),:where(.ag-filter-add-select),:where(.ag-filter-filter),:where(.ag-filter-toolpanel-search),:where(.ag-floating-filter-search-icon),:where(.ag-mini-filter){.ag-input-wrapper:before{background-color:currentcolor;color:var(--ag-input-icon-color);content:\"\";display:block;height:12px;-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMS41Ij48cGF0aCBkPSJNNS4zIDlhMy43IDMuNyAwIDEgMCAwLTcuNSAzLjcgMy43IDAgMCAwIDAgNy41Wk0xMC41IDEwLjUgOC4zIDguMiIvPjwvc3ZnPg==\");mask-image:url(\"data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMS41Ij48cGF0aCBkPSJNNS4zIDlhMy43IDMuNyAwIDEgMCAwLTcuNSAzLjcgMy43IDAgMCAwIDAgNy41Wk0xMC41IDEwLjUgOC4zIDguMiIvPjwvc3ZnPg==\");-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;opacity:.5;position:absolute;width:12px}}:where(.ag-ltr) :where(.ag-column-select-header-filter-wrapper),:where(.ag-ltr) :where(.ag-filter-add-select),:where(.ag-ltr) :where(.ag-filter-filter),:where(.ag-ltr) :where(.ag-filter-toolpanel-search),:where(.ag-ltr) :where(.ag-floating-filter-search-icon),:where(.ag-ltr) :where(.ag-mini-filter){.ag-input-wrapper:before{margin-left:var(--ag-spacing)}.ag-number-field-input,.ag-text-field-input{padding-left:calc(var(--ag-spacing)*1.5 + 12px)}}:where(.ag-rtl) :where(.ag-column-select-header-filter-wrapper),:where(.ag-rtl) :where(.ag-filter-add-select),:where(.ag-rtl) :where(.ag-filter-filter),:where(.ag-rtl) :where(.ag-filter-toolpanel-search),:where(.ag-rtl) :where(.ag-floating-filter-search-icon),:where(.ag-rtl) :where(.ag-mini-filter){.ag-input-wrapper:before{margin-right:var(--ag-spacing)}.ag-number-field-input,.ag-text-field-input{padding-right:calc(var(--ag-spacing)*1.5 + 12px)}}"; var input_style_bordered_default = ".ag-input-field-input:where(input:not([type]),input[type=text],input[type=number],input[type=tel],input[type=date],input[type=datetime-local],textarea){&:focus{box-shadow:var(--ag-focus-shadow);&:where(.invalid),&:where(:invalid){box-shadow:var(--ag-focus-error-shadow)}}}"; var baseParams4 = { inputBackgroundColor: "transparent", inputBorder: false, inputBorderRadius: 0, inputTextColor: { ref: "textColor" }, inputPlaceholderTextColor: { ref: "inputTextColor", mix: 0.5 }, inputPaddingStart: 0, inputHeight: { calc: "max(iconSize, fontSize) + spacing * 2" }, inputFocusBackgroundColor: { ref: "inputBackgroundColor" }, inputFocusBorder: { ref: "inputBorder" }, inputFocusShadow: "none", inputFocusTextColor: { ref: "inputTextColor" }, inputDisabledBackgroundColor: { ref: "inputBackgroundColor" }, inputDisabledBorder: { ref: "inputBorder" }, inputDisabledTextColor: { ref: "inputTextColor" }, inputInvalidBackgroundColor: { ref: "inputBackgroundColor" }, inputInvalidBorder: { ref: "inputBorder" }, inputInvalidTextColor: { ref: "inputTextColor" }, inputIconColor: { ref: "inputTextColor" }, pickerButtonBorder: false, pickerButtonFocusBorder: { ref: "inputFocusBorder" }, pickerButtonBackgroundColor: { ref: "backgroundColor" }, pickerButtonFocusBackgroundColor: { ref: "backgroundColor" }, pickerListBorder: false, pickerListBackgroundColor: { ref: "backgroundColor" }, colorPickerThumbSize: 18, colorPickerTrackSize: 12, colorPickerThumbBorderWidth: 3, colorPickerTrackBorderRadius: 12, colorPickerColorBorderRadius: 4 }; var makeInputStyleBorderedTreeShakeable = () => createPart({ feature: "inputStyle", params: { ...baseParams4, inputBackgroundColor: backgroundColor, inputBorder: true, inputBorderRadius: { ref: "borderRadius" }, inputPaddingStart: { ref: "spacing" }, inputFocusBorder: { color: accentColor }, inputFocusShadow: { ref: "focusShadow" }, inputDisabledBackgroundColor: foregroundBackgroundMix(0.06), inputDisabledTextColor: { ref: "textColor", mix: 0.5 }, inputInvalidBorder: { color: { ref: "invalidColor" } }, pickerButtonBorder: true, pickerListBorder: true }, css: () => input_style_base_default + input_style_bordered_default }); var inputStyleBordered = /* @__PURE__ */ makeInputStyleBorderedTreeShakeable(); var tab_style_base_default = ".ag-tabs-header{background-color:var(--ag-tab-bar-background-color);border-bottom:var(--ag-tab-bar-border);display:flex;flex:1;gap:var(--ag-tab-spacing);padding:var(--ag-tab-bar-top-padding) var(--ag-tab-bar-horizontal-padding) 0}.ag-tabs-header-wrapper{display:flex}.ag-tabs-close-button-wrapper{align-items:center;border:0;display:flex;padding:var(--ag-spacing)}:where(.ag-ltr) .ag-tabs-close-button-wrapper{border-right:solid var(--ag-border-width) var(--ag-border-color)}:where(.ag-rtl) .ag-tabs-close-button-wrapper{border-left:solid var(--ag-border-width) var(--ag-border-color)}.ag-tabs-close-button{background-color:unset;border:0;cursor:pointer;padding:0}.ag-tab{align-items:center;background-color:var(--ag-tab-background-color);border-left:var(--ag-tab-selected-border-width) solid transparent;border-right:var(--ag-tab-selected-border-width) solid transparent;color:var(--ag-tab-text-color);cursor:pointer;display:flex;flex:1;justify-content:center;padding:var(--ag-tab-top-padding) var(--ag-tab-horizontal-padding) var(--ag-tab-bottom-padding);position:relative}.ag-tab:hover{background-color:var(--ag-tab-hover-background-color);color:var(--ag-tab-hover-text-color)}.ag-tab.ag-tab-selected{background-color:var(--ag-tab-selected-background-color);color:var(--ag-tab-selected-text-color)}:where(.ag-ltr) .ag-tab.ag-tab-selected:where(:not(:first-of-type)){border-left-color:var(--ag-tab-selected-border-color)}:where(.ag-rtl) .ag-tab.ag-tab-selected:where(:not(:first-of-type)){border-right-color:var(--ag-tab-selected-border-color)}:where(.ag-ltr) .ag-tab.ag-tab-selected:where(:not(:last-of-type)){border-right-color:var(--ag-tab-selected-border-color)}:where(.ag-rtl) .ag-tab.ag-tab-selected:where(:not(:last-of-type)){border-left-color:var(--ag-tab-selected-border-color)}.ag-tab:after{background-color:var(--ag-tab-selected-underline-color);bottom:0;content:\"\";display:block;height:var(--ag-tab-selected-underline-width);left:0;opacity:0;position:absolute;right:0;transition:opacity var(--ag-tab-selected-underline-transition-duration)}.ag-tab.ag-tab-selected:after{opacity:1}"; var baseParams5 = { tabBarBackgroundColor: "transparent", tabBarHorizontalPadding: 0, tabBarTopPadding: 0, tabBackgroundColor: "transparent", tabTextColor: { ref: "textColor" }, tabHorizontalPadding: { ref: "spacing" }, tabTopPadding: { ref: "spacing" }, tabBottomPadding: { ref: "spacing" }, tabSpacing: "0", tabHoverBackgroundColor: { ref: "tabBackgroundColor" }, tabHoverTextColor: { ref: "tabTextColor" }, tabSelectedBackgroundColor: { ref: "tabBackgroundColor" }, tabSelectedTextColor: { ref: "tabTextColor" }, tabSelectedBorderWidth: { ref: "borderWidth" }, tabSelectedBorderColor: "transparent", tabSelectedUnderlineColor: "transparent", tabSelectedUnderlineWidth: 0, tabSelectedUnderlineTransitionDuration: 0, tabBarBorder: false }; var makeTabStyleQuartzTreeShakeable = () => createPart({ feature: "tabStyle", params: { ...baseParams5, tabBarBorder: true, tabBarBackgroundColor: foregroundMix(0.05), tabTextColor: { ref: "textColor", mix: 0.7 }, tabSelectedTextColor: { ref: "textColor" }, tabHoverTextColor: { ref: "textColor" }, tabSelectedBorderColor: { ref: "borderColor" }, tabSelectedBackgroundColor: backgroundColor }, css: tab_style_base_default }); var tabStyleQuartz = /* @__PURE__ */ makeTabStyleQuartzTreeShakeable(); var themeQuartzParams = () => ({ fontFamily: [ { googleFont: "IBM Plex Sans" }, "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu" ] }); var makeThemeQuartzTreeShakeable = () => createTheme().withPart(checkboxStyleDefault).withPart(colorSchemeVariable).withPart(iconSetQuartzRegular).withPart(tabStyleQuartz).withPart(inputStyleBordered).withPart(columnDropStyleBordered).withParams(themeQuartzParams()); var themeQuartz = /* @__PURE__ */ makeThemeQuartzTreeShakeable(); var cssVariable = (changeKey, type, defaultValue, noWarn, cacheDefault) => ({ changeKey, type, defaultValue, noWarn, cacheDefault }); var CELL_HORIZONTAL_PADDING = cssVariable("cellHorizontalPadding", "length", 16); var INDENTATION_LEVEL = cssVariable("indentationLevel", "length", 0, true, true); var ROW_GROUP_INDENT_SIZE = cssVariable("rowGroupIndentSize", "length", 0); var ROW_HEIGHT = cssVariable("rowHeight", "length", 42); var HEADER_HEIGHT = cssVariable("headerHeight", "length", 48); var ROW_BORDER_WIDTH = cssVariable("rowBorderWidth", "border", 1); var PINNED_BORDER_WIDTH = cssVariable("pinnedRowBorderWidth", "border", 1); var HEADER_ROW_BORDER_WIDTH = cssVariable("headerRowBorderWidth", "border", 1); function _addAdditionalCss(cssMap, modules) { for (const module of modules.sort((a, b) => a.moduleName.localeCompare(b.moduleName))) { const moduleCss = module.css; if (moduleCss) { cssMap.set(`module-${module.moduleName}`, moduleCss); } } } var Environment = class extends BaseEnvironment { initVariables() { this.addManagedPropertyListener("rowHeight", () => this.refreshRowHeightVariable()); this.getSizeEl(ROW_HEIGHT); this.getSizeEl(HEADER_HEIGHT); this.getSizeEl(ROW_BORDER_WIDTH); this.getSizeEl(PINNED_BORDER_WIDTH); this.refreshRowBorderWidthVariable(); } getPinnedRowBorderWidth() { return this.getCSSVariablePixelValue(PINNED_BORDER_WIDTH); } getRowBorderWidth() { return this.getCSSVariablePixelValue(ROW_BORDER_WIDTH); } getHeaderRowBorderWidth() { return this.getCSSVariablePixelValue(HEADER_ROW_BORDER_WIDTH); } getDefaultRowHeight() { return this.getCSSVariablePixelValue(ROW_HEIGHT); } getDefaultHeaderHeight() { return this.getCSSVariablePixelValue(HEADER_HEIGHT); } getDefaultCellHorizontalPadding() { return this.getCSSVariablePixelValue(CELL_HORIZONTAL_PADDING); } getCellPaddingLeft() { const cellHorizontalPadding = this.getDefaultCellHorizontalPadding(); const indentationLevel = this.getCSSVariablePixelValue(INDENTATION_LEVEL); const rowGroupIndentSize = this.getCSSVariablePixelValue(ROW_GROUP_INDENT_SIZE); return cellHorizontalPadding - 1 + rowGroupIndentSize * indentationLevel; } getCellPadding() { const cellPaddingRight = this.getDefaultCellHorizontalPadding() - 1; return this.getCellPaddingLeft() + cellPaddingRight; } getDefaultColumnMinWidth() { return Math.min(36, this.getDefaultRowHeight()); } refreshRowHeightVariable() { const { eRootDiv } = this; const oldRowHeight = eRootDiv.style.getPropertyValue("--ag-line-height").trim(); const height = this.gos.get("rowHeight"); if (height == null || isNaN(height) || !isFinite(height)) { if (oldRowHeight !== null) { eRootDiv.style.setProperty("--ag-line-height", null); } return -1; } const newRowHeight = `${height}px`; if (oldRowHeight != newRowHeight) { eRootDiv.style.setProperty("--ag-line-height", newRowHeight); return height; } return oldRowHeight != "" ? Number.parseFloat(oldRowHeight) : -1; } fireStylesChangedEvent(change) { if (change === "rowBorderWidth") { this.refreshRowBorderWidthVariable(); } super.fireStylesChangedEvent(change); } refreshRowBorderWidthVariable() { const width = this.getCSSVariablePixelValue(ROW_BORDER_WIDTH); this.eRootDiv.style.setProperty("--ag-internal-row-border-width", `${width}px`); } postProcessThemeChange(newGridTheme, themeGridOption) { if (newGridTheme && getComputedStyle(this.getMeasurementContainer()).getPropertyValue("--ag-legacy-styles-loaded")) { if (themeGridOption) { _error(106); } else { _error(239); } } } getAdditionalCss() { const additionalCss = /* @__PURE__ */ new Map; additionalCss.set("core", [core_default]); _addAdditionalCss(additionalCss, Array.from(_getAllRegisteredModules())); return additionalCss; } getDefaultTheme() { return themeQuartz; } varError(cssName, defaultValue) { _warn(9, { variable: { cssName, defaultValue } }); } themeError(theme) { _error(240, { theme }); } shadowRootError() { _error(293); } }; var BaseEventService = class extends AgBeanStub { constructor() { super(...arguments); this.beanName = "eventSvc"; this.eventServiceType = "global"; this.globalSvc = new LocalEventService; } addListener(eventType, listener, async) { this.globalSvc.addEventListener(eventType, listener, async); } removeListener(eventType, listener, async) { this.globalSvc.removeEventListener(eventType, listener, async); } addGlobalListener(listener, async = false) { this.globalSvc.addGlobalListener(listener, async); } removeGlobalListener(listener, async = false) { this.globalSvc.removeGlobalListener(listener, async); } dispatchEvent(event) { this.globalSvc.dispatchEvent(this.gos.addCommon(event)); } dispatchEventOnce(event) { this.globalSvc.dispatchEventOnce(this.gos.addCommon(event)); } }; var EventService = class extends BaseEventService { postConstruct() { const { globalListener, globalSyncListener } = this.beans; if (globalListener) { this.addGlobalListener(globalListener, true); } if (globalSyncListener) { this.addGlobalListener(globalSyncListener, false); } } }; function getHeaderIndexToFocus(beans, column, level) { const columnRowIndex = beans.visibleCols.headerGroupRowCount; if (level >= columnRowIndex) { return { column, headerRowIndex: level }; } let parent = column.getParent(); while (parent && parent.getProvidedColumnGroup().getLevel() > level) { parent = parent.getParent(); } const isColSpanning = column.isSpanHeaderHeight(); if (!parent || isColSpanning && parent.isPadding()) { return { column, headerRowIndex: columnRowIndex }; } return { column: parent, headerRowIndex: parent.getProvidedColumnGroup().getLevel() }; } var HeaderNavigationService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "headerNavigation"; this.currentHeaderRowWithoutSpan = -1; } postConstruct() { const beans = this.beans; beans.ctrlsSvc.whenReady(this, (p) => { this.gridBodyCon = p.gridBodyCtrl; }); const eDocument = _getDocument(beans); this.addManagedElementListeners(eDocument, { mousedown: () => { this.currentHeaderRowWithoutSpan = -1; } }); } getHeaderPositionForColumn(colKey, floatingFilter) { let column; const { colModel, colGroupSvc, ctrlsSvc } = this.beans; if (typeof colKey === "string") { column = colModel.getCol(colKey); if (!column) { column = colGroupSvc?.getColumnGroup(colKey) ?? null; } } else { column = colKey; } if (!column) { return null; } const centerHeaderContainer = ctrlsSvc.getHeaderRowContainerCtrl(); const allCtrls = centerHeaderContainer?.getAllCtrls(); const isFloatingFilterVisible = _last(allCtrls || []).type === "filter"; const headerRowCount = getFocusHeaderRowCount(this.beans) - 1; let row = -1; let col = column; while (col) { row++; col = col.getParent(); } let headerRowIndex = row; if (floatingFilter && isFloatingFilterVisible && headerRowIndex === headerRowCount - 1) { headerRowIndex++; } return headerRowIndex === -1 ? null : { headerRowIndex, column }; } navigateVertically(direction, event) { const { focusSvc, visibleCols } = this.beans; const { focusedHeader } = focusSvc; if (!focusedHeader) { return false; } const { headerRowIndex } = focusedHeader; const column = focusedHeader.column; const rowLen = getFocusHeaderRowCount(this.beans); const currentRowType = this.getHeaderRowType(headerRowIndex); const columnHeaderRowIndex = visibleCols.headerGroupRowCount; let { headerRowIndex: nextRow, column: nextFocusColumn, headerRowIndexWithoutSpan } = direction === "UP" ? getColumnVisibleParent(currentRowType, column, headerRowIndex) : getColumnVisibleChild(column, headerRowIndex, columnHeaderRowIndex); let skipColumn = false; if (nextRow < 0) { nextRow = 0; nextFocusColumn = column; skipColumn = true; } if (nextRow >= rowLen) { nextRow = -1; this.currentHeaderRowWithoutSpan = -1; } else if (headerRowIndexWithoutSpan !== undefined) { this.currentHeaderRowWithoutSpan = headerRowIndexWithoutSpan; } if (!skipColumn && !nextFocusColumn) { return false; } return focusSvc.focusHeaderPosition({ headerPosition: { headerRowIndex: nextRow, column: nextFocusColumn }, allowUserOverride: true, event }); } navigateHorizontally(direction, fromTab = false, event) { const { focusSvc, gos } = this.beans; const focusedHeader = { ...focusSvc.focusedHeader }; let nextHeader; let normalisedDirection; if (this.currentHeaderRowWithoutSpan !== -1) { focusedHeader.headerRowIndex = this.currentHeaderRowWithoutSpan; } else { this.currentHeaderRowWithoutSpan = focusedHeader.headerRowIndex; } if (direction === "LEFT" !== gos.get("enableRtl")) { normalisedDirection = "Before"; nextHeader = this.findHeader(focusedHeader, normalisedDirection); } else { normalisedDirection = "After"; nextHeader = this.findHeader(focusedHeader, normalisedDirection); } const userFunc = gos.getCallback("tabToNextHeader"); if (fromTab && userFunc) { const wasFocusedFromUserFunc = focusSvc.focusHeaderPositionFromUserFunc({ userFunc, headerPosition: nextHeader, direction: normalisedDirection }); if (wasFocusedFromUserFunc) { const { headerRowIndex } = focusSvc.focusedHeader || {}; if (headerRowIndex != null && headerRowIndex != focusedHeader.headerRowIndex) { this.currentHeaderRowWithoutSpan = headerRowIndex; } } return wasFocusedFromUserFunc; } if (nextHeader || !fromTab) { return focusSvc.focusHeaderPosition({ headerPosition: nextHeader, direction: normalisedDirection, fromTab, allowUserOverride: true, event }); } return this.focusNextHeaderRow(focusedHeader, normalisedDirection, event); } focusNextHeaderRow(focusedHeader, direction, event) { const beans = this.beans; const currentIndex = focusedHeader.headerRowIndex; let nextFocusedCol = null; let nextRowIndex; const headerRowCount = getFocusHeaderRowCount(beans); const allVisibleCols = this.beans.visibleCols.allCols; if (direction === "Before") { if (currentIndex <= 0) { return false; } nextFocusedCol = _last(allVisibleCols); nextRowIndex = currentIndex - 1; this.currentHeaderRowWithoutSpan -= 1; } else { nextFocusedCol = allVisibleCols[0]; nextRowIndex = currentIndex + 1; if (this.currentHeaderRowWithoutSpan < headerRowCount) { this.currentHeaderRowWithoutSpan += 1; } else { this.currentHeaderRowWithoutSpan = -1; } } let { column, headerRowIndex } = getHeaderIndexToFocus(this.beans, nextFocusedCol, nextRowIndex); if (headerRowIndex >= headerRowCount) { headerRowIndex = -1; } return beans.focusSvc.focusHeaderPosition({ headerPosition: { column, headerRowIndex }, direction, fromTab: true, allowUserOverride: true, event }); } scrollToColumn(column, direction = "After") { if (column.getPinned()) { return; } let columnToScrollTo; if (isColumnGroup(column)) { const columns = column.getDisplayedLeafColumns(); columnToScrollTo = direction === "Before" ? _last(columns) : columns[0]; } else { columnToScrollTo = column; } this.gridBodyCon.scrollFeature.ensureColumnVisible(columnToScrollTo); } findHeader(focusedHeader, direction) { const { colGroupSvc, visibleCols } = this.beans; let currentFocusedColumn = focusedHeader.column; if (currentFocusedColumn instanceof AgColumnGroup) { const leafChildren = currentFocusedColumn.getDisplayedLeafColumns(); currentFocusedColumn = direction === "Before" ? leafChildren[0] : leafChildren[leafChildren.length - 1]; } const nextFocusedCol = direction === "Before" ? visibleCols.getColBefore(currentFocusedColumn) : visibleCols.getColAfter(currentFocusedColumn); if (!nextFocusedCol) { return; } const headerGroupRowIndex = visibleCols.headerGroupRowCount; if (focusedHeader.headerRowIndex >= headerGroupRowIndex) { return { headerRowIndex: focusedHeader.headerRowIndex, column: nextFocusedCol }; } const groupAtLevel = colGroupSvc?.getColGroupAtLevel(nextFocusedCol, focusedHeader.headerRowIndex); if (!groupAtLevel) { const isSpanningCol = nextFocusedCol instanceof AgColumn && nextFocusedCol.isSpanHeaderHeight(); return { headerRowIndex: isSpanningCol ? visibleCols.headerGroupRowCount : focusedHeader.headerRowIndex, column: nextFocusedCol }; } if (groupAtLevel.isPadding() && nextFocusedCol.isSpanHeaderHeight()) { return { headerRowIndex: visibleCols.headerGroupRowCount, column: nextFocusedCol }; } return { headerRowIndex: focusedHeader.headerRowIndex, column: groupAtLevel ?? nextFocusedCol }; } getHeaderRowType(rowIndex) { const centerHeaderContainer = this.beans.ctrlsSvc.getHeaderRowContainerCtrl(); if (centerHeaderContainer) { return centerHeaderContainer.getRowType(rowIndex); } } }; function getColumnVisibleParent(currentRowType, currentColumn, currentIndex) { const optimisticNextIndex = currentIndex - 1; if (currentRowType !== "filter") { const isSpanningCol = currentColumn instanceof AgColumn && currentColumn.isSpanHeaderHeight(); let nextVisibleParent = currentColumn.getParent(); while (nextVisibleParent && (nextVisibleParent.getProvidedColumnGroup().getLevel() > optimisticNextIndex || isSpanningCol && nextVisibleParent.isPadding())) { nextVisibleParent = nextVisibleParent.getParent(); } if (nextVisibleParent) { if (isSpanningCol) { return { column: nextVisibleParent, headerRowIndex: nextVisibleParent.getProvidedColumnGroup().getLevel(), headerRowIndexWithoutSpan: optimisticNextIndex }; } else { return { column: nextVisibleParent, headerRowIndex: optimisticNextIndex, headerRowIndexWithoutSpan: optimisticNextIndex }; } } } return { column: currentColumn, headerRowIndex: optimisticNextIndex, headerRowIndexWithoutSpan: optimisticNextIndex }; } function getColumnVisibleChild(column, currentIndex, columnHeaderRowIndex) { const optimisticNextIndex = currentIndex + 1; const result = { column, headerRowIndex: optimisticNextIndex, headerRowIndexWithoutSpan: optimisticNextIndex }; if (column instanceof AgColumnGroup) { if (optimisticNextIndex >= columnHeaderRowIndex) { return { column: column.getDisplayedLeafColumns()[0], headerRowIndex: columnHeaderRowIndex, headerRowIndexWithoutSpan: optimisticNextIndex }; } const children = column.getDisplayedChildren(); let firstChild = children[0]; if (firstChild instanceof AgColumnGroup && firstChild.isPadding()) { const firstCol = firstChild.getDisplayedLeafColumns()[0]; if (firstCol.isSpanHeaderHeight()) { firstChild = firstCol; } } result.column = firstChild; const isSpanningCol = firstChild instanceof AgColumn && firstChild.isSpanHeaderHeight(); if (isSpanningCol) { result.headerRowIndex = columnHeaderRowIndex; result.headerRowIndexWithoutSpan = optimisticNextIndex; } } return result; } var FocusService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "focusSvc"; this.focusFallbackTimeout = null; this.needsFocusRestored = false; } wireBeans(beans) { this.colModel = beans.colModel; this.visibleCols = beans.visibleCols; this.rowRenderer = beans.rowRenderer; this.navigation = beans.navigation; this.filterManager = beans.filterManager; this.overlays = beans.overlays; } postConstruct() { const clearFocusedCellListener = this.clearFocusedCell.bind(this); this.addManagedEventListeners({ columnPivotModeChanged: clearFocusedCellListener, newColumnsLoaded: this.onColumnEverythingChanged.bind(this), columnGroupOpened: clearFocusedCellListener, columnRowGroupChanged: clearFocusedCellListener }); this.addDestroyFunc(_registerKeyboardFocusEvents(this.beans)); } attemptToRecoverFocus() { this.needsFocusRestored = true; if (this.focusFallbackTimeout != null) { clearTimeout(this.focusFallbackTimeout); } this.focusFallbackTimeout = window.setTimeout(this.setFocusRecovered.bind(this), 100); } setFocusRecovered() { this.needsFocusRestored = false; if (this.focusFallbackTimeout != null) { clearTimeout(this.focusFallbackTimeout); this.focusFallbackTimeout = null; } } shouldTakeFocus() { if (this.gos.get("suppressFocusAfterRefresh")) { this.setFocusRecovered(); return false; } if (this.needsFocusRestored) { this.setFocusRecovered(); return true; } return this.doesRowOrCellHaveBrowserFocus(); } onColumnEverythingChanged() { if (!this.focusedCell) { return; } const col = this.focusedCell.column; const colFromColumnModel = this.colModel.getCol(col.getId()); if (col !== colFromColumnModel) { this.clearFocusedCell(); } } getFocusCellToUseAfterRefresh() { const { gos, focusedCell } = this; if (gos.get("suppressFocusAfterRefresh") || gos.get("suppressCellFocus") || !focusedCell) { return null; } if (!this.doesRowOrCellHaveBrowserFocus()) { return null; } return focusedCell; } getFocusHeaderToUseAfterRefresh() { if (this.gos.get("suppressFocusAfterRefresh") || !this.focusedHeader) { return null; } if (!this.isDomDataPresentInHierarchy(_getActiveDomElement(this.beans), DOM_DATA_KEY_HEADER_CTRL)) { return null; } return this.focusedHeader; } doesRowOrCellHaveBrowserFocus() { const activeElement = _getActiveDomElement(this.beans); if (this.isDomDataPresentInHierarchy(activeElement, DOM_DATA_KEY_CELL_CTRL, true)) { return true; } return this.isDomDataPresentInHierarchy(activeElement, DOM_DATA_KEY_ROW_CTRL, true); } isDomDataPresentInHierarchy(eBrowserCell, key, attemptToRefocusIfDestroyed) { let ePointer = eBrowserCell; while (ePointer) { const data = _getDomData(this.gos, ePointer, key); if (data) { if (data.destroyed && attemptToRefocusIfDestroyed) { this.attemptToRecoverFocus(); return false; } return true; } ePointer = ePointer.parentNode; } return false; } getFocusedCell() { return this.focusedCell; } getFocusEventParams(focusedCellPosition) { const { rowIndex, rowPinned, column } = focusedCellPosition; const params = { rowIndex, rowPinned, column, isFullWidthCell: false }; const rowCtrl = this.rowRenderer.getRowByPosition({ rowIndex, rowPinned }); if (rowCtrl) { params.isFullWidthCell = rowCtrl.isFullWidth(); } return params; } clearFocusedCell() { if (this.focusedCell == null) { return; } const focusEventParams = this.getFocusEventParams(this.focusedCell); this.focusedCell = null; this.eventSvc.dispatchEvent({ type: "cellFocusCleared", ...focusEventParams }); } setFocusedCell(params) { this.setFocusRecovered(); const { column, rowIndex, rowPinned, forceBrowserFocus = false, preventScrollOnBrowserFocus = false, sourceEvent } = params; const gridColumn = this.colModel.getCol(column); if (!gridColumn) { this.focusedCell = null; return; } this.focusedCell = { rowIndex, rowPinned: _makeNull(rowPinned), column: gridColumn }; const focusEventParams = this.getFocusEventParams(this.focusedCell); this.eventSvc.dispatchEvent({ type: "cellFocused", ...focusEventParams, ...this.previousCellFocusParams && { previousParams: this.previousCellFocusParams }, forceBrowserFocus, preventScrollOnBrowserFocus, sourceEvent }); this.previousCellFocusParams = focusEventParams; } isCellFocused(cellPosition) { if (this.focusedCell == null) { return false; } return _areCellsEqual(cellPosition, this.focusedCell); } isHeaderWrapperFocused(headerCtrl) { if (this.focusedHeader == null) { return false; } const { column, rowCtrl: { rowIndex: headerRowIndex, pinned } } = headerCtrl; const { column: focusedColumn, headerRowIndex: focusedHeaderRowIndex } = this.focusedHeader; return column === focusedColumn && headerRowIndex === focusedHeaderRowIndex && pinned == focusedColumn.getPinned(); } focusHeaderPosition(params) { this.setFocusRecovered(); if (_isHeaderFocusSuppressed(this.beans)) { return false; } const { direction, fromTab, allowUserOverride, event, fromCell, rowWithoutSpanValue, scroll = true } = params; let { headerPosition } = params; if (fromCell && this.filterManager?.isAdvFilterHeaderActive()) { return this.focusAdvancedFilter(headerPosition); } if (allowUserOverride) { const currentPosition = this.focusedHeader; const headerRowCount = getFocusHeaderRowCount(this.beans); if (fromTab) { const userFunc = this.gos.getCallback("tabToNextHeader"); if (userFunc) { headerPosition = this.getHeaderPositionFromUserFunc({ userFunc, direction, currentPosition, headerPosition, headerRowCount }); } } else { const userFunc = this.gos.getCallback("navigateToNextHeader"); if (userFunc && event) { const params2 = { key: event.key, previousHeaderPosition: currentPosition, nextHeaderPosition: headerPosition, headerRowCount, event }; const userResult = userFunc(params2); headerPosition = userResult === null ? currentPosition : userResult; } } } if (!headerPosition) { return false; } return this.focusProvidedHeaderPosition({ headerPosition, direction, event, fromCell, rowWithoutSpanValue, scroll }); } focusHeaderPositionFromUserFunc(params) { if (_isHeaderFocusSuppressed(this.beans)) { return false; } const { userFunc, headerPosition, direction, event } = params; const currentPosition = this.focusedHeader; const headerRowCount = getFocusHeaderRowCount(this.beans); const newHeaderPosition = this.getHeaderPositionFromUserFunc({ userFunc, direction, currentPosition, headerPosition, headerRowCount }); return !!newHeaderPosition && this.focusProvidedHeaderPosition({ headerPosition: newHeaderPosition, direction, event }); } getHeaderPositionFromUserFunc(params) { const { userFunc, direction, currentPosition, headerPosition, headerRowCount } = params; const userFuncParams = { backwards: direction === "Before", previousHeaderPosition: currentPosition, nextHeaderPosition: headerPosition, headerRowCount }; const userResult = userFunc(userFuncParams); if (userResult === true) { return currentPosition; } if (userResult === false) { return null; } return userResult; } focusProvidedHeaderPosition(params) { const { headerPosition, direction, fromCell, rowWithoutSpanValue, event, scroll = true } = params; const { column, headerRowIndex } = headerPosition; const { filterManager, ctrlsSvc, headerNavigation } = this.beans; if (this.focusedHeader && isHeaderPositionEqual(params.headerPosition, this.focusedHeader)) { return false; } if (headerRowIndex === -1) { if (filterManager?.isAdvFilterHeaderActive()) { return this.focusAdvancedFilter(headerPosition); } return this.focusGridView({ column, event }); } if (scroll) { headerNavigation?.scrollToColumn(column, direction); } const headerRowContainerCtrl = ctrlsSvc.getHeaderRowContainerCtrl(column.getPinned()); const focusSuccess = headerRowContainerCtrl?.focusHeader(headerPosition.headerRowIndex, column, event) || false; if (headerNavigation && focusSuccess && (rowWithoutSpanValue != null || fromCell)) { headerNavigation.currentHeaderRowWithoutSpan = rowWithoutSpanValue ?? -1; } return focusSuccess; } focusFirstHeader() { if (this.overlays?.exclusive && this.focusOverlay()) { return true; } const firstColumn = this.visibleCols.allCols[0]; if (!firstColumn) { return false; } const headerPosition = getHeaderIndexToFocus(this.beans, firstColumn, 0); return this.focusHeaderPosition({ headerPosition, rowWithoutSpanValue: 0 }); } focusLastHeader(event) { if (this.overlays?.exclusive && this.focusOverlay(true)) { return true; } const headerRowIndex = getFocusHeaderRowCount(this.beans) - 1; const column = _last(this.visibleCols.allCols); return this.focusHeaderPosition({ headerPosition: { headerRowIndex, column }, rowWithoutSpanValue: -1, event }); } focusPreviousFromFirstCell(event) { if (this.filterManager?.isAdvFilterHeaderActive()) { return this.focusAdvancedFilter(null); } return this.focusLastHeader(event); } isAnyCellFocused() { return !!this.focusedCell; } isRowFocused(rowIndex, rowPinnedType) { if (this.focusedCell == null) { return false; } return this.focusedCell.rowIndex === rowIndex && this.focusedCell.rowPinned === _makeNull(rowPinnedType); } focusOverlay(backwards) { const overlayGui = this.overlays?.isVisible() && this.overlays.eWrapper?.getGui(); return !!overlayGui && _focusInto(overlayGui, backwards); } getDefaultTabToNextGridContainerTarget(params) { const { backwards, focusableContainers } = params; const step = backwards ? -1 : 1; let gridBodyTarget; const getGridBodyTabTarget = () => { if (gridBodyTarget === undefined) { gridBodyTarget = this.getGridBodyTabTarget(backwards); } return gridBodyTarget; }; for (let index = params.nextIndex;index >= 0 && index < focusableContainers.length; index += step) { const target = _getDefaultTabTargetForContainer(focusableContainers[index], getGridBodyTabTarget); if (target) { return target; } } return null; } getGridBodyTabTarget(backwards) { if (backwards) { return this.getGridViewTabTarget({ column: _last(this.visibleCols.allCols), backwards: true }); } const firstColumn = this.visibleCols.allCols[0]; if (this.gos.get("headerHeight") === 0 || _isHeaderFocusSuppressed(this.beans)) { return this.getGridViewTabTarget({ column: firstColumn }); } if (!firstColumn) { return null; } return getHeaderIndexToFocus(this.beans, firstColumn, 0); } getGridViewTabTarget(params) { const { backwards = false } = params; const column = params.column ?? this.focusedHeader?.column; if (!column) { return null; } if (this.overlays?.exclusive) { return null; } if (_isCellFocusSuppressed(this.beans)) { return backwards && !_isHeaderFocusSuppressed(this.beans) ? { headerRowIndex: getFocusHeaderRowCount(this.beans) - 1, column } : null; } const nextRow = backwards ? _getLastRow(this.beans) : _getFirstRow(this.beans); if (nextRow?.rowIndex == null) { if (this.overlays?.isVisible()) { return null; } if (backwards && !_isHeaderFocusSuppressed(this.beans)) { const lastColumn = _last(this.visibleCols.allCols); if (lastColumn) { return { headerRowIndex: getFocusHeaderRowCount(this.beans) - 1, column: lastColumn }; } } return null; } const rowNode = _getRowNode(this.beans, nextRow); if (!rowNode || column.isSuppressNavigable(rowNode)) { return null; } if (backwards) { const rowCtrl = this.rowRenderer.getRowByPosition(nextRow); if (rowCtrl?.isFullWidth()) { return null; } } return { rowIndex: nextRow.rowIndex, rowPinned: nextRow.rowPinned, column }; } focusGridView(params) { const { backwards = false, canFocusOverlay = true, event } = params; if (this.overlays?.exclusive) { return canFocusOverlay && this.focusOverlay(backwards); } if (_isCellFocusSuppressed(this.beans)) { if (backwards) { if (!_isHeaderFocusSuppressed(this.beans)) { return this.focusLastHeader(); } } if (canFocusOverlay && this.focusOverlay(backwards)) { return true; } if (backwards) { return false; } return _focusNextGridCoreContainer(this.beans, backwards); } const nextRow = backwards ? _getLastRow(this.beans) : _getFirstRow(this.beans); if (nextRow) { const column = params.column ?? this.focusedHeader?.column; const { rowIndex, rowPinned } = nextRow; const rowNode = _getRowNode(this.beans, nextRow); if (!column || !rowNode || rowIndex == null) { return false; } if (column.isSuppressNavigable(rowNode)) { const isRtl = this.gos.get("enableRtl"); let key; if (!event || event.key === KeyCode.TAB) { key = isRtl ? KeyCode.LEFT : KeyCode.RIGHT; } else { key = event.key; } this.beans.navigation?.navigateToNextCell(null, key, { rowIndex, column, rowPinned: rowPinned || null }, true); return true; } this.navigation?.ensureCellVisible({ rowIndex, column, rowPinned }); if (backwards) { const rowCtrl = this.rowRenderer.getRowByPosition(nextRow); if (rowCtrl?.isFullWidth() && this.navigation?.tryToFocusFullWidthRow(nextRow, backwards)) { return true; } } this.setFocusedCell({ rowIndex, column, rowPinned: _makeNull(rowPinned), forceBrowserFocus: true }); if (!isRowNumberCol(column)) { this.beans.rangeSvc?.setRangeToCell({ rowIndex, rowPinned, column }); } return true; } if (canFocusOverlay && this.focusOverlay(backwards)) { return true; } if (backwards && this.focusLastHeader()) { return true; } return false; } focusAdvancedFilter(position) { this.advFilterFocusColumn = position?.column; return this.beans.advancedFilter?.getCtrl().focusHeaderComp() ?? false; } focusNextFromAdvancedFilter(backwards, forceFirstColumn) { const column = (forceFirstColumn ? undefined : this.advFilterFocusColumn) ?? this.visibleCols.allCols?.[0]; if (backwards) { return this.focusHeaderPosition({ headerPosition: { column, headerRowIndex: getFocusHeaderRowCount(this.beans) - 1 } }); } return this.focusGridView({ column }); } clearAdvancedFilterColumn() { this.advFilterFocusColumn = undefined; } }; var ScrollVisibleService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "scrollVisibleSvc"; } wireBeans(beans) { this.ctrlsSvc = beans.ctrlsSvc; this.colAnimation = beans.colAnimation; } postConstruct() { const { gos } = this; this.horizontalScrollShowing = gos.get("alwaysShowHorizontalScroll") === true; this.verticalScrollShowing = gos.get("alwaysShowVerticalScroll") === true; this.getScrollbarWidth(); const updateScrollVisible = this.updateScrollVisible.bind(this); this.addManagedEventListeners({ displayedColumnsChanged: updateScrollVisible, displayedColumnsWidthChanged: updateScrollVisible, newColumnsLoaded: updateScrollVisible }); } updateScrollVisible() { const { colAnimation } = this; if (colAnimation?.isActive()) { colAnimation.executeLaterVMTurn(() => { colAnimation.executeLaterVMTurn(() => this.updateScrollVisibleImpl()); }); } else { this.updateScrollVisibleImpl(); } } updateScrollVisibleImpl() { const centerRowCtrl = this.ctrlsSvc.get("center"); if (!centerRowCtrl || this.colAnimation?.isActive()) { return; } const params = { horizontalScrollShowing: centerRowCtrl.isHorizontalScrollShowing(), verticalScrollShowing: this.verticalScrollShowing }; this.setScrollsVisible(params); this.updateScrollGap(); } updateScrollGap() { const centerRowCtrl = this.ctrlsSvc.get("center"); const horizontalGap = centerRowCtrl.hasHorizontalScrollGap(); const verticalGap = centerRowCtrl.hasVerticalScrollGap(); const atLeastOneDifferent = this.horizontalScrollGap !== horizontalGap || this.verticalScrollGap !== verticalGap; if (atLeastOneDifferent) { this.horizontalScrollGap = horizontalGap; this.verticalScrollGap = verticalGap; this.eventSvc.dispatchEvent({ type: "scrollGapChanged" }); } } setScrollsVisible(params) { const atLeastOneDifferent = this.horizontalScrollShowing !== params.horizontalScrollShowing || this.verticalScrollShowing !== params.verticalScrollShowing; if (atLeastOneDifferent) { this.horizontalScrollShowing = params.horizontalScrollShowing; this.verticalScrollShowing = params.verticalScrollShowing; this.eventSvc.dispatchEvent({ type: "scrollVisibilityChanged" }); } } getScrollbarWidth() { if (this.scrollbarWidth == null) { const gridOptionsScrollbarWidth = this.gos.get("scrollbarWidth"); const useGridOptions = typeof gridOptionsScrollbarWidth === "number" && gridOptionsScrollbarWidth >= 0; const scrollbarWidth = useGridOptions ? gridOptionsScrollbarWidth : _getScrollbarWidth(); if (scrollbarWidth != null) { this.scrollbarWidth = scrollbarWidth; this.eventSvc.dispatchEvent({ type: "scrollbarWidthChanged" }); } } return this.scrollbarWidth; } }; var GridDestroyService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "gridDestroySvc"; this.destroyCalled = false; } destroy() { if (this.destroyCalled) { return; } const { stateSvc, ctrlsSvc, context } = this.beans; this.eventSvc.dispatchEvent({ type: "gridPreDestroyed", state: stateSvc?.getState() ?? {} }); this.destroyCalled = true; ctrlsSvc.get("gridCtrl")?.destroyGridUi(); context.destroy(); super.destroy(); } }; var _PUBLIC_EVENTS = [ "columnEverythingChanged", "newColumnsLoaded", "columnPivotModeChanged", "pivotMaxColumnsExceeded", "columnRowGroupChanged", "expandOrCollapseAll", "columnPivotChanged", "gridColumnsChanged", "columnValueChanged", "columnMoved", "columnVisible", "columnPinned", "columnGroupOpened", "columnResized", "displayedColumnsChanged", "virtualColumnsChanged", "columnHeaderMouseOver", "columnHeaderMouseLeave", "columnHeaderClicked", "columnHeaderContextMenu", "asyncTransactionsFlushed", "rowGroupOpened", "rowDataUpdated", "pinnedRowDataChanged", "pinnedRowsChanged", "rangeSelectionChanged", "cellSelectionChanged", "chartCreated", "chartRangeSelectionChanged", "chartOptionsChanged", "chartDestroyed", "toolPanelVisibleChanged", "toolPanelSizeChanged", "modelUpdated", "cutStart", "cutEnd", "pasteStart", "pasteEnd", "fillStart", "fillEnd", "cellSelectionDeleteStart", "cellSelectionDeleteEnd", "rangeDeleteStart", "rangeDeleteEnd", "undoStarted", "undoEnded", "redoStarted", "redoEnded", "cellClicked", "cellDoubleClicked", "cellMouseDown", "cellContextMenu", "cellValueChanged", "cellEditRequest", "rowValueChanged", "headerFocused", "cellFocused", "rowSelected", "selectionChanged", "tooltipShow", "tooltipHide", "cellKeyDown", "cellMouseOver", "cellMouseOut", "filterChanged", "filterModified", "filterUiChanged", "filterOpened", "floatingFilterUiChanged", "advancedFilterBuilderVisibleChanged", "sortChanged", "virtualRowRemoved", "rowClicked", "rowDoubleClicked", "gridReady", "gridPreDestroyed", "gridSizeChanged", "viewportChanged", "firstDataRendered", "dragStarted", "dragStopped", "dragCancelled", "rowEditingStarted", "rowEditingStopped", "cellEditingStarted", "cellEditingStopped", "bodyScroll", "bodyScrollEnd", "paginationChanged", "componentStateChanged", "storeRefreshed", "stateUpdated", "columnMenuVisibleChanged", "contextMenuVisibleChanged", "rowDragEnter", "rowDragMove", "rowDragLeave", "rowDragEnd", "rowDragCancel", "findChanged", "rowResizeStarted", "rowResizeEnded", "columnsReset", "bulkEditingStarted", "bulkEditingStopped", "batchEditingStarted", "batchEditingStopped" ]; var ALWAYS_SYNC_GLOBAL_EVENTS = /* @__PURE__ */ new Set(["gridPreDestroyed", "fillStart", "pasteStart"]); var _PUBLIC_EVENT_HANDLERS_MAP = _PUBLIC_EVENTS.reduce((mem, ev) => { mem[ev] = _getCallbackForEvent(ev); return mem; }, {}); var USER_COMP_MODULES = { agSetColumnFilter: "SetFilter", agSetColumnFloatingFilter: "SetFilter", agMultiColumnFilter: "MultiFilter", agMultiColumnFloatingFilter: "MultiFilter", agGroupColumnFilter: "GroupFilter", agGroupColumnFloatingFilter: "GroupFilter", agGroupCellRenderer: "GroupCellRenderer", agGroupRowRenderer: "GroupCellRenderer", agRichSelect: "RichSelect", agRichSelectCellEditor: "RichSelect", agDetailCellRenderer: "SharedMasterDetail", agSparklineCellRenderer: "Sparklines", agDragAndDropImage: "SharedDragAndDrop", agColumnHeader: "ColumnHeaderComp", agColumnGroupHeader: "ColumnGroupHeaderComp", agSortIndicator: "Sort", agAnimateShowChangeCellRenderer: "HighlightChanges", agAnimateSlideCellRenderer: "HighlightChanges", agLoadingCellRenderer: "LoadingCellRenderer", agSkeletonCellRenderer: "SkeletonCellRenderer", agCheckboxCellRenderer: "CheckboxCellRenderer", agLoadingOverlay: "Overlay", agExportingOverlay: "Overlay", agNoRowsOverlay: "Overlay", agNoMatchingRowsOverlay: "Overlay", agTooltipComponent: "Tooltip", agReadOnlyFloatingFilter: "CustomFilter", agTextColumnFilter: "TextFilter", agNumberColumnFilter: "NumberFilter", agBigIntColumnFilter: "BigIntFilter", agDateColumnFilter: "DateFilter", agDateInput: "DateFilter", agTextColumnFloatingFilter: "TextFilter", agNumberColumnFloatingFilter: "NumberFilter", agBigIntColumnFloatingFilter: "BigIntFilter", agDateColumnFloatingFilter: "DateFilter", agFormulaCellEditor: "Formula", agCellEditor: "TextEditor", agSelectCellEditor: "SelectEditor", agTextCellEditor: "TextEditor", agNumberCellEditor: "NumberEditor", agDateCellEditor: "DateEditor", agDateStringCellEditor: "DateEditor", agCheckboxCellEditor: "CheckboxEditor", agLargeTextCellEditor: "LargeTextEditor", agMenuItem: "MenuItem", agColumnsToolPanel: "ColumnsToolPanel", agFiltersToolPanel: "FiltersToolPanel", agNewFiltersToolPanel: "NewFiltersToolPanel", agAggregationComponent: "StatusBar", agSelectedRowCountComponent: "StatusBar", agTotalRowCountComponent: "StatusBar", agFilteredRowCountComponent: "StatusBar", agTotalAndFilteredRowCountComponent: "StatusBar", agFindCellRenderer: "Find" }; function quote(s) { return `"${s}"`; } var COLUMN_DEFINITION_DEPRECATIONS = () => ({ checkboxSelection: { version: "32.2", message: "Use `rowSelection.checkboxes` in `GridOptions` instead." }, headerCheckboxSelection: { version: "32.2", message: "Use `rowSelection.headerCheckbox = true` in `GridOptions` instead." }, headerCheckboxSelectionFilteredOnly: { version: "32.2", message: 'Use `rowSelection.selectAll = "filtered"` in `GridOptions` instead.' }, headerCheckboxSelectionCurrentPageOnly: { version: "32.2", message: 'Use `rowSelection.selectAll = "currentPage"` in `GridOptions` instead.' }, showDisabledCheckboxes: { version: "32.2", message: "Use `rowSelection.hideDisabledCheckboxes = true` in `GridOptions` instead." }, rowGroupingHierarchy: { version: "34.3", message: "Use `colDef.groupHierarchy` instead." } }); var COLUMN_DEFINITION_MOD_VALIDATIONS = { allowFormula: "Formula", aggFunc: "SharedAggregation", autoHeight: "RowAutoHeight", cellClass: "CellStyle", cellClassRules: "CellStyle", cellEditor: ({ cellEditor, editable, groupRowEditable }) => { const editingEnabled = !!editable || !!groupRowEditable; if (!editingEnabled) { return null; } if (typeof cellEditor === "string") { return USER_COMP_MODULES[cellEditor] ?? "CustomEditor"; } return "CustomEditor"; }, cellRenderer: ({ cellRenderer }) => { if (typeof cellRenderer !== "string") { return null; } return USER_COMP_MODULES[cellRenderer]; }, cellStyle: "CellStyle", columnChooserParams: "ColumnMenu", contextMenuItems: "ContextMenu", dndSource: "DragAndDrop", dndSourceOnRowDrag: "DragAndDrop", editable: ({ editable, cellEditor }) => { if (editable && !cellEditor) { return "TextEditor"; } return null; }, groupRowEditable: ({ groupRowEditable, cellEditor }) => { if (!groupRowEditable) { return null; } return cellEditor ? "RowGroupingEdit" : ["RowGroupingEdit", "TextEditor"]; }, groupRowValueSetter: ({ groupRowValueSetter }) => groupRowValueSetter ? "RowGroupingEdit" : null, enableCellChangeFlash: "HighlightChanges", enablePivot: "SharedPivot", enableRowGroup: "SharedRowGrouping", enableValue: "SharedAggregation", filter: ({ filter }) => { if (filter && typeof filter !== "string" && typeof filter !== "boolean") { return "CustomFilter"; } if (typeof filter === "string") { return USER_COMP_MODULES[filter] ?? "ColumnFilter"; } return "ColumnFilter"; }, floatingFilter: "ColumnFilter", getQuickFilterText: "QuickFilter", headerTooltip: "Tooltip", headerTooltipValueGetter: "Tooltip", mainMenuItems: "ColumnMenu", menuTabs: (options) => { const enterpriseMenuTabs = ["columnsMenuTab", "generalMenuTab"]; if (options.menuTabs?.some((tab) => enterpriseMenuTabs.includes(tab))) { return "ColumnMenu"; } return null; }, pivot: "SharedPivot", pivotIndex: "SharedPivot", rowDrag: "RowDrag", rowGroup: "SharedRowGrouping", rowGroupIndex: "SharedRowGrouping", tooltipField: "Tooltip", tooltipValueGetter: "Tooltip", tooltipComponentSelector: "Tooltip", spanRows: "CellSpan", groupHierarchy: "SharedRowGrouping" }; var COLUMN_DEFINITION_VALIDATIONS = () => { const validations = { autoHeight: { supportedRowModels: ["clientSide", "serverSide"], validate: (_colDef, { paginationAutoPageSize }) => { if (paginationAutoPageSize) { return "colDef.autoHeight is not supported with paginationAutoPageSize."; } return null; } }, allowFormula: { supportedRowModels: ["clientSide"] }, cellRendererParams: { validate: (colDef) => { const groupColumn = colDef.rowGroup != null || colDef.rowGroupIndex != null || colDef.cellRenderer === "agGroupCellRenderer"; if (groupColumn && "checkbox" in colDef.cellRendererParams) { return 'Since v33.0, `cellRendererParams.checkbox` has been deprecated. Use `rowSelection.checkboxLocation = "autoGroupColumn"` instead.'; } return null; } }, flex: { validate: (_options, gridOptions) => { if (gridOptions.autoSizeStrategy) { return "colDef.flex is not supported with gridOptions.autoSizeStrategy"; } return null; } }, headerCheckboxSelection: { supportedRowModels: ["clientSide", "serverSide"], validate: (_options, { rowSelection }) => rowSelection === "multiple" ? null : "headerCheckboxSelection is only supported with rowSelection=multiple" }, headerCheckboxSelectionCurrentPageOnly: { supportedRowModels: ["clientSide"], validate: (_options, { rowSelection }) => rowSelection === "multiple" ? null : "headerCheckboxSelectionCurrentPageOnly is only supported with rowSelection=multiple" }, headerCheckboxSelectionFilteredOnly: { supportedRowModels: ["clientSide"], validate: (_options, { rowSelection }) => rowSelection === "multiple" ? null : "headerCheckboxSelectionFilteredOnly is only supported with rowSelection=multiple" }, headerValueGetter: { validate: (_options) => { const headerValueGetter = _options.headerValueGetter; if (typeof headerValueGetter === "function" || typeof headerValueGetter === "string") { return null; } return "headerValueGetter must be a function or a valid string expression"; } }, icons: { validate: ({ icons }) => { if (icons) { if (icons["smallDown"]) { return _errMsg(262); } if (icons["smallLeft"]) { return _errMsg(263); } if (icons["smallRight"]) { return _errMsg(264); } } return null; } }, sort: { validate: (_options) => { if (_isSortDefValid(_options.sort) || _isSortDirectionValid(_options.sort)) { return null; } return `sort must be of type (SortDirection | SortDef), currently it is ${typeof _options.sort === "object" ? JSON.stringify(_options.sort) : toStringWithNullUndefined(_options.sort)}`; } }, initialSort: { validate: (_options) => { if (_isSortDefValid(_options.initialSort) || _isSortDirectionValid(_options.initialSort)) { return null; } return `initialSort must be of non-null type (SortDirection | SortDef), currently it is ${typeof _options.initialSort === "object" ? JSON.stringify(_options.initialSort) : toStringWithNullUndefined(_options.initialSort)}`; } }, sortingOrder: { validate: (_options) => { const sortingOrder = _options.sortingOrder; if (Array.isArray(sortingOrder) && sortingOrder.length > 0) { const invalidItems = sortingOrder.filter((a) => { return !(_isSortDefValid(a) || _isSortDirectionValid(a)); }); if (invalidItems.length > 0) { return `sortingOrder must be an array of type non-null (SortDirection | SortDef)[], incorrect items are: [${invalidItems.map((item) => typeof item === "string" || item == null ? toStringWithNullUndefined(item) : JSON.stringify(item)).join(", ")}]`; } } else if (!Array.isArray(sortingOrder) || !sortingOrder.length) { return `sortingOrder must be an array with at least one element, currently it is [${sortingOrder}]`; } return null; } }, type: { validate: (_options) => { const type = _options.type; if (type instanceof Array) { const invalidArray = type.some((a) => typeof a !== "string"); if (invalidArray) { return "if colDef.type is supplied an array it should be of type 'string[]'"; } return null; } if (typeof type === "string") { return null; } return "colDef.type should be of type 'string' | 'string[]'"; } }, rowSpan: { validate: (_options, { suppressRowTransform }) => { if (!suppressRowTransform) { return "colDef.rowSpan requires suppressRowTransform to be enabled."; } return null; } }, spanRows: { dependencies: { editable: { required: [false, undefined] }, groupRowEditable: { required: [false, undefined] }, rowDrag: { required: [false, undefined] }, colSpan: { required: [undefined] }, rowSpan: { required: [undefined] } }, validate: (_options, { rowSelection, cellSelection, suppressRowTransform, enableCellSpan, rowDragEntireRow, enableCellTextSelection }) => { if (typeof rowSelection === "object") { if (rowSelection?.mode === "singleRow" && rowSelection?.enableClickSelection) { return "colDef.spanRows is not supported with rowSelection.clickSelection"; } } if (cellSelection) { return "colDef.spanRows is not supported with cellSelection."; } if (suppressRowTransform) { return "colDef.spanRows is not supported with suppressRowTransform."; } if (!enableCellSpan) { return "colDef.spanRows requires enableCellSpan to be enabled."; } if (rowDragEntireRow) { return "colDef.spanRows is not supported with rowDragEntireRow."; } if (enableCellTextSelection) { return "colDef.spanRows is not supported with enableCellTextSelection."; } return null; } }, groupHierarchy: { validate(options, { groupHierarchyConfig = {} }, beans) { const GROUP_HIERARCHY_PARTS = /* @__PURE__ */ new Set([ "year", "quarter", "month", "formattedMonth", "day", "hour", "minute", "second" ]); const unrecognisedParts = []; for (const part of options.groupHierarchy ?? []) { if (typeof part === "object") { beans.validation?.validateColDef(part); continue; } if (!GROUP_HIERARCHY_PARTS.has(part) && !(part in groupHierarchyConfig)) { unrecognisedParts.push(quote(part)); } } if (unrecognisedParts.length > 0) { const warning = `The following parts of colDef.groupHierarchy are not recognised: ${unrecognisedParts.join(", ")}.`; const suggestions = `Choose one of ${[...GROUP_HIERARCHY_PARTS].map(quote).join(", ")}, or define your own parts in gridOptions.groupHierarchyConfig.`; return `${warning} ${suggestions}`; } return null; } } }; return validations; }; var colDefPropertyMap = { headerName: undefined, columnGroupShow: undefined, headerStyle: undefined, headerClass: undefined, toolPanelClass: undefined, headerValueGetter: undefined, pivotKeys: undefined, groupId: undefined, colId: undefined, sort: undefined, initialSort: undefined, field: undefined, type: undefined, cellDataType: undefined, tooltipComponent: undefined, tooltipField: undefined, headerTooltip: undefined, headerTooltipValueGetter: undefined, cellClass: undefined, showRowGroup: undefined, filter: undefined, initialAggFunc: undefined, defaultAggFunc: undefined, aggFunc: undefined, groupRowEditable: undefined, groupRowValueSetter: undefined, pinned: undefined, initialPinned: undefined, chartDataType: undefined, cellAriaRole: undefined, cellEditorPopupPosition: undefined, headerGroupComponent: undefined, headerGroupComponentParams: undefined, cellStyle: undefined, cellRenderer: undefined, cellRendererParams: undefined, cellEditor: undefined, cellEditorParams: undefined, filterParams: undefined, pivotValueColumn: undefined, headerComponent: undefined, headerComponentParams: undefined, floatingFilterComponent: undefined, floatingFilterComponentParams: undefined, tooltipComponentParams: undefined, refData: undefined, columnChooserParams: undefined, children: undefined, sortingOrder: undefined, allowedAggFuncs: undefined, menuTabs: undefined, pivotTotalColumnIds: undefined, cellClassRules: undefined, icons: undefined, sortIndex: undefined, initialSortIndex: undefined, flex: undefined, initialFlex: undefined, width: undefined, initialWidth: undefined, minWidth: undefined, maxWidth: undefined, rowGroupIndex: undefined, initialRowGroupIndex: undefined, pivotIndex: undefined, initialPivotIndex: undefined, suppressColumnsToolPanel: undefined, suppressFiltersToolPanel: undefined, openByDefault: undefined, marryChildren: undefined, suppressStickyLabel: undefined, hide: undefined, initialHide: undefined, rowGroup: undefined, initialRowGroup: undefined, pivot: undefined, initialPivot: undefined, checkboxSelection: undefined, showDisabledCheckboxes: undefined, headerCheckboxSelection: undefined, headerCheckboxSelectionFilteredOnly: undefined, headerCheckboxSelectionCurrentPageOnly: undefined, suppressHeaderMenuButton: undefined, suppressMovable: undefined, lockPosition: undefined, lockVisible: undefined, lockPinned: undefined, unSortIcon: undefined, suppressSizeToFit: undefined, suppressAutoSize: undefined, enableRowGroup: undefined, enablePivot: undefined, enableValue: undefined, editable: undefined, suppressPaste: undefined, suppressNavigable: undefined, enableCellChangeFlash: undefined, rowDrag: undefined, dndSource: undefined, autoHeight: undefined, wrapText: undefined, sortable: undefined, resizable: undefined, singleClickEdit: undefined, floatingFilter: undefined, cellEditorPopup: undefined, suppressFillHandle: undefined, wrapHeaderText: undefined, autoHeaderHeight: undefined, dndSourceOnRowDrag: undefined, valueGetter: undefined, valueSetter: undefined, filterValueGetter: undefined, keyCreator: undefined, valueFormatter: undefined, valueParser: undefined, comparator: undefined, equals: undefined, pivotComparator: undefined, suppressKeyboardEvent: undefined, suppressHeaderKeyboardEvent: undefined, colSpan: undefined, rowSpan: undefined, spanRows: undefined, getQuickFilterText: undefined, onCellValueChanged: undefined, onCellClicked: undefined, onCellDoubleClicked: undefined, onCellContextMenu: undefined, rowDragText: undefined, tooltipValueGetter: undefined, tooltipComponentSelector: undefined, cellRendererSelector: undefined, cellEditorSelector: undefined, suppressSpanHeaderHeight: undefined, useValueFormatterForExport: undefined, useValueParserForImport: undefined, mainMenuItems: undefined, contextMenuItems: undefined, suppressFloatingFilterButton: undefined, suppressHeaderFilterButton: undefined, suppressHeaderContextMenu: undefined, loadingCellRenderer: undefined, loadingCellRendererParams: undefined, loadingCellRendererSelector: undefined, context: undefined, dateComponent: undefined, dateComponentParams: undefined, getFindText: undefined, rowGroupingHierarchy: undefined, groupHierarchy: undefined, allowFormula: undefined }; var ALL_PROPERTIES = () => Object.keys(colDefPropertyMap); var COL_DEF_VALIDATORS = () => ({ objectName: "colDef", allProperties: ALL_PROPERTIES(), docsUrl: "column-properties/", deprecations: COLUMN_DEFINITION_DEPRECATIONS(), validations: COLUMN_DEFINITION_VALIDATIONS() }); var STRING_GRID_OPTIONS = [ "overlayLoadingTemplate", "overlayNoRowsTemplate", "gridId", "quickFilterText", "rowModelType", "editType", "domLayout", "clipboardDelimiter", "rowGroupPanelShow", "multiSortKey", "pivotColumnGroupTotals", "pivotRowTotals", "pivotPanelShow", "fillHandleDirection", "groupDisplayType", "treeDataDisplayType", "treeDataChildrenField", "treeDataParentIdField", "colResizeDefault", "tooltipTrigger", "serverSidePivotResultFieldSeparator", "columnMenu", "tooltipShowMode", "invalidEditValueMode", "grandTotalRow", "themeCssLayer", "findSearchValue", "styleNonce", "renderingMode" ]; var OBJECT_GRID_OPTIONS = [ "components", "rowStyle", "context", "autoGroupColumnDef", "localeText", "icons", "datasource", "dragAndDropImageComponentParams", "serverSideDatasource", "viewportDatasource", "groupRowRendererParams", "aggFuncs", "fullWidthCellRendererParams", "defaultColGroupDef", "defaultColDef", "defaultCsvExportParams", "defaultExcelExportParams", "columnTypes", "rowClassRules", "detailCellRendererParams", "loadingCellRendererParams", "overlayComponentParams", "loadingOverlayComponentParams", "noRowsOverlayComponentParams", "activeOverlayParams", "popupParent", "themeStyleContainer", "statusBar", "chartThemeOverrides", "customChartThemes", "chartToolPanelsDef", "dataTypeDefinitions", "advancedFilterParent", "advancedFilterBuilderParams", "advancedFilterParams", "formulaDataSource", "formulaFuncs", "initialState", "autoSizeStrategy", "selectionColumnDef", "findOptions", "filterHandlers", "groupHierarchyConfig" ]; var ARRAY_GRID_OPTIONS = [ "sortingOrder", "alignedGrids", "rowData", "columnDefs", "excelStyles", "pinnedTopRowData", "pinnedBottomRowData", "chartThemes", "rowClass", "paginationPageSizeSelector", "suppressOverlays" ]; var _NUMBER_GRID_OPTIONS = [ "rowHeight", "detailRowHeight", "rowBuffer", "headerHeight", "groupHeaderHeight", "groupLockGroupColumns", "floatingFiltersHeight", "pivotHeaderHeight", "pivotGroupHeaderHeight", "groupDefaultExpanded", "pivotDefaultExpanded", "viewportRowModelPageSize", "viewportRowModelBufferSize", "autoSizePadding", "maxBlocksInCache", "maxConcurrentDatasourceRequests", "tooltipShowDelay", "tooltipSwitchShowDelay", "tooltipHideDelay", "cacheOverflowSize", "paginationPageSize", "cacheBlockSize", "infiniteInitialRowCount", "serverSideInitialRowCount", "scrollbarWidth", "asyncTransactionWaitMillis", "blockLoadDebounceMillis", "keepDetailRowsCount", "undoRedoCellEditingLimit", "cellFlashDuration", "cellFadeDuration", "tabIndex", "pivotMaxGeneratedColumns", "rowDragInsertDelay" ]; var OTHER_GRID_OPTIONS = ["theme", "rowSelection"]; var _BOOLEAN_MIXED_GRID_OPTIONS = [ "cellSelection", "sideBar", "rowNumbers", "suppressGroupChangesColumnVisibility", "groupAggFiltering", "suppressStickyTotalRow", "groupHideParentOfSingleChild", "enableRowPinning" ]; var _BOOLEAN_GRID_OPTIONS = [ "loadThemeGoogleFonts", "suppressMakeColumnVisibleAfterUnGroup", "suppressRowClickSelection", "suppressCellFocus", "suppressHeaderFocus", "suppressHorizontalScroll", "groupSelectsChildren", "alwaysShowHorizontalScroll", "alwaysShowVerticalScroll", "debug", "enableBrowserTooltips", "enableCellExpressions", "groupSuppressBlankHeader", "suppressMenuHide", "suppressRowDeselection", "unSortIcon", "suppressMultiSort", "alwaysMultiSort", "singleClickEdit", "suppressLoadingOverlay", "suppressNoRowsOverlay", "suppressAutoSize", "skipHeaderOnAutoSize", "suppressColumnMoveAnimation", "suppressMoveWhenColumnDragging", "suppressMovableColumns", "suppressFieldDotNotation", "enableRangeSelection", "enableRangeHandle", "enableFillHandle", "suppressClearOnFillReduction", "deltaSort", "suppressTouch", "allowContextMenuWithControlKey", "suppressContextMenu", "suppressDragLeaveHidesColumns", "suppressRowGroupHidesColumns", "suppressMiddleClickScrolls", "suppressPreventDefaultOnMouseWheel", "suppressCopyRowsToClipboard", "copyHeadersToClipboard", "copyGroupHeadersToClipboard", "pivotMode", "suppressAggFuncInHeader", "suppressColumnVirtualisation", "alwaysAggregateAtRootLevel", "suppressFocusAfterRefresh", "functionsReadOnly", "animateRows", "groupSelectsFiltered", "groupRemoveSingleChildren", "groupRemoveLowestSingleChildren", "enableRtl", "enableCellSpan", "suppressClickEdit", "rowDragEntireRow", "rowDragManaged", "refreshAfterGroupEdit", "suppressRowDrag", "suppressMoveWhenRowDragging", "rowDragMultiRow", "enableGroupEdit", "embedFullWidthRows", "suppressPaginationPanel", "groupHideOpenParents", "groupHideColumnsUntilExpanded", "groupAllowUnbalanced", "pagination", "paginationAutoPageSize", "suppressScrollOnNewData", "suppressScrollWhenPopupsAreOpen", "purgeClosedRowNodes", "cacheQuickFilter", "includeHiddenColumnsInQuickFilter", "ensureDomOrder", "accentedSort", "suppressChangeDetection", "valueCache", "valueCacheNeverExpires", "aggregateOnlyChangedColumns", "suppressAnimationFrame", "suppressExcelExport", "suppressCsvExport", "includeHiddenColumnsInAdvancedFilter", "suppressMultiRangeSelection", "enterNavigatesVerticallyAfterEdit", "enterNavigatesVertically", "suppressPropertyNamesCheck", "rowMultiSelectWithClick", "suppressRowHoverHighlight", "suppressRowTransform", "suppressClipboardPaste", "suppressLastEmptyLineOnPaste", "enableCharts", "suppressMaintainUnsortedOrder", "enableCellTextSelection", "suppressBrowserResizeObserver", "suppressMaxRenderedRowRestriction", "excludeChildrenWhenTreeDataFiltering", "tooltipMouseTrack", "tooltipInteraction", "keepDetailRows", "paginateChildRows", "preventDefaultOnContextMenu", "undoRedoCellEditing", "allowDragFromColumnsToolPanel", "pivotSuppressAutoColumn", "suppressExpandablePivotGroups", "debounceVerticalScrollbar", "detailRowAutoHeight", "serverSideSortAllLevels", "serverSideEnableClientSideSort", "serverSideOnlyRefreshFilteredGroups", "suppressAggFilteredOnly", "showOpenedGroup", "suppressClipboardApi", "suppressModelUpdateAfterUpdateTransaction", "stopEditingWhenCellsLoseFocus", "groupMaintainOrder", "columnHoverHighlight", "readOnlyEdit", "suppressRowVirtualisation", "enableCellEditingOnBackspace", "resetRowDataOnUpdate", "removePivotHeaderRowWhenSingleValueColumn", "suppressCopySingleCellRanges", "suppressGroupRowsSticky", "suppressCutToClipboard", "rowGroupPanelSuppressSort", "allowShowChangeAfterFilter", "enableAdvancedFilter", "masterDetail", "treeData", "reactiveCustomComponents", "applyQuickFilterBeforePivotOrAgg", "suppressServerSideFullWidthLoadingRow", "suppressAdvancedFilterEval", "loading", "maintainColumnOrder", "enableStrictPivotColumnOrder", "suppressSetFilterByDefault", "enableFilterHandlers", "suppressStartEditOnTab", "hidePaddedHeaderRows", "ssrmExpandAllAffectsAllRows", "animateColumnResizing" ]; var _FUNCTION_GRID_OPTIONS = [ "doesExternalFilterPass", "processPivotResultColDef", "processPivotResultColGroupDef", "getBusinessKeyForNode", "isRowSelectable", "rowDragText", "groupRowRenderer", "dragAndDropImageComponent", "fullWidthCellRenderer", "loadingCellRenderer", "overlayComponent", "loadingOverlayComponent", "noRowsOverlayComponent", "overlayComponentSelector", "activeOverlay", "detailCellRenderer", "quickFilterParser", "quickFilterMatcher", "getLocaleText", "isExternalFilterPresent", "getRowHeight", "getRowClass", "getRowStyle", "getFullRowEditValidationErrors", "getContextMenuItems", "getMainMenuItems", "processRowPostCreate", "processCellForClipboard", "getGroupRowAgg", "isFullWidthRow", "sendToClipboard", "focusGridInnerElement", "navigateToNextHeader", "tabToNextHeader", "navigateToNextCell", "tabToNextCell", "tabToNextGridContainer", "processCellFromClipboard", "getDocument", "postProcessPopup", "getChildCount", "getDataPath", "isRowMaster", "postSortRows", "processHeaderForClipboard", "processUnpinnedColumns", "processGroupHeaderForClipboard", "paginationNumberFormatter", "processDataFromClipboard", "getServerSideGroupKey", "isServerSideGroup", "createChartContainer", "getChartToolbarItems", "fillOperation", "isApplyServerSideTransaction", "getServerSideGroupLevelParams", "isServerSideGroupOpenByDefault", "isGroupOpenByDefault", "initialGroupOrderComparator", "loadingCellRendererSelector", "getRowId", "chartMenuItems", "groupTotalRow", "alwaysPassFilter", "isRowPinnable", "isRowPinned", "isRowValidDropPosition" ]; var _GET_ALL_GRID_OPTIONS = () => [ ...ARRAY_GRID_OPTIONS, ...OBJECT_GRID_OPTIONS, ...STRING_GRID_OPTIONS, ..._NUMBER_GRID_OPTIONS, ..._FUNCTION_GRID_OPTIONS, ..._BOOLEAN_GRID_OPTIONS, ..._BOOLEAN_MIXED_GRID_OPTIONS, ...OTHER_GRID_OPTIONS ]; var GRID_OPTION_DEPRECATIONS = () => ({ suppressLoadingOverlay: { version: "32", message: "Use `loading`=false instead." }, enableFillHandle: { version: "32.2", message: "Use `cellSelection.handle` instead." }, enableRangeHandle: { version: "32.2", message: "Use `cellSelection.handle` instead." }, enableRangeSelection: { version: "32.2", message: "Use `cellSelection = true` instead." }, suppressMultiRangeSelection: { version: "32.2", message: "Use `cellSelection.suppressMultiRanges` instead." }, suppressClearOnFillReduction: { version: "32.2", message: "Use `cellSelection.handle.suppressClearOnFillReduction` instead." }, fillHandleDirection: { version: "32.2", message: "Use `cellSelection.handle.direction` instead." }, fillOperation: { version: "32.2", message: "Use `cellSelection.handle.setFillValue` instead." }, suppressRowClickSelection: { version: "32.2", message: "Use `rowSelection.enableClickSelection` instead." }, suppressRowDeselection: { version: "32.2", message: "Use `rowSelection.enableClickSelection` instead." }, rowMultiSelectWithClick: { version: "32.2", message: "Use `rowSelection.enableSelectionWithoutKeys` instead." }, groupSelectsChildren: { version: "32.2", message: 'Use `rowSelection.groupSelects = "descendants"` instead.' }, groupSelectsFiltered: { version: "32.2", message: 'Use `rowSelection.groupSelects = "filteredDescendants"` instead.' }, isRowSelectable: { version: "32.2", message: "Use `selectionOptions.isRowSelectable` instead." }, suppressCopySingleCellRanges: { version: "32.2", message: "Use `rowSelection.copySelectedRows` instead." }, suppressCopyRowsToClipboard: { version: "32.2", message: "Use `rowSelection.copySelectedRows` instead." }, onRangeSelectionChanged: { version: "32.2", message: "Use `onCellSelectionChanged` instead." }, onRangeDeleteStart: { version: "32.2", message: "Use `onCellSelectionDeleteStart` instead." }, onRangeDeleteEnd: { version: "32.2", message: "Use `onCellSelectionDeleteEnd` instead." }, suppressBrowserResizeObserver: { version: "32.2", message: "The grid always uses the browser's ResizeObserver, this grid option has no effect." }, onColumnEverythingChanged: { version: "32.2", message: "Either use `onDisplayedColumnsChanged` which is fired at the same time, or use one of the more specific column events." }, groupRemoveSingleChildren: { version: "33", message: "Use `groupHideParentOfSingleChild` instead." }, groupRemoveLowestSingleChildren: { version: "33", message: 'Use `groupHideParentOfSingleChild: "leafGroupsOnly"` instead.' }, suppressRowGroupHidesColumns: { version: "33", message: 'Use `suppressGroupChangesColumnVisibility: "suppressHideOnGroup"` instead.' }, suppressMakeColumnVisibleAfterUnGroup: { version: "33", message: 'Use `suppressGroupChangesColumnVisibility: "suppressShowOnUngroup"` instead.' }, unSortIcon: { version: "33", message: "Use `defaultColDef.unSortIcon` instead." }, sortingOrder: { version: "33", message: "Use `defaultColDef.sortingOrder` instead." }, suppressPropertyNamesCheck: { version: "33", message: "`gridOptions` and `columnDefs` both have a `context` property that should be used for arbitrary user data. This means that column definitions and gridOptions should only contain valid properties making this property redundant." }, suppressAdvancedFilterEval: { version: "34", message: "Advanced filter no longer uses function evaluation, so this option has no effect." } }); function toConstrainedNum(key, value, min) { if (typeof value === "number" || value == null) { if (value == null) { return null; } return value >= min ? null : `${key}: value should be greater than or equal to ${min}`; } return `${key}: value should be a number`; } var GRID_OPTIONS_MODULES = { alignedGrids: "AlignedGrids", allowContextMenuWithControlKey: "ContextMenu", autoSizeStrategy: "ColumnAutoSize", cellSelection: "CellSelection", columnHoverHighlight: "ColumnHover", datasource: "InfiniteRowModel", doesExternalFilterPass: "ExternalFilter", editType: "EditCore", invalidEditValueMode: "EditCore", enableAdvancedFilter: "AdvancedFilter", enableCellSpan: "CellSpan", enableCharts: "IntegratedCharts", enableRangeSelection: "CellSelection", enableRowPinning: "PinnedRow", findSearchValue: "Find", getFullRowEditValidationErrors: "EditCore", getContextMenuItems: "ContextMenu", getLocaleText: "Locale", getMainMenuItems: "ColumnMenu", getRowClass: "RowStyle", getRowStyle: "RowStyle", groupTotalRow: "SharedRowGrouping", grandTotalRow: "ClientSideRowModelHierarchy", initialState: "GridState", isExternalFilterPresent: "ExternalFilter", isRowPinnable: "PinnedRow", isRowPinned: "PinnedRow", localeText: "Locale", masterDetail: "SharedMasterDetail", pagination: "Pagination", pinnedBottomRowData: "PinnedRow", pinnedTopRowData: "PinnedRow", pivotMode: "SharedPivot", pivotPanelShow: "RowGroupingPanel", quickFilterText: "QuickFilter", rowClass: "RowStyle", rowClassRules: "RowStyle", rowData: "ClientSideRowModel", rowDragManaged: "RowDrag", refreshAfterGroupEdit: ["RowGrouping", "TreeData"], rowGroupPanelShow: "RowGroupingPanel", rowNumbers: "RowNumbers", rowSelection: "SharedRowSelection", rowStyle: "RowStyle", serverSideDatasource: "ServerSideRowModel", sideBar: "SideBar", statusBar: "StatusBar", treeData: "SharedTreeData", undoRedoCellEditing: "UndoRedoEdit", valueCache: "ValueCache", viewportDatasource: "ViewportRowModel" }; var GRID_OPTION_VALIDATIONS = () => { const definedValidations = { autoSizePadding: { validate({ autoSizePadding }) { return toConstrainedNum("autoSizePadding", autoSizePadding, 0); } }, cacheBlockSize: { supportedRowModels: ["serverSide", "infinite"], validate({ cacheBlockSize }) { return toConstrainedNum("cacheBlockSize", cacheBlockSize, 1); } }, cacheOverflowSize: { validate({ cacheOverflowSize }) { return toConstrainedNum("cacheOverflowSize", cacheOverflowSize, 1); } }, datasource: { supportedRowModels: ["infinite"] }, domLayout: { validate: (options) => { const domLayout = options.domLayout; const validLayouts = ["autoHeight", "normal", "print"]; if (domLayout && !validLayouts.includes(domLayout)) { return `domLayout must be one of [${validLayouts.join()}], currently it's ${domLayout}`; } return null; } }, enableFillHandle: { dependencies: { enableRangeSelection: { required: [true] } } }, enableRangeHandle: { dependencies: { enableRangeSelection: { required: [true] } } }, enableCellSpan: { supportedRowModels: ["clientSide", "serverSide"] }, enableRangeSelection: { dependencies: { rowDragEntireRow: { required: [false, undefined] } } }, enableRowPinning: { supportedRowModels: ["clientSide"], validate({ enableRowPinning, pinnedTopRowData, pinnedBottomRowData }) { if (enableRowPinning && (pinnedTopRowData || pinnedBottomRowData)) { return "Manual row pinning cannot be used together with pinned row data. Either set `enableRowPinning` to `false`, or remove `pinnedTopRowData` and `pinnedBottomRowData`."; } return null; } }, isRowPinnable: { supportedRowModels: ["clientSide"], validate({ enableRowPinning, isRowPinnable, pinnedTopRowData, pinnedBottomRowData }) { if (isRowPinnable && (pinnedTopRowData || pinnedBottomRowData)) { return "Manual row pinning cannot be used together with pinned row data. Either remove `isRowPinnable`, or remove `pinnedTopRowData` and `pinnedBottomRowData`."; } if (!enableRowPinning && isRowPinnable) { return "`isRowPinnable` requires `enableRowPinning` to be set."; } return null; } }, isRowPinned: { supportedRowModels: ["clientSide"], validate({ enableRowPinning, isRowPinned, pinnedTopRowData, pinnedBottomRowData }) { if (isRowPinned && (pinnedTopRowData || pinnedBottomRowData)) { return "Manual row pinning cannot be used together with pinned row data. Either remove `isRowPinned`, or remove `pinnedTopRowData` and `pinnedBottomRowData`."; } if (!enableRowPinning && isRowPinned) { return "`isRowPinned` requires `enableRowPinning` to be set."; } return null; } }, groupDefaultExpanded: { supportedRowModels: ["clientSide"] }, groupHideColumnsUntilExpanded: { supportedRowModels: ["clientSide"], validate({ groupHideColumnsUntilExpanded, groupHideOpenParents, groupDisplayType }) { if (groupHideColumnsUntilExpanded && !groupHideOpenParents && groupDisplayType !== "multipleColumns") { return "`groupHideColumnsUntilExpanded = true` requires either `groupDisplayType = 'multipleColumns'` or `groupHideOpenParents = true`"; } return null; } }, groupHideOpenParents: { supportedRowModels: ["clientSide", "serverSide"], dependencies: { groupTotalRow: { required: [undefined, "bottom"] }, treeData: { required: [undefined, false], reason: "Tree Data has values at the group level so it doesn't make sense to hide them." } } }, groupHideParentOfSingleChild: { dependencies: { groupHideOpenParents: { required: [undefined, false] } } }, groupRemoveLowestSingleChildren: { dependencies: { groupHideOpenParents: { required: [undefined, false] }, groupRemoveSingleChildren: { required: [undefined, false] } } }, groupRemoveSingleChildren: { dependencies: { groupHideOpenParents: { required: [undefined, false] }, groupRemoveLowestSingleChildren: { required: [undefined, false] } } }, groupSelectsChildren: { dependencies: { rowSelection: { required: ["multiple"] } } }, groupHierarchyConfig: { validate({ groupHierarchyConfig = {} }, gridOptions, beans) { for (const k of Object.keys(groupHierarchyConfig)) { beans.validation?.validateColDef(groupHierarchyConfig[k]); } return null; } }, icons: { validate: ({ icons }) => { if (icons) { if (icons["smallDown"]) { return _errMsg(262); } if (icons["smallLeft"]) { return _errMsg(263); } if (icons["smallRight"]) { return _errMsg(264); } } return null; } }, infiniteInitialRowCount: { validate({ infiniteInitialRowCount }) { return toConstrainedNum("infiniteInitialRowCount", infiniteInitialRowCount, 1); } }, initialGroupOrderComparator: { supportedRowModels: ["clientSide"] }, ssrmExpandAllAffectsAllRows: { validate: (options) => { if (typeof options.ssrmExpandAllAffectsAllRows === "boolean") { if (options.rowModelType !== "serverSide") { return "'ssrmExpandAllAffectsAllRows' is only supported with the Server Side Row Model."; } if (options.ssrmExpandAllAffectsAllRows && typeof options.getRowId !== "function") { return `'getRowId' callback must be provided for Server Side Row Model grouping to work correctly.`; } } return null; } }, keepDetailRowsCount: { validate({ keepDetailRowsCount }) { return toConstrainedNum("keepDetailRowsCount", keepDetailRowsCount, 1); } }, paginationPageSize: { validate({ paginationPageSize }) { return toConstrainedNum("paginationPageSize", paginationPageSize, 1); } }, paginationPageSizeSelector: { validate: (options) => { const values = options.paginationPageSizeSelector; if (typeof values === "boolean" || values == null) { return null; } if (!values.length) { return `'paginationPageSizeSelector' cannot be an empty array. If you want to hide the page size selector, set paginationPageSizeSelector to false.`; } return null; } }, pivotMode: { dependencies: { treeData: { required: [false, undefined], reason: "Pivot Mode is not supported with Tree Data." } } }, quickFilterText: { supportedRowModels: ["clientSide"] }, rowBuffer: { validate({ rowBuffer }) { return toConstrainedNum("rowBuffer", rowBuffer, 0); } }, rowClass: { validate: (options) => { const rowClass = options.rowClass; if (typeof rowClass === "function") { return "rowClass should not be a function, please use getRowClass instead"; } return null; } }, rowData: { supportedRowModels: ["clientSide"] }, rowDragManaged: { supportedRowModels: ["clientSide"], dependencies: { pagination: { required: [false, undefined] } } }, rowSelection: { validate({ rowSelection }) { if (rowSelection && typeof rowSelection === "string") { return 'As of version 32.2.1, using `rowSelection` with the values "single" or "multiple" has been deprecated. Use the object value instead.'; } if (rowSelection && typeof rowSelection !== "object") { return "Expected `RowSelectionOptions` object for the `rowSelection` property."; } if (rowSelection && rowSelection.mode !== "multiRow" && rowSelection.mode !== "singleRow") { return `Selection mode "${rowSelection.mode}" is invalid. Use one of 'singleRow' or 'multiRow'.`; } return null; } }, rowStyle: { validate: (options) => { const rowStyle = options.rowStyle; if (rowStyle && typeof rowStyle === "function") { return "rowStyle should be an object of key/value styles, not be a function, use getRowStyle() instead"; } return null; } }, serverSideDatasource: { supportedRowModels: ["serverSide"] }, serverSideInitialRowCount: { supportedRowModels: ["serverSide"], validate({ serverSideInitialRowCount }) { return toConstrainedNum("serverSideInitialRowCount", serverSideInitialRowCount, 1); } }, serverSideOnlyRefreshFilteredGroups: { supportedRowModels: ["serverSide"] }, serverSideSortAllLevels: { supportedRowModels: ["serverSide"] }, sortingOrder: { validate: (_options) => { const sortingOrder = _options.sortingOrder; if (Array.isArray(sortingOrder) && sortingOrder.length > 0) { const invalidItems = sortingOrder.filter((a) => !_getSortDefFromInput(a)); if (invalidItems.length > 0) { return `sortingOrder must be an array of type (SortDirection | SortDef)[], incorrect items are: ${invalidItems.map((item) => typeof item === "string" || item == null ? toStringWithNullUndefined(item) : JSON.stringify(item))}]`; } } else if (!Array.isArray(sortingOrder) || !sortingOrder.length) { return `sortingOrder must be an array with at least one element, currently it's ${sortingOrder}`; } return null; } }, tooltipHideDelay: { validate: (options) => { if (options.tooltipHideDelay && options.tooltipHideDelay < 0) { return "tooltipHideDelay should not be lower than 0"; } return null; } }, tooltipShowDelay: { validate: (options) => { if (options.tooltipShowDelay && options.tooltipShowDelay < 0) { return "tooltipShowDelay should not be lower than 0"; } return null; } }, tooltipSwitchShowDelay: { validate: (options) => { if (options.tooltipSwitchShowDelay && options.tooltipSwitchShowDelay < 0) { return "tooltipSwitchShowDelay should not be lower than 0"; } return null; } }, treeData: { supportedRowModels: ["clientSide", "serverSide"], validate: (options) => { const rowModel = options.rowModelType ?? "clientSide"; switch (rowModel) { case "clientSide": { const { treeDataChildrenField, treeDataParentIdField, getDataPath, getRowId } = options; if (!treeDataChildrenField && !treeDataParentIdField && !getDataPath) { return "treeData requires either 'treeDataChildrenField' or 'treeDataParentIdField' or 'getDataPath' in the clientSide row model."; } if (treeDataChildrenField) { if (getDataPath) { return "Cannot use both 'treeDataChildrenField' and 'getDataPath' at the same time."; } if (treeDataParentIdField) { return "Cannot use both 'treeDataChildrenField' and 'treeDataParentIdField' at the same time."; } } if (treeDataParentIdField) { if (!getRowId) { return "getRowId callback not provided, tree data with parent id cannot be built."; } if (getDataPath) { return "Cannot use both 'treeDataParentIdField' and 'getDataPath' at the same time."; } } return null; } case "serverSide": { const ssrmWarning = `treeData requires 'isServerSideGroup' and 'getServerSideGroupKey' in the ${rowModel} row model.`; return options.isServerSideGroup && options.getServerSideGroupKey ? null : ssrmWarning; } } return null; } }, viewportDatasource: { supportedRowModels: ["viewport"] }, viewportRowModelBufferSize: { validate({ viewportRowModelBufferSize }) { return toConstrainedNum("viewportRowModelBufferSize", viewportRowModelBufferSize, 0); } }, viewportRowModelPageSize: { validate({ viewportRowModelPageSize }) { return toConstrainedNum("viewportRowModelPageSize", viewportRowModelPageSize, 1); } }, rowDragEntireRow: { dependencies: { cellSelection: { required: [undefined] } } }, autoGroupColumnDef: { validate({ autoGroupColumnDef, showOpenedGroup }) { if (autoGroupColumnDef?.field && showOpenedGroup) { return "autoGroupColumnDef.field and showOpenedGroup are not supported when used together."; } if (autoGroupColumnDef?.valueGetter && showOpenedGroup) { return "autoGroupColumnDef.valueGetter and showOpenedGroup are not supported when used together."; } return null; } }, renderingMode: { validate: (options) => { const renderingMode = options.renderingMode; const validModes = ["default", "legacy"]; if (renderingMode && !validModes.includes(renderingMode)) { return `renderingMode must be one of [${validModes.join()}], currently it's ${renderingMode}`; } return null; } }, autoSizeStrategy: { validate: ({ autoSizeStrategy }) => { if (!autoSizeStrategy) { return null; } const validModes = [ "fitCellContents", "fitGridWidth", "fitProvidedWidth" ]; const type = autoSizeStrategy.type; if (type !== "fitCellContents" && type !== "fitGridWidth" && type !== "fitProvidedWidth") { return `Invalid Auto-size strategy. \`autoSizeStrategy\` must be one of ${validModes.map((m) => '"' + m + '"').join(", ")}, currently it's ${type}`; } if (type === "fitProvidedWidth" && typeof autoSizeStrategy.width != "number") { return `When using the 'fitProvidedWidth' auto-size strategy, must provide a numeric \`width\`. You provided ${autoSizeStrategy.width}`; } return null; } } }; const validations = {}; for (const key of _BOOLEAN_GRID_OPTIONS) { validations[key] = { expectedType: "boolean" }; } for (const key of _NUMBER_GRID_OPTIONS) { validations[key] = { expectedType: "number" }; } _mergeDeep(validations, definedValidations); return validations; }; var GRID_OPTIONS_VALIDATORS = () => ({ objectName: "gridOptions", allProperties: [..._GET_ALL_GRID_OPTIONS(), ...Object.values(_PUBLIC_EVENT_HANDLERS_MAP)], propertyExceptions: ["api"], docsUrl: "grid-options/", deprecations: GRID_OPTION_DEPRECATIONS(), validations: GRID_OPTION_VALIDATIONS() }); var changeSetId = 0; var gridInstanceSequence = 0; var GRID_DOM_KEY = "__ag_grid_instance"; var GridOptionsService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "gos"; this.domDataKey = "__AG_" + Math.random().toString(); this.instanceId = gridInstanceSequence++; this.gridReadyFired = false; this.queueEvents = []; this.propEventSvc = new LocalEventService; this.globalEventHandlerFactory = (restrictToSyncOnly) => { return (eventName, event) => { if (!this.isAlive()) { return; } const alwaysSync = ALWAYS_SYNC_GLOBAL_EVENTS.has(eventName); if (alwaysSync && !restrictToSyncOnly || !alwaysSync && restrictToSyncOnly) { return; } if (!isPublicEventHandler(eventName)) { return; } const fireEvent = (name, e) => { const eventHandlerName = _PUBLIC_EVENT_HANDLERS_MAP[name]; const eventHandler = this.gridOptions[eventHandlerName]; if (typeof eventHandler === "function") { this.beans.frameworkOverrides.wrapOutgoing(() => eventHandler(e)); } }; if (this.gridReadyFired) { fireEvent(eventName, event); } else if (eventName === "gridReady") { fireEvent(eventName, event); this.gridReadyFired = true; for (const q of this.queueEvents) { fireEvent(q.eventName, q.event); } this.queueEvents = []; } else { this.queueEvents.push({ eventName, event }); } }; }; } wireBeans(beans) { this.gridOptions = beans.gridOptions; this.validation = beans.validation; this.api = beans.gridApi; this.gridId = beans.context.getId(); } get gridOptionsContext() { return this.gridOptions["context"]; } postConstruct() { this.validateGridOptions(this.gridOptions); this.eventSvc.addGlobalListener(this.globalEventHandlerFactory().bind(this), true); this.eventSvc.addGlobalListener(this.globalEventHandlerFactory(true).bind(this), false); this.propEventSvc.setFrameworkOverrides(this.beans.frameworkOverrides); this.addManagedEventListeners({ gridOptionsChanged: ({ options }) => { this.updateGridOptions({ options, force: true, source: "optionsUpdated" }); } }); } destroy() { super.destroy(); this.queueEvents = []; } get(property) { return this.gridOptions[property] ?? GRID_OPTION_DEFAULTS[property]; } getCallback(property) { return this.mergeGridCommonParams(this.gridOptions[property]); } exists(property) { return _exists(this.gridOptions[property]); } mergeGridCommonParams(callback) { if (callback) { const wrapped = (callbackParams) => { return callback(this.addCommon(callbackParams)); }; return wrapped; } return callback; } updateGridOptions({ options, force, source = "api" }) { const changeSet = { id: changeSetId++, properties: [] }; const events = []; const { gridOptions, validation } = this; for (const key of Object.keys(options)) { const value = GlobalGridOptions.applyGlobalGridOption(key, options[key]); validation?.warnOnInitialPropertyUpdate(source, key); const shouldForce = force || typeof value === "object" && source === "api"; const previousValue = gridOptions[key]; if (shouldForce || previousValue !== value) { gridOptions[key] = value; const event = { type: key, currentValue: value, previousValue, changeSet, source }; events.push(event); } } this.validateGridOptions(this.gridOptions); changeSet.properties = events.map((event) => event.type); for (const event of events) { _logIfDebug(this, `Updated property ${event.type} from`, event.previousValue, ` to `, event.currentValue); this.propEventSvc.dispatchEvent(event); } } addPropertyEventListener(key, listener) { this.propEventSvc.addEventListener(key, listener); } removePropertyEventListener(key, listener) { this.propEventSvc.removeEventListener(key, listener); } getDomDataKey() { return this.domDataKey; } addCommon(params) { params.api = this.api; params.context = this.gridOptionsContext; return params; } validateOptions(options, modValidations) { for (const key of Object.keys(options)) { const value = options[key]; if (value == null || value === false) { continue; } let moduleToCheck = modValidations[key]; if (typeof moduleToCheck === "function") { moduleToCheck = moduleToCheck(options, this.gridOptions, this.beans); } if (moduleToCheck) { this.assertModuleRegistered(moduleToCheck, key); } } } validateGridOptions(gridOptions) { this.validateOptions(gridOptions, GRID_OPTIONS_MODULES); this.validation?.processGridOptions(gridOptions); } validateColDef(colDef, colId, skipInferenceCheck) { if (skipInferenceCheck || !this.beans.dataTypeSvc?.isColPendingInference(colId)) { this.validateOptions(colDef, COLUMN_DEFINITION_MOD_VALIDATIONS); this.validation?.validateColDef(colDef); } } assertModuleRegistered(moduleName, reasonOrId) { const registered = Array.isArray(moduleName) ? moduleName.some((modName) => this.isModuleRegistered(modName)) : this.isModuleRegistered(moduleName); if (!registered) { _error(200, { ...this.getModuleErrorParams(), moduleName, reasonOrId }); } return registered; } getModuleErrorParams() { return { gridId: this.gridId, gridScoped: _areModulesGridScoped(), rowModelType: this.get("rowModelType"), isUmd: _isUmd() }; } isModuleRegistered(moduleName) { return _isModuleRegistered(moduleName, this.gridId, this.get("rowModelType")); } setInstanceDomData(element) { element[GRID_DOM_KEY] = this.instanceId; } isElementInThisInstance(element) { let pointer = element; while (pointer) { const instanceId = pointer[GRID_DOM_KEY]; if (_exists(instanceId)) { const eventFromThisGrid = instanceId === this.instanceId; return eventFromThisGrid; } pointer = pointer.parentElement; } return false; } }; function isPublicEventHandler(eventName) { return !!_PUBLIC_EVENT_HANDLERS_MAP[eventName]; } var HeaderCellMouseListenerFeature = class extends BeanStub { constructor(column, eGui) { super(); this.column = column; this.eGui = eGui; this.lastMovingChanged = 0; } postConstruct() { this.addManagedElementListeners(this.eGui, { click: (e) => e && this.onClick(e) }); this.addManagedListeners(this.column, { movingChanged: () => { this.lastMovingChanged = Date.now(); } }); } onClick(event) { const { sortSvc, rangeSvc, gos } = this.beans; const sortFromClick = _getEnableColumnSelection(gos) ? event.altKey : true; if (!sortFromClick) { rangeSvc?.handleColumnSelection(this.column, event); } else if (this.column.isSortable()) { const moving = this.column.isMoving(); const nowTime = Date.now(); const movedRecently = nowTime - this.lastMovingChanged < 50; const columnMoving = moving || movedRecently; if (!columnMoving) { sortSvc?.progressSortFromEvent(this.column, event); } } } }; function getHeaderCompElementParams(includeColumnRefIndicator, includeSortIndicator) { const hiddenAttrs = { "aria-hidden": "true" }; return { tag: "div", cls: "ag-cell-label-container", role: "presentation", children: [ { tag: "span", ref: "eMenu", cls: "ag-header-icon ag-header-cell-menu-button", attrs: hiddenAttrs }, { tag: "span", ref: "eFilterButton", cls: "ag-header-icon ag-header-cell-filter-button", attrs: hiddenAttrs }, { tag: "div", ref: "eLabel", cls: "ag-header-cell-label", role: "presentation", children: [ includeColumnRefIndicator ? { tag: "span", ref: "eColRef", cls: "ag-header-col-ref" } : null, { tag: "span", ref: "eText", cls: "ag-header-cell-text" }, { tag: "span", ref: "eFilter", cls: "ag-header-icon ag-header-label-icon ag-filter-icon", attrs: hiddenAttrs }, includeSortIndicator ? { tag: "ag-sort-indicator", ref: "eSortIndicator" } : null ] } ] }; } var HeaderComp = class extends Component { constructor() { super(...arguments); this.eFilter = RefPlaceholder; this.eFilterButton = RefPlaceholder; this.eSortIndicator = RefPlaceholder; this.eMenu = RefPlaceholder; this.eLabel = RefPlaceholder; this.eText = RefPlaceholder; this.eColRef = RefPlaceholder; this.eSortOrder = RefPlaceholder; this.eSortAsc = RefPlaceholder; this.eSortDesc = RefPlaceholder; this.eSortMixed = RefPlaceholder; this.eSortNone = RefPlaceholder; this.eSortAbsoluteAsc = RefPlaceholder; this.eSortAbsoluteDesc = RefPlaceholder; this.isLoadingInnerComponent = false; } refresh(params) { const oldParams = this.params; this.params = params; if (this.workOutTemplate(params, !!this.beans?.sortSvc) != this.currentTemplate || this.workOutShowMenu() != this.currentShowMenu || params.enableSorting != this.currentSort || params.column.formulaRef != this.currentRef || this.currentSuppressMenuHide != null && this.shouldSuppressMenuHide() != this.currentSuppressMenuHide || oldParams.enableFilterButton != params.enableFilterButton || oldParams.enableFilterIcon != params.enableFilterIcon) { return false; } if (this.innerHeaderComponent) { const mergedParams = { ...params }; _mergeDeep(mergedParams, params.innerHeaderComponentParams); this.innerHeaderComponent.refresh?.(mergedParams); } else { this.setDisplayName(params); } return true; } workOutTemplate(params, isSorting) { const { formula } = this.beans; const paramsTemplate = params.template; if (paramsTemplate) { return paramsTemplate?.trim ? paramsTemplate.trim() : paramsTemplate; } return getHeaderCompElementParams(!!formula?.active, isSorting); } init(params) { this.params = params; const { sortSvc, touchSvc, rowNumbersSvc, userCompFactory } = this.beans; const sortComp = sortSvc?.getSortIndicatorSelector(); this.currentTemplate = this.workOutTemplate(params, !!sortComp); this.setTemplate(this.currentTemplate, sortComp ? [sortComp] : undefined); if (this.eLabel) { this.mouseListener ?? (this.mouseListener = this.createManagedBean(new HeaderCellMouseListenerFeature(params.column, this.eLabel))); } touchSvc?.setupForHeader(this); this.setMenu(); this.setupSort(); this.setupColumnRefIndicator(); rowNumbersSvc?.setupForHeader(this); this.setupFilterIcon(); this.setupFilterButton(); this.workOutInnerHeaderComponent(userCompFactory, params); this.setDisplayName(params); } workOutInnerHeaderComponent(userCompFactory, params) { const userCompDetails = _getInnerHeaderCompDetails(userCompFactory, params, params); if (!userCompDetails) { return; } this.isLoadingInnerComponent = true; userCompDetails.newAgStackInstance().then((comp) => { this.isLoadingInnerComponent = false; if (!comp) { return; } if (this.isAlive()) { this.innerHeaderComponent = comp; if (this.eText) { this.eText.appendChild(comp.getGui()); } } else { this.destroyBean(comp); } }); } setDisplayName(params) { const { displayName } = params; const oldDisplayName = this.currentDisplayName; this.currentDisplayName = displayName; if (!this.eText || oldDisplayName === displayName || this.innerHeaderComponent || this.isLoadingInnerComponent) { return; } this.eText.textContent = _toString(displayName); } addInIcon(iconName, eParent, column) { const eIcon = _createIconNoSpan(iconName, this.beans, column); if (eIcon) { eParent.appendChild(eIcon); } } workOutShowMenu() { return this.params.enableMenu && !!this.beans.menuSvc?.isHeaderMenuButtonEnabled(); } shouldSuppressMenuHide() { return !!this.beans.menuSvc?.isHeaderMenuButtonAlwaysShowEnabled(); } setMenu() { if (!this.eMenu) { return; } this.currentShowMenu = this.workOutShowMenu(); if (!this.currentShowMenu) { _removeFromParent(this.eMenu); this.eMenu = undefined; return; } const { gos, eMenu, params } = this; const isLegacyMenu = _isLegacyMenuEnabled(gos); this.addInIcon(isLegacyMenu ? "menu" : "menuAlt", eMenu, params.column); eMenu.classList.toggle("ag-header-menu-icon", !isLegacyMenu); const currentSuppressMenuHide = this.shouldSuppressMenuHide(); this.currentSuppressMenuHide = currentSuppressMenuHide; this.addManagedElementListeners(eMenu, { click: () => this.showColumnMenu(this.eMenu) }); this.toggleMenuAlwaysShow(currentSuppressMenuHide); } toggleMenuAlwaysShow(alwaysShow) { this.eMenu?.classList.toggle("ag-header-menu-always-show", alwaysShow); } showColumnMenu(element) { const { currentSuppressMenuHide, params } = this; if (!currentSuppressMenuHide) { this.toggleMenuAlwaysShow(true); } params.showColumnMenu(element, () => { if (!currentSuppressMenuHide) { this.toggleMenuAlwaysShow(false); } }); } onMenuKeyboardShortcut(isFilterShortcut) { const { params, gos, beans, eMenu, eFilterButton } = this; const column = params.column; const isLegacyMenuEnabled = _isLegacyMenuEnabled(gos); if (isFilterShortcut && !isLegacyMenuEnabled) { if (beans.menuSvc?.isFilterMenuInHeaderEnabled(column)) { params.showFilter(eFilterButton ?? eMenu ?? this.getGui()); return true; } } else if (params.enableMenu) { this.showColumnMenu(eMenu ?? eFilterButton ?? this.getGui()); return true; } return false; } setupSort() { const { sortSvc } = this.beans; if (!sortSvc) { return; } const { enableSorting, column } = this.params; this.currentSort = enableSorting; if (!this.eSortIndicator) { this.eSortIndicator = this.createBean(sortSvc.createSortIndicator(true)); const { eSortIndicator, eSortOrder, eSortAsc, eSortDesc, eSortMixed, eSortNone, eSortAbsoluteAsc, eSortAbsoluteDesc } = this; eSortIndicator.attachCustomElements(eSortOrder, eSortAsc, eSortDesc, eSortMixed, eSortNone, eSortAbsoluteAsc, eSortAbsoluteDesc); } this.eSortIndicator.setupSort(column); if (!this.currentSort) { return; } sortSvc.setupHeader(this, column); } setupColumnRefIndicator() { const { eColRef, beans: { editModelSvc }, params } = this; if (!eColRef) { return; } this.currentRef = params.column.formulaRef; eColRef.textContent = this.currentRef; _setDisplayed(eColRef, false); this.addManagedEventListeners({ cellEditingStarted: () => { const editPositions = editModelSvc?.getEditPositions(); const shouldDisplay = !!this.currentRef && !!editPositions?.some((position) => position.column.isAllowFormula()); _setDisplayed(eColRef, shouldDisplay); }, cellEditingStopped: () => { _setDisplayed(eColRef, false); } }); } setupFilterIcon() { const { eFilter, params } = this; if (!eFilter) { return; } const onFilterChangedIcon = () => { const filterPresent = params.column.isFilterActive(); _setDisplayed(eFilter, filterPresent, { skipAriaHidden: true }); }; this.configureFilter(params.enableFilterIcon, eFilter, onFilterChangedIcon, "filterActive"); } setupFilterButton() { const { eFilterButton, params } = this; if (!eFilterButton) { return; } const configured = this.configureFilter(params.enableFilterButton, eFilterButton, this.onFilterChangedButton.bind(this), "filter"); if (configured) { this.addManagedElementListeners(eFilterButton, { click: () => params.showFilter(eFilterButton) }); } else { this.eFilterButton = undefined; } } configureFilter(enabled, element, filterChangedCallback, icon) { if (!enabled) { _removeFromParent(element); return false; } const column = this.params.column; this.addInIcon(icon, element, column); this.addManagedListeners(column, { filterChanged: filterChangedCallback }); filterChangedCallback(); return true; } onFilterChangedButton() { const filterPresent = this.params.column.isFilterActive(); this.eFilterButton.classList.toggle("ag-filter-active", filterPresent); } getAnchorElementForMenu(isFilter) { const { eFilterButton, eMenu } = this; if (isFilter) { return eFilterButton ?? eMenu ?? this.getGui(); } return eMenu ?? eFilterButton ?? this.getGui(); } destroy() { super.destroy(); this.innerHeaderComponent = this.destroyBean(this.innerHeaderComponent); this.mouseListener = this.destroyBean(this.mouseListener); } }; var GroupStickyLabelFeature = class extends BeanStub { constructor(eLabel, columnGroup) { super(); this.eLabel = eLabel; this.columnGroup = columnGroup; this.isSticky = false; this.left = null; this.right = null; } postConstruct() { const { columnGroup, beans } = this; const { ctrlsSvc } = beans; ctrlsSvc.whenReady(this, () => { const refreshPosition = this.refreshPosition.bind(this); if (columnGroup.getPinned() == null) { this.addManagedEventListeners({ bodyScroll: (event) => { if (event.direction === "horizontal") { this.updateSticky(event.left); } } }); } this.addManagedListeners(columnGroup, { leftChanged: refreshPosition, displayedChildrenChanged: refreshPosition }); this.addManagedEventListeners({ columnResized: refreshPosition }); this.refreshPosition(); }); } refreshPosition() { const { columnGroup, beans } = this; const left = columnGroup.getLeft(); const width = columnGroup.getActualWidth(); if (left == null || width === 0) { this.left = null; this.right = null; this.setSticky(false); return; } this.left = left; this.right = left + width; const scrollPosition = beans.colViewport.getScrollPosition(); if (scrollPosition != null) { this.updateSticky(scrollPosition); } } updateSticky(scrollLeft) { const { beans, left, right } = this; if (left == null || right == null) { this.setSticky(false); return; } const { gos, visibleCols } = beans; const isRtl = gos.get("enableRtl"); const viewportEdge = isRtl ? visibleCols.bodyWidth - scrollLeft : scrollLeft; this.setSticky(left < viewportEdge && right > viewportEdge); } setSticky(value) { const { isSticky, eLabel } = this; if (isSticky === value) { return; } this.isSticky = value; eLabel.classList.toggle("ag-sticky-label", value); } }; var HeaderGroupCompElement = { tag: "div", cls: "ag-header-group-cell-label", role: "presentation", children: [ { tag: "span", ref: "agLabel", cls: "ag-header-group-text", role: "presentation" }, { tag: "span", ref: "agOpened", cls: `ag-header-icon ag-header-expand-icon ag-header-expand-icon-expanded` }, { tag: "span", ref: "agClosed", cls: `ag-header-icon ag-header-expand-icon ag-header-expand-icon-collapsed` } ] }; var HeaderGroupComp = class extends Component { constructor() { super(HeaderGroupCompElement); this.agOpened = RefPlaceholder; this.agClosed = RefPlaceholder; this.agLabel = RefPlaceholder; this.isLoadingInnerComponent = false; } init(params) { const { userCompFactory, touchSvc } = this.beans; this.params = params; this.checkWarnings(); this.workOutInnerHeaderGroupComponent(userCompFactory, params); this.setupLabel(params); this.addGroupExpandIcon(params); this.setupExpandIcons(); touchSvc?.setupForHeaderGroup(this); } checkWarnings() { const paramsAny = this.params; if (paramsAny.template) { _warn(89); } } workOutInnerHeaderGroupComponent(userCompFactory, params) { const userCompDetails = _getInnerHeaderGroupCompDetails(userCompFactory, params, params); if (!userCompDetails) { return; } this.isLoadingInnerComponent = true; userCompDetails.newAgStackInstance().then((comp) => { this.isLoadingInnerComponent = false; if (!comp) { return; } if (this.isAlive()) { this.innerHeaderGroupComponent = comp; this.agLabel.appendChild(comp.getGui()); } else { this.destroyBean(comp); } }); } setupExpandIcons() { const { agOpened, agClosed, params: { columnGroup }, beans: { colGroupSvc } } = this; this.addInIcon("columnGroupOpened", agOpened); this.addInIcon("columnGroupClosed", agClosed); const expandAction = (event) => { if (_isStopPropagationForAgGrid(event)) { return; } const newExpandedValue = !columnGroup.isExpanded(); colGroupSvc.setColumnGroupOpened(columnGroup.getProvidedColumnGroup(), newExpandedValue, "uiColumnExpanded"); }; this.addTouchAndClickListeners(agClosed, expandAction); this.addTouchAndClickListeners(agOpened, expandAction); const stopPropagationAction = (event) => { _stopPropagationForAgGrid(event); }; this.addManagedElementListeners(agClosed, { dblclick: stopPropagationAction }); this.addManagedElementListeners(agOpened, { dblclick: stopPropagationAction }); this.addManagedElementListeners(this.getGui(), { dblclick: expandAction }); this.updateIconVisibility(); const providedColumnGroup = columnGroup.getProvidedColumnGroup(); const updateIcon = this.updateIconVisibility.bind(this); this.addManagedListeners(providedColumnGroup, { expandedChanged: updateIcon, expandableChanged: updateIcon }); } addTouchAndClickListeners(eElement, action) { this.beans.touchSvc?.setupForHeaderGroupElement(this, eElement, action); this.addManagedElementListeners(eElement, { click: action }); } updateIconVisibility() { const { agOpened, agClosed, params: { columnGroup } } = this; if (columnGroup.isExpandable()) { const expanded = columnGroup.isExpanded(); _setDisplayed(agOpened, expanded); _setDisplayed(agClosed, !expanded); } else { _setDisplayed(agOpened, false); _setDisplayed(agClosed, false); } } addInIcon(iconName, element) { const eIcon = _createIconNoSpan(iconName, this.beans, null); if (eIcon) { element.appendChild(eIcon); } } addGroupExpandIcon(params) { if (!params.columnGroup.isExpandable()) { const { agOpened, agClosed } = this; _setDisplayed(agOpened, false); _setDisplayed(agClosed, false); } } setupLabel(params) { const { displayName, columnGroup } = params; const { innerHeaderGroupComponent, isLoadingInnerComponent } = this; const hasInnerComponent = innerHeaderGroupComponent || isLoadingInnerComponent; if (_exists(displayName) && !hasInnerComponent) { this.agLabel.textContent = _toString(displayName); } if (!columnGroup.getColGroupDef()?.suppressStickyLabel) { this.createManagedBean(new GroupStickyLabelFeature(this.getGui(), columnGroup)); } } destroy() { super.destroy(); if (this.innerHeaderGroupComponent) { this.destroyBean(this.innerHeaderGroupComponent); this.innerHeaderGroupComponent = undefined; } } }; var ColumnHeaderCompModule = { moduleName: "ColumnHeaderComp", version: VERSION, userComponents: { agColumnHeader: HeaderComp }, icons: { menu: "menu", menuAlt: "menu-alt" } }; var ColumnGroupHeaderCompModule = { moduleName: "ColumnGroupHeaderComp", version: VERSION, userComponents: { agColumnGroupHeader: HeaderGroupComp }, icons: { columnGroupOpened: "expanded", columnGroupClosed: "contracted" } }; var AnimationFrameService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "animationFrameSvc"; this.p1 = { list: [], sorted: false }; this.p2 = { list: [], sorted: false }; this.f1 = { list: [], sorted: false }; this.destroyTasks = []; this.ticking = false; this.scrollGoingDown = true; this.lastScrollTop = 0; this.taskCount = 0; } setScrollTop(scrollTop) { this.scrollGoingDown = scrollTop >= this.lastScrollTop; if (scrollTop === 0) { this.scrollGoingDown = true; } this.lastScrollTop = scrollTop; } postConstruct() { this.active = !this.gos.get("suppressAnimationFrame"); this.batchFrameworkComps = this.beans.frameworkOverrides.batchFrameworkComps; } verify() { if (this.active === false) { _warn(92); } } createTask(task, index, list, isFramework, isDeferred = false) { this.verify(); let taskList = list; if (isFramework && this.batchFrameworkComps) { taskList = "f1"; } const taskItem = { task, index, createOrder: ++this.taskCount, deferred: isDeferred }; this.addTaskToList(this[taskList], taskItem); this.schedule(); } addTaskToList(taskList, task) { taskList.list.push(task); taskList.sorted = false; } sortTaskList(taskList) { if (taskList.sorted) { return; } const sortDirection = this.scrollGoingDown ? 1 : -1; taskList.list.sort((a, b) => { if (a.deferred !== b.deferred) { return a.deferred ? -1 : 1; } if (a.index !== b.index) { return sortDirection * (b.index - a.index); } return b.createOrder - a.createOrder; }); taskList.sorted = true; } addDestroyTask(task) { this.verify(); this.destroyTasks.push(task); this.schedule(); } executeFrame(millis) { const { p1, p2, f1, destroyTasks, beans } = this; const { ctrlsSvc, frameworkOverrides } = beans; const p1Tasks = p1.list; const p2Tasks = p2.list; const f1Tasks = f1.list; const frameStart = Date.now(); let duration = 0; const noMaxMillis = millis <= 0; const scrollFeature = ctrlsSvc.getScrollFeature(); while (noMaxMillis || duration < millis) { const gridBodyDidSomething = scrollFeature.scrollGridIfNeeded(); if (!gridBodyDidSomething) { let task; if (p1Tasks.length) { this.sortTaskList(p1); task = p1Tasks.pop().task; } else if (p2Tasks.length) { this.sortTaskList(p2); task = p2Tasks.pop().task; } else if (f1Tasks.length) { frameworkOverrides.wrapOutgoing(() => { while (noMaxMillis || duration < millis) { const gridBodyDidSomething2 = scrollFeature.scrollGridIfNeeded(); if (!gridBodyDidSomething2) { if (f1Tasks.length) { this.sortTaskList(f1); task = f1Tasks.pop().task; task(); } else { break; } } else { break; } duration = Date.now() - frameStart; } }); task = () => {}; } else if (destroyTasks.length) { task = destroyTasks.pop(); } else { break; } task(); } duration = Date.now() - frameStart; } if (p1Tasks.length || p2Tasks.length || f1Tasks.length || destroyTasks.length) { this.requestFrame(); } else { this.ticking = false; } } flushAllFrames() { if (!this.active) { return; } this.executeFrame(-1); } schedule() { if (!this.active) { return; } if (!this.ticking) { this.ticking = true; this.requestFrame(); } } requestFrame() { const callback = this.executeFrame.bind(this, 60); _requestAnimationFrame(this.beans, callback); } isQueueEmpty() { return !this.ticking; } }; var AnimationFrameModule = { moduleName: "AnimationFrame", version: VERSION, beans: [AnimationFrameService] }; var IconService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "iconSvc"; } createIconNoSpan(iconName, params) { return _createIconNoSpan(iconName, this.beans, params?.column); } }; var _shouldOpenHeaderMenuOnLongTap = (enableMenu, isHeaderContextMenuEnabled, isLegacyMenuEnabled) => isHeaderContextMenuEnabled || enableMenu && isLegacyMenuEnabled; var TouchService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "touchSvc"; } mockBodyContextMenu(ctrl, listener) { this.mockContextMenu(ctrl, ctrl.eBodyViewport, listener); } mockHeaderContextMenu(ctrl, listener) { this.mockContextMenu(ctrl, ctrl.eGui, listener); } mockRowContextMenu(ctrl) { if (!_isIOSUserAgent()) { return; } const listener = (mouseListener, touch, touchEvent) => { const { rowCtrl, cellCtrl } = ctrl.getControlsForEventTarget(touchEvent?.target ?? null); if (cellCtrl?.column) { cellCtrl.dispatchCellContextMenuEvent(touchEvent ?? null); } this.beans.contextMenuSvc?.handleContextMenuMouseEvent(undefined, touchEvent, rowCtrl, cellCtrl); }; this.mockContextMenu(ctrl, ctrl.element, listener); } handleCellDoubleClick(ctrl, mouseEvent) { const isDoubleClickOnIPad = () => { if (!_isIOSUserAgent() || _isEventSupported("dblclick")) { return false; } const nowMillis = Date.now(); const res = nowMillis - ctrl.lastIPadMouseClickEvent < 200; ctrl.lastIPadMouseClickEvent = nowMillis; return res; }; if (isDoubleClickOnIPad()) { ctrl.onCellDoubleClicked(mouseEvent); mouseEvent.preventDefault(); return true; } return false; } setupForHeader(comp) { const { gos, sortSvc, menuSvc } = this.beans; if (gos.get("suppressTouch")) { return; } const { params, eMenu, eFilterButton } = comp; const touchListener = new TouchListener(comp.getGui(), true); comp.addDestroyFunc(() => touchListener.destroy()); const suppressMenuHide = comp.shouldSuppressMenuHide(); const tapMenuButton = suppressMenuHide && _exists(eMenu) && params.enableMenu; const isHeaderContextMenuEnabled = !!menuSvc?.isHeaderContextMenuEnabled(params.column); const shouldOpenMenuOnLongTap = _shouldOpenHeaderMenuOnLongTap(params.enableMenu, isHeaderContextMenuEnabled, _isLegacyMenuEnabled(gos)); let menuTouchListener = touchListener; if (tapMenuButton) { menuTouchListener = new TouchListener(eMenu, true); comp.addDestroyFunc(() => menuTouchListener.destroy()); } const showMenuFn = (event) => params.showColumnMenuAfterMouseClick(event.touchStart); if (tapMenuButton && params.enableMenu) { comp.addManagedListeners(menuTouchListener, { tap: showMenuFn }); } if (shouldOpenMenuOnLongTap) { comp.addManagedListeners(touchListener, { longTap: showMenuFn }); } if (params.enableSorting) { const tapListener = (event) => { const target = event.touchStart.target; if (suppressMenuHide && (eMenu?.contains(target) || eFilterButton?.contains(target))) { return; } sortSvc?.progressSort(params.column, false, "uiColumnSorted"); }; comp.addManagedListeners(touchListener, { tap: tapListener }); } if (params.enableFilterButton && eFilterButton) { const filterButtonTouchListener = new TouchListener(eFilterButton, true); comp.addManagedListeners(filterButtonTouchListener, { tap: () => params.showFilter(eFilterButton) }); comp.addDestroyFunc(() => filterButtonTouchListener.destroy()); } } setupForHeaderGroup(comp) { const params = comp.params; if (this.beans.menuSvc?.isHeaderContextMenuEnabled(params.columnGroup.getProvidedColumnGroup())) { const touchListener = new TouchListener(params.eGridHeader, true); const showMenuFn = (event) => params.showColumnMenuAfterMouseClick(event.touchStart); comp.addManagedListeners(touchListener, { longTap: showMenuFn }); comp.addDestroyFunc(() => touchListener.destroy()); } } setupForHeaderGroupElement(comp, eElement, action) { const touchListener = new TouchListener(eElement, true); comp.addManagedListeners(touchListener, { tap: action }); comp.addDestroyFunc(() => touchListener.destroy()); } mockContextMenu(ctrl, element, listener) { if (!_isIOSUserAgent()) { return; } const touchListener = new TouchListener(element); const longTapListener = (event) => { if (!_isEventFromThisInstance(this.beans, event.touchEvent)) { return; } listener(undefined, event.touchStart, event.touchEvent); }; ctrl.addManagedListeners(touchListener, { longTap: longTapListener }); ctrl.addDestroyFunc(() => touchListener.destroy()); } }; var TouchModule = { moduleName: "Touch", version: VERSION, beans: [TouchService] }; var CellNavigationService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "cellNavigation"; } wireBeans(beans) { this.rowSpanSvc = beans.rowSpanSvc; } getNextCellToFocus(key, focusedCell, ctrlPressed = false) { if (ctrlPressed) { return this.getNextCellToFocusWithCtrlPressed(key, focusedCell); } return this.getNextCellToFocusWithoutCtrlPressed(key, focusedCell); } getNextCellToFocusWithCtrlPressed(key, focusedCell) { const upKey = key === KeyCode.UP; const downKey = key === KeyCode.DOWN; const leftKey = key === KeyCode.LEFT; let column; let rowIndex; const { pageBounds, gos, visibleCols, pinnedRowModel } = this.beans; const { rowPinned } = focusedCell; if (upKey || downKey) { if (rowPinned && pinnedRowModel) { if (upKey) { rowIndex = 0; } else { rowIndex = rowPinned === "top" ? pinnedRowModel.getPinnedTopRowCount() - 1 : pinnedRowModel.getPinnedBottomRowCount() - 1; } } else { rowIndex = upKey ? pageBounds.getFirstRow() : pageBounds.getLastRow(); } column = focusedCell.column; } else { const isRtl = gos.get("enableRtl"); rowIndex = focusedCell.rowIndex; const allColumns = leftKey !== isRtl ? visibleCols.allCols : [...visibleCols.allCols].reverse(); column = allColumns.find((col) => !isRowNumberCol(col) && this.isCellGoodToFocusOn({ rowIndex, rowPinned: null, column: col })); } return column ? { rowIndex, rowPinned, column } : null; } getNextCellToFocusWithoutCtrlPressed(key, focusedCell) { let pointer = focusedCell; let finished = false; while (!finished) { switch (key) { case KeyCode.UP: pointer = this.getCellAbove(pointer); break; case KeyCode.DOWN: pointer = this.getCellBelow(pointer); break; case KeyCode.RIGHT: pointer = this.gos.get("enableRtl") ? this.getCellToLeft(pointer) : this.getCellToRight(pointer); break; case KeyCode.LEFT: pointer = this.gos.get("enableRtl") ? this.getCellToRight(pointer) : this.getCellToLeft(pointer); break; default: pointer = null; _warn(8, { key }); break; } if (pointer) { finished = this.isCellGoodToFocusOn(pointer); } else { finished = true; } } return pointer; } isCellGoodToFocusOn(gridCell) { const column = gridCell.column; let rowNode; const { pinnedRowModel, rowModel } = this.beans; switch (gridCell.rowPinned) { case "top": rowNode = pinnedRowModel?.getPinnedTopRow(gridCell.rowIndex); break; case "bottom": rowNode = pinnedRowModel?.getPinnedBottomRow(gridCell.rowIndex); break; default: rowNode = rowModel.getRow(gridCell.rowIndex); break; } if (!rowNode) { return false; } const suppressNavigable = this.isSuppressNavigable(column, rowNode); return !suppressNavigable; } getCellToLeft(lastCell) { if (!lastCell) { return null; } const colToLeft = this.beans.visibleCols.getColBefore(lastCell.column); if (!colToLeft) { return null; } return { rowIndex: lastCell.rowIndex, column: colToLeft, rowPinned: lastCell.rowPinned }; } getCellToRight(lastCell) { if (!lastCell) { return null; } const colToRight = this.beans.visibleCols.getColAfter(lastCell.column); if (!colToRight) { return null; } return { rowIndex: lastCell.rowIndex, column: colToRight, rowPinned: lastCell.rowPinned }; } getCellBelow(lastCell) { if (!lastCell) { return null; } const adjustedLastCell = this.rowSpanSvc?.getCellEnd(lastCell) ?? lastCell; const rowBelow = _getRowBelow(this.beans, adjustedLastCell, true); if (rowBelow) { return { rowIndex: rowBelow.rowIndex, column: lastCell.column, rowPinned: rowBelow.rowPinned }; } return null; } getCellAbove(lastCell) { if (!lastCell) { return null; } const adjustedLastCell = this.rowSpanSvc?.getCellStart(lastCell) ?? lastCell; const rowAbove = _getRowAbove(this.beans, { rowIndex: adjustedLastCell.rowIndex, rowPinned: adjustedLastCell.rowPinned }, true); if (rowAbove) { return { rowIndex: rowAbove.rowIndex, column: lastCell.column, rowPinned: rowAbove.rowPinned }; } return null; } getNextTabbedCell(gridCell, backwards) { if (backwards) { return this.getNextTabbedCellBackwards(gridCell); } return this.getNextTabbedCellForwards(gridCell); } getNextTabbedCellForwards(gridCell) { const { visibleCols, pagination } = this.beans; const displayedColumns = visibleCols.allCols; let newRowIndex = gridCell.rowIndex; let newFloating = gridCell.rowPinned; let newColumn = visibleCols.getColAfter(gridCell.column); if (!newColumn) { newColumn = displayedColumns[0]; const rowBelow = _getRowBelow(this.beans, gridCell, true); if (_missing(rowBelow)) { return null; } if (!rowBelow.rowPinned && !(pagination?.isRowInPage(rowBelow.rowIndex) ?? true)) { return null; } newRowIndex = rowBelow ? rowBelow.rowIndex : null; newFloating = rowBelow ? rowBelow.rowPinned : null; } return { rowIndex: newRowIndex, column: newColumn, rowPinned: newFloating }; } getNextTabbedCellBackwards(gridCell) { const { beans } = this; const { visibleCols, pagination } = beans; const displayedColumns = visibleCols.allCols; let newRowIndex = gridCell.rowIndex; let newFloating = gridCell.rowPinned; let newColumn = visibleCols.getColBefore(gridCell.column); if (!newColumn) { newColumn = _last(displayedColumns); const rowAbove = _getRowAbove(beans, { rowIndex: gridCell.rowIndex, rowPinned: gridCell.rowPinned }, true); if (_missing(rowAbove)) { return null; } if (!rowAbove.rowPinned && !(pagination?.isRowInPage(rowAbove.rowIndex) ?? true)) { return null; } newRowIndex = rowAbove ? rowAbove.rowIndex : null; newFloating = rowAbove ? rowAbove.rowPinned : null; } return { rowIndex: newRowIndex, column: newColumn, rowPinned: newFloating }; } isSuppressNavigable(column, rowNode) { const { suppressNavigable } = column.colDef; if (typeof suppressNavigable === "boolean") { return suppressNavigable; } if (typeof suppressNavigable === "function") { const params = column.createColumnFunctionCallbackParams(rowNode); const userFunc = suppressNavigable; return userFunc(params); } return false; } }; function getFocusedCell(beans) { return beans.focusSvc.getFocusedCell(); } function clearFocusedCell(beans) { return beans.focusSvc.clearFocusedCell(); } function setFocusedCell(beans, rowIndex, colKey, rowPinned) { beans.focusSvc.setFocusedCell({ rowIndex, column: colKey, rowPinned, forceBrowserFocus: true }); } function tabToNextCell(beans, event) { return beans.navigation?.tabToNextCell(false, event) ?? false; } function tabToPreviousCell(beans, event) { return beans.navigation?.tabToNextCell(true, event) ?? false; } function setFocusedHeader(beans, colKey, floatingFilter = false) { const headerPosition = beans.headerNavigation?.getHeaderPositionForColumn(colKey, floatingFilter); if (!headerPosition) { return; } beans.focusSvc.focusHeaderPosition({ headerPosition }); } function _unwrapUserComp(comp) { const compAsAny = comp; const isProxy = compAsAny?.getFrameworkComponentInstance != null; return isProxy ? compAsAny.getFrameworkComponentInstance() : comp; } var EditModelService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "editModelSvc"; this.edits = /* @__PURE__ */ new Map; this.cellValidations = new EditCellValidationModel; this.rowValidations = new EditRowValidationModel; this.suspendEdits = false; } suspend(suspend) { this.suspendEdits = suspend; } removeEdits({ rowNode, column }) { if (!this.hasEdits({ rowNode }) || !rowNode) { return; } const editRow = this.getEditRow(rowNode); if (column) { editRow.delete(column); } else { editRow.clear(); } if (editRow.size === 0) { this.edits.delete(rowNode); } } getEditRow(rowNode, params = {}) { if (this.suspendEdits) { return; } if (this.edits.size === 0) { return; } const edits = rowNode && this.edits.get(rowNode); if (edits) { return edits; } if (params.checkSiblings) { const pinnedSibling = rowNode.pinnedSibling; if (pinnedSibling) { return this.getEditRow(pinnedSibling); } } return; } getEditRowDataValue(rowNode, { checkSiblings } = {}) { if (!rowNode || this.edits.size === 0) { return; } const editRow = this.getEditRow(rowNode); const pinnedSibling = rowNode.pinnedSibling; const siblingRow = checkSiblings && pinnedSibling && this.getEditRow(pinnedSibling); if (!editRow && !siblingRow) { return; } const data = { ...rowNode.data }; const applyEdits = (edits, data2) => edits.forEach(({ editorValue, pendingValue }, column) => { const value = editorValue === undefined ? pendingValue : editorValue; if (value !== UNEDITED) { data2[column.getColId()] = value; } }); if (editRow) { applyEdits(editRow, data); } if (siblingRow) { applyEdits(siblingRow, data); } return data; } getEdit(position = {}, params) { const { rowNode, column } = position; const edits = this.edits; if (this.suspendEdits || edits.size === 0 || !rowNode || !column) { return; } const edit = edits.get(rowNode)?.get(column); if (edit) { return edit; } if (params?.checkSiblings) { const pinnedSibling = rowNode.pinnedSibling; if (pinnedSibling) { return edits.get(pinnedSibling)?.get(column); } } return; } getEditMap(copy = true) { if (this.suspendEdits || this.edits.size === 0) { return /* @__PURE__ */ new Map; } if (!copy) { return this.edits; } const map = /* @__PURE__ */ new Map; this.edits.forEach((editRow, rowNode) => { const newEditRow = /* @__PURE__ */ new Map; editRow.forEach(({ editorState: _, ...cellData }, column) => newEditRow.set(column, { ...cellData })); map.set(rowNode, newEditRow); }); return map; } setEditMap(newEdits) { this.edits.clear(); newEdits.forEach((editRow, rowNode) => { const newRow = /* @__PURE__ */ new Map; editRow.forEach((cellData, column) => newRow.set(column, { ...cellData })); this.edits.set(rowNode, newRow); }); } setEdit(position, edit) { const edits = this.edits; if (edits.size === 0 || !edits.has(position.rowNode)) { edits.set(position.rowNode, /* @__PURE__ */ new Map); } const currentEdit = this.getEdit(position); const updatedEdit = { editorState: { isCancelAfterEnd: undefined, isCancelBeforeStart: undefined }, ...currentEdit, ...edit }; this.getEditRow(position.rowNode).set(position.column, updatedEdit); return updatedEdit; } clearEditValue(position) { const { rowNode, column } = position; if (!rowNode) { return; } const update = (edit2) => { edit2.editorValue = undefined; edit2.pendingValue = edit2.sourceValue; edit2.state = "changed"; }; if (!column) { this.getEditRow(rowNode)?.forEach(update); return; } const edit = this.getEdit(position); if (edit) { update(edit); } } getState(position) { if (this.suspendEdits) { return; } return this.getEdit(position)?.state; } getEditPositions(editMap) { if (this.suspendEdits || (editMap ?? this.edits).size === 0) { return []; } const positions = []; (editMap ?? this.edits).forEach((editRow, rowNode) => { for (const column of editRow.keys()) { const { editorState: _, ...rest } = editRow.get(column); positions.push({ rowNode, column, ...rest }); } }); return positions; } hasRowEdits(rowNode, params) { if (this.suspendEdits) { return false; } if (this.edits.size === 0) { return false; } const rowEdits = this.getEditRow(rowNode, params); return !!rowEdits; } hasEdits(position = {}, params = {}) { if (this.suspendEdits) { return false; } if (this.edits.size === 0) { return false; } const { rowNode, column } = position; const { withOpenEditor } = params; if (rowNode) { const rowEdits = this.getEditRow(rowNode, params); if (!rowEdits) { return false; } if (column) { if (withOpenEditor) { return this.getEdit(position)?.state === "editing"; } return rowEdits.has(column); } if (rowEdits.size !== 0) { if (withOpenEditor) { return Array.from(rowEdits.values()).some(({ state }) => state === "editing"); } return true; } return false; } if (withOpenEditor) { return this.getEditPositions().some(({ state }) => state === "editing"); } return this.edits.size > 0; } start(position) { const map = this.getEditRow(position.rowNode) ?? /* @__PURE__ */ new Map; const { rowNode, column } = position; if (column && !map.has(column)) { map.set(column, { editorValue: undefined, pendingValue: UNEDITED, sourceValue: this.beans.valueSvc.getValue(column, rowNode, "data"), state: "editing", editorState: { isCancelAfterEnd: undefined, isCancelBeforeStart: undefined } }); } this.edits.set(rowNode, map); } stop(position, preserveBatch, cancel) { if (!this.hasEdits(position)) { return; } if (preserveBatch) { const edit = this.getEditRow(position.rowNode)?.get(position.column); if (edit && (edit.pendingValue === UNEDITED || edit.pendingValue === edit.sourceValue)) { this.removeEdits(position); } else if (edit && cancel) { edit.editorValue = undefined; } } else { this.removeEdits(position); } } clear() { for (const pendingRowEdits of this.edits.values()) { pendingRowEdits.clear(); } this.edits.clear(); } getCellValidationModel() { return this.cellValidations; } getRowValidationModel() { return this.rowValidations; } setCellValidationModel(model) { this.cellValidations = model; } setRowValidationModel(model) { this.rowValidations = model; } destroy() { super.destroy(); this.clear(); } }; var EditCellValidationModel = class { constructor() { this.cellValidations = /* @__PURE__ */ new Map; } getCellValidation(position) { const { rowNode, column } = position || {}; return this.cellValidations?.get(rowNode)?.get(column); } hasCellValidation(position) { if (!position?.rowNode || !position.column) { return this.cellValidations.size > 0; } return !!this.getCellValidation(position); } setCellValidation(position, validation) { const { rowNode, column } = position; if (!this.cellValidations.has(rowNode)) { this.cellValidations.set(rowNode, /* @__PURE__ */ new Map); } this.cellValidations.get(rowNode).set(column, validation); } clearCellValidation(position) { const { rowNode, column } = position; this.cellValidations.get(rowNode)?.delete(column); } setCellValidationMap(validationMap) { this.cellValidations = validationMap; } getCellValidationMap() { return this.cellValidations; } clearCellValidationMap() { this.cellValidations.clear(); } }; var EditRowValidationModel = class { constructor() { this.rowValidations = /* @__PURE__ */ new Map; } getRowValidation(position) { const { rowNode } = position || {}; return this.rowValidations.get(rowNode); } hasRowValidation(position) { if (!position?.rowNode) { return this.rowValidations.size > 0; } return !!this.getRowValidation(position); } setRowValidation({ rowNode }, rowValidation) { this.rowValidations.set(rowNode, rowValidation); } clearRowValidation({ rowNode }) { this.rowValidations.delete(rowNode); } setRowValidationMap(validationMap) { this.rowValidations = validationMap; } getRowValidationMap() { return this.rowValidations; } clearRowValidationMap() { this.rowValidations.clear(); } }; function _getRowCtrl(beans, inputs = {}) { const { rowIndex, rowId, rowCtrl, rowPinned } = inputs; if (rowCtrl) { return rowCtrl; } const { rowModel, rowRenderer } = beans; let { rowNode } = inputs; if (!rowNode) { if (rowId) { rowNode = _getRowById(beans, rowId, rowPinned); } else if (rowIndex != null) { rowNode = rowModel.getRow(rowIndex); } } return rowNode ? rowRenderer.getRowCtrlByNode(rowNode) : undefined; } function _getCellCtrl(beans, inputs = {}) { const { cellCtrl, colId, columnId, column } = inputs; if (cellCtrl) { return cellCtrl; } const actualColumn = beans.colModel.getCol(colId ?? columnId ?? _getColId(column)); const rowCtrl = inputs.rowCtrl ?? _getRowCtrl(beans, inputs); const result = rowCtrl?.getCellCtrl(actualColumn) ?? undefined; if (result) { return result; } const rowNode = inputs.rowNode ?? rowCtrl?.rowNode; if (rowNode) { return beans.rowRenderer.getCellCtrls([rowNode], [actualColumn])?.[0]; } return; } function _stopEditing(beans) { const { editSvc } = beans; if (editSvc?.isBatchEditing()) { _syncFromEditors(beans, { persist: true }); _destroyEditors(beans); } else { editSvc?.stopEditing(undefined, { source: "api" }); } } function _addStopEditingWhenGridLosesFocus(bean, beans, viewports) { const { gos, popupSvc } = beans; if (!gos.get("stopEditingWhenCellsLoseFocus")) { return; } const focusOutListener = (event) => { const elementWithFocus = event.relatedTarget; if (_getTabIndex(elementWithFocus) === null) { _stopEditing(beans); return; } let clickInsideGrid = viewports.some((viewport) => viewport.contains(elementWithFocus)) && gos.isElementInThisInstance(elementWithFocus); if (!clickInsideGrid) { clickInsideGrid = !!popupSvc && (popupSvc.getActivePopups().some((popup) => popup.contains(elementWithFocus)) || popupSvc.isElementWithinCustomPopup(elementWithFocus)); } if (!clickInsideGrid) { _stopEditing(beans); } }; for (const viewport of viewports) { bean.addManagedElementListeners(viewport, { focusout: focusOutListener }); } } function _getColId(column) { if (!column) { return; } if (typeof column === "string") { return column; } return column.getColId(); } var UNEDITED = Symbol("unedited"); var getCellEditorInstances = (beans, params = {}) => { const ctrls = beans.rowRenderer.getCellCtrls(params.rowNodes, params.columns); const editors = new Array(ctrls.length); let count = 0; for (let i = 0, len = ctrls.length;i < len; ++i) { const ctrl = ctrls[i]; const cellEditor = ctrl.comp?.getCellEditor(); if (cellEditor) { editors[count++] = _unwrapUserComp(cellEditor); } } editors.length = count; return editors; }; function _setupEditors(beans, editingCells, position, key, event, cellStartedEdit) { if (editingCells.length === 0 && position?.rowNode && position?.column) { _setupEditor(beans, position, { key, event, cellStartedEdit }); } const { valueSvc, editSvc, editModelSvc } = beans; const { rowNode, column } = position ?? {}; for (const cellPosition of editingCells) { const { rowNode: cellRowNode, column: cellColumn } = cellPosition; const curCellCtrl = _getCellCtrl(beans, cellPosition); if (!curCellCtrl) { if (cellRowNode && cellColumn) { const oldValue = valueSvc.getValue(cellColumn, cellRowNode, "data"); const isNewValueCell = position?.rowNode === cellRowNode && position?.column === cellColumn; const cellStartValue = isNewValueCell && key || undefined; const newValue = cellStartValue ?? editSvc?.getCellDataValue(cellPosition) ?? valueSvc.getValueForDisplay({ column: cellColumn, node: cellRowNode, from: "edit" })?.value ?? oldValue ?? UNEDITED; editModelSvc?.setEdit(cellPosition, { pendingValue: getNormalisedFormula(beans, newValue, false, cellColumn), sourceValue: oldValue, state: "editing" }); } continue; } const shouldStartEditing2 = cellStartedEdit && rowNode === curCellCtrl.rowNode && curCellCtrl.column === column; _setupEditor(beans, { rowNode, column: curCellCtrl.column }, { key: shouldStartEditing2 ? key : null, event: shouldStartEditing2 ? event : null, cellStartedEdit: shouldStartEditing2 && cellStartedEdit }); } } function _sourceAndPendingDiffer({ pendingValue, sourceValue }) { if (pendingValue === UNEDITED) { pendingValue = sourceValue; } return pendingValue !== sourceValue; } function _filterChangedEdits(edits) { const result = /* @__PURE__ */ new Map; for (const [rowNode, editRow] of edits) { const filtered = /* @__PURE__ */ new Map; for (const [column, editValue] of editRow) { if (_sourceAndPendingDiffer(editValue)) { filtered.set(column, editValue); } } if (filtered.size > 0) { result.set(rowNode, filtered); } } return result; } function _setupEditor(beans, position, params) { const { key, event, cellStartedEdit, silent } = params ?? {}; const { editModelSvc, gos, userCompFactory } = beans; const cellCtrl = _getCellCtrl(beans, position); const editorComp = cellCtrl?.comp?.getCellEditor(); const editorParams = _createEditorParams(beans, position, key, cellStartedEdit && !silent); const previousEdit = editModelSvc?.getEdit(position); const newValue = editorParams.value ?? previousEdit?.sourceValue; if (editorComp) { editModelSvc?.setEdit(position, { editorValue: getNormalisedFormula(beans, newValue, true, position.column), state: "editing" }); editorComp.refresh?.(editorParams); return; } const colDef = position.column.getColDef(); const compDetails = _getCellEditorDetails(userCompFactory, colDef, editorParams); if (!compDetails) { return; } const { popupFromSelector, popupPositionFromSelector } = compDetails; const popup = popupFromSelector ?? !!colDef.cellEditorPopup; const popupLocation = popupPositionFromSelector ?? colDef.cellEditorPopupPosition; checkAndPreventDefault(compDetails.params, event); if (!cellCtrl) { return; } const { rangeFeature, rowCtrl, comp, onEditorAttachedFuncs } = cellCtrl; editModelSvc?.setEdit(position, { editorValue: getNormalisedFormula(beans, newValue, true, position.column), state: "editing", editorState: { cellStartedEditing: undefined, cellStoppedEditing: undefined } }); cellCtrl.editCompDetails = compDetails; onEditorAttachedFuncs.push(() => rangeFeature?.unsetComp()); comp?.setEditDetails(compDetails, popup, popupLocation, gos.get("reactiveCustomComponents")); rowCtrl?.refreshRow({ suppressFlash: true }); dispatchEditingStarted(beans, position, event, newValue, silent); } function dispatchEditingStarted(beans, position, event, value, silent) { const { editSvc, editModelSvc } = beans; const edit = editModelSvc?.getEdit(position); if (!silent && edit?.state === "editing" && !edit?.editorState?.cellStartedEditing) { editSvc?.dispatchCellEvent(position, event, "cellEditingStarted", { value }); editModelSvc?.setEdit(position, { editorState: { cellStartedEditing: true } }); } } function _valueFromEditor(beans, cellEditor, params) { const noValueResult = { editorValueExists: false }; if (_hasValidationRules(beans)) { const validationErrors = cellEditor.getValidationErrors?.(); if ((validationErrors?.length ?? 0) > 0) { return noValueResult; } } if (params?.isCancelling) { return noValueResult; } if (params?.isStopping) { const isCancelAfterEnd = cellEditor?.isCancelAfterEnd?.(); if (isCancelAfterEnd) { return { ...noValueResult, isCancelAfterEnd }; } } const editorValue = cellEditor.getValue(); return { editorValue, editorValueExists: true }; } function _createEditorParams(beans, position, key, cellStartedEdit) { const { valueSvc, gos, editSvc } = beans; const enableGroupEditing = beans.gos.get("enableGroupEdit"); const cellCtrl = _getCellCtrl(beans, position); const rowIndex = position.rowNode?.rowIndex ?? undefined; const batchEdit = editSvc?.isBatchEditing(); const agColumn = beans.colModel.getCol(position.column.getId()); const { rowNode, column } = position; const editor = cellCtrl.comp?.getCellEditor(); const cellDataValue = editSvc?.getCellDataValue(position); const initialNewValue = cellDataValue === undefined ? editor ? _valueFromEditor(beans, editor)?.editorValue : undefined : cellDataValue; const value = initialNewValue === UNEDITED ? valueSvc.getValueForDisplay({ column: agColumn, node: rowNode, from: "edit" })?.value : initialNewValue; let paramsValue = enableGroupEditing ? initialNewValue : value; if (column.isAllowFormula() && beans.formula?.isFormula(paramsValue)) { paramsValue = beans.formula?.normaliseFormula(paramsValue, true) ?? paramsValue; } return _addGridCommonParams(gos, { value: paramsValue, eventKey: key ?? null, column, colDef: column.getColDef(), rowIndex, node: rowNode, data: rowNode.data, cellStartedEdit: !!cellStartedEdit, onKeyDown: cellCtrl?.onKeyDown.bind(cellCtrl), stopEditing: (suppressNavigateAfterEdit) => { editSvc.stopEditing(position, { source: batchEdit ? "ui" : "api", suppressNavigateAfterEdit }); _destroyEditor(beans, position, {}); }, eGridCell: cellCtrl?.eGui, parseValue: (newValue) => valueSvc.parseValue(agColumn, rowNode, newValue, cellCtrl?.value), formatValue: cellCtrl?.formatValue.bind(cellCtrl), validate: () => { editSvc?.validateEdit(); } }); } function _purgeUnchangedEdits(beans, includeEditing) { const { editModelSvc } = beans; editModelSvc?.getEditMap().forEach((editRow, rowNode) => { editRow.forEach((edit, column) => { if (!includeEditing && (edit.state === "editing" || edit.pendingValue === UNEDITED)) { return; } if (!_sourceAndPendingDiffer(edit) && (edit.state !== "editing" || includeEditing)) { editModelSvc?.removeEdits({ rowNode, column }); } }); }); } function _refreshEditorOnColDefChanged(beans, cellCtrl) { const editor = cellCtrl.comp?.getCellEditor(); if (!editor?.refresh) { return; } const { eventKey, cellStartedEdit } = cellCtrl.editCompDetails.params; const { column } = cellCtrl; const editorParams = _createEditorParams(beans, cellCtrl, eventKey, cellStartedEdit); const colDef = column.getColDef(); const compDetails = _getCellEditorDetails(beans.userCompFactory, colDef, editorParams); editor.refresh(checkAndPreventDefault(compDetails.params, eventKey)); } function checkAndPreventDefault(params, event) { if (event instanceof KeyboardEvent && params.column.getColDef().cellEditor === "agNumberCellEditor") { params.suppressPreventDefault = ["-", "+", ".", "e"].includes(event?.key ?? "") || params.suppressPreventDefault; } else { event?.preventDefault?.(); } return params; } function _syncFromEditors(beans, params) { for (const cellId of beans.editModelSvc?.getEditPositions() ?? []) { const cellCtrl = _getCellCtrl(beans, cellId); if (!cellCtrl) { continue; } const editor = cellCtrl.comp?.getCellEditor(); if (!editor) { continue; } const { editorValue, editorValueExists, isCancelAfterEnd } = _valueFromEditor(beans, editor, params); if (isCancelAfterEnd) { const { cellStartedEditing, cellStoppedEditing } = beans.editModelSvc?.getEdit(cellId)?.editorState || {}; beans.editModelSvc?.setEdit(cellId, { editorState: { isCancelAfterEnd, cellStartedEditing, cellStoppedEditing } }); } _syncFromEditor(beans, cellId, editorValue, undefined, !editorValueExists, params); } } function _syncFromEditor(beans, position, editorValue, _source, valueSameAsSource, params) { const { editModelSvc, valueSvc } = beans; if (!editModelSvc) { return; } const { rowNode, column } = position; if (!(rowNode && column)) { return; } let edit = editModelSvc.getEdit(position); if (edit?.sourceValue === undefined) { const pendingValue = edit ? getNormalisedFormula(beans, edit.editorValue, false, column) : UNEDITED; const editValue = { sourceValue: valueSvc.getValue(column, rowNode, "data"), pendingValue }; if (params?.persist) { editValue.state = "changed"; } edit = editModelSvc.setEdit(position, editValue); } editModelSvc.setEdit(position, { editorValue: valueSameAsSource ? getNormalisedFormula(beans, edit.sourceValue, true, column) : editorValue }); if (params?.persist) { _persistEditorValue(beans, position); } } function getNormalisedFormula(beans, value, forEditing, column) { const { formula } = beans; if (column.isAllowFormula() && formula?.isFormula(value)) { return formula?.normaliseFormula(value, forEditing) ?? value; } return value; } function _persistEditorValue(beans, position) { const { editModelSvc } = beans; const edit = editModelSvc?.getEdit(position); const pendingValue = getNormalisedFormula(beans, edit?.editorValue, false, position.column); const editValue = { pendingValue }; if (!edit?.editorState?.cellStoppedEditing && edit?.state !== "editing") { editValue.state = "changed"; } editModelSvc?.setEdit(position, editValue); } function _destroyEditors(beans, edits, params = {}) { if (!edits) { edits = beans.editModelSvc?.getEditPositions(); } if (edits) { for (const cellPosition of edits) { _destroyEditor(beans, cellPosition, params); } } } function _destroyEditor(beans, position, params, cellCtrl = _getCellCtrl(beans, position)) { const editModelSvc = beans.editModelSvc; const edit = editModelSvc?.getEdit(position); let state; if (edit && edit.state !== "editing" && edit.editorState?.cellStoppedEditing) { state = edit.state; } else { state = "changed"; } if (!cellCtrl) { if (edit) { editModelSvc?.setEdit(position, { state }); } return; } const comp = cellCtrl.comp; const cellEditor = comp?.getCellEditor(); if (comp && !cellEditor) { cellCtrl?.refreshCell(); if (edit) { editModelSvc?.setEdit(position, { state }); const args = beans.gos.get("enableGroupEdit") ? _enabledGroupEditStoppedArgs(edit, params?.cancel) : { valueChanged: false, newValue: undefined, oldValue: edit.sourceValue }; dispatchEditingStopped(beans, position, args, params); } return; } if (_hasValidationRules(beans)) { const errorMessages = edit && cellEditor?.getValidationErrors?.(); const cellValidationModel = editModelSvc?.getCellValidationModel(); if (errorMessages?.length) { cellValidationModel?.setCellValidation(position, { errorMessages }); } else { cellValidationModel?.clearCellValidation(position); } } if (edit) { editModelSvc?.setEdit(position, { state }); } comp?.setEditDetails(); comp?.refreshEditStyles(false, false); cellCtrl?.refreshCell({ force: true, suppressFlash: true }); const latest = editModelSvc?.getEdit(position); if (latest && latest.state !== "editing") { const cancel = params?.cancel; const args = beans.gos.get("enableGroupEdit") ? _enabledGroupEditStoppedArgs(latest, cancel) : _cellEditStoppedArgs(latest, edit, cancel); dispatchEditingStopped(beans, position, args, params); } } function _enabledGroupEditStoppedArgs(latest, cancel) { const { sourceValue, pendingValue } = latest; let newValue; if (!cancel && pendingValue !== UNEDITED) { newValue = pendingValue; } return { valueChanged: !cancel && _sourceAndPendingDiffer(latest), newValue, oldValue: sourceValue, value: sourceValue }; } function _cellEditStoppedArgs(latest, edit, cancel) { if (cancel || latest.editorState.isCancelAfterEnd) { return { valueChanged: false, newValue: undefined, oldValue: latest.sourceValue }; } let newValue = latest.editorValue; if (newValue == null || newValue === UNEDITED) { newValue = edit?.pendingValue; } if (newValue === UNEDITED) { newValue = undefined; } return { valueChanged: _sourceAndPendingDiffer(latest), newValue, oldValue: latest.sourceValue }; } function dispatchEditingStopped(beans, position, args, { silent, event } = {}) { const { editSvc, editModelSvc } = beans; const latest = editModelSvc?.getEdit(position); const { editorState } = latest || {}; const { isCancelBeforeStart, cellStartedEditing, cellStoppedEditing } = editorState || {}; if (!silent && !isCancelBeforeStart && cellStartedEditing && !cellStoppedEditing) { editSvc?.dispatchCellEvent(position, event, "cellEditingStopped", args); editModelSvc?.setEdit(position, { editorState: { cellStoppedEditing: true } }); } } function _columnDefsRequireValidation(columnDefs) { if (!columnDefs) { return false; } for (let i = 0, len = columnDefs.length;i < len; ++i) { const colDef = columnDefs[i]; const params = colDef.cellEditorParams; if (!params || !colDef.editable && !colDef.groupRowEditable) { continue; } if (params.minLength !== undefined || params.maxLength !== undefined || params.getValidationErrors !== undefined || params.min !== undefined || params.max !== undefined) { return true; } } return false; } function _editorsRequireValidation(beans) { const ctrls = beans.rowRenderer.getCellCtrls(); for (let i = 0, len = ctrls.length;i < len; ++i) { const ctrl = ctrls[i]; const cellEditor = ctrl.comp?.getCellEditor(); if (cellEditor) { const editor = _unwrapUserComp(cellEditor); if (editor.getValidationElement || editor.getValidationErrors) { return true; } } } return false; } function _hasValidationRules(beans) { return !!beans.gos.get("getFullRowEditValidationErrors") || _columnDefsRequireValidation(beans.colModel.getColumnDefs()) || _editorsRequireValidation(beans); } function _populateModelValidationErrors(beans, force) { if (!(force || _hasValidationRules(beans))) { return; } const cellValidationModel = new EditCellValidationModel; const { ariaAnnounce, localeSvc, editModelSvc, gos } = beans; const includeRows = gos.get("editType") === "fullRow"; const translate = _getLocaleTextFunc(localeSvc); const ariaValidationErrorPrefix = translate("ariaValidationErrorPrefix", "Cell Editor Validation"); const rowCtrlSet = /* @__PURE__ */ new Set; for (const ctrl of beans.rowRenderer.getCellCtrls()) { const cellEditorComp = ctrl.comp?.getCellEditor(); if (!cellEditorComp) { continue; } const editor = _unwrapUserComp(cellEditorComp); const { rowNode, column } = ctrl; const errorMessages = editor.getValidationErrors?.() ?? []; const el = editor.getValidationElement?.(false) || !editor.isPopup?.() && ctrl.eGui; if (el) { const isInvalid = errorMessages != null && errorMessages.length > 0; const invalidMessage = isInvalid ? errorMessages.join(". ") : ""; _setAriaInvalid(el, isInvalid); if (isInvalid) { ariaAnnounce.announceValue(`${ariaValidationErrorPrefix} ${errorMessages}`, "editorValidation"); } if (el instanceof HTMLInputElement) { el.setCustomValidity(invalidMessage); } else { el.classList.toggle("invalid", isInvalid); } } if (errorMessages?.length > 0) { cellValidationModel.setCellValidation({ rowNode, column }, { errorMessages }); } rowCtrlSet.add(ctrl.rowCtrl); } _syncFromEditors(beans, { persist: false }); editModelSvc?.setCellValidationModel(cellValidationModel); if (includeRows) { const rowValidations = _generateRowValidationErrors(beans); editModelSvc?.setRowValidationModel(rowValidations); } for (const rowCtrl of rowCtrlSet.values()) { rowCtrl.rowEditStyleFeature?.applyRowStyles(); for (const cellCtrl of rowCtrl.getAllCellCtrls()) { cellCtrl.tooltipFeature?.refreshTooltip(true); cellCtrl.editorTooltipFeature?.refreshTooltip(true); cellCtrl.editStyleFeature?.applyCellStyles?.(); } } } var _generateRowValidationErrors = (beans) => { const rowValidationModel = new EditRowValidationModel; const getFullRowEditValidationErrors = beans.gos.get("getFullRowEditValidationErrors"); const editMap = beans.editModelSvc?.getEditMap(); if (!editMap) { return rowValidationModel; } for (const rowNode of editMap.keys()) { const rowEditMap = editMap.get(rowNode); if (!rowEditMap) { continue; } const editorsState = []; const { rowIndex, rowPinned } = rowNode; for (const column of rowEditMap.keys()) { const editValue = rowEditMap.get(column); if (!editValue) { continue; } const { editorValue, pendingValue, sourceValue } = editValue; const newValue = editorValue ?? (pendingValue === UNEDITED ? undefined : pendingValue) ?? sourceValue; editorsState.push({ column, colId: column.getColId(), rowIndex, rowPinned, oldValue: sourceValue, newValue }); } const errorMessages = getFullRowEditValidationErrors?.({ editorsState }) ?? []; if (errorMessages.length > 0) { rowValidationModel.setRowValidation({ rowNode }, { errorMessages }); } } return rowValidationModel; }; function _validateEdit(beans) { _populateModelValidationErrors(beans, true); const map = beans.editModelSvc?.getCellValidationModel().getCellValidationMap(); if (!map) { return null; } const validations = []; map.forEach((rowValidations, rowNode) => { rowValidations.forEach(({ errorMessages }, column) => { validations.push({ column, rowIndex: rowNode.rowIndex, rowPinned: rowNode.rowPinned, messages: errorMessages ?? null }); }); }); return validations; } function _isManualPinnedRow(rowNode) { return !!(rowNode.rowPinned && rowNode.pinnedSibling); } function _getNodesInRangeForSelection(rowModel, float, start, end) { const isTop = float === "top"; if (!start) { return _getNodesInRangeForSelection(rowModel, float, isTop ? rowModel.getPinnedTopRow(0) : rowModel.getPinnedBottomRow(0), end); } if (!end) { const count = isTop ? rowModel.getPinnedTopRowCount() : rowModel.getPinnedBottomRowCount(); return _getNodesInRangeForSelection(rowModel, float, start, isTop ? rowModel.getPinnedTopRow(count - 1) : rowModel.getPinnedBottomRow(count - 1)); } let started = false; let finished = false; const range = []; rowModel.forEachPinnedRow(float, (node) => { if (node === start && !started) { started = true; range.push(node); return; } if (started && node === end) { finished = true; range.push(node); return; } if (started && !finished) { range.push(node); } }); return range; } function _createCellEvent(beans, domEvent, eventType, { rowNode, column }, value) { const event = _addGridCommonParams(beans.gos, { type: eventType, node: rowNode, data: rowNode.data, value, column, colDef: column.getColDef(), rowPinned: rowNode.rowPinned, event: domEvent, rowIndex: rowNode.rowIndex }); return event; } function _isDeleteKey(key, alwaysReturnFalseOnBackspace = false) { if (key === KeyCode.DELETE) { return true; } if (!alwaysReturnFalseOnBackspace && key === KeyCode.BACKSPACE) { return _isMacOsUserAgent(); } return false; } var CellKeyboardListenerFeature = class extends BeanStub { constructor(cellCtrl, beans, rowNode, rowCtrl) { super(); this.cellCtrl = cellCtrl; this.rowNode = rowNode; this.rowCtrl = rowCtrl; this.beans = beans; } init() { this.eGui = this.cellCtrl.eGui; } onKeyDown(event) { const key = event.key; if (key === KeyCode.ENTER && isRowNumberCol(this.cellCtrl.column) && this.beans.rowNumbersSvc?.handleKeyDownOnCell(this.cellCtrl.cellPosition, event)) { return; } switch (key) { case KeyCode.ENTER: this.onEnterKeyDown(event); break; case KeyCode.F2: this.onF2KeyDown(event); break; case KeyCode.ESCAPE: this.onEscapeKeyDown(event); break; case KeyCode.TAB: this.onTabKeyDown(event); break; case KeyCode.BACKSPACE: case KeyCode.DELETE: this.onBackspaceOrDeleteKeyDown(key, event); break; case KeyCode.DOWN: case KeyCode.UP: case KeyCode.RIGHT: case KeyCode.LEFT: this.onNavigationKeyDown(event, key); break; } } onNavigationKeyDown(event, key) { const { cellCtrl, beans } = this; if (beans.editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { return; } if (event.shiftKey && cellCtrl.isRangeSelectionEnabled()) { this.onShiftRangeSelect(event); } else { const currentCellPosition = cellCtrl.getFocusedCellPosition(); beans.navigation?.navigateToNextCell(event, key, currentCellPosition, true); } event.preventDefault(); } onShiftRangeSelect(event) { const { rangeSvc, navigation } = this.beans; if (!rangeSvc) { return; } const endCell = rangeSvc.extendLatestRangeInDirection(event); if (!endCell) { return; } if (event.key === KeyCode.LEFT || event.key === KeyCode.RIGHT) { navigation?.ensureColumnVisible(endCell.column); } else { navigation?.ensureRowVisible(endCell.rowIndex); } } onTabKeyDown(event) { this.beans.navigation?.onTabKeyDown(this.cellCtrl, event); } onBackspaceOrDeleteKeyDown(key, event) { const { cellCtrl, beans, rowNode } = this; const { gos, rangeSvc, eventSvc, editSvc } = beans; eventSvc.dispatchEvent({ type: "keyShortcutChangedCellStart" }); if (_isDeleteKey(key, gos.get("enableCellEditingOnBackspace")) && !editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { if (rangeSvc && _isCellSelectionEnabled(gos)) { rangeSvc.clearCellRangeCellValues({ dispatchWrapperEvents: true, wrapperEventSource: "deleteKey" }); } else if (cellCtrl.isCellEditable()) { const deleteValue = beans.valueSvc.getDeleteValue(cellCtrl.column, rowNode); rowNode.setDataValue(cellCtrl.column, deleteValue, "cellClear"); } } else if (!editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { beans.editSvc?.startEditing(cellCtrl, { startedEdit: true, event }); } eventSvc.dispatchEvent({ type: "keyShortcutChangedCellEnd" }); } onEnterKeyDown(event) { const { cellCtrl, beans } = this; const { editSvc, navigation } = beans; const cellEditing = editSvc?.isEditing(cellCtrl, { withOpenEditor: true }); const rowNode = cellCtrl.rowNode; const rowEditing = editSvc?.isRowEditing(rowNode, { withOpenEditor: true }); const startEditingAction = (cellCtrl2) => { const started = editSvc?.startEditing(cellCtrl2, { startedEdit: true, event, source: "edit" }); if (started) { event.preventDefault(); } }; if (cellEditing || rowEditing) { if (this.isCtrlEnter(event)) { editSvc?.applyBulkEdit(cellCtrl, beans?.rangeSvc?.getCellRanges() || []); return; } _populateModelValidationErrors(beans); if (editSvc?.checkNavWithValidation(undefined, event) === "block-stop") { return; } if (editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { editSvc?.stopEditing(cellCtrl, { event, source: "edit" }); } else if (rowEditing && !cellCtrl.isCellEditable()) { editSvc?.stopEditing({ rowNode }, { event, source: "edit" }); } else { startEditingAction(cellCtrl); } } else if (beans.gos.get("enterNavigatesVertically")) { const key = event.shiftKey ? KeyCode.UP : KeyCode.DOWN; navigation?.navigateToNextCell(null, key, cellCtrl.cellPosition, false); } else { if (editSvc?.hasValidationErrors()) { return; } if (editSvc?.hasValidationErrors(cellCtrl)) { editSvc.revertSingleCellEdit(cellCtrl, true); } startEditingAction(cellCtrl); } } isCtrlEnter(e) { return (e.ctrlKey || e.metaKey) && e.key === KeyCode.ENTER; } onF2KeyDown(event) { const { cellCtrl, beans: { editSvc } } = this; const editing = editSvc?.isEditing(); if (editing) { _populateModelValidationErrors(this.beans); if (editSvc?.checkNavWithValidation(undefined, event) === "block-stop") { return; } } editSvc?.startEditing(cellCtrl, { startedEdit: true, event }); } onEscapeKeyDown(event) { const { cellCtrl, beans: { editSvc } } = this; if (editSvc?.checkNavWithValidation(cellCtrl, event) === "block-stop") { editSvc.revertSingleCellEdit(cellCtrl); } setTimeout(() => { editSvc?.stopEditing(cellCtrl, { event, cancel: true }); }); } processCharacter(event) { const eventTarget = event.target; const eventOnChildComponent = eventTarget !== this.eGui; const { beans: { editSvc }, cellCtrl } = this; if (eventOnChildComponent) { return; } if (editSvc?.isEditing(cellCtrl, { withOpenEditor: true })) { return; } const key = event.key; if (key === KeyCode.SPACE) { this.onSpaceKeyDown(event); } else if (editSvc?.isCellEditable(cellCtrl, "ui")) { if (editSvc?.hasValidationErrors() && !editSvc?.hasValidationErrors(cellCtrl)) { return; } editSvc?.startEditing(cellCtrl, { startedEdit: true, event, source: "api", editable: true }); const compDetails = cellCtrl.editCompDetails; const shouldPreventDefault = !compDetails?.params?.suppressPreventDefault; if (shouldPreventDefault) { event.preventDefault(); } } } onSpaceKeyDown(event) { const { gos, editSvc } = this.beans; const { rowNode } = this.cellCtrl; if (!editSvc?.isEditing(this.cellCtrl, { withOpenEditor: true }) && _isRowSelection(gos)) { this.beans.selectionSvc?.handleSelectionEvent(event, rowNode, "spaceKey"); } event.preventDefault(); } }; var CellMouseListenerFeature = class extends BeanStub { constructor(cellCtrl, beans, column) { super(); this.cellCtrl = cellCtrl; this.column = column; this.beans = beans; } onMouseEvent(eventName, mouseEvent) { if (_isStopPropagationForAgGrid(mouseEvent)) { return; } switch (eventName) { case "click": this.onCellClicked(mouseEvent); break; case "pointerdown": case "mousedown": case "touchstart": this.onMouseDown(mouseEvent); break; case "dblclick": this.onCellDoubleClicked(mouseEvent); break; case "mouseout": this.onMouseOut(mouseEvent); break; case "mouseover": this.onMouseOver(mouseEvent); break; } } onCellClicked(event) { if (this.beans.touchSvc?.handleCellDoubleClick(this, event)) { return; } const { eventSvc, rangeSvc, editSvc, editModelSvc, frameworkOverrides, gos } = this.beans; const isMultiKey = event.ctrlKey || event.metaKey; const { cellCtrl } = this; const { column, cellPosition, rowNode } = cellCtrl; const suppressMouseEvent2 = _suppressCellMouseEvent(gos, column, rowNode, event); if (rangeSvc && isMultiKey && !suppressMouseEvent2) { if (rangeSvc.getCellRangeCount(cellPosition) > 1) { rangeSvc.intersectLastRange(true); } } const cellClickedEvent = cellCtrl.createEvent(event, "cellClicked"); cellClickedEvent.isEventHandlingSuppressed = suppressMouseEvent2; eventSvc.dispatchEvent(cellClickedEvent); const colDef = column.getColDef(); if (colDef.onCellClicked) { window.setTimeout(() => { frameworkOverrides.wrapOutgoing(() => { colDef.onCellClicked(cellClickedEvent); }); }, 0); } if (suppressMouseEvent2) { return; } if (editModelSvc?.getState(cellCtrl) !== "editing") { const editing = editSvc?.isEditing(); const isRangeSelectionEnabledWhileEditing = editSvc?.isRangeSelectionEnabledWhileEditing(); const cellValidations = editModelSvc?.getCellValidationModel().getCellValidationMap().size ?? 0; const rowValidations = editModelSvc?.getRowValidationModel().getRowValidationMap().size ?? 0; if (editing && (isRangeSelectionEnabledWhileEditing || cellValidations > 0 || rowValidations > 0)) { return; } if (editSvc?.shouldStartEditing(cellCtrl, event)) { editSvc?.startEditing(cellCtrl, { event }); } else if (editSvc?.shouldStopEditing(cellCtrl, event)) { if (this.beans.gos.get("editType") === "fullRow") { editSvc?.stopEditing(cellCtrl, { event, source: "edit" }); } else { editSvc?.stopEditing(undefined, { event, source: "edit" }); } } } } onCellDoubleClicked(event) { const { column, beans, cellCtrl } = this; const { eventSvc, frameworkOverrides, editSvc, editModelSvc, gos } = beans; const suppressMouseEvent2 = _suppressCellMouseEvent(gos, cellCtrl.column, cellCtrl.rowNode, event); const colDef = column.getColDef(); const cellDoubleClickedEvent = cellCtrl.createEvent(event, "cellDoubleClicked"); cellDoubleClickedEvent.isEventHandlingSuppressed = suppressMouseEvent2; eventSvc.dispatchEvent(cellDoubleClickedEvent); if (typeof colDef.onCellDoubleClicked === "function") { window.setTimeout(() => { frameworkOverrides.wrapOutgoing(() => { colDef.onCellDoubleClicked(cellDoubleClickedEvent); }); }, 0); } if (suppressMouseEvent2) { return; } if (editSvc?.shouldStartEditing(cellCtrl, event) && editModelSvc?.getState(cellCtrl) !== "editing") { const editing = editSvc?.isEditing(); const isRangeSelectionEnabledWhileEditing = editSvc?.isRangeSelectionEnabledWhileEditing(); const cellValidations = editModelSvc?.getCellValidationModel().getCellValidationMap().size ?? 0; const rowValidations = editModelSvc?.getRowValidationModel().getRowValidationMap().size ?? 0; if (editing && (isRangeSelectionEnabledWhileEditing || cellValidations > 0 || rowValidations > 0)) { return; } editSvc?.startEditing(cellCtrl, { event }); } } onMouseDown(mouseEvent) { const { shiftKey } = mouseEvent; const target = mouseEvent.target; const { cellCtrl, beans } = this; const { eventSvc, rangeSvc, rowNumbersSvc, focusSvc, gos, editSvc } = beans; const { column, rowNode, cellPosition } = cellCtrl; const suppressMouseEvent2 = _suppressCellMouseEvent(gos, column, rowNode, mouseEvent); const fireMouseDownEvent = () => { const cellMouseDownEvent = cellCtrl.createEvent(mouseEvent, "cellMouseDown"); cellMouseDownEvent.isEventHandlingSuppressed = suppressMouseEvent2; eventSvc.dispatchEvent(cellMouseDownEvent); }; if (suppressMouseEvent2) { fireMouseDownEvent(); return; } if (this.isRightClickInExistingRange(mouseEvent)) { return; } const hasRanges = rangeSvc && !rangeSvc.isEmpty(); const containsWidget = this.containsWidget(target); const isRowNumberColumn = isRowNumberCol(column); if (rowNumbersSvc && isRowNumberColumn && !rowNumbersSvc.handleMouseDownOnCell(cellPosition, mouseEvent)) { return; } if (!shiftKey || !hasRanges) { const editing = editSvc?.isEditing(cellCtrl); const isEnableCellTextSelection = gos.get("enableCellTextSelection"); const shouldFocus = isEnableCellTextSelection && mouseEvent.defaultPrevented; const forceBrowserFocus = (_isBrowserSafari() || shouldFocus) && !editing && !_isFocusableFormField(target) && !containsWidget; cellCtrl.focusCell(forceBrowserFocus, mouseEvent); } if (shiftKey && hasRanges && !focusSvc.isCellFocused(cellPosition)) { mouseEvent.preventDefault(); const focusedCell = focusSvc.getFocusedCell(); if (focusedCell) { const { column: column2, rowIndex, rowPinned } = focusedCell; const allowRangesWhileEditing = !!editSvc?.isRangeSelectionEnabledWhileEditing?.(); if (editSvc?.isEditing(focusedCell) && !allowRangesWhileEditing) { editSvc?.stopEditing(focusedCell); } if (!allowRangesWhileEditing) { focusSvc.setFocusedCell({ column: column2, rowIndex, rowPinned, forceBrowserFocus: true, preventScrollOnBrowserFocus: true, sourceEvent: mouseEvent }); } } } if (containsWidget) { return; } rangeSvc?.handleCellMouseDown(mouseEvent, cellPosition); fireMouseDownEvent(); } isRightClickInExistingRange(mouseEvent) { const { rangeSvc } = this.beans; if (rangeSvc) { const cellInRange = rangeSvc.isCellInAnyRange(this.cellCtrl.cellPosition); const isRightClick = _interpretAsRightClick(this.beans, mouseEvent); if (cellInRange && isRightClick) { return true; } } return false; } containsWidget(target) { return _isElementChildOfClass(target, "ag-selection-checkbox", 3) || _isElementChildOfClass(target, "ag-drag-handle", 3); } onMouseOut(mouseEvent) { if (this.mouseStayingInsideCell(mouseEvent)) { return; } const { eventSvc, colHover } = this.beans; eventSvc.dispatchEvent(this.cellCtrl.createEvent(mouseEvent, "cellMouseOut")); colHover?.clearMouseOver(); } onMouseOver(mouseEvent) { if (this.mouseStayingInsideCell(mouseEvent)) { return; } const { eventSvc, colHover } = this.beans; eventSvc.dispatchEvent(this.cellCtrl.createEvent(mouseEvent, "cellMouseOver")); colHover?.setMouseOver([this.column]); } mouseStayingInsideCell(e) { if (!e.target || !e.relatedTarget) { return false; } const eCell = this.cellCtrl.eGui; const cellContainsTarget = eCell.contains(e.target); const cellContainsRelatedTarget = eCell.contains(e.relatedTarget); return cellContainsTarget && cellContainsRelatedTarget; } }; var CellPositionFeature = class extends BeanStub { constructor(cellCtrl, beans) { super(); this.cellCtrl = cellCtrl; this.beans = beans; this.column = cellCtrl.column; this.rowNode = cellCtrl.rowNode; } setupRowSpan() { this.rowSpan = this.column.getRowSpan(this.rowNode); this.addManagedListeners(this.beans.eventSvc, { newColumnsLoaded: () => this.onNewColumnsLoaded() }); } init() { this.eSetLeft = this.cellCtrl.getRootElement(); this.eContent = this.cellCtrl.eGui; const cellSpan = this.cellCtrl.getCellSpan(); if (!cellSpan) { this.setupColSpan(); this.setupRowSpan(); } this.onLeftChanged(); this.onWidthChanged(); if (!cellSpan) { this._legacyApplyRowSpan(); } if (cellSpan) { const refreshSpanHeight = this.refreshSpanHeight.bind(this, cellSpan); refreshSpanHeight(); this.addManagedListeners(this.beans.eventSvc, { paginationChanged: refreshSpanHeight, recalculateRowBounds: refreshSpanHeight, pinnedHeightChanged: refreshSpanHeight }); } } refreshSpanHeight(cellSpan) { const spanHeight = cellSpan.getCellHeight(); if (spanHeight != null) { this.eContent.style.height = `${spanHeight}px`; } } onNewColumnsLoaded() { const rowSpan = this.column.getRowSpan(this.rowNode); if (this.rowSpan === rowSpan) { return; } this.rowSpan = rowSpan; this._legacyApplyRowSpan(true); } onDisplayColumnsChanged() { const colsSpanning = this.getColSpanningList(); if (!_areEqual(this.colsSpanning, colsSpanning)) { this.colsSpanning = colsSpanning; this.onWidthChanged(); this.onLeftChanged(); } } setupColSpan() { if (this.column.getColDef().colSpan == null) { return; } this.colsSpanning = this.getColSpanningList(); this.addManagedListeners(this.beans.eventSvc, { displayedColumnsChanged: this.onDisplayColumnsChanged.bind(this), displayedColumnsWidthChanged: this.onWidthChanged.bind(this) }); } onWidthChanged() { if (!this.eContent) { return; } const width = this.getCellWidth(); this.eContent.style.width = `${width}px`; } getCellWidth() { if (!this.colsSpanning) { return this.column.getActualWidth(); } return this.colsSpanning.reduce((width, col) => width + col.getActualWidth(), 0); } getColSpanningList() { const { column, rowNode } = this; const colSpan = column.getColSpan(rowNode); const colsSpanning = []; if (colSpan === 1) { colsSpanning.push(column); } else { let pointer = column; const pinned = column.getPinned(); for (let i = 0;pointer && i < colSpan; i++) { colsSpanning.push(pointer); pointer = this.beans.visibleCols.getColAfter(pointer); if (!pointer || _missing(pointer)) { break; } if (pinned !== pointer.getPinned()) { break; } } } return colsSpanning; } onLeftChanged() { if (!this.eSetLeft) { return; } const left = this.modifyLeftForPrintLayout(this.getCellLeft()); this.eSetLeft.style.left = left + "px"; } getCellLeft() { let mostLeftCol; if (this.beans.gos.get("enableRtl") && this.colsSpanning) { mostLeftCol = _last(this.colsSpanning); } else { mostLeftCol = this.column; } return mostLeftCol.getLeft(); } modifyLeftForPrintLayout(leftPosition) { if (!this.cellCtrl.printLayout || this.column.getPinned() === "left") { return leftPosition; } const { visibleCols } = this.beans; const leftWidth = visibleCols.getColsLeftWidth(); if (this.column.getPinned() === "right") { const bodyWidth = visibleCols.bodyWidth; return leftWidth + bodyWidth + (leftPosition || 0); } return leftWidth + (leftPosition || 0); } _legacyApplyRowSpan(force) { if (this.rowSpan === 1 && !force) { return; } const singleRowHeight = _getRowHeightAsNumber(this.beans); const totalRowHeight = singleRowHeight * this.rowSpan; this.eContent.style.height = `${totalRowHeight}px`; this.eContent.style.zIndex = "1"; } destroy() { super.destroy(); } }; var CSS_CELL = "ag-cell"; var CSS_AUTO_HEIGHT = "ag-cell-auto-height"; var CSS_NORMAL_HEIGHT = "ag-cell-normal-height"; var CSS_CELL_FOCUS = "ag-cell-focus"; var CSS_CELL_FIRST_RIGHT_PINNED = "ag-cell-first-right-pinned"; var CSS_CELL_LAST_LEFT_PINNED = "ag-cell-last-left-pinned"; var CSS_CELL_NOT_INLINE_EDITING = "ag-cell-not-inline-editing"; var CSS_CELL_WRAP_TEXT = "ag-cell-wrap-text"; var instanceIdSequence4 = 0; var CellCtrl = class extends BeanStub { constructor(column, rowNode, beans, rowCtrl) { super(); this.column = column; this.rowNode = rowNode; this.rowCtrl = rowCtrl; this.rangeFeature = undefined; this.rowResizeFeature = undefined; this.positionFeature = undefined; this.customStyleFeature = undefined; this.editStyleFeature = undefined; this.mouseListener = undefined; this.keyboardListener = undefined; this.suppressRefreshCell = false; this.onCompAttachedFuncs = []; this.onEditorAttachedFuncs = []; this.focusEventWhileNotReady = null; this.hasBeenFocused = false; this.hasEdit = false; this.tooltipFeature = undefined; this.editorTooltipFeature = undefined; this.beans = beans; this.gos = beans.gos; this.editSvc = beans.editSvc; this.hasEdit = !!beans.editSvc; const { colId } = column; this.instanceId = colId + "-" + instanceIdSequence4++; this.createCellPosition(); this.updateAndFormatValue(false); } addFeatures() { const { beans } = this; this.positionFeature = new CellPositionFeature(this, beans); this.customStyleFeature = beans.cellStyles?.createCellCustomStyleFeature(this); this.editStyleFeature = beans.editSvc?.createCellStyleFeature(this); this.mouseListener = new CellMouseListenerFeature(this, beans, this.column); this.keyboardListener = new CellKeyboardListenerFeature(this, beans, this.rowNode, this.rowCtrl); this.enableTooltipFeature(); const { rangeSvc } = beans; const cellSelectionEnabled = rangeSvc && _isCellSelectionEnabled(beans.gos); if (cellSelectionEnabled) { this.rangeFeature = rangeSvc.createCellRangeFeature(this); } if (isRowNumberCol(this.column)) { this.rowResizeFeature = this.beans.rowNumbersSvc.createRowNumbersRowResizerFeature(this); } } isCellSpanning() { return false; } getCellSpan() { return; } removeFeatures() { const context = this.beans.context; this.positionFeature = context.destroyBean(this.positionFeature); this.editorTooltipFeature = context.destroyBean(this.editorTooltipFeature); this.customStyleFeature = context.destroyBean(this.customStyleFeature); this.editStyleFeature = context.destroyBean(this.editStyleFeature); this.mouseListener = context.destroyBean(this.mouseListener); this.keyboardListener = context.destroyBean(this.keyboardListener); this.rangeFeature = context.destroyBean(this.rangeFeature); this.rowResizeFeature = context.destroyBean(this.rowResizeFeature); this.disableTooltipFeature(); } enableTooltipFeature(value, shouldDisplayTooltip) { this.tooltipFeature = this.beans.tooltipSvc?.enableCellTooltipFeature(this, value, shouldDisplayTooltip); } disableTooltipFeature() { this.tooltipFeature = this.beans.context.destroyBean(this.tooltipFeature); } enableEditorTooltipFeature(editor) { if (this.editorTooltipFeature) { this.disableEditorTooltipFeature(); } this.editorTooltipFeature = this.beans.tooltipSvc?.setupCellEditorTooltip(this, editor); _populateModelValidationErrors(this.beans); } disableEditorTooltipFeature() { this.editorTooltipFeature = this.beans.context.destroyBean(this.editorTooltipFeature); } setComp(comp, eCell, _eWrapper, eCellWrapper, printLayout, startEditing, compBean) { this.comp = comp; this.eGui = eCell; this.printLayout = printLayout; compBean ?? (compBean = this); this.addDomData(compBean); this.addFeatures(); compBean.addDestroyFunc(() => this.removeFeatures()); this.onSuppressCellFocusChanged(this.beans.gos.get("suppressCellFocus")); this.setupFocus(); this.applyStaticCssClasses(); this.setWrapText(); this.onFirstRightPinnedChanged(); this.onLastLeftPinnedChanged(); this.onColumnHover(); this.setupControlComps(); this.setupAutoHeight(eCellWrapper, compBean); this.refreshFirstAndLastStyles(); this.checkFormulaError(); this.refreshAriaRowIndex(); this.refreshAriaColIndex(); this.positionFeature?.init(); this.customStyleFeature?.setComp(comp); this.editStyleFeature?.setComp(comp); this.tooltipFeature?.refreshTooltip(); this.keyboardListener?.init(); this.rangeFeature?.setComp(comp); this.rowResizeFeature?.refreshRowResizer(); const editable = startEditing ? this.isCellEditable() : undefined; const continuingEdit = !editable && this.hasEdit && this.editSvc?.isEditing(this, { withOpenEditor: true }); if (editable || continuingEdit) { this.editSvc?.startEditing(this, { startedEdit: false, source: "api", silent: true, continueEditing: true, editable }); } else { this.showValue(false, true); } if (this.onCompAttachedFuncs.length) { for (const func of this.onCompAttachedFuncs) { func(); } this.onCompAttachedFuncs = []; } } checkFormulaError() { const isFormulaError = !!this.beans.formula?.getFormulaError(this.column, this.rowNode); this.eGui.classList.toggle("formula-error", isFormulaError); } setupAutoHeight(eCellWrapper, compBean) { this.isAutoHeight = this.beans.rowAutoHeight?.setupCellAutoHeight(this, eCellWrapper, compBean) ?? false; } getCellAriaRole() { return this.column.getColDef().cellAriaRole ?? "gridcell"; } isCellRenderer() { const colDef = this.column.getColDef(); return colDef.cellRenderer != null || colDef.cellRendererSelector != null; } getValueToDisplay() { return this.valueFormatted ?? this.value; } getDeferLoadingCellRenderer() { const { beans, column } = this; const { userCompFactory, ctrlsSvc, eventSvc } = beans; const colDef = column.getColDef(); const params = this.createCellRendererParams(); params.deferRender = true; const loadingDetails = _getLoadingCellRendererDetails(userCompFactory, colDef, params); if (ctrlsSvc.getGridBodyCtrl()?.scrollFeature?.isScrolling()) { let resolver; const onReady = new AgPromise((resolve) => { resolver = resolve; }); const [removeBodyScrollEnd] = this.addManagedListeners(eventSvc, { bodyScrollEnd: () => { resolver(); removeBodyScrollEnd(); } }); return { loadingComp: loadingDetails, onReady }; } return { loadingComp: loadingDetails, onReady: AgPromise.resolve() }; } showValue(forceNewCellRendererInstance, skipRangeHandleRefresh) { const { beans, column, rowNode, rangeFeature } = this; const { userCompFactory } = beans; let valueToDisplay = this.getValueToDisplay(); let compDetails; const isSsrmLoading = rowNode.stub && rowNode.groupData?.[column.getId()] == null; const colDef = column.getColDef(); if (isSsrmLoading || this.isCellRenderer()) { const params = this.createCellRendererParams(); if (!isSsrmLoading || isRowNumberCol(column)) { compDetails = _getCellRendererDetails(userCompFactory, colDef, params); } else { compDetails = _getLoadingCellRendererDetails(userCompFactory, colDef, params); } } if (!compDetails && !isSsrmLoading && beans.findSvc?.isMatch(rowNode, column)) { const params = this.createCellRendererParams(); compDetails = _getCellRendererDetails(userCompFactory, { ...column.getColDef(), cellRenderer: "agFindCellRenderer" }, params); } if (this.hasEdit && this.editSvc.isBatchEditing() && this.editSvc.isRowEditing(rowNode, { checkSiblings: true })) { const result = this.editSvc.prepDetailsDuringBatch(this, { compDetails, valueToDisplay }); if (result) { if (result.compDetails) { compDetails = result.compDetails; } else if (result.valueToDisplay) { valueToDisplay = result.valueToDisplay; } } } this.comp.setRenderDetails(compDetails, valueToDisplay, forceNewCellRendererInstance); this.customRowDragComp?.refreshVisibility(); if (!skipRangeHandleRefresh && rangeFeature) { _requestAnimationFrame(beans, () => rangeFeature?.refreshRangeStyleAndHandle()); } this.rowResizeFeature?.refreshRowResizer(); } setupControlComps() { const colDef = this.column.getColDef(); this.includeSelection = this.isIncludeControl(this.isCheckboxSelection(colDef), true); this.includeRowDrag = this.isIncludeControl(colDef.rowDrag); this.includeDndSource = this.isIncludeControl(colDef.dndSource); this.comp.setIncludeSelection(this.includeSelection); this.comp.setIncludeDndSource(this.includeDndSource); this.comp.setIncludeRowDrag(this.includeRowDrag); } isForceWrapper() { return this.beans.gos.get("enableCellTextSelection") || this.column.isAutoHeight(); } getCellValueClass() { const prefix = "ag-cell-value"; const isCheckboxRenderer = this.column.getColDef().cellRenderer === "agCheckboxCellRenderer"; let suffix = ""; if (isCheckboxRenderer) { suffix = " ag-allow-overflow"; } return `${prefix}${suffix}`; } isIncludeControl(value, allowManuallyPinned = false) { const rowUnpinned = this.rowNode.rowPinned == null; return (rowUnpinned || allowManuallyPinned && _isManualPinnedRow(this.rowNode)) && !!value; } isCheckboxSelection(colDef) { const { rowSelection, groupDisplayType } = this.beans.gridOptions; const checkboxLocation = _getCheckboxLocation(rowSelection); const isSelectionColumn = isColumnSelectionCol(this.column); if (groupDisplayType === "custom" && checkboxLocation !== "selectionColumn" && isSelectionColumn) { return false; } return colDef.checkboxSelection || isSelectionColumn && typeof rowSelection === "object" && _getCheckboxes(rowSelection); } refreshShouldDestroy() { const colDef = this.column.getColDef(); const selectionChanged = this.includeSelection != this.isIncludeControl(this.isCheckboxSelection(colDef), true); const rowDragChanged = this.includeRowDrag != this.isIncludeControl(colDef.rowDrag); const dndSourceChanged = this.includeDndSource != this.isIncludeControl(colDef.dndSource); const autoHeightChanged = this.isAutoHeight != this.column.isAutoHeight(); return selectionChanged || rowDragChanged || dndSourceChanged || autoHeightChanged; } onPopupEditorClosed(e) { const { editSvc } = this.beans; if (!editSvc?.isEditing(this, { withOpenEditor: true })) { return; } const isKeyboardEvent = e instanceof KeyboardEvent; const isMouseEvent = e instanceof MouseEvent; const isEscape = isKeyboardEvent && e.key === KeyCode.ESCAPE; editSvc.stopEditing(this, { source: editSvc.isBatchEditing() ? "ui" : "api", cancel: isEscape, event: isKeyboardEvent || isMouseEvent ? e : undefined }); if (isEscape) { this.focusCell(true, e); } } stopEditing(cancel = false) { const { editSvc } = this.beans; return editSvc?.stopEditing(this, { cancel, source: editSvc?.isBatchEditing() ? "ui" : "api" }) ?? false; } createCellRendererParams() { const { value, valueFormatted, column, rowNode, comp, eGui, beans: { valueSvc, gos, editSvc } } = this; const res = _addGridCommonParams(gos, { value, valueFormatted, getValue: () => valueSvc.getValueForDisplay({ column, node: rowNode, from: "edit" }).value, setValue: (value2) => editSvc?.setDataValue({ rowNode, column }, value2) || rowNode.setDataValue(column, value2), formatValue: this.formatValue.bind(this), data: rowNode.data, node: rowNode, pinned: column.getPinned(), colDef: column.getColDef(), column, refreshCell: this.refreshCell.bind(this), eGridCell: eGui, eParentOfValue: comp.getParentOfValue(), registerRowDragger: (rowDraggerElement, dragStartPixels, value2, suppressVisibilityChange) => this.registerRowDragger(rowDraggerElement, dragStartPixels, suppressVisibilityChange), setTooltip: (value2, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); if (this.tooltipFeature) { this.disableTooltipFeature(); } this.enableTooltipFeature(value2, shouldDisplayTooltip); this.tooltipFeature?.refreshTooltip(); } }); return res; } onCellChanged(event) { const eventImpactsThisCell = event.column === this.column; if (eventImpactsThisCell) { this.refreshCell(); } } refreshOrDestroyCell(params) { if (this.refreshShouldDestroy()) { this.rowCtrl?.recreateCell(this); } else { this.refreshCell(params); } if (this.hasEdit && this.editCompDetails) { const { editSvc, comp } = this; if (!comp?.getCellEditor() && editSvc.isEditing(this, { withOpenEditor: true })) { editSvc.startEditing(this, { startedEdit: false, source: "api", silent: true }); } } } refreshCell(params) { const { editStyleFeature, customStyleFeature, rowCtrl: { rowEditStyleFeature }, beans: { cellFlashSvc, filterManager }, column, comp, suppressRefreshCell, tooltipFeature } = this; if (suppressRefreshCell) { return; } const { field, valueGetter, showRowGroup, enableCellChangeFlash } = column.getColDef(); const noValueProvided = field == null && valueGetter == null && showRowGroup == null; const newData = params?.newData ?? false; const forceRefresh = noValueProvided || params && (params.force || newData); const isCellCompReady = !!comp; const valuesDifferent = this.updateAndFormatValue(isCellCompReady); const dataNeedsUpdating = forceRefresh || valuesDifferent; if (!isCellCompReady) { return; } if (dataNeedsUpdating) { this.showValue(!!newData, false); const processingFilterChange = filterManager?.isSuppressFlashingCellsBecauseFiltering(); const flashCell = !params?.suppressFlash && !processingFilterChange && enableCellChangeFlash; if (flashCell) { cellFlashSvc?.flashCell(this); } editStyleFeature?.applyCellStyles?.(); customStyleFeature?.applyUserStyles(); customStyleFeature?.applyClassesFromColDef(); rowEditStyleFeature?.applyRowStyles(); this.checkFormulaError(); } tooltipFeature?.refreshTooltip(); customStyleFeature?.applyCellClassRules(); } isCellEditable() { return this.column.isCellEditable(this.rowNode); } formatValue(value) { return this.callValueFormatter(value) ?? value; } callValueFormatter(value) { return this.beans.valueSvc.formatValue(this.column, this.rowNode, value); } updateAndFormatValue(compareValues) { const oldValue = this.value; const oldValueFormatted = this.valueFormatted; const { value, valueFormatted } = this.beans.valueSvc.getValueForDisplay({ column: this.column, node: this.rowNode, includeValueFormatted: true, from: "edit" }); this.value = value; this.valueFormatted = valueFormatted; if (compareValues) { return !this.valuesAreEqual(oldValue, this.value) || this.valueFormatted != oldValueFormatted; } return true; } valuesAreEqual(val1, val2) { const colDef = this.column.getColDef(); return colDef.equals ? colDef.equals(val1, val2) : val1 === val2; } addDomData(compBean) { const element = this.eGui; _setDomData(this.beans.gos, element, DOM_DATA_KEY_CELL_CTRL, this); compBean.addDestroyFunc(() => _setDomData(this.beans.gos, element, DOM_DATA_KEY_CELL_CTRL, null)); } createEvent(domEvent, eventType) { const { rowNode, column, value, beans } = this; return _createCellEvent(beans, domEvent, eventType, { rowNode, column }, value); } processCharacter(event) { this.keyboardListener?.processCharacter(event); } onKeyDown(event) { this.keyboardListener?.onKeyDown(event); } onMouseEvent(eventName, mouseEvent) { this.mouseListener?.onMouseEvent(eventName, mouseEvent); } getColSpanningList() { return this.positionFeature?.getColSpanningList() ?? []; } onLeftChanged() { if (!this.comp) { return; } this.positionFeature?.onLeftChanged(); } onDisplayedColumnsChanged() { if (!this.eGui) { return; } this.refreshAriaColIndex(); this.refreshFirstAndLastStyles(); } refreshFirstAndLastStyles() { const { comp, column, beans } = this; refreshFirstAndLastStyles(comp, column, beans.visibleCols); } refreshAriaColIndex() { const colIdx = this.beans.visibleCols.getAriaColIndex(this.column); _setAriaColIndex(this.eGui, colIdx); } onWidthChanged() { return this.positionFeature?.onWidthChanged(); } getRowPosition() { const { rowIndex, rowPinned } = this.cellPosition; return { rowIndex, rowPinned }; } updateRangeBordersIfRangeCount() { if (!this.comp) { return; } this.rangeFeature?.updateRangeBordersIfRangeCount(); } onCellSelectionChanged() { if (!this.comp) { return; } this.rangeFeature?.onCellSelectionChanged(); } isRangeSelectionEnabled() { return this.rangeFeature != null; } focusCell(forceBrowserFocus = false, sourceEvent) { const allowedTarget = this.editSvc?.allowedFocusTargetOnValidation(this); if (allowedTarget && allowedTarget !== this) { return; } this.beans.focusSvc.setFocusedCell({ ...this.getFocusedCellPosition(), forceBrowserFocus, sourceEvent }); } restoreFocus(waitForRender = false) { const { beans: { editSvc, focusSvc }, comp } = this; if (!comp || editSvc?.isEditing(this) || !this.isCellFocused() || !focusSvc.shouldTakeFocus()) { return; } const focus = () => { if (!this.isAlive()) { return; } const focusableElement = comp.getFocusableElement(); if (this.isCellFocused()) { focusableElement.focus({ preventScroll: true }); } }; if (waitForRender) { setTimeout(focus, 0); return; } focus(); } onRowIndexChanged() { this.createCellPosition(); this.refreshAriaRowIndex(); this.onCellFocused(); this.restoreFocus(); this.rangeFeature?.onCellSelectionChanged(); this.rowResizeFeature?.refreshRowResizer(); } onSuppressCellFocusChanged(suppressCellFocus) { const element = this.eGui; if (!element) { return; } _addOrRemoveAttribute(element, "tabindex", suppressCellFocus ? undefined : -1); } onFirstRightPinnedChanged() { if (!this.comp) { return; } const firstRightPinned = this.column.isFirstRightPinned(); this.comp.toggleCss(CSS_CELL_FIRST_RIGHT_PINNED, firstRightPinned); } onLastLeftPinnedChanged() { if (!this.comp) { return; } const lastLeftPinned = this.column.isLastLeftPinned(); this.comp.toggleCss(CSS_CELL_LAST_LEFT_PINNED, lastLeftPinned); } checkCellFocused() { return this.beans.focusSvc.isCellFocused(this.cellPosition); } isCellFocused() { const isFocused = this.checkCellFocused(); this.hasBeenFocused || (this.hasBeenFocused = isFocused); return isFocused; } setupFocus() { this.restoreFocus(true); this.onCellFocused(this.focusEventWhileNotReady ?? undefined); } onCellFocused(event) { const { beans } = this; if (_isCellFocusSuppressed(beans)) { return; } if (!this.comp) { if (event) { this.focusEventWhileNotReady = event; } return; } const cellFocused = this.isCellFocused(); const editing = beans.editSvc?.isEditing(this) ?? false; this.comp.toggleCss(CSS_CELL_FOCUS, cellFocused); if (cellFocused && (event?.forceBrowserFocus || !this.hasBrowserFocus() && this.beans.focusSvc.shouldTakeFocus())) { let focusEl = this.comp.getFocusableElement(); if (editing) { const focusableEls = _findFocusableElements(focusEl, null, true); if (focusableEls.length) { focusEl = focusableEls[0]; } } const preventScroll = event ? event.preventScrollOnBrowserFocus : true; focusEl.focus({ preventScroll }); _placeCaretAtEnd(beans, focusEl); } if (cellFocused && this.focusEventWhileNotReady) { this.focusEventWhileNotReady = null; } if (cellFocused && event) { this.rowCtrl.announceDescription(); } } createCellPosition() { const { rowIndex, rowPinned } = this.rowNode; this.cellPosition = { rowIndex, rowPinned: _makeNull(rowPinned), column: this.column }; } applyStaticCssClasses() { const { comp } = this; comp.toggleCss(CSS_CELL, true); comp.toggleCss(CSS_CELL_NOT_INLINE_EDITING, true); const autoHeight = this.column.isAutoHeight() == true; comp.toggleCss(CSS_AUTO_HEIGHT, autoHeight); comp.toggleCss(CSS_NORMAL_HEIGHT, !autoHeight); } onColumnHover() { this.beans.colHover?.onCellColumnHover(this.column, this.comp); } onColDefChanged() { if (!this.comp) { return; } if (this.column.isTooltipEnabled()) { this.disableTooltipFeature(); this.enableTooltipFeature(); } else { this.disableTooltipFeature(); } this.setWrapText(); if (this.editSvc?.isEditing(this)) { this.editSvc?.handleColDefChanged(this); } else { this.refreshOrDestroyCell({ force: true, suppressFlash: true }); } } setWrapText() { const value = this.column.getColDef().wrapText == true; this.comp.toggleCss(CSS_CELL_WRAP_TEXT, value); } dispatchCellContextMenuEvent(event) { const colDef = this.column.getColDef(); const cellContextMenuEvent = this.createEvent(event, "cellContextMenu"); const { beans } = this; beans.eventSvc.dispatchEvent(cellContextMenuEvent); if (colDef.onCellContextMenu) { window.setTimeout(() => { beans.frameworkOverrides.wrapOutgoing(() => { colDef.onCellContextMenu(cellContextMenuEvent); }); }, 0); } } getCellRenderer() { return this.comp?.getCellRenderer() ?? null; } destroy() { this.onCompAttachedFuncs = []; this.onEditorAttachedFuncs = []; if (this.isCellFocused() && this.hasBrowserFocus()) { this.beans.focusSvc.attemptToRecoverFocus(); } super.destroy(); } hasBrowserFocus() { return this.eGui?.contains(_getActiveDomElement(this.beans)) ?? false; } createSelectionCheckbox() { const cbSelectionComponent = this.beans.selectionSvc?.createCheckboxSelectionComponent(); if (!cbSelectionComponent) { return; } this.beans.context.createBean(cbSelectionComponent); cbSelectionComponent.init({ rowNode: this.rowNode, column: this.column }); return cbSelectionComponent; } createDndSource() { const dndSourceComp = this.beans.registry.createDynamicBean("dndSourceComp", false, this.rowNode, this.column, this.eGui); if (dndSourceComp) { this.beans.context.createBean(dndSourceComp); } return dndSourceComp; } registerRowDragger(customElement, dragStartPixels, alwaysVisible) { if (this.customRowDragComp) { this.customRowDragComp.setDragElement(customElement, dragStartPixels); return; } const newComp = this.createRowDragComp(customElement, dragStartPixels, alwaysVisible); if (newComp) { this.customRowDragComp = newComp; this.addDestroyFunc(() => { this.beans.context.destroyBean(newComp); this.customRowDragComp = null; }); newComp.refreshVisibility(); } } createRowDragComp(customElement, dragStartPixels, alwaysVisible) { const rowDragComp = this.beans.rowDragSvc?.createRowDragCompForCell(this.rowNode, this.column, () => this.value, customElement, dragStartPixels, alwaysVisible); if (!rowDragComp) { return; } this.beans.context.createBean(rowDragComp); return rowDragComp; } cellEditorAttached() { for (const func of this.onEditorAttachedFuncs) { func(); } this.onEditorAttachedFuncs = []; } setFocusedCellPosition(_cellPosition) {} getFocusedCellPosition() { return this.cellPosition; } refreshAriaRowIndex() { if (!isRowNumberCol(this.column) || !this.eGui) { return; } const { ariaRowIndex } = this.rowCtrl; if (ariaRowIndex != null) { _setAriaRowIndex(this.eGui, ariaRowIndex); } } getRootElement() { return this.eGui; } }; function processClassRules(expressionSvc, previousClassRules, classRules, params, onApplicableClass, onNotApplicableClass) { if (classRules == null && previousClassRules == null) { return; } const classesToApply = {}; const classesToRemove = {}; const forEachSingleClass = (className, callback) => { for (const singleClass of className.split(" ")) { if (singleClass.trim() == "") { continue; } callback(singleClass); } }; if (classRules) { const classNames = Object.keys(classRules); for (let i = 0;i < classNames.length; i++) { const className = classNames[i]; const rule = classRules[className]; let resultOfRule; if (typeof rule === "string") { resultOfRule = expressionSvc ? expressionSvc.evaluate(rule, params) : true; } else if (typeof rule === "function") { resultOfRule = rule(params); } forEachSingleClass(className, (singleClass) => { if (resultOfRule) { classesToApply[singleClass] = true; } else { classesToRemove[singleClass] = true; } }); } } if (previousClassRules && onNotApplicableClass) { for (const className of Object.keys(previousClassRules)) { forEachSingleClass(className, (singleClass) => { if (!classesToApply[singleClass]) { classesToRemove[singleClass] = true; } }); } } if (onNotApplicableClass) { Object.keys(classesToRemove).forEach(onNotApplicableClass); } Object.keys(classesToApply).forEach(onApplicableClass); } function calculateRowLevel(rowNode) { if (rowNode.group) { return rowNode.level; } const parent = rowNode.parent; return parent ? parent.level + 1 : 0; } var instanceIdSequence5 = 0; var RowCtrl = class extends BeanStub { constructor(rowNode, beans, animateIn, useAnimationFrameForCreate, printLayout) { super(); this.rowNode = rowNode; this.useAnimationFrameForCreate = useAnimationFrameForCreate; this.printLayout = printLayout; this.focusEventWhileNotReady = null; this.allRowGuis = []; this.active = true; this.centerCellCtrls = { list: [], map: {} }; this.leftCellCtrls = { list: [], map: {} }; this.rightCellCtrls = { list: [], map: {} }; this.slideInAnimation = { left: false, center: false, right: false, fullWidth: false }; this.fadeInAnimation = { left: false, center: false, right: false, fullWidth: false }; this.rowDragComps = []; this.lastMouseDownOnDragger = false; this.emptyStyle = {}; this.updateColumnListsPending = false; this.rowId = null; this.ariaRowIndex = null; this.businessKey = null; this.beans = beans; this.gos = beans.gos; this.paginationPage = beans.pagination?.getCurrentPage() ?? 0; this.suppressRowTransform = this.gos.get("suppressRowTransform"); this.instanceId = rowNode.id + "-" + instanceIdSequence5++; this.rowId = _escapeString(rowNode.id); this.initRowBusinessKey(); this.rowFocused = beans.focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned); this.rowLevel = calculateRowLevel(this.rowNode); this.setRowType(); this.setAnimateFlags(animateIn); this.rowStyles = this.processStylesFromGridOptions(); this.rowEditStyleFeature = beans.editSvc?.createRowStyleFeature(this); this.addListeners(); } initRowBusinessKey() { this.businessKeyForNodeFunc = this.gos.get("getBusinessKeyForNode"); this.updateRowBusinessKey(); } updateRowBusinessKey() { if (typeof this.businessKeyForNodeFunc !== "function") { return; } const businessKey = this.businessKeyForNodeFunc(this.rowNode); this.businessKey = _escapeString(businessKey); } updateGui(containerType, gui) { if (containerType === "left") { this.leftGui = gui; } else if (containerType === "right") { this.rightGui = gui; } else if (containerType === "fullWidth") { this.fullWidthGui = gui; } else { this.centerGui = gui; } } setComp(rowComp, element, containerType, compBean) { const { context, rowRenderer } = this.beans; compBean = setupCompBean(this, context, compBean); const gui = { rowComp, element, containerType, compBean }; this.allRowGuis.push(gui); this.updateGui(containerType, gui); this.initialiseRowComp(gui); const rowNode = this.rowNode; const isSsrmLoadingRow = this.rowType === "FullWidthLoading" || rowNode.stub; const isIrmLoadingRow = !rowNode.data && this.beans.rowModel.getType() === "infinite"; if (!isSsrmLoadingRow && !isIrmLoadingRow && !rowNode.rowPinned) { rowRenderer.dispatchFirstDataRenderedEvent(); } this.setupFocus(); } unsetComp(containerType) { this.allRowGuis = this.allRowGuis.filter((rowGui) => rowGui.containerType !== containerType); this.updateGui(containerType, undefined); } isCacheable() { return this.rowType === "FullWidthDetail" && this.gos.get("keepDetailRows"); } setCached(cached) { const displayValue = cached ? "none" : ""; for (const rg of this.allRowGuis) { rg.element.style.display = displayValue; } } initialiseRowComp(gui) { const gos = this.gos; this.onSuppressCellFocusChanged(this.beans.gos.get("suppressCellFocus")); this.listenOnDomOrder(gui); this.onRowHeightChanged(gui); this.updateRowIndexes(gui); this.setFocusedClasses(gui); this.setStylesFromGridOptions(false, gui); if (_isRowSelection(gos) && this.rowNode.selectable) { this.onRowSelected(gui); } this.updateColumnLists(!this.useAnimationFrameForCreate); const comp = gui.rowComp; const initialRowClasses = this.getInitialRowClasses(gui.containerType); for (const name of initialRowClasses) { comp.toggleCss(name, true); } this.executeSlideAndFadeAnimations(gui); if (this.rowNode.group) { _setAriaExpanded(gui.element, !!this.rowNode.expanded); } this.setRowCompRowId(comp); this.setRowCompRowBusinessKey(comp); _setDomData(gos, gui.element, DOM_DATA_KEY_ROW_CTRL, this); gui.compBean.addDestroyFunc(() => _setDomData(gos, gui.element, DOM_DATA_KEY_ROW_CTRL, null)); if (this.useAnimationFrameForCreate) { this.beans.animationFrameSvc.createTask(this.addHoverFunctionality.bind(this, gui), this.rowNode.rowIndex, "p2", false); } else { this.addHoverFunctionality(gui); } if (this.isFullWidth()) { this.setupFullWidth(gui); } if (gos.get("rowDragEntireRow")) { this.addRowDraggerToRow(gui); } if (this.useAnimationFrameForCreate) { this.beans.animationFrameSvc.addDestroyTask(() => { if (!this.isAlive()) { return; } gui.rowComp.toggleCss("ag-after-created", true); }); } this.executeProcessRowPostCreateFunc(); } setRowCompRowBusinessKey(comp) { if (this.businessKey == null) { return; } comp.setRowBusinessKey(this.businessKey); } setRowCompRowId(comp) { const rowId = _escapeString(this.rowNode.id); this.rowId = rowId; if (rowId == null) { return; } comp.setRowId(rowId); } executeSlideAndFadeAnimations(gui) { const { containerType } = gui; const shouldSlide = this.slideInAnimation[containerType]; if (shouldSlide) { _batchCall(() => { this.onTopChanged(); }); this.slideInAnimation[containerType] = false; } const shouldFade = this.fadeInAnimation[containerType]; if (shouldFade) { _batchCall(() => { gui.rowComp.toggleCss("ag-opacity-zero", false); }); this.fadeInAnimation[containerType] = false; } } addRowDraggerToRow(gui) { const rowDragComp = this.beans.rowDragSvc?.createRowDragCompForRow(this.rowNode, gui.element); if (!rowDragComp) { return; } const rowDragBean = this.createBean(rowDragComp, this.beans.context); this.rowDragComps.push(rowDragBean); gui.compBean.addDestroyFunc(() => { this.rowDragComps = this.rowDragComps.filter((r) => r !== rowDragBean); this.rowEditStyleFeature = this.destroyBean(this.rowEditStyleFeature, this.beans.context); this.destroyBean(rowDragBean, this.beans.context); }); } setupFullWidth(gui) { const pinned = this.getPinnedForContainer(gui.containerType); const compDetails = this.createFullWidthCompDetails(gui.element, pinned); gui.rowComp.showFullWidth(compDetails); } getFullWidthCellRenderers() { if (this.gos.get("embedFullWidthRows")) { return this.allRowGuis.map((gui) => gui?.rowComp?.getFullWidthCellRenderer()); } return [this.fullWidthGui?.rowComp?.getFullWidthCellRenderer()]; } executeProcessRowPostCreateFunc() { const func = this.gos.getCallback("processRowPostCreate"); if (!func || !this.areAllContainersReady()) { return; } const params = { eRow: this.centerGui.element, ePinnedLeftRow: this.leftGui ? this.leftGui.element : undefined, ePinnedRightRow: this.rightGui ? this.rightGui.element : undefined, node: this.rowNode, rowIndex: this.rowNode.rowIndex, addRenderedRowListener: this.addEventListener.bind(this) }; func(params); } areAllContainersReady() { const { leftGui, centerGui, rightGui, beans: { visibleCols } } = this; const isLeftReady = !!leftGui || !visibleCols.isPinningLeft(); const isCenterReady = !!centerGui; const isRightReady = !!rightGui || !visibleCols.isPinningRight(); return isLeftReady && isCenterReady && isRightReady; } isNodeFullWidthCell() { if (this.rowNode.detail) { return true; } const isFullWidthCellFunc = this.beans.gos.getCallback("isFullWidthRow"); return isFullWidthCellFunc ? isFullWidthCellFunc({ rowNode: this.rowNode }) : false; } setRowType() { const { rowNode, gos, beans: { colModel } } = this; const isStub = rowNode.stub && !gos.get("suppressServerSideFullWidthLoadingRow") && !gos.get("groupHideOpenParents"); const isFullWidthCell = this.isNodeFullWidthCell(); const isDetailCell = gos.get("masterDetail") && rowNode.detail; const pivotMode = colModel.isPivotMode(); const isFullWidthGroup = _isFullWidthGroupRow(gos, rowNode, pivotMode); if (isStub) { this.rowType = "FullWidthLoading"; } else if (isDetailCell) { this.rowType = "FullWidthDetail"; } else if (isFullWidthCell) { this.rowType = "FullWidth"; } else if (isFullWidthGroup) { this.rowType = "FullWidthGroup"; } else { this.rowType = "Normal"; } } updateColumnLists(suppressAnimationFrame = false, useFlushSync = false) { if (this.isFullWidth()) { return; } const { animationFrameSvc } = this.beans; const noAnimation = !animationFrameSvc?.active || suppressAnimationFrame || this.printLayout; if (noAnimation) { this.updateColumnListsImpl(useFlushSync); return; } if (this.updateColumnListsPending) { return; } animationFrameSvc.createTask(() => { if (!this.active) { return; } this.updateColumnListsImpl(true); }, this.rowNode.rowIndex, "p1", false); this.updateColumnListsPending = true; } getNewCellCtrl(col) { const isCellSpan = this.beans.rowSpanSvc?.isCellSpanning(col, this.rowNode); if (isCellSpan) { return; } return new CellCtrl(col, this.rowNode, this.beans, this); } isCorrectCtrlForSpan(cell) { return !this.beans.rowSpanSvc?.isCellSpanning(cell.column, this.rowNode); } createCellCtrls(prev, cols, pinned = null) { const res = { list: [], map: {} }; const addCell = (colInstanceId, cellCtrl, index) => { if (index != null) { res.list.splice(index, 0, cellCtrl); } else { res.list.push(cellCtrl); } res.map[colInstanceId] = cellCtrl; }; const colsFromPrev = []; for (const col of cols) { const colInstanceId = col.getInstanceId(); let cellCtrl = prev.map[colInstanceId]; if (cellCtrl && !this.isCorrectCtrlForSpan(cellCtrl)) { cellCtrl.destroy(); cellCtrl = undefined; } if (!cellCtrl) { cellCtrl = this.getNewCellCtrl(col); } if (!cellCtrl) { continue; } addCell(colInstanceId, cellCtrl); } for (const prevCellCtrl of prev.list) { const colInstanceId = prevCellCtrl.column.getInstanceId(); const cellInResult = res.map[colInstanceId] != null; if (cellInResult) { continue; } const keepCell = !this.isCellEligibleToBeRemoved(prevCellCtrl, pinned); if (keepCell) { colsFromPrev.push([colInstanceId, prevCellCtrl]); } else { prevCellCtrl.destroy(); } } if (colsFromPrev.length) { for (const [colInstanceId, cellCtrl] of colsFromPrev) { const index = res.list.findIndex((ctrl) => ctrl.column.getLeft() > cellCtrl.column.getLeft()); const normalisedIndex = index === -1 ? undefined : Math.max(index - 1, 0); addCell(colInstanceId, cellCtrl, normalisedIndex); } } const { focusSvc, visibleCols } = this.beans; const focusedCell = focusSvc.getFocusedCell(); if (focusedCell && focusedCell.column.getPinned() == pinned) { const focusedColInstanceId = focusedCell.column.getInstanceId(); const focusedCellCtrl = res.map[focusedColInstanceId]; if (!focusedCellCtrl && visibleCols.allCols.includes(focusedCell.column)) { const cellCtrl = this.createFocusedCellCtrl(); if (cellCtrl) { const index = res.list.findIndex((ctrl) => ctrl.column.getLeft() > cellCtrl.column.getLeft()); const normalisedIndex = index === -1 ? undefined : Math.max(index - 1, 0); addCell(focusedColInstanceId, cellCtrl, normalisedIndex); } } } return res; } createFocusedCellCtrl() { const { focusSvc, rowSpanSvc } = this.beans; const focusedCell = focusSvc.getFocusedCell(); if (!focusedCell) { return; } const focusedSpan = rowSpanSvc?.getCellSpan(focusedCell.column, this.rowNode); if (focusedSpan) { if (focusedSpan.firstNode !== this.rowNode || !focusedSpan.doesSpanContain(focusedCell)) { return; } } else if (!focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned)) { return; } return this.getNewCellCtrl(focusedCell.column); } updateColumnListsImpl(useFlushSync) { this.updateColumnListsPending = false; this.createAllCellCtrls(); this.setCellCtrls(useFlushSync); } setCellCtrls(useFlushSync) { for (const item of this.allRowGuis) { const cellControls = this.getCellCtrlsForContainer(item.containerType); item.rowComp.setCellCtrls(cellControls, useFlushSync); } } getCellCtrlsForContainer(containerType) { switch (containerType) { case "left": return this.leftCellCtrls.list; case "right": return this.rightCellCtrls.list; case "fullWidth": return []; case "center": return this.centerCellCtrls.list; } } createAllCellCtrls() { const colViewport = this.beans.colViewport; const presentedColsService = this.beans.visibleCols; if (this.printLayout) { this.centerCellCtrls = this.createCellCtrls(this.centerCellCtrls, presentedColsService.allCols); this.leftCellCtrls = { list: [], map: {} }; this.rightCellCtrls = { list: [], map: {} }; } else { const centerCols = colViewport.getColsWithinViewport(this.rowNode); this.centerCellCtrls = this.createCellCtrls(this.centerCellCtrls, centerCols); const leftCols = presentedColsService.getLeftColsForRow(this.rowNode); this.leftCellCtrls = this.createCellCtrls(this.leftCellCtrls, leftCols, "left"); const rightCols = presentedColsService.getRightColsForRow(this.rowNode); this.rightCellCtrls = this.createCellCtrls(this.rightCellCtrls, rightCols, "right"); } } isCellEligibleToBeRemoved(cellCtrl, nextContainerPinned) { const REMOVE_CELL = true; const KEEP_CELL = false; const { column } = cellCtrl; if (column.getPinned() != nextContainerPinned) { return REMOVE_CELL; } if (!this.isCorrectCtrlForSpan(cellCtrl)) { return REMOVE_CELL; } const { visibleCols, editSvc } = this.beans; const editing = editSvc?.isEditing(cellCtrl); const focused = cellCtrl.isCellFocused(); const mightWantToKeepCell = editing || focused; if (mightWantToKeepCell) { const displayedColumns = visibleCols.allCols; const cellStillDisplayed = displayedColumns.indexOf(column) >= 0; return cellStillDisplayed ? KEEP_CELL : REMOVE_CELL; } return REMOVE_CELL; } getDomOrder() { const isEnsureDomOrder = this.gos.get("ensureDomOrder"); return isEnsureDomOrder || _isDomLayout(this.gos, "print"); } listenOnDomOrder(gui) { const listener = () => { gui.rowComp.setDomOrder(this.getDomOrder()); }; gui.compBean.addManagedPropertyListeners(["domLayout", "ensureDomOrder"], listener); } setAnimateFlags(animateIn) { if (this.rowNode.sticky || !animateIn) { return; } const oldRowTopExists = _exists(this.rowNode.oldRowTop); const { visibleCols } = this.beans; const pinningLeft = visibleCols.isPinningLeft(); const pinningRight = visibleCols.isPinningRight(); if (oldRowTopExists) { const { slideInAnimation } = this; if (this.isFullWidth() && !this.gos.get("embedFullWidthRows")) { slideInAnimation.fullWidth = true; return; } slideInAnimation.center = true; slideInAnimation.left = pinningLeft; slideInAnimation.right = pinningRight; } else { const { fadeInAnimation } = this; if (this.isFullWidth() && !this.gos.get("embedFullWidthRows")) { fadeInAnimation.fullWidth = true; return; } fadeInAnimation.center = true; fadeInAnimation.left = pinningLeft; fadeInAnimation.right = pinningRight; } } isFullWidth() { return this.rowType !== "Normal"; } refreshFullWidth() { const tryRefresh = (gui, pinned) => { if (!gui) { return true; } return gui.rowComp.refreshFullWidth(() => { const compDetails = this.createFullWidthCompDetails(gui.element, pinned); return compDetails.params; }); }; const fullWidthSuccess = tryRefresh(this.fullWidthGui, null); const centerSuccess = tryRefresh(this.centerGui, null); const leftSuccess = tryRefresh(this.leftGui, "left"); const rightSuccess = tryRefresh(this.rightGui, "right"); const allFullWidthRowsRefreshed = fullWidthSuccess && centerSuccess && leftSuccess && rightSuccess; return allFullWidthRowsRefreshed; } addListeners() { const { beans, gos, rowNode } = this; const { expansionSvc, eventSvc, context, rowSpanSvc } = beans; this.addManagedListeners(this.rowNode, { heightChanged: () => this.onRowHeightChanged(), rowSelected: () => this.onRowSelected(), rowIndexChanged: this.onRowIndexChanged.bind(this), topChanged: this.onTopChanged.bind(this), ...expansionSvc?.getRowExpandedListeners(this) ?? {} }); if (rowNode.detail) { this.addManagedListeners(rowNode.parent, { dataChanged: this.onRowNodeDataChanged.bind(this) }); } this.addManagedListeners(rowNode, { dataChanged: this.onRowNodeDataChanged.bind(this), cellChanged: this.postProcessCss.bind(this), rowHighlightChanged: this.onRowNodeHighlightChanged.bind(this), draggingChanged: this.postProcessRowDragging.bind(this), uiLevelChanged: this.onUiLevelChanged.bind(this), rowPinned: this.onRowPinned.bind(this) }); this.addManagedListeners(eventSvc, { paginationPixelOffsetChanged: this.onPaginationPixelOffsetChanged.bind(this), heightScaleChanged: this.onTopChanged.bind(this), displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this), virtualColumnsChanged: this.onVirtualColumnsChanged.bind(this), cellFocused: this.onCellFocusChanged.bind(this), cellFocusCleared: this.onCellFocusChanged.bind(this), paginationChanged: this.onPaginationChanged.bind(this), modelUpdated: this.refreshFirstAndLastRowStyles.bind(this), columnMoved: () => this.updateColumnLists() }); if (rowSpanSvc) { this.addManagedListeners(rowSpanSvc, { spannedCellsUpdated: ({ pinned }) => { if (pinned && !rowNode.rowPinned) { return; } this.updateColumnLists(); } }); } this.addDestroyFunc(() => { this.rowDragComps = this.destroyBeans(this.rowDragComps, context); this.tooltipFeature = this.destroyBean(this.tooltipFeature, context); this.rowEditStyleFeature = this.destroyBean(this.rowEditStyleFeature, context); }); this.addManagedPropertyListeners(["rowStyle", "getRowStyle", "rowClass", "getRowClass", "rowClassRules"], this.postProcessCss.bind(this)); this.addManagedPropertyListener("rowDragEntireRow", () => { const useRowDragEntireRow = gos.get("rowDragEntireRow"); if (useRowDragEntireRow) { for (const gui of this.allRowGuis) { this.addRowDraggerToRow(gui); } return; } this.rowDragComps = this.destroyBeans(this.rowDragComps, context); }); this.addListenersForCellComps(); } addListenersForCellComps() { this.addManagedListeners(this.rowNode, { rowIndexChanged: () => { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onRowIndexChanged(); } }, cellChanged: (event) => { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onCellChanged(event); } } }); } onRowPinned() { for (const gui of this.allRowGuis) { gui.rowComp.toggleCss("ag-row-pinned-source", !!this.rowNode.pinnedSibling); } } onRowNodeDataChanged(event) { this.refreshRow({ suppressFlash: !event.update, newData: !event.update }); } refreshRow(params) { const fullWidthChanged = this.isFullWidth() !== !!this.isNodeFullWidthCell(); if (fullWidthChanged) { this.beans.rowRenderer.redrawRow(this.rowNode); return; } if (this.isFullWidth()) { const refresh = this.refreshFullWidth(); if (!refresh) { this.beans.rowRenderer.redrawRow(this.rowNode); } return; } for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.refreshCell(params); } for (const gui of this.allRowGuis) { this.setRowCompRowId(gui.rowComp); this.updateRowBusinessKey(); this.setRowCompRowBusinessKey(gui.rowComp); } this.onRowSelected(); this.postProcessCss(); } postProcessCss() { this.setStylesFromGridOptions(true); this.postProcessClassesFromGridOptions(); this.postProcessRowClassRules(); this.rowEditStyleFeature?.applyRowStyles(); this.postProcessRowDragging(); } onRowNodeHighlightChanged() { const rowDropHighlightSvc = this.beans.rowDropHighlightSvc; const highlighted = rowDropHighlightSvc?.row === this.rowNode ? rowDropHighlightSvc.position : "none"; const aboveOn = highlighted === "above"; const insideOn = highlighted === "inside"; const belowOn = highlighted === "below"; const highlightActive = highlighted !== "none"; const dropEdge = aboveOn || belowOn; const uiLevel = this.rowNode.uiLevel; const shouldIndent = dropEdge && uiLevel > 0; const highlightLevel = shouldIndent ? uiLevel.toString() : "0"; for (const gui of this.allRowGuis) { const rowComp = gui.rowComp; rowComp.toggleCss("ag-row-highlight-above", aboveOn); rowComp.toggleCss("ag-row-highlight-inside", insideOn); rowComp.toggleCss("ag-row-highlight-below", belowOn); rowComp.toggleCss("ag-row-highlight-indent", shouldIndent); if (highlightActive) { gui.element.style.setProperty("--ag-row-highlight-level", highlightLevel); } else { gui.element.style.removeProperty("--ag-row-highlight-level"); } } } postProcessRowDragging() { const dragging = this.rowNode.dragging; for (const gui of this.allRowGuis) { gui.rowComp.toggleCss("ag-row-dragging", dragging); } } onDisplayedColumnsChanged() { this.updateColumnLists(true); this.beans.rowAutoHeight?.requestCheckAutoHeight(); } onVirtualColumnsChanged() { this.updateColumnLists(false, true); } getRowPosition() { return { rowPinned: _makeNull(this.rowNode.rowPinned), rowIndex: this.rowNode.rowIndex }; } onKeyboardNavigate(keyboardEvent) { const groupInfo = this.findFullWidthInfoForEvent(keyboardEvent); if (!groupInfo) { return; } const { rowGui, column } = groupInfo; const currentFullWidthContainer = rowGui.element; const isFullWidthContainerFocused = currentFullWidthContainer === keyboardEvent.target; if (!isFullWidthContainerFocused) { return; } const node = this.rowNode; const { focusSvc, navigation } = this.beans; const lastFocusedCell = focusSvc.getFocusedCell(); const cellPosition = { rowIndex: node.rowIndex, rowPinned: node.rowPinned, column: lastFocusedCell?.column ?? column }; navigation?.navigateToNextCell(keyboardEvent, keyboardEvent.key, cellPosition, true); keyboardEvent.preventDefault(); } onTabKeyDown(keyboardEvent) { if (keyboardEvent.defaultPrevented || _isStopPropagationForAgGrid(keyboardEvent)) { return; } const currentFullWidthComp = this.allRowGuis.find((c) => c.element.contains(keyboardEvent.target)); const currentFullWidthContainer = currentFullWidthComp ? currentFullWidthComp.element : null; const isFullWidthContainerFocused = currentFullWidthContainer === keyboardEvent.target; const activeEl = _getActiveDomElement(this.beans); let isDetailGridCellFocused = false; if (currentFullWidthContainer && activeEl) { isDetailGridCellFocused = currentFullWidthContainer.contains(activeEl) && activeEl.classList.contains("ag-cell"); } let nextEl = null; if (!isFullWidthContainerFocused && !isDetailGridCellFocused) { nextEl = _findNextFocusableElement(this.beans, currentFullWidthContainer, false, keyboardEvent.shiftKey); } if (this.isFullWidth() && isFullWidthContainerFocused || !nextEl) { this.beans.navigation?.onTabKeyDown(this, keyboardEvent); } } getFullWidthElement() { if (this.fullWidthGui) { return this.fullWidthGui.element; } return null; } getRowYPosition() { const displayedEl = this.allRowGuis.find((el) => _isVisible(el.element))?.element; if (displayedEl) { return displayedEl.getBoundingClientRect().top; } return 0; } onSuppressCellFocusChanged(suppressCellFocus) { const tabIndex = this.isFullWidth() && suppressCellFocus ? undefined : this.gos.get("tabIndex"); for (const gui of this.allRowGuis) { _addOrRemoveAttribute(gui.element, "tabindex", tabIndex); } } setupFocus() { if (!this.isFullWidth()) { return; } this.restoreFullWidthFocus(true); this.onFullWidthRowFocused(this.focusEventWhileNotReady ?? undefined); } restoreFullWidthFocus(waitForRender = false) { const { focusSvc, editSvc } = this.beans; if (editSvc?.isEditing(this)) { return; } if (!focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned) || !focusSvc.shouldTakeFocus()) { return; } const targetGui = this.getFullWidthRowGuiForFocus(); if (!targetGui) { return; } const focus = () => { if (!this.isAlive()) { return; } if (focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned)) { targetGui.element.focus({ preventScroll: true }); } }; if (waitForRender) { setTimeout(focus, 0); return; } focus(); } getFullWidthRowGuiForFocus(event) { if (this.fullWidthGui) { return this.fullWidthGui; } const focusedCell = this.beans.focusSvc.getFocusedCell(); const column = this.beans.colModel.getCol(event?.column ?? focusedCell?.column); if (!column) { return; } const pinned = column?.pinned; if (pinned === "right") { return this.rightGui; } if (pinned === "left") { return this.leftGui; } return this.centerGui; } setFullWidthRowFocusedClass(targetGui, isFocused) { this.forEachGui(undefined, (gui) => { gui.element.classList.toggle("ag-full-width-focus", isFocused && gui === targetGui); }); } onFullWidthRowFocused(event) { const { focusSvc } = this.beans; const isFocused = this.isFullWidth() && focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned); if (!isFocused) { this.setFullWidthRowFocusedClass(undefined, false); return; } const targetGui = this.getFullWidthRowGuiForFocus(event); if (!targetGui) { if (event) { this.focusEventWhileNotReady = event; } this.setFullWidthRowFocusedClass(undefined, false); return; } this.setFullWidthRowFocusedClass(targetGui, true); this.focusEventWhileNotReady = null; if (event?.forceBrowserFocus) { targetGui.element.focus({ preventScroll: true }); } } recreateCell(cellCtrl) { this.centerCellCtrls = this.removeCellCtrl(this.centerCellCtrls, cellCtrl); this.leftCellCtrls = this.removeCellCtrl(this.leftCellCtrls, cellCtrl); this.rightCellCtrls = this.removeCellCtrl(this.rightCellCtrls, cellCtrl); cellCtrl.destroy(); this.updateColumnLists(); } removeCellCtrl(prev, cellCtrlToRemove) { const res = { list: [], map: {} }; for (const cellCtrl of prev.list) { if (cellCtrl === cellCtrlToRemove) { continue; } res.list.push(cellCtrl); res.map[cellCtrl.column.getInstanceId()] = cellCtrl; } return res; } onMouseEvent(eventName, mouseEvent) { switch (eventName) { case "dblclick": this.onRowDblClick(mouseEvent); break; case "click": this.onRowClick(mouseEvent); break; case "pointerdown": case "touchstart": case "mousedown": this.onRowMouseDown(mouseEvent); break; } } createRowEvent(type, domEvent) { const { rowNode } = this; return _addGridCommonParams(this.gos, { type, node: rowNode, data: rowNode.data, rowIndex: rowNode.rowIndex, rowPinned: rowNode.rowPinned, event: domEvent }); } createRowEventWithSource(type, domEvent) { const event = this.createRowEvent(type, domEvent); event.source = this; return event; } onRowDblClick(mouseEvent) { if (_isStopPropagationForAgGrid(mouseEvent)) { return; } const rowEvent = this.createRowEventWithSource("rowDoubleClicked", mouseEvent); rowEvent.isEventHandlingSuppressed = this.isSuppressMouseEvent(mouseEvent); this.beans.eventSvc.dispatchEvent(rowEvent); } findFullWidthInfoForEvent(event) { if (!event) { return; } const rowGui = this.findFullWidthRowGui(event.target); const column = this.getColumnForFullWidth(rowGui); if (!rowGui || !column) { return; } return { rowGui, column }; } findFullWidthRowGui(target) { return this.allRowGuis.find((c) => c.element.contains(target)); } getColumnForFullWidth(fullWidthRowGui) { const { visibleCols } = this.beans; switch (fullWidthRowGui?.containerType) { case "center": return visibleCols.centerCols[0]; case "left": return visibleCols.leftCols[0]; case "right": return visibleCols.rightCols[0]; default: return visibleCols.allCols[0]; } } onRowMouseDown(mouseEvent) { this.lastMouseDownOnDragger = _isElementChildOfClass(mouseEvent.target, "ag-row-drag", 3); if (!this.isFullWidth() || this.isSuppressMouseEvent(mouseEvent)) { return; } const { rangeSvc, focusSvc } = this.beans; rangeSvc?.removeAllCellRanges(); const groupInfo = this.findFullWidthInfoForEvent(mouseEvent); if (!groupInfo) { return; } const { rowGui, column } = groupInfo; const element = rowGui.element; const target = mouseEvent.target; const node = this.rowNode; let forceBrowserFocus = mouseEvent.defaultPrevented || _isBrowserSafari(); if (element && element.contains(target) && _isFocusableFormField(target)) { forceBrowserFocus = false; } focusSvc.setFocusedCell({ rowIndex: node.rowIndex, column, rowPinned: node.rowPinned, forceBrowserFocus }); } isSuppressMouseEvent(mouseEvent) { const { gos, rowNode } = this; if (this.isFullWidth()) { const fullWidthRowGui = this.findFullWidthRowGui(mouseEvent.target); return _suppressFullWidthMouseEvent(gos, fullWidthRowGui?.rowComp.getFullWidthCellRendererParams(), rowNode, mouseEvent); } const cellCtrl = _getCellCtrlForEventTarget(gos, mouseEvent.target); return cellCtrl != null && _suppressCellMouseEvent(gos, cellCtrl.column, rowNode, mouseEvent); } onRowClick(mouseEvent) { const stop = _isStopPropagationForAgGrid(mouseEvent) || this.lastMouseDownOnDragger; if (stop) { return; } const isSuppressMouseEvent = this.isSuppressMouseEvent(mouseEvent); const { eventSvc, selectionSvc } = this.beans; const rowEvent = this.createRowEventWithSource("rowClicked", mouseEvent); rowEvent.isEventHandlingSuppressed = isSuppressMouseEvent; eventSvc.dispatchEvent(rowEvent); if (isSuppressMouseEvent) { return; } selectionSvc?.handleSelectionEvent(mouseEvent, this.rowNode, "rowClicked"); } setupDetailRowAutoHeight(eDetailGui) { if (this.rowType !== "FullWidthDetail") { return; } this.beans.masterDetailSvc?.setupDetailRowAutoHeight(this, eDetailGui); } createFullWidthCompDetails(eRow, pinned) { const { gos, rowNode } = this; const params = _addGridCommonParams(gos, { fullWidth: true, data: rowNode.data, node: rowNode, value: rowNode.key, valueFormatted: rowNode.key, eGridCell: eRow, eParentOfValue: eRow, pinned, addRenderedRowListener: this.addEventListener.bind(this), registerRowDragger: (rowDraggerElement, dragStartPixels, value, rowDragEntireRow) => this.addFullWidthRowDragging(rowDraggerElement, dragStartPixels, value, rowDragEntireRow), setTooltip: (value, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); this.setupFullWidthRowTooltip(value, shouldDisplayTooltip); } }); const compFactory = this.beans.userCompFactory; switch (this.rowType) { case "FullWidthDetail": return _getFullWidthDetailCellRendererDetails(compFactory, params); case "FullWidthGroup": { const { value, valueFormatted } = this.beans.valueSvc.getValueForDisplay({ node: this.rowNode, includeValueFormatted: true, from: "edit" }); params.value = value; params.valueFormatted = valueFormatted; return _getFullWidthGroupCellRendererDetails(compFactory, params); } case "FullWidthLoading": return _getFullWidthLoadingCellRendererDetails(compFactory, params); default: return _getFullWidthCellRendererDetails(compFactory, params); } } setupFullWidthRowTooltip(value, shouldDisplayTooltip) { if (!this.fullWidthGui) { return; } this.tooltipFeature = this.beans.tooltipSvc?.setupFullWidthRowTooltip(this.tooltipFeature, this, value, shouldDisplayTooltip); } addFullWidthRowDragging(rowDraggerElement, dragStartPixels, value = "", alwaysVisible) { const { rowDragSvc, context } = this.beans; if (!rowDragSvc || !this.isFullWidth()) { return; } const rowDragComp = rowDragSvc.createRowDragComp(() => value, this.rowNode, undefined, rowDraggerElement, dragStartPixels, alwaysVisible); this.createBean(rowDragComp, context); this.addDestroyFunc(() => { this.destroyBean(rowDragComp, context); }); } onUiLevelChanged() { const newLevel = calculateRowLevel(this.rowNode); if (this.rowLevel != newLevel) { const classToAdd = "ag-row-level-" + newLevel; const classToRemove = "ag-row-level-" + this.rowLevel; for (const gui of this.allRowGuis) { gui.rowComp.toggleCss(classToAdd, true); gui.rowComp.toggleCss(classToRemove, false); } } this.rowLevel = newLevel; } isFirstRowOnPage() { return this.rowNode.rowIndex === this.beans.pageBounds.getFirstRow(); } isLastRowOnPage() { return this.rowNode.rowIndex === this.beans.pageBounds.getLastRow(); } refreshFirstAndLastRowStyles() { const newFirst = this.isFirstRowOnPage(); const newLast = this.isLastRowOnPage(); if (this.firstRowOnPage !== newFirst) { this.firstRowOnPage = newFirst; for (const gui of this.allRowGuis) { gui.rowComp.toggleCss("ag-row-first", newFirst); } } if (this.lastRowOnPage !== newLast) { this.lastRowOnPage = newLast; for (const gui of this.allRowGuis) { gui.rowComp.toggleCss("ag-row-last", newLast); } } } getAllCellCtrls() { if (this.leftCellCtrls.list.length === 0 && this.rightCellCtrls.list.length === 0) { return this.centerCellCtrls.list; } const res = [...this.centerCellCtrls.list, ...this.leftCellCtrls.list, ...this.rightCellCtrls.list]; return res; } postProcessClassesFromGridOptions() { const cssClasses = []; this.beans.rowStyleSvc?.processClassesFromGridOptions(cssClasses, this.rowNode); if (!cssClasses.length) { return; } for (const classStr of cssClasses) { for (const c of this.allRowGuis) { c.rowComp.toggleCss(classStr, true); } } } postProcessRowClassRules() { this.beans.rowStyleSvc?.processRowClassRules(this.rowNode, (className) => { for (const gui of this.allRowGuis) { gui.rowComp.toggleCss(className, true); } }, (className) => { for (const gui of this.allRowGuis) { gui.rowComp.toggleCss(className, false); } }); } setStylesFromGridOptions(updateStyles, gui) { if (updateStyles) { this.rowStyles = this.processStylesFromGridOptions(); } this.forEachGui(gui, (gui2) => gui2.rowComp.setUserStyles(this.rowStyles)); } getPinnedForContainer(rowContainerType) { if (rowContainerType === "left" || rowContainerType === "right") { return rowContainerType; } return null; } getInitialRowClasses(rowContainerType) { const pinned = this.getPinnedForContainer(rowContainerType); const fullWidthRow = this.isFullWidth(); const { rowNode, beans } = this; const classes = []; classes.push("ag-row"); classes.push(this.rowFocused ? "ag-row-focus" : "ag-row-no-focus"); if (this.fadeInAnimation[rowContainerType]) { classes.push("ag-opacity-zero"); } classes.push(rowNode.rowIndex % 2 === 0 ? "ag-row-even" : "ag-row-odd"); if (rowNode.isRowPinned()) { classes.push("ag-row-pinned"); if (beans.pinnedRowModel?.isManual()) { classes.push("ag-row-pinned-manual"); } } if (!rowNode.isRowPinned() && rowNode.pinnedSibling) { classes.push("ag-row-pinned-source"); } if (rowNode.isSelected()) { classes.push("ag-row-selected"); } if (rowNode.footer) { classes.push("ag-row-footer"); } classes.push("ag-row-level-" + this.rowLevel); if (rowNode.stub) { classes.push("ag-row-loading"); } if (fullWidthRow) { classes.push("ag-full-width-row"); } beans.expansionSvc?.addExpandedCss(classes, rowNode); if (rowNode.dragging) { classes.push("ag-row-dragging"); } const { rowStyleSvc } = beans; if (rowStyleSvc) { rowStyleSvc.processClassesFromGridOptions(classes, rowNode); rowStyleSvc.preProcessRowClassRules(classes, rowNode); } classes.push(this.printLayout ? "ag-row-position-relative" : "ag-row-position-absolute"); if (this.isFirstRowOnPage()) { classes.push("ag-row-first"); } if (this.isLastRowOnPage()) { classes.push("ag-row-last"); } if (fullWidthRow) { if (pinned === "left") { classes.push("ag-cell-last-left-pinned"); } if (pinned === "right") { classes.push("ag-cell-first-right-pinned"); } } return classes; } processStylesFromGridOptions() { return this.beans.rowStyleSvc?.processStylesFromGridOptions(this.rowNode) ?? this.emptyStyle; } onRowSelected(gui) { this.beans.selectionSvc?.onRowCtrlSelected(this, (gui2) => { if (gui2 === this.centerGui || gui2 === this.fullWidthGui) { this.announceDescription(); } }, gui); } announceDescription() { this.beans.selectionSvc?.announceAriaRowSelection(this.rowNode); } addHoverFunctionality(eGui) { if (!this.active) { return; } const { element, compBean } = eGui; const { rowNode, beans, gos } = this; compBean.addManagedListeners(element, { pointerenter: (e) => { if (e.pointerType === "mouse") { rowNode.dispatchRowEvent("mouseEnter"); } }, pointerleave: (e) => { if (e.pointerType === "mouse") { rowNode.dispatchRowEvent("mouseLeave"); } } }); compBean.addManagedListeners(rowNode, { mouseEnter: () => { if (!beans.dragSvc?.dragging && !gos.get("suppressRowHoverHighlight")) { element.classList.add("ag-row-hover"); rowNode.setHovered(true); } }, mouseLeave: () => { this.resetHoveredStatus(element); } }); } resetHoveredStatus(el) { const elements = el ? [el] : this.allRowGuis.map((gui) => gui.element); for (const element of elements) { element.classList.remove("ag-row-hover"); } this.rowNode.setHovered(false); } roundRowTopToBounds(rowTop) { const range = this.beans.ctrlsSvc.getScrollFeature().getApproximateVScollPosition(); const minPixel = this.applyPaginationOffset(range.top, true) - 100; const maxPixel = this.applyPaginationOffset(range.bottom, true) + 100; return Math.min(Math.max(minPixel, rowTop), maxPixel); } forEachGui(gui, callback) { if (gui) { callback(gui); } else { for (const gui2 of this.allRowGuis) { callback(gui2); } } } isRowRendered() { return this.allRowGuis.length > 0; } onRowHeightChanged(gui) { if (this.rowNode.rowHeight == null) { return; } const rowHeight = this.rowNode.rowHeight; const defaultRowHeight = this.beans.environment.getDefaultRowHeight(); const isHeightFromFunc = _isGetRowHeightFunction(this.gos); const heightFromFunc = isHeightFromFunc ? _getRowHeightForNode(this.beans, this.rowNode).height : undefined; const lineHeight = heightFromFunc ? `${Math.min(defaultRowHeight, heightFromFunc) - 2}px` : undefined; this.forEachGui(gui, (gui2) => { gui2.element.style.height = `${rowHeight}px`; if (lineHeight) { gui2.element.style.setProperty("--ag-line-height", lineHeight); } }); } destroyFirstPass(suppressAnimation = false) { this.active = false; const { rowNode } = this; if (!suppressAnimation && _isAnimateRows(this.gos) && !rowNode.sticky) { const rowStillVisibleJustNotInViewport = rowNode.rowTop != null; if (rowStillVisibleJustNotInViewport) { const rowTop = this.roundRowTopToBounds(rowNode.rowTop); this.setRowTop(rowTop); } else { for (const gui of this.allRowGuis) { gui.rowComp.toggleCss("ag-opacity-zero", true); } } } if (this.fullWidthGui?.element.contains(_getActiveDomElement(this.beans))) { this.beans.focusSvc.attemptToRecoverFocus(); } rowNode.setHovered(false); const event = this.createRowEvent("virtualRowRemoved"); this.dispatchLocalEvent(event); this.beans.eventSvc.dispatchEvent(event); super.destroy(); } destroySecondPass() { this.allRowGuis.length = 0; const destroyCellCtrls = (ctrls) => { for (const c of ctrls.list) { c.destroy(); } return { list: [], map: {} }; }; this.centerCellCtrls = destroyCellCtrls(this.centerCellCtrls); this.leftCellCtrls = destroyCellCtrls(this.leftCellCtrls); this.rightCellCtrls = destroyCellCtrls(this.rightCellCtrls); } setFocusedClasses(gui) { this.forEachGui(gui, (gui2) => { gui2.rowComp.toggleCss("ag-row-focus", this.rowFocused); gui2.rowComp.toggleCss("ag-row-no-focus", !this.rowFocused); }); } onCellFocusChanged() { const { focusSvc } = this.beans; const rowFocused = focusSvc.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned); if (rowFocused !== this.rowFocused) { this.rowFocused = rowFocused; this.setFocusedClasses(); } } onPaginationChanged() { const currentPage = this.beans.pagination?.getCurrentPage() ?? 0; if (this.paginationPage !== currentPage) { this.paginationPage = currentPage; this.onTopChanged(); } this.refreshFirstAndLastRowStyles(); } onTopChanged() { this.setRowTop(this.rowNode.rowTop); } onPaginationPixelOffsetChanged() { this.onTopChanged(); } applyPaginationOffset(topPx, reverse = false) { if (this.rowNode.isRowPinned() || this.rowNode.sticky) { return topPx; } const pixelOffset = this.beans.pageBounds.getPixelOffset(); const multiplier = reverse ? 1 : -1; return topPx + pixelOffset * multiplier; } setRowTop(pixels) { if (this.printLayout) { return; } if (_exists(pixels)) { const afterPaginationPixels = this.applyPaginationOffset(pixels); const skipScaling = this.rowNode.isRowPinned() || this.rowNode.sticky; const afterScalingPixels = skipScaling ? afterPaginationPixels : this.beans.rowContainerHeight.getRealPixelPosition(afterPaginationPixels); const topPx = `${afterScalingPixels}px`; this.setRowTopStyle(topPx); } } getInitialRowTop(rowContainerType) { return this.suppressRowTransform ? this.getInitialRowTopShared(rowContainerType) : undefined; } getInitialTransform(rowContainerType) { return this.suppressRowTransform ? undefined : `translateY(${this.getInitialRowTopShared(rowContainerType)})`; } getInitialRowTopShared(rowContainerType) { if (this.printLayout) { return ""; } const rowNode = this.rowNode; let rowTop; if (rowNode.sticky) { rowTop = rowNode.stickyRowTop; } else { const pixels = this.slideInAnimation[rowContainerType] ? this.roundRowTopToBounds(rowNode.oldRowTop) : rowNode.rowTop; const afterPaginationPixels = this.applyPaginationOffset(pixels); rowTop = rowNode.isRowPinned() ? afterPaginationPixels : this.beans.rowContainerHeight.getRealPixelPosition(afterPaginationPixels); } return rowTop + "px"; } setRowTopStyle(topPx) { for (const gui of this.allRowGuis) { if (this.suppressRowTransform) { gui.rowComp.setTop(topPx); } else { gui.rowComp.setTransform(`translateY(${topPx})`); } } } getCellCtrl(column, skipColSpanSearch = false) { let res = null; for (const cellCtrl of this.getAllCellCtrls()) { if (cellCtrl.column == column) { res = cellCtrl; } } if (res != null || skipColSpanSearch) { return res; } for (const cellCtrl of this.getAllCellCtrls()) { if (cellCtrl?.getColSpanningList().indexOf(column) >= 0) { res = cellCtrl; } } return res; } onRowIndexChanged() { if (this.rowNode.rowIndex != null) { this.onCellFocusChanged(); this.updateRowIndexes(); this.postProcessCss(); } } updateRowIndexes(gui) { const rowIndexStr = this.rowNode.getRowIndexString(); if (rowIndexStr === null) { return; } const headerRowCount = (this.beans.ctrlsSvc.getHeaderRowContainerCtrl()?.getRowCount() ?? 0) + (this.beans.filterManager?.getHeaderRowCount() ?? 0); const rowIsEven = this.rowNode.rowIndex % 2 === 0; const ariaRowIndex = this.ariaRowIndex = headerRowCount + this.rowNode.rowIndex + 1; this.forEachGui(gui, (c) => { c.rowComp.setRowIndex(rowIndexStr); c.rowComp.toggleCss("ag-row-even", rowIsEven); c.rowComp.toggleCss("ag-row-odd", !rowIsEven); _setAriaRowIndex(c.element, ariaRowIndex); }); } }; var NavigationService = class extends BeanStub { constructor() { super(); this.beanName = "navigation"; this.onPageDown = _throttle(this.onPageDown, 100); this.onPageUp = _throttle(this.onPageUp, 100); } postConstruct() { this.beans.ctrlsSvc.whenReady(this, (p) => { this.gridBodyCon = p.gridBodyCtrl; }); } handlePageScrollingKey(event, fromFullWidth = false) { const key = event.key; const alt = event.altKey; const ctrl = event.ctrlKey || event.metaKey; const rangeServiceShouldHandleShift = !!this.beans.rangeSvc && event.shiftKey; const currentCell = _getCellPositionForEvent(this.gos, event); let processed = false; switch (key) { case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: if (!ctrl && !alt) { this.onHomeOrEndKey(key); processed = true; } break; case KeyCode.LEFT: case KeyCode.RIGHT: case KeyCode.UP: case KeyCode.DOWN: if (!currentCell) { return false; } if (ctrl && !alt && !rangeServiceShouldHandleShift) { this.onCtrlUpDownLeftRight(key, currentCell); processed = true; } break; case KeyCode.PAGE_DOWN: case KeyCode.PAGE_UP: if (!ctrl && !alt) { processed = this.handlePageUpDown(key, currentCell, fromFullWidth); } break; } if (processed) { event.preventDefault(); } return processed; } handlePageUpDown(key, currentCell, fromFullWidth) { if (fromFullWidth) { currentCell = this.beans.focusSvc.getFocusedCell(); } if (!currentCell) { return false; } if (key === KeyCode.PAGE_UP) { this.onPageUp(currentCell); } else { this.onPageDown(currentCell); } return true; } navigateTo({ scrollIndex, scrollType, scrollColumn, focusIndex, focusColumn, isAsync, rowPinned }) { const { scrollFeature } = this.gridBodyCon; if (_exists(scrollColumn) && !scrollColumn.isPinned()) { scrollFeature.ensureColumnVisible(scrollColumn); } if (_exists(scrollIndex)) { scrollFeature.ensureIndexVisible(scrollIndex, scrollType); } if (!isAsync) { scrollFeature.ensureIndexVisible(focusIndex); } const { focusSvc } = this.beans; focusSvc.setFocusedCell({ rowIndex: focusIndex, column: focusColumn, rowPinned, forceBrowserFocus: true }); this.setRangeToCellIfSupported({ rowIndex: focusIndex, rowPinned, column: focusColumn }); } onPageDown(gridCell) { const beans = this.beans; const scrollPosition = getVScroll(beans); const pixelsInOnePage = this.getViewportHeight(); const { pageBounds, rowModel, rowAutoHeight } = beans; const pagingPixelOffset = pageBounds.getPixelOffset(); const currentPageBottomPixel = scrollPosition.top + pixelsInOnePage; const currentPageBottomRow = rowModel.getRowIndexAtPixel(currentPageBottomPixel + pagingPixelOffset); if (rowAutoHeight?.active) { this.navigateToNextPageWithAutoHeight(gridCell, currentPageBottomRow); } else { this.navigateToNextPage(gridCell, currentPageBottomRow); } } onPageUp(gridCell) { const beans = this.beans; const scrollPosition = getVScroll(beans); const { pageBounds, rowModel, rowAutoHeight } = beans; const pagingPixelOffset = pageBounds.getPixelOffset(); const currentPageTopPixel = scrollPosition.top; const currentPageTopRow = rowModel.getRowIndexAtPixel(currentPageTopPixel + pagingPixelOffset); if (rowAutoHeight?.active) { this.navigateToNextPageWithAutoHeight(gridCell, currentPageTopRow, true); } else { this.navigateToNextPage(gridCell, currentPageTopRow, true); } } navigateToNextPage(gridCell, scrollIndex, up = false) { const { pageBounds, rowModel } = this.beans; const pixelsInOnePage = this.getViewportHeight(); const firstRow = pageBounds.getFirstRow(); const lastRow = pageBounds.getLastRow(); const pagingPixelOffset = pageBounds.getPixelOffset(); const currentRowNode = rowModel.getRow(gridCell.rowIndex); const rowPixelDiff = up ? currentRowNode?.rowHeight - pixelsInOnePage - pagingPixelOffset : pixelsInOnePage - pagingPixelOffset; const nextCellPixel = currentRowNode?.rowTop + rowPixelDiff; let focusIndex = rowModel.getRowIndexAtPixel(nextCellPixel + pagingPixelOffset); if (focusIndex === gridCell.rowIndex) { const diff = up ? -1 : 1; scrollIndex = focusIndex = gridCell.rowIndex + diff; } let scrollType; if (up) { scrollType = "bottom"; if (focusIndex < firstRow) { focusIndex = firstRow; } if (scrollIndex < firstRow) { scrollIndex = firstRow; } } else { scrollType = "top"; if (focusIndex > lastRow) { focusIndex = lastRow; } if (scrollIndex > lastRow) { scrollIndex = lastRow; } } if (this.isRowTallerThanView(rowModel.getRow(focusIndex))) { scrollIndex = focusIndex; scrollType = "top"; } this.navigateTo({ scrollIndex, scrollType, scrollColumn: null, focusIndex, focusColumn: gridCell.column }); } navigateToNextPageWithAutoHeight(gridCell, scrollIndex, up = false) { this.navigateTo({ scrollIndex, scrollType: up ? "bottom" : "top", scrollColumn: null, focusIndex: scrollIndex, focusColumn: gridCell.column }); setTimeout(() => { const focusIndex = this.getNextFocusIndexForAutoHeight(gridCell, up); this.navigateTo({ scrollIndex, scrollType: up ? "bottom" : "top", scrollColumn: null, focusIndex, focusColumn: gridCell.column, isAsync: true }); }, 50); } getNextFocusIndexForAutoHeight(gridCell, up = false) { const step = up ? -1 : 1; const pixelsInOnePage = this.getViewportHeight(); const { pageBounds, rowModel } = this.beans; const lastRowIndex = pageBounds.getLastRow(); let pixelSum = 0; let currentIndex = gridCell.rowIndex; while (currentIndex >= 0 && currentIndex <= lastRowIndex) { const currentCell = rowModel.getRow(currentIndex); if (currentCell) { const currentCellHeight = currentCell.rowHeight ?? 0; if (pixelSum + currentCellHeight > pixelsInOnePage) { break; } pixelSum += currentCellHeight; } currentIndex += step; } return Math.max(0, Math.min(currentIndex, lastRowIndex)); } getViewportHeight() { const beans = this.beans; const scrollPosition = getVScroll(beans); const scrollbarWidth = this.beans.scrollVisibleSvc.getScrollbarWidth(); let pixelsInOnePage = scrollPosition.bottom - scrollPosition.top; if (beans.ctrlsSvc.get("center").isHorizontalScrollShowing()) { pixelsInOnePage -= scrollbarWidth; } return pixelsInOnePage; } isRowTallerThanView(rowNode) { if (!rowNode) { return false; } const rowHeight = rowNode.rowHeight; if (typeof rowHeight !== "number") { return false; } return rowHeight > this.getViewportHeight(); } onCtrlUpDownLeftRight(key, gridCell) { const cellToFocus = this.beans.cellNavigation.getNextCellToFocus(key, gridCell, true); if (!cellToFocus) { return; } const normalisedPosition = this.getNormalisedPosition(cellToFocus); const { rowIndex, rowPinned, column } = normalisedPosition ?? cellToFocus; const col = column; this.navigateTo({ scrollIndex: rowIndex, scrollType: null, scrollColumn: col, focusIndex: rowIndex, focusColumn: col, rowPinned }); } onHomeOrEndKey(key) { const homeKey = key === KeyCode.PAGE_HOME; const { visibleCols, pageBounds, rowModel } = this.beans; const allColumns = visibleCols.allCols; const scrollIndex = homeKey ? pageBounds.getFirstRow() : pageBounds.getLastRow(); const rowNode = rowModel.getRow(scrollIndex); if (!rowNode) { return; } const columnToSelect = (homeKey ? allColumns : [...allColumns].reverse()).find((col) => !col.isSuppressNavigable(rowNode) && !isRowNumberCol(col)); if (!columnToSelect) { return; } this.navigateTo({ scrollIndex, scrollType: null, scrollColumn: columnToSelect, focusIndex: scrollIndex, focusColumn: columnToSelect }); } onTabKeyDown(previous, keyboardEvent) { const backwards = keyboardEvent.shiftKey; const movedToNextCell = this.tabToNextCellCommon(previous, backwards, keyboardEvent); const beans = this.beans; const { ctrlsSvc, pageBounds, focusSvc, gos } = beans; if (movedToNextCell !== false) { if (movedToNextCell) { keyboardEvent.preventDefault(); } else if (movedToNextCell === null) { ctrlsSvc.get("gridCtrl").allowFocusForNextCoreContainer(backwards); } return; } if (backwards) { const { rowIndex, rowPinned } = previous.getRowPosition(); const firstRow = rowPinned ? rowIndex === 0 : rowIndex === pageBounds.getFirstRow(); if (firstRow) { if (gos.get("headerHeight") === 0 || _isHeaderFocusSuppressed(beans)) { _focusNextGridCoreContainer(beans, true, true); } else { keyboardEvent.preventDefault(); focusSvc.focusPreviousFromFirstCell(keyboardEvent); } } } else { if (previous instanceof CellCtrl) { previous.focusCell(true); } if (focusSvc.focusOverlay(false) || _focusNextGridCoreContainer(beans, backwards)) { keyboardEvent.preventDefault(); } } } tabToNextCell(backwards, event) { const beans = this.beans; const { focusSvc, rowRenderer } = beans; const focusedCell = focusSvc.getFocusedCell(); if (!focusedCell) { return false; } let cellOrRow = _getCellByPosition(beans, focusedCell); if (!cellOrRow) { cellOrRow = rowRenderer.getRowByPosition(focusedCell); if (!cellOrRow?.isFullWidth()) { return false; } } return !!this.tabToNextCellCommon(cellOrRow, backwards, event, "api"); } tabToNextCellCommon(previous, backwards, event, source = "ui") { const { editSvc, focusSvc } = this.beans; let res = undefined; const cellCtrl = previous instanceof CellCtrl ? previous : previous.getAllCellCtrls()?.[0]; if (editSvc?.isEditing()) { res = editSvc?.moveToNextCell(cellCtrl, backwards, event, source); } else { res = this.moveToNextCellNotEditing(previous, backwards, event); } if (res === null) { return res; } return res || !!focusSvc.focusedHeader; } moveToNextCellNotEditing(previousCell, backwards, event) { const displayedColumns = this.beans.visibleCols.allCols; let cellPos; if (previousCell instanceof RowCtrl) { cellPos = { ...previousCell.getRowPosition(), column: backwards ? displayedColumns[0] : _last(displayedColumns) }; if (this.gos.get("embedFullWidthRows") && event) { const focusedContainer = previousCell.findFullWidthInfoForEvent(event); if (focusedContainer) { cellPos.column = focusedContainer.column; } } } else { cellPos = previousCell.getFocusedCellPosition(); } const nextCell = this.findNextCellToFocusOn(cellPos, { backwards, startEditing: false }); if (nextCell === false) { return null; } if (nextCell instanceof CellCtrl) { nextCell.focusCell(true); } else if (nextCell) { return this.tryToFocusFullWidthRow(nextCell, backwards); } return _exists(nextCell); } findNextCellToFocusOn(previousPosition, { backwards, startEditing, skipToNextEditableCell }) { let nextPosition = previousPosition; const beans = this.beans; const { cellNavigation, gos, focusSvc, rowRenderer } = beans; while (true) { if (previousPosition !== nextPosition) { previousPosition = nextPosition; } if (!backwards) { nextPosition = this.getLastCellOfColSpan(nextPosition); } nextPosition = cellNavigation.getNextTabbedCell(nextPosition, backwards); const userFunc = gos.getCallback("tabToNextCell"); if (_exists(userFunc)) { const params = { backwards, editing: startEditing, previousCellPosition: previousPosition, nextCellPosition: nextPosition ? nextPosition : null }; const userResult = userFunc(params); if (userResult === true) { nextPosition = previousPosition; } else if (userResult === false) { return false; } else { nextPosition = { rowIndex: userResult.rowIndex, column: userResult.column, rowPinned: userResult.rowPinned }; } } if (!nextPosition) { return null; } if (nextPosition.rowIndex < 0) { const headerLen = getFocusHeaderRowCount(beans); focusSvc.focusHeaderPosition({ headerPosition: { headerRowIndex: headerLen + nextPosition.rowIndex, column: nextPosition.column }, fromCell: true }); return null; } const fullRowEdit = gos.get("editType") === "fullRow"; if (startEditing && (!fullRowEdit || skipToNextEditableCell)) { const cellIsEditable = this.isCellEditable(nextPosition); if (!cellIsEditable) { continue; } } this.ensureCellVisible(nextPosition); const nextCell = _getCellByPosition(beans, nextPosition); if (!nextCell) { const row = rowRenderer.getRowByPosition(nextPosition); if (!row || !row.isFullWidth() || startEditing) { continue; } return { ...row.getRowPosition(), column: nextPosition?.column }; } if (cellNavigation.isSuppressNavigable(nextCell.column, nextCell.rowNode)) { continue; } nextCell.setFocusedCellPosition(nextPosition); this.setRangeToCellIfSupported(nextPosition); return nextCell; } } isCellEditable(cell) { const rowNode = this.lookupRowNodeForCell(cell); if (rowNode) { return cell.column.isCellEditable(rowNode); } return false; } lookupRowNodeForCell({ rowIndex, rowPinned }) { const { pinnedRowModel, rowModel } = this.beans; if (rowPinned === "top") { return pinnedRowModel?.getPinnedTopRow(rowIndex); } if (rowPinned === "bottom") { return pinnedRowModel?.getPinnedBottomRow(rowIndex); } return rowModel.getRow(rowIndex); } navigateToNextCell(event, key, currentCell, allowUserOverride) { let nextCell = currentCell; let hitEdgeOfGrid = false; const beans = this.beans; const { cellNavigation, focusSvc, gos } = beans; while (nextCell && (nextCell === currentCell || !this.isValidNavigateCell(nextCell))) { if (gos.get("enableRtl")) { if (key === KeyCode.LEFT) { nextCell = this.getLastCellOfColSpan(nextCell); } } else if (key === KeyCode.RIGHT) { nextCell = this.getLastCellOfColSpan(nextCell); } nextCell = cellNavigation.getNextCellToFocus(key, nextCell); hitEdgeOfGrid = _missing(nextCell); } if (hitEdgeOfGrid && event && event.key === KeyCode.UP) { nextCell = { rowIndex: -1, rowPinned: null, column: currentCell.column }; } if (allowUserOverride) { const userFunc = gos.getCallback("navigateToNextCell"); if (_exists(userFunc)) { const params = { key, previousCellPosition: currentCell, nextCellPosition: nextCell ? nextCell : null, event }; const userCell = userFunc(params); if (_exists(userCell)) { nextCell = { rowPinned: userCell.rowPinned, rowIndex: userCell.rowIndex, column: userCell.column }; } else { nextCell = null; } } } if (!nextCell) { return; } if (nextCell.rowIndex < 0) { const headerLen = getFocusHeaderRowCount(beans); focusSvc.focusHeaderPosition({ headerPosition: { headerRowIndex: headerLen + nextCell.rowIndex, column: nextCell.column ?? currentCell.column }, event: event || undefined, fromCell: true }); return; } const normalisedPosition = this.getNormalisedPosition(nextCell); if (normalisedPosition) { this.focusPosition(normalisedPosition); } else { this.tryToFocusFullWidthRow(nextCell); } } getNormalisedPosition(cellPosition) { const isSpannedCell = !!this.beans.spannedRowRenderer?.getCellByPosition(cellPosition); if (isSpannedCell) { return cellPosition; } this.ensureCellVisible(cellPosition); const cellCtrl = _getCellByPosition(this.beans, cellPosition); if (!cellCtrl) { return null; } cellPosition = cellCtrl.getFocusedCellPosition(); this.ensureCellVisible(cellPosition); return cellPosition; } tryToFocusFullWidthRow(position, backwards) { const { visibleCols, rowRenderer, focusSvc, eventSvc } = this.beans; const displayedColumns = visibleCols.allCols; const rowComp = rowRenderer.getRowByPosition(position); if (!rowComp?.isFullWidth()) { return false; } const currentCellFocused = focusSvc.getFocusedCell(); const cellPosition = { rowIndex: position.rowIndex, rowPinned: position.rowPinned, column: position.column || (backwards ? _last(displayedColumns) : displayedColumns[0]) }; this.focusPosition(cellPosition); const fromBelow = backwards == null ? currentCellFocused != null && _isRowBefore(cellPosition, currentCellFocused) : backwards; eventSvc.dispatchEvent({ type: "fullWidthRowFocused", rowIndex: cellPosition.rowIndex, rowPinned: cellPosition.rowPinned, column: cellPosition.column, isFullWidthCell: true, fromBelow }); return true; } focusPosition(cellPosition) { const { focusSvc } = this.beans; focusSvc.setFocusedCell({ rowIndex: cellPosition.rowIndex, column: cellPosition.column, rowPinned: cellPosition.rowPinned, forceBrowserFocus: true }); this.setRangeToCellIfSupported(cellPosition); } setRangeToCellIfSupported(cellPosition) { if (isRowNumberCol(cellPosition.column)) { return; } this.beans.rangeSvc?.setRangeToCell(cellPosition); } isValidNavigateCell(cell) { const rowNode = _getRowNode(this.beans, cell); return !!rowNode; } getLastCellOfColSpan(cell) { const cellCtrl = _getCellByPosition(this.beans, cell); if (!cellCtrl) { return cell; } const colSpanningList = cellCtrl.getColSpanningList(); if (colSpanningList.length === 1) { return cell; } return { rowIndex: cell.rowIndex, column: _last(colSpanningList), rowPinned: cell.rowPinned }; } ensureCellVisible(gridCell) { const isGroupStickyEnabled = _isGroupRowsSticky(this.gos); const rowNode = this.beans.rowModel.getRow(gridCell.rowIndex); const skipScrollToRow = isGroupStickyEnabled && rowNode?.sticky; const { scrollFeature } = this.gridBodyCon; if (!skipScrollToRow && _missing(gridCell.rowPinned)) { scrollFeature.ensureIndexVisible(gridCell.rowIndex); } if (!gridCell.column.isPinned()) { scrollFeature.ensureColumnVisible(gridCell.column); } } ensureColumnVisible(column) { const scrollFeature = this.gridBodyCon.scrollFeature; if (!column.isPinned()) { scrollFeature.ensureColumnVisible(column); } } ensureRowVisible(rowIndex) { const scrollFeature = this.gridBodyCon.scrollFeature; scrollFeature.ensureIndexVisible(rowIndex); } }; function getVScroll(beans) { return beans.ctrlsSvc.getScrollFeature().getVScrollPosition(); } var KeyboardNavigationModule = { moduleName: "KeyboardNavigation", version: VERSION, beans: [NavigationService, CellNavigationService, HeaderNavigationService], apiFunctions: { getFocusedCell, clearFocusedCell, setFocusedCell, setFocusedHeader, tabToNextCell, tabToPreviousCell } }; var PageBoundsListener = class extends BeanStub { constructor() { super(...arguments); this.beanName = "pageBoundsListener"; } postConstruct() { this.addManagedEventListeners({ modelUpdated: this.onModelUpdated.bind(this), recalculateRowBounds: this.calculatePages.bind(this) }); this.onModelUpdated(); } onModelUpdated(modelUpdatedEvent) { this.calculatePages(); this.eventSvc.dispatchEvent({ type: "paginationChanged", animate: modelUpdatedEvent?.animate ?? false, newData: modelUpdatedEvent?.newData ?? false, newPage: modelUpdatedEvent?.newPage ?? false, newPageSize: modelUpdatedEvent?.newPageSize ?? false, keepRenderedRows: modelUpdatedEvent?.keepRenderedRows ?? false }); } calculatePages() { const { pageBounds, pagination, rowModel } = this.beans; if (pagination) { pagination.calculatePages(); } else { pageBounds.calculateBounds(0, rowModel.getRowCount() - 1); } } }; var PageBoundsService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "pageBounds"; this.pixelOffset = 0; } getFirstRow() { return this.topRowBounds?.rowIndex ?? -1; } getLastRow() { return this.bottomRowBounds?.rowIndex ?? -1; } getCurrentPageHeight() { const { topRowBounds, bottomRowBounds } = this; if (!topRowBounds || !bottomRowBounds) { return 0; } return Math.max(bottomRowBounds.rowTop + bottomRowBounds.rowHeight - topRowBounds.rowTop, 0); } getCurrentPagePixelRange() { const { topRowBounds, bottomRowBounds } = this; const pageFirstPixel = topRowBounds?.rowTop ?? 0; const pageLastPixel = bottomRowBounds ? bottomRowBounds.rowTop + bottomRowBounds.rowHeight : 0; return { pageFirstPixel, pageLastPixel }; } calculateBounds(topDisplayedRowIndex, bottomDisplayedRowIndex) { const { rowModel } = this.beans; const topRowBounds = rowModel.getRowBounds(topDisplayedRowIndex); if (topRowBounds) { topRowBounds.rowIndex = topDisplayedRowIndex; } this.topRowBounds = topRowBounds; const bottomRowBounds = rowModel.getRowBounds(bottomDisplayedRowIndex); if (bottomRowBounds) { bottomRowBounds.rowIndex = bottomDisplayedRowIndex; } this.bottomRowBounds = bottomRowBounds; this.calculatePixelOffset(); } getPixelOffset() { return this.pixelOffset; } calculatePixelOffset() { const value = this.topRowBounds?.rowTop ?? 0; if (this.pixelOffset === value) { return; } this.pixelOffset = value; this.eventSvc.dispatchEvent({ type: "paginationPixelOffsetChanged" }); } }; var pinnedColumnModule_default = ".ag-pinned-left-floating-bottom,.ag-pinned-left-floating-top,.ag-pinned-right-floating-bottom,.ag-pinned-right-floating-top{min-width:0;overflow:hidden;position:relative}.ag-pinned-left-sticky-top,.ag-pinned-right-sticky-top{height:100%;overflow:hidden;position:relative}.ag-sticky-bottom-full-width-container,.ag-sticky-top-full-width-container{height:100%;overflow:hidden;width:100%}.ag-pinned-left-header,.ag-pinned-right-header{display:inline-block;height:100%;overflow:hidden;position:relative}.ag-body-horizontal-scroll:not(.ag-scrollbar-invisible){.ag-horizontal-left-spacer:not(.ag-scroller-corner){border-right:var(--ag-pinned-column-border)}.ag-horizontal-right-spacer:not(.ag-scroller-corner){border-left:var(--ag-pinned-column-border)}}.ag-pinned-right-header{border-left:var(--ag-pinned-column-border)}.ag-pinned-left-header{border-right:var(--ag-pinned-column-border)}.ag-cell.ag-cell-first-right-pinned:not(.ag-cell-range-left,.ag-cell-range-single-cell,.ag-cell-focus:not(.ag-cell-range-selected):focus-within){border-left:var(--ag-pinned-column-border)}.ag-cell.ag-cell-last-left-pinned:not(.ag-cell-range-right,.ag-cell-range-single-cell,.ag-cell-focus:not(.ag-cell-range-selected):focus-within){border-right:var(--ag-pinned-column-border)}.ag-pinned-left-header .ag-header-cell-resize:after{left:calc(50% - var(--ag-header-column-resize-handle-width))}.ag-pinned-right-header .ag-header-cell-resize:after{left:50%}.ag-pinned-left-header .ag-header-cell-resize{right:-3px}.ag-pinned-right-header .ag-header-cell-resize{left:-3px}"; var SetPinnedWidthFeature = class extends BeanStub { constructor(isLeft, elements) { super(); this.isLeft = isLeft; this.elements = elements; this.getWidth = isLeft ? () => this.beans.pinnedCols.leftWidth : () => this.beans.pinnedCols.rightWidth; } postConstruct() { this.addManagedEventListeners({ [`${this.isLeft ? "left" : "right"}PinnedWidthChanged`]: this.onPinnedWidthChanged.bind(this) }); } onPinnedWidthChanged() { const width = this.getWidth(); const displayed = width > 0; for (const element of this.elements) { if (element) { _setDisplayed(element, displayed); _setFixedWidth(element, width); } } } }; var PinnedColumnService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "pinnedCols"; } postConstruct() { this.beans.ctrlsSvc.whenReady(this, (p) => { this.gridBodyCtrl = p.gridBodyCtrl; }); const listener = this.checkContainerWidths.bind(this); this.addManagedEventListeners({ displayedColumnsChanged: listener, displayedColumnsWidthChanged: listener }); this.addManagedPropertyListener("domLayout", listener); } checkContainerWidths() { const { gos, visibleCols, eventSvc } = this.beans; const printLayout = _isDomLayout(gos, "print"); const newLeftWidth = printLayout ? 0 : visibleCols.getColsLeftWidth(); const newRightWidth = printLayout ? 0 : visibleCols.getDisplayedColumnsRightWidth(); if (newLeftWidth != this.leftWidth) { this.leftWidth = newLeftWidth; eventSvc.dispatchEvent({ type: "leftPinnedWidthChanged" }); } if (newRightWidth != this.rightWidth) { this.rightWidth = newRightWidth; eventSvc.dispatchEvent({ type: "rightPinnedWidthChanged" }); } } keepPinnedColumnsNarrowerThanViewport() { const eBodyViewport = this.gridBodyCtrl.eBodyViewport; const bodyWidth = _getInnerWidth(eBodyViewport); if (bodyWidth <= 50) { return; } const processedColumnsToRemove = this.getPinnedColumnsOverflowingViewport(bodyWidth - 50); const processUnpinnedColumns = this.gos.getCallback("processUnpinnedColumns"); const { columns, hasLockedPinned } = processedColumnsToRemove; let columnsToRemove = columns; if (!columnsToRemove.length && !hasLockedPinned) { return; } if (processUnpinnedColumns) { const params = { columns: columnsToRemove, viewportWidth: bodyWidth }; columnsToRemove = processUnpinnedColumns(params); } if (!columnsToRemove?.length) { return; } columnsToRemove = columnsToRemove.filter((col) => !isRowNumberCol(col)); this.setColsPinned(columnsToRemove, null, "viewportSizeFeature"); } createPinnedWidthFeature(isLeft, ...elements) { return new SetPinnedWidthFeature(isLeft, elements); } setColsPinned(keys, pinned, source) { const { colModel, colAnimation, visibleCols, gos } = this.beans; if (!colModel.cols) { return; } if (!keys?.length) { return; } if (_isDomLayout(gos, "print")) { _warn(37); return; } colAnimation?.start(); let actualPinned; if (pinned === true || pinned === "left") { actualPinned = "left"; } else if (pinned === "right") { actualPinned = "right"; } else { actualPinned = null; } const updatedCols = []; for (const key of keys) { if (!key) { continue; } const column = colModel.getCol(key); if (!column) { continue; } if (column.getPinned() !== actualPinned) { this.setColPinned(column, actualPinned); updatedCols.push(column); } } if (updatedCols.length) { visibleCols.refresh(source); dispatchColumnPinnedEvent(this.eventSvc, updatedCols, source); } colAnimation?.finish(); } initCol(column) { const { pinned, initialPinned } = column.colDef; if (pinned !== undefined) { this.setColPinned(column, pinned); } else { this.setColPinned(column, initialPinned); } } setColPinned(column, pinned) { if (pinned === true || pinned === "left") { column.pinned = "left"; } else if (pinned === "right") { column.pinned = "right"; } else { column.pinned = null; } column.dispatchStateUpdatedEvent("pinned"); } setupHeaderPinnedWidth(ctrl) { const { scrollVisibleSvc } = this.beans; if (ctrl.pinned == null) { return; } const pinningLeft = ctrl.pinned === "left"; const pinningRight = ctrl.pinned === "right"; ctrl.hidden = true; const listener = () => { const width = pinningLeft ? this.leftWidth : this.rightWidth; if (width == null) { return; } const hidden = width == 0; const hiddenChanged = ctrl.hidden !== hidden; const isRtl = this.gos.get("enableRtl"); const scrollbarWidth = scrollVisibleSvc.getScrollbarWidth(); const addPaddingForScrollbar = scrollVisibleSvc.verticalScrollShowing && (isRtl && pinningLeft || !isRtl && pinningRight); const widthWithPadding = addPaddingForScrollbar ? width + scrollbarWidth : width; ctrl.comp.setPinnedContainerWidth(`${widthWithPadding}px`); ctrl.comp.setDisplayed(!hidden); if (hiddenChanged) { ctrl.hidden = hidden; ctrl.refresh(); } }; ctrl.addManagedEventListeners({ leftPinnedWidthChanged: listener, rightPinnedWidthChanged: listener, scrollVisibilityChanged: listener, scrollbarWidthChanged: listener }); } getHeaderResizeDiff(diff, column) { const pinned = column.getPinned(); if (pinned) { const { leftWidth, rightWidth } = this; const bodyWidth = _getInnerWidth(this.beans.ctrlsSvc.getGridBodyCtrl().eBodyViewport) - 50; if (leftWidth + rightWidth + diff > bodyWidth) { if (bodyWidth > leftWidth + rightWidth) { diff = bodyWidth - leftWidth - rightWidth; } else { return 0; } } } return diff; } getPinnedColumnsOverflowingViewport(viewportWidth) { const pinnedRightWidth = this.rightWidth ?? 0; const pinnedLeftWidth = this.leftWidth ?? 0; const totalPinnedWidth = pinnedRightWidth + pinnedLeftWidth; let hasLockedPinned = false; if (totalPinnedWidth < viewportWidth) { return { columns: [], hasLockedPinned }; } const { visibleCols } = this.beans; const pinnedLeftColumns = [...visibleCols.leftCols]; const pinnedRightColumns = [...visibleCols.rightCols]; let indexRight = 0; let indexLeft = 0; const totalWidthRemoved = 0; const columnsToRemove = []; let spaceNecessary = totalPinnedWidth - totalWidthRemoved - viewportWidth; while ((indexLeft < pinnedLeftColumns.length || indexRight < pinnedRightColumns.length) && spaceNecessary > 0) { if (indexRight < pinnedRightColumns.length) { const currentColumn = pinnedRightColumns[indexRight++]; if (currentColumn.colDef.lockPinned) { hasLockedPinned = true; continue; } spaceNecessary -= currentColumn.getActualWidth(); columnsToRemove.push(currentColumn); } if (indexLeft < pinnedLeftColumns.length && spaceNecessary > 0) { const currentColumn = pinnedLeftColumns[indexLeft++]; if (currentColumn.colDef.lockPinned) { hasLockedPinned = true; continue; } spaceNecessary -= currentColumn.getActualWidth(); columnsToRemove.push(currentColumn); } } return { columns: columnsToRemove, hasLockedPinned }; } }; var PinnedColumnModule = { moduleName: "PinnedColumn", version: VERSION, beans: [PinnedColumnService], css: [pinnedColumnModule_default] }; var BaseAriaAnnouncementService = class extends AgBeanStub { constructor() { super(); this.beanName = "ariaAnnounce"; this.descriptionContainer = null; this.pendingAnnouncements = /* @__PURE__ */ new Map; this.lastAnnouncement = ""; this.updateAnnouncement = _debounce(this, this.updateAnnouncement.bind(this), 200); } postConstruct() { const beans = this.beans; const eDocument = _getDocument(beans); const div = this.descriptionContainer = eDocument.createElement("div"); div.classList.add("ag-aria-description-container"); _setAriaLive(div, "polite"); _setAriaRelevant(div, "additions text"); _setAriaAtomic(div, true); beans.eRootDiv.appendChild(div); } announceValue(value, key) { this.pendingAnnouncements.set(key, value); this.updateAnnouncement(); } updateAnnouncement() { if (!this.descriptionContainer) { return; } const value = Array.from(this.pendingAnnouncements.values()).join(". "); this.pendingAnnouncements.clear(); this.descriptionContainer.textContent = ""; setTimeout(() => { this.handleAnnouncementUpdate(value); }, 50); } handleAnnouncementUpdate(value) { if (!this.isAlive() || !this.descriptionContainer) { return; } let valueToAnnounce = value; if (valueToAnnounce == null || valueToAnnounce.replace(/[ .]/g, "") == "") { this.lastAnnouncement = ""; return; } if (this.lastAnnouncement === valueToAnnounce) { valueToAnnounce = `${valueToAnnounce}​`; } this.lastAnnouncement = valueToAnnounce; this.descriptionContainer.textContent = valueToAnnounce; } destroy() { super.destroy(); const { descriptionContainer } = this; if (descriptionContainer) { _clearElement(descriptionContainer); descriptionContainer.remove(); } this.descriptionContainer = null; this.pendingAnnouncements.clear(); } }; var AriaAnnouncementService = class extends BaseAriaAnnouncementService { }; var AriaModule = { moduleName: "Aria", version: VERSION, beans: [AriaAnnouncementService] }; var column_delay_render_default = ":where(.ag-delay-render){.ag-cell,.ag-header-cell,.ag-header-group-cell,.ag-row,.ag-spanned-cell-wrapper{visibility:hidden}}"; var HideClass = "ag-delay-render"; var ColumnDelayRenderService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colDelayRenderSvc"; this.hideRequested = false; this.alreadyRevealed = false; this.timesRetried = 0; this.requesters = /* @__PURE__ */ new Set; } hideColumns(key) { if (this.alreadyRevealed || this.requesters.has(key)) { return; } this.requesters.add(key); if (!this.hideRequested) { this.beans.ctrlsSvc.whenReady(this, (p) => { p.gridBodyCtrl.eGridBody.classList.add(HideClass); }); this.hideRequested = true; } } revealColumns(key) { if (this.alreadyRevealed || !this.isAlive()) { return; } this.requesters.delete(key); if (this.requesters.size > 0) { return; } const { renderStatus, ctrlsSvc } = this.beans; if (renderStatus) { if (!renderStatus.areHeaderCellsRendered() && this.timesRetried < 5) { this.timesRetried++; setTimeout(() => this.revealColumns(key)); return; } this.timesRetried = 0; } ctrlsSvc.getGridBodyCtrl().eGridBody.classList.remove(HideClass); this.alreadyRevealed = true; } }; var ColumnDelayRenderModule = { moduleName: "ColumnDelayRender", version: VERSION, beans: [ColumnDelayRenderService], css: [column_delay_render_default] }; var OverlayComponent = class extends Component { constructor() { super(); } }; var ExportingOverlayElement = { tag: "div", cls: "ag-overlay-exporting-center", children: [ { tag: "span", ref: "eExportingIcon", cls: "ag-loading-icon" }, { tag: "span", ref: "eExportingText", cls: "ag-exporting-text" } ] }; var ExportingOverlayComponent = class extends OverlayComponent { constructor() { super(...arguments); this.eExportingIcon = RefPlaceholder; this.eExportingText = RefPlaceholder; } init(params) { const { beans } = this; this.setTemplate(ExportingOverlayElement); const eExportingIcon = _createIconNoSpan("overlayExporting", beans, null); if (eExportingIcon) { this.eExportingIcon.appendChild(eExportingIcon); } const exportingText = params.exporting?.overlayText ?? this.getLocaleTextFunc()("exportingOoo", "Exporting..."); this.eExportingText.textContent = exportingText; beans.ariaAnnounce.announceValue(exportingText, "overlay"); } }; var LoadingOverlayElement = { tag: "div", cls: "ag-overlay-loading-center", children: [ { tag: "span", ref: "eLoadingIcon", cls: "ag-loading-icon" }, { tag: "span", ref: "eLoadingText", cls: "ag-loading-text" } ] }; var LoadingOverlayComponent = class extends OverlayComponent { constructor() { super(...arguments); this.eLoadingIcon = RefPlaceholder; this.eLoadingText = RefPlaceholder; } init(params) { const { beans, gos } = this; const customTemplate = _makeNull(gos.get("overlayLoadingTemplate")?.trim()); this.setTemplate(customTemplate ?? LoadingOverlayElement); if (!customTemplate) { const eLoadingIcon = _createIconNoSpan("overlayLoading", beans, null); if (eLoadingIcon) { this.eLoadingIcon.appendChild(eLoadingIcon); } const loadingText = params.loading?.overlayText ?? this.getLocaleTextFunc()("loadingOoo", "Loading..."); this.eLoadingText.textContent = loadingText; beans.ariaAnnounce.announceValue(loadingText, "overlay"); } } }; var NoMatchingRowsOverlayElement = { tag: "span", cls: "ag-overlay-no-matching-rows-center" }; var NoMatchingRowsOverlayComponent = class extends OverlayComponent { init(params) { const { beans } = this; this.setTemplate(NoMatchingRowsOverlayElement); const noRowsText = params.noMatchingRows?.overlayText ?? this.getLocaleTextFunc()("noMatchingRows", "No Matching Rows"); this.getGui().textContent = noRowsText; beans.ariaAnnounce.announceValue(noRowsText, "overlay"); } }; var NoRowsOverlayElement = { tag: "span", cls: "ag-overlay-no-rows-center" }; var NoRowsOverlayComponent = class extends OverlayComponent { init(params) { const { beans, gos } = this; const customTemplate = _makeNull(gos.get("overlayNoRowsTemplate")?.trim()); this.setTemplate(customTemplate ?? NoRowsOverlayElement); if (!customTemplate) { const noRowsText = params.noRows?.overlayText ?? this.getLocaleTextFunc()("noRowsToShow", "No Rows To Show"); this.getGui().textContent = noRowsText; beans.ariaAnnounce.announceValue(noRowsText, "overlay"); } } }; function showLoadingOverlay(beans) { beans.overlays?.showLoadingOverlay(); } function showNoRowsOverlay(beans) { beans.overlays?.showNoRowsOverlay(); } function hideOverlay(beans) { beans.overlays?.hideOverlay(); } var overlayWrapperComponent_default = ".ag-overlay{inset:0;pointer-events:none;position:absolute;z-index:2}.ag-overlay-panel,.ag-overlay-wrapper{display:flex;height:100%;width:100%}.ag-overlay-wrapper{align-items:center;flex:none;justify-content:center;text-align:center}.ag-overlay-exporting-wrapper,.ag-overlay-loading-wrapper,.ag-overlay-modal-wrapper{pointer-events:all}.ag-overlay-exporting-center,.ag-overlay-loading-center{background:var(--ag-background-color);border:solid var(--ag-border-width) var(--ag-border-color);border-radius:var(--ag-border-radius);box-shadow:var(--ag-popup-shadow);display:flex;padding:var(--ag-spacing)}"; var OverlayWrapperElement = { tag: "div", cls: "ag-overlay", role: "presentation", children: [ { tag: "div", cls: "ag-overlay-panel", role: "presentation", children: [{ tag: "div", ref: "eOverlayWrapper", cls: "ag-overlay-wrapper", role: "presentation" }] } ] }; var OverlayWrapperComponent = class extends Component { constructor() { super(OverlayWrapperElement); this.eOverlayWrapper = RefPlaceholder; this.activeOverlay = null; this.activePromise = null; this.activeCssClass = null; this.elToFocusAfter = null; this.overlayExclusive = false; this.oldWrapperPadding = null; this.registerCSS(overlayWrapperComponent_default); } handleKeyDown(e) { if (e.key !== KeyCode.TAB || e.defaultPrevented || _isStopPropagationForAgGrid(e)) { return; } const { beans, eOverlayWrapper } = this; const nextEl = eOverlayWrapper && _findNextFocusableElement(beans, eOverlayWrapper, false, e.shiftKey); if (nextEl) { return; } let isFocused = false; if (e.shiftKey) { isFocused = beans.focusSvc.focusGridView({ column: _last(beans.visibleCols.allCols), backwards: true, canFocusOverlay: false }); } else { isFocused = _focusNextGridCoreContainer(beans, false); } if (isFocused) { e.preventDefault(); } } updateLayoutClasses(cssClass, params) { const eOverlayWrapper = this.eOverlayWrapper; if (!eOverlayWrapper) { return; } const overlayWrapperClassList = eOverlayWrapper.classList; const { AUTO_HEIGHT, NORMAL, PRINT } = LayoutCssClasses; overlayWrapperClassList.toggle(AUTO_HEIGHT, params.autoHeight); overlayWrapperClassList.toggle(NORMAL, params.normal); overlayWrapperClassList.toggle(PRINT, params.print); } postConstruct() { this.createManagedBean(new LayoutFeature(this)); this.setDisplayed(false, { skipAriaHidden: true }); this.beans.overlays.setWrapperComp(this, false); this.addManagedElementListeners(this.getFocusableElement(), { keydown: this.handleKeyDown.bind(this) }); this.addManagedEventListeners({ gridSizeChanged: this.refreshWrapperPadding.bind(this) }); } setWrapperTypeClass(overlayWrapperCssClass) { const overlayWrapperClassList = this.eOverlayWrapper?.classList; if (!overlayWrapperClassList) { this.activeCssClass = null; return; } if (this.activeCssClass) { overlayWrapperClassList.toggle(this.activeCssClass, false); } this.activeCssClass = overlayWrapperCssClass; overlayWrapperClassList.toggle(overlayWrapperCssClass, true); } showOverlay(overlayComponentPromise, overlayWrapperCssClass, exclusive) { this.destroyActiveOverlay(); this.elToFocusAfter = null; this.activePromise = overlayComponentPromise; this.overlayExclusive = exclusive; if (!overlayComponentPromise) { this.refreshWrapperPadding(); return AgPromise.resolve(); } this.setWrapperTypeClass(overlayWrapperCssClass); this.setDisplayed(true, { skipAriaHidden: true }); this.refreshWrapperPadding(); if (exclusive && this.isGridFocused()) { const activeElement = _getActiveDomElement(this.beans); if (activeElement && !_isNothingFocused(this.beans)) { this.elToFocusAfter = activeElement; } } overlayComponentPromise.then((comp) => { const eOverlayWrapper = this.eOverlayWrapper; if (!eOverlayWrapper) { this.destroyBean(comp); return; } if (this.activePromise !== overlayComponentPromise) { if (this.activeOverlay !== comp) { this.destroyBean(comp); comp = null; } return; } this.activePromise = null; if (!comp) { return; } if (this.activeOverlay !== comp) { eOverlayWrapper.appendChild(comp.getGui()); this.activeOverlay = comp; } if (exclusive && this.isGridFocused()) { _focusInto(eOverlayWrapper); } }); return overlayComponentPromise; } refreshWrapperPadding() { if (!this.eOverlayWrapper) { this.oldWrapperPadding = null; return; } const overlayActive = !!this.activeOverlay || !!this.activePromise; let padding = 0; if (overlayActive && !this.overlayExclusive) { padding = this.beans.ctrlsSvc.get("gridHeaderCtrl")?.headerHeight || 0; } if (padding !== this.oldWrapperPadding) { this.oldWrapperPadding = padding; this.eOverlayWrapper.style.setProperty("padding-top", `${padding}px`); } } destroyActiveOverlay() { this.activePromise = null; const activeOverlay = this.activeOverlay; if (!activeOverlay) { this.overlayExclusive = false; this.elToFocusAfter = null; this.refreshWrapperPadding(); return; } let elementToFocus = this.elToFocusAfter; this.elToFocusAfter = null; this.activeOverlay = null; this.overlayExclusive = false; if (elementToFocus && !this.isGridFocused()) { elementToFocus = null; } this.destroyBean(activeOverlay); const eOverlayWrapper = this.eOverlayWrapper; if (eOverlayWrapper) { _clearElement(eOverlayWrapper); } elementToFocus?.focus?.({ preventScroll: true }); this.refreshWrapperPadding(); } hideOverlay() { this.destroyActiveOverlay(); this.setDisplayed(false, { skipAriaHidden: true }); } isGridFocused() { const activeEl = _getActiveDomElement(this.beans); return !!activeEl && this.beans.eGridDiv.contains(activeEl); } destroy() { this.elToFocusAfter = null; this.destroyActiveOverlay(); this.beans.overlays.setWrapperComp(this, true); super.destroy(); this.eOverlayWrapper = null; } }; var OverlayWrapperSelector = { selector: "AG-OVERLAY-WRAPPER", component: OverlayWrapperComponent }; var overlayCompTypeOptionalMethods = ["refresh"]; var overlayCompType = (name) => ({ name, optionalMethods: overlayCompTypeOptionalMethods }); var LoadingOverlayDef = { id: "agLoadingOverlay", overlayType: "loading", comp: overlayCompType("loadingOverlayComponent"), wrapperCls: "ag-overlay-loading-wrapper", exclusive: true, compKey: "loadingOverlayComponent", paramsKey: "loadingOverlayComponentParams", isSuppressed: (gos) => { const isLoading = gos.get("loading"); return isLoading === false || gos.get("suppressLoadingOverlay") === true && isLoading !== true; } }; var NoRowsOverlayDef = { id: "agNoRowsOverlay", overlayType: "noRows", comp: overlayCompType("noRowsOverlayComponent"), wrapperCls: "ag-overlay-no-rows-wrapper", compKey: "noRowsOverlayComponent", paramsKey: "noRowsOverlayComponentParams", isSuppressed: (gos) => gos.get("suppressNoRowsOverlay") }; var NoMatchingRowsOverlayDef = { id: "agNoMatchingRowsOverlay", overlayType: "noMatchingRows", comp: overlayCompType("noMatchingRowsOverlayComponent"), wrapperCls: "ag-overlay-no-matching-rows-wrapper" }; var ExportingOverlayDef = { id: "agExportingOverlay", overlayType: "exporting", comp: overlayCompType("exportingOverlayComponent"), wrapperCls: "ag-overlay-exporting-wrapper", exclusive: true }; var CustomOverlayDef = { id: "activeOverlay", comp: overlayCompType("activeOverlay"), wrapperCls: "ag-overlay-modal-wrapper", exclusive: true }; var getActiveOverlayDef = (activeOverlay) => { if (!activeOverlay) { return null; } return { agLoadingOverlay: LoadingOverlayDef, agNoRowsOverlay: NoRowsOverlayDef, agNoMatchingRowsOverlay: NoMatchingRowsOverlayDef, agExportingOverlay: ExportingOverlayDef }[activeOverlay] ?? CustomOverlayDef; }; var getOverlayDefForType = (overlayType) => { if (!overlayType) { return null; } return { loading: LoadingOverlayDef, noRows: NoRowsOverlayDef, noMatchingRows: NoMatchingRowsOverlayDef, exporting: ExportingOverlayDef }[overlayType]; }; var OverlayService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "overlays"; this.eWrapper = undefined; this.exclusive = false; this.oldExclusive = false; this.currentDef = null; this.showInitialOverlay = true; this.userForcedNoRows = false; this.exportsInProgress = 0; this.newColumnsLoadedCleanup = null; } postConstruct() { const gos = this.gos; this.showInitialOverlay = _isClientSideRowModel(gos); const updateOverlayVisibility = () => { if (this.userForcedNoRows) { return; } this.updateOverlay(false); }; const [newColumnsLoadedCleanup, rowCountReadyCleanup, _, __] = this.addManagedEventListeners({ newColumnsLoaded: updateOverlayVisibility, rowCountReady: () => { this.disableInitialOverlay(); updateOverlayVisibility(); rowCountReadyCleanup(); }, rowDataUpdated: updateOverlayVisibility, modelUpdated: updateOverlayVisibility }); this.newColumnsLoadedCleanup = newColumnsLoadedCleanup; this.addManagedPropertyListeners([ "loading", "activeOverlay", "activeOverlayParams", "overlayComponentParams", "loadingOverlayComponentParams", "noRowsOverlayComponentParams" ], (params) => this.onPropChange(new Set(params.changeSet?.properties))); } destroy() { this.doHideOverlay(); super.destroy(); this.eWrapper = undefined; } setWrapperComp(overlayWrapperComp, destroyed) { if (!this.isAlive()) { return; } if (!destroyed) { this.eWrapper = overlayWrapperComp; } else if (this.eWrapper === overlayWrapperComp) { this.eWrapper = undefined; } this.updateOverlay(false); } isVisible() { return !!this.currentDef; } showLoadingOverlay() { this.showInitialOverlay = false; const gos = this.gos; if (!this.eWrapper || gos.get("activeOverlay")) { return; } if (this.isDisabled(LoadingOverlayDef)) { return; } const loading = gos.get("loading"); if (!loading && loading !== undefined) { return; } this.doShowOverlay(LoadingOverlayDef); } showNoRowsOverlay() { this.showInitialOverlay = false; const gos = this.gos; if (!this.eWrapper || gos.get("activeOverlay") || gos.get("loading") || this.isDisabled(NoRowsOverlayDef)) { return; } this.userForcedNoRows = true; this.doShowOverlay(NoRowsOverlayDef); } async showExportOverlay(heavyOperation) { const { gos, beans } = this; if (!this.eWrapper || gos.get("activeOverlay") || gos.get("loading") || this.isDisabled(ExportingOverlayDef) || this.userForcedNoRows && this.currentDef === NoRowsOverlayDef) { heavyOperation(); return; } const desiredDef = this.getDesiredDefWithOverride(ExportingOverlayDef); if (!desiredDef) { heavyOperation(); return; } this.exportsInProgress++; this.focusedCell = beans.focusSvc.getFocusedCell(); await this.doShowOverlay(desiredDef); await new Promise((resolve) => setTimeout(() => resolve())); const shownAt = Date.now(); try { heavyOperation(); } finally { const elapsed = Date.now() - shownAt; const remaining = Math.max(0, 300 - elapsed); const clearExportOverlay = () => { this.exportsInProgress--; if (this.exportsInProgress === 0) { this.updateOverlay(false); _attemptToRestoreCellFocus(beans, this.focusedCell); this.focusedCell = null; } }; if (remaining > 0) { setTimeout(() => clearExportOverlay(), remaining); } else { clearExportOverlay(); } } } hideOverlay() { const gos = this.gos; this.showInitialOverlay = false; const userHadForced = this.userForcedNoRows; this.userForcedNoRows = false; if (gos.get("loading")) { _warn(99); return; } if (gos.get("activeOverlay")) { _warn(296); return; } if (this.currentDef === NoMatchingRowsOverlayDef) { _warn(297); return; } this.doHideOverlay(); if (userHadForced) { if (this.getOverlayDef() !== NoRowsOverlayDef) { this.updateOverlay(false); } } } getOverlayWrapperSelector() { return OverlayWrapperSelector; } getOverlayWrapperCompClass() { return OverlayWrapperComponent; } onPropChange(changedProps) { const activeOverlayChanged = changedProps.has("activeOverlay"); if (activeOverlayChanged || changedProps.has("loading")) { if (this.updateOverlay(activeOverlayChanged)) { return; } } const currentDef = this.currentDef; const currOverlayComp = this.eWrapper?.activeOverlay; if (currOverlayComp && currentDef) { const activeOverlayParamsChanged = changedProps.has("activeOverlayParams"); if (currentDef === CustomOverlayDef) { if (activeOverlayParamsChanged) { currOverlayComp.refresh?.(this.makeCompParams(true)); } } else { const paramsKey = currentDef.paramsKey; if (changedProps.has("overlayComponentParams") || paramsKey && changedProps.has(paramsKey)) { currOverlayComp.refresh?.(this.makeCompParams(false, paramsKey, currentDef.overlayType)); } } } } updateOverlay(activeOverlayChanged) { const eWrapper = this.eWrapper; if (!eWrapper) { this.currentDef = null; return false; } const desiredDef = this.getDesiredDefWithOverride(); const currentDef = this.currentDef; const shouldReload = desiredDef === CustomOverlayDef && activeOverlayChanged; if (desiredDef !== currentDef) { if (!desiredDef) { this.disableInitialOverlay(); return this.doHideOverlay(); } this.doShowOverlay(desiredDef); return true; } if (shouldReload && desiredDef) { eWrapper.hideOverlay(); this.doShowOverlay(desiredDef); return true; } if (!desiredDef) { this.disableInitialOverlay(); } return false; } getDesiredDefWithOverride(defaultDef) { const { gos } = this; let desiredDef = getActiveOverlayDef(gos.get("activeOverlay")); if (!desiredDef) { desiredDef = defaultDef ?? this.getOverlayDef(); if (desiredDef && this.isDisabled(desiredDef)) { desiredDef = null; } } return desiredDef; } getOverlayDef() { const { gos, beans } = this; const { rowModel } = beans; const loading = gos.get("loading"); const loadingDefined = loading !== undefined; if (loadingDefined) { this.disableInitialOverlay(); if (loading) { return LoadingOverlayDef; } } else if (this.showInitialOverlay) { if (!this.isDisabled(LoadingOverlayDef) && (!gos.get("columnDefs") || !gos.get("rowData"))) { return LoadingOverlayDef; } this.disableInitialOverlay(); } else { this.disableInitialOverlay(); } const overlayType = rowModel.getOverlayType(); return getOverlayDefForType(overlayType); } disableInitialOverlay() { this.showInitialOverlay = false; this.newColumnsLoadedCleanup?.(); this.newColumnsLoadedCleanup = null; } doShowOverlay(componentDef) { const { gos, beans } = this; const { userCompFactory } = beans; this.currentDef = componentDef; const isProvidedOverlay = componentDef !== CustomOverlayDef; const exclusive = !!componentDef.exclusive; this.exclusive = exclusive; let legacyParamsKey; if (componentDef.paramsKey && gos.get(componentDef.paramsKey) || componentDef.compKey && gos.get(componentDef.compKey)) { legacyParamsKey = componentDef.paramsKey; } let compDetails = undefined; if (isProvidedOverlay) { if (gos.get("overlayComponent") || gos.get("overlayComponentSelector")) { compDetails = userCompFactory.getCompDetailsFromGridOptions({ name: "overlayComponent", optionalMethods: ["refresh"] }, undefined, this.makeCompParams(false, componentDef.paramsKey, componentDef.overlayType)); } } compDetails ?? (compDetails = userCompFactory.getCompDetailsFromGridOptions(componentDef.comp, isProvidedOverlay ? componentDef.id : undefined, this.makeCompParams(!isProvidedOverlay, legacyParamsKey, componentDef.overlayType), false)); const promise = compDetails?.newAgStackInstance() ?? null; const mountedPromise = this.eWrapper ? this.eWrapper.showOverlay(promise, componentDef.wrapperCls, exclusive) : AgPromise.resolve(); this.eWrapper?.refreshWrapperPadding(); this.setExclusive(exclusive); return mountedPromise; } makeCompParams(includeActiveOverlayParams, legacyParamsKey, overlayType) { const { gos } = this; const params = includeActiveOverlayParams ? gos.get("activeOverlayParams") : { ...gos.get("overlayComponentParams"), ...legacyParamsKey && gos.get(legacyParamsKey) || null, overlayType }; return _addGridCommonParams(gos, params ?? {}); } doHideOverlay() { let changed = false; if (this.currentDef) { this.currentDef = null; changed = true; } this.exclusive = false; const eWrapper = this.eWrapper; if (eWrapper) { eWrapper.hideOverlay(); eWrapper.refreshWrapperPadding(); this.setExclusive(false); } return changed; } setExclusive(exclusive) { if (this.oldExclusive !== exclusive) { this.oldExclusive = exclusive; this.eventSvc.dispatchEvent({ type: "overlayExclusiveChanged" }); } } isDisabled(def) { const { gos } = this; return def.overlayType && gos.get("suppressOverlays")?.includes(def.overlayType) || def.isSuppressed?.(gos) === true; } }; var OverlayModule = { moduleName: "Overlay", version: VERSION, userComponents: { agLoadingOverlay: LoadingOverlayComponent, agNoRowsOverlay: NoRowsOverlayComponent, agNoMatchingRowsOverlay: NoMatchingRowsOverlayComponent, agExportingOverlay: ExportingOverlayComponent }, apiFunctions: { showLoadingOverlay, showNoRowsOverlay, hideOverlay }, icons: { overlayLoading: "loading", overlayExporting: "loading" }, beans: [OverlayService] }; var RowContainerHeightService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "rowContainerHeight"; this.scrollY = 0; this.uiBodyHeight = 0; } postConstruct() { this.addManagedEventListeners({ bodyHeightChanged: this.updateOffset.bind(this) }); this.maxDivHeight = _getMaxDivHeight(); _logIfDebug(this.gos, "RowContainerHeightService - maxDivHeight = " + this.maxDivHeight); } updateOffset() { if (!this.stretching) { return; } const newScrollY = this.beans.ctrlsSvc.getScrollFeature().getVScrollPosition().top; const newBodyHeight = this.getUiBodyHeight(); const atLeastOneChanged = newScrollY !== this.scrollY || newBodyHeight !== this.uiBodyHeight; if (atLeastOneChanged) { this.scrollY = newScrollY; this.uiBodyHeight = newBodyHeight; this.calculateOffset(); } } calculateOffset() { this.setUiContainerHeight(this.maxDivHeight); this.pixelsToShave = this.modelHeight - this.uiContainerHeight; this.maxScrollY = this.uiContainerHeight - this.uiBodyHeight; const scrollPercent = this.scrollY / this.maxScrollY; const divStretchOffset = scrollPercent * this.pixelsToShave; _logIfDebug(this.gos, `RowContainerHeightService - Div Stretch Offset = ${divStretchOffset} (${this.pixelsToShave} * ${scrollPercent})`); this.setDivStretchOffset(divStretchOffset); } setUiContainerHeight(height) { if (height !== this.uiContainerHeight) { this.uiContainerHeight = height; this.eventSvc.dispatchEvent({ type: "rowContainerHeightChanged" }); } } clearOffset() { this.setUiContainerHeight(this.modelHeight); this.pixelsToShave = 0; this.setDivStretchOffset(0); } setDivStretchOffset(newOffset) { const newOffsetFloor = typeof newOffset === "number" ? Math.floor(newOffset) : null; if (this.divStretchOffset === newOffsetFloor) { return; } this.divStretchOffset = newOffsetFloor; this.eventSvc.dispatchEvent({ type: "heightScaleChanged" }); } setModelHeight(modelHeight) { this.modelHeight = modelHeight; this.stretching = modelHeight != null && this.maxDivHeight > 0 && modelHeight > this.maxDivHeight; if (this.stretching) { this.calculateOffset(); } else { this.clearOffset(); } } getRealPixelPosition(modelPixel) { return modelPixel - this.divStretchOffset; } getUiBodyHeight() { const pos = this.beans.ctrlsSvc.getScrollFeature().getVScrollPosition(); return pos.bottom - pos.top; } getScrollPositionForPixel(rowTop) { if (this.pixelsToShave <= 0) { return rowTop; } const modelMaxScroll = this.modelHeight - this.getUiBodyHeight(); const scrollPercent = rowTop / modelMaxScroll; const scrollPixel = this.maxScrollY * scrollPercent; return scrollPixel; } }; var ROW_ANIMATION_TIMEOUT = 400; var RowRenderer = class extends BeanStub { constructor() { super(...arguments); this.beanName = "rowRenderer"; this.destroyFuncsForColumnListeners = []; this.rowCtrlsByRowIndex = {}; this.zombieRowCtrls = {}; this.allRowCtrls = []; this.topRowCtrls = []; this.bottomRowCtrls = []; this.refreshInProgress = false; this.dataFirstRenderedFired = false; this.setupRangeSelectionListeners = () => { const onCellSelectionChanged = () => { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onCellSelectionChanged(); } }; const onColumnMovedPinnedVisible = () => { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.updateRangeBordersIfRangeCount(); } }; const addCellSelectionListeners = () => { this.eventSvc.addListener("cellSelectionChanged", onCellSelectionChanged); this.eventSvc.addListener("columnMoved", onColumnMovedPinnedVisible); this.eventSvc.addListener("columnPinned", onColumnMovedPinnedVisible); this.eventSvc.addListener("columnVisible", onColumnMovedPinnedVisible); }; const removeCellSelectionListeners = () => { this.eventSvc.removeListener("cellSelectionChanged", onCellSelectionChanged); this.eventSvc.removeListener("columnMoved", onColumnMovedPinnedVisible); this.eventSvc.removeListener("columnPinned", onColumnMovedPinnedVisible); this.eventSvc.removeListener("columnVisible", onColumnMovedPinnedVisible); }; this.addDestroyFunc(() => removeCellSelectionListeners()); this.addManagedPropertyListeners(["enableRangeSelection", "cellSelection"], () => { const isEnabled = _isCellSelectionEnabled(this.gos); if (isEnabled) { addCellSelectionListeners(); } else { removeCellSelectionListeners(); } }); const cellSelectionEnabled = _isCellSelectionEnabled(this.gos); if (cellSelectionEnabled) { addCellSelectionListeners(); } }; } wireBeans(beans) { this.pageBounds = beans.pageBounds; this.colModel = beans.colModel; this.pinnedRowModel = beans.pinnedRowModel; this.rowModel = beans.rowModel; this.focusSvc = beans.focusSvc; this.rowContainerHeight = beans.rowContainerHeight; this.ctrlsSvc = beans.ctrlsSvc; this.editSvc = beans.editSvc; } postConstruct() { this.ctrlsSvc.whenReady(this, (p) => { this.gridBodyCtrl = p.gridBodyCtrl; this.initialise(); }); } initialise() { this.addManagedEventListeners({ paginationChanged: this.onPageLoaded.bind(this), pinnedRowDataChanged: this.onPinnedRowDataChanged.bind(this), pinnedRowsChanged: this.onPinnedRowsChanged.bind(this), displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this), bodyScroll: this.onBodyScroll.bind(this), bodyHeightChanged: this.redraw.bind(this, {}) }); this.addManagedPropertyListeners(["domLayout", "embedFullWidthRows"], () => this.onDomLayoutChanged()); this.addManagedPropertyListeners(["suppressMaxRenderedRowRestriction", "rowBuffer"], () => this.redraw()); this.addManagedPropertyListener("suppressCellFocus", (e) => this.onSuppressCellFocusChanged(e.currentValue)); this.addManagedPropertyListeners([ "groupSuppressBlankHeader", "getBusinessKeyForNode", "fullWidthCellRenderer", "fullWidthCellRendererParams", "suppressStickyTotalRow", "groupRowRenderer", "groupRowRendererParams", "loadingCellRenderer", "loadingCellRendererParams", "detailCellRenderer", "detailCellRendererParams", "enableRangeSelection", "enableCellTextSelection" ], () => this.redrawRows()); this.addManagedPropertyListener("cellSelection", ({ currentValue, previousValue }) => { if (!previousValue && currentValue || previousValue && !currentValue) { this.redrawRows(); } }); const { stickyRowSvc, gos, showRowGroupCols } = this.beans; if (showRowGroupCols) { this.addManagedPropertyListener("showOpenedGroup", () => { const columns = showRowGroupCols.columns; if (columns.length) { this.refreshCells({ columns, force: true }); } }); } if (stickyRowSvc) { this.stickyRowFeature = stickyRowSvc.createStickyRowFeature(this, this.createRowCon.bind(this), this.destroyRowCtrls.bind(this)); } else { const gridBodyCtrl = this.gridBodyCtrl; gridBodyCtrl.setStickyTopHeight(0); gridBodyCtrl.setStickyBottomHeight(0); } this.registerCellEventListeners(); this.initialiseCache(); this.printLayout = _isDomLayout(gos, "print"); this.embedFullWidthRows = this.printLayout || gos.get("embedFullWidthRows"); this.redrawAfterModelUpdate(); } initialiseCache() { if (this.gos.get("keepDetailRows")) { const countProp = this.getKeepDetailRowsCount(); const count = countProp != null ? countProp : 3; this.cachedRowCtrls = new RowCtrlCache(count); } } getKeepDetailRowsCount() { return this.gos.get("keepDetailRowsCount"); } getStickyTopRowCtrls() { return this.stickyRowFeature?.stickyTopRowCtrls ?? []; } getStickyBottomRowCtrls() { return this.stickyRowFeature?.stickyBottomRowCtrls ?? []; } updateAllRowCtrls() { const liveList = Object.values(this.rowCtrlsByRowIndex); const zombieList = Object.values(this.zombieRowCtrls); const cachedList = this.cachedRowCtrls?.getEntries() ?? []; if (zombieList.length > 0 || cachedList.length > 0) { this.allRowCtrls = [...liveList, ...zombieList, ...cachedList]; } else { this.allRowCtrls = liveList; } } isCellBeingRendered(rowIndex, column) { const rowCtrl = this.rowCtrlsByRowIndex[rowIndex]; if (!column || !rowCtrl) { return !!rowCtrl; } if (rowCtrl.isFullWidth()) { return true; } const spannedCell = this.beans.spannedRowRenderer?.getCellByPosition({ rowIndex, column, rowPinned: null }); return !!spannedCell || !!rowCtrl.getCellCtrl(column) || !rowCtrl.isRowRendered(); } updateCellFocus(event) { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onCellFocused(event); } for (const rowCtrl of this.getFullWidthRowCtrls()) { rowCtrl.onFullWidthRowFocused(event); } } onCellFocusChanged(event) { if (event?.rowIndex != null && !event.rowPinned) { const col = this.beans.colModel.getCol(event.column) ?? undefined; if (!this.isCellBeingRendered(event.rowIndex, col)) { this.redraw(); } } this.updateCellFocus(event); } onSuppressCellFocusChanged(suppressCellFocus) { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onSuppressCellFocusChanged(suppressCellFocus); } for (const rowCtrl of this.getFullWidthRowCtrls()) { rowCtrl.onSuppressCellFocusChanged(suppressCellFocus); } } registerCellEventListeners() { this.addManagedEventListeners({ cellFocused: (event) => this.onCellFocusChanged(event), cellFocusCleared: () => this.updateCellFocus(), flashCells: (event) => { const { cellFlashSvc } = this.beans; if (cellFlashSvc) { for (const cellCtrl of this.getAllCellCtrls()) { cellFlashSvc.onFlashCells(cellCtrl, event); } } }, columnHoverChanged: () => { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onColumnHover(); } }, displayedColumnsChanged: () => { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onDisplayedColumnsChanged(); } }, displayedColumnsWidthChanged: () => { if (this.printLayout) { for (const cellCtrl of this.getAllCellCtrls()) { cellCtrl.onLeftChanged(); } } } }); this.setupRangeSelectionListeners(); this.refreshListenersToColumnsForCellComps(); this.addManagedEventListeners({ gridColumnsChanged: this.refreshListenersToColumnsForCellComps.bind(this) }); this.addDestroyFunc(this.removeGridColumnListeners.bind(this)); } removeGridColumnListeners() { for (const func of this.destroyFuncsForColumnListeners) { func(); } this.destroyFuncsForColumnListeners.length = 0; } refreshListenersToColumnsForCellComps() { this.removeGridColumnListeners(); const cols = this.colModel.getCols(); for (const col of cols) { const forEachCellWithThisCol = (callback) => { for (const cellCtrl of this.getAllCellCtrls()) { if (cellCtrl.column === col) { callback(cellCtrl); } } }; const leftChangedListener = () => { forEachCellWithThisCol((cellCtrl) => cellCtrl.onLeftChanged()); }; const widthChangedListener = () => { forEachCellWithThisCol((cellCtrl) => cellCtrl.onWidthChanged()); }; const firstRightPinnedChangedListener = () => { forEachCellWithThisCol((cellCtrl) => cellCtrl.onFirstRightPinnedChanged()); }; const lastLeftPinnedChangedListener = () => { forEachCellWithThisCol((cellCtrl) => cellCtrl.onLastLeftPinnedChanged()); }; const colDefChangedListener = () => { forEachCellWithThisCol((cellCtrl) => cellCtrl.onColDefChanged()); }; col.__addEventListener("leftChanged", leftChangedListener); col.__addEventListener("widthChanged", widthChangedListener); col.__addEventListener("firstRightPinnedChanged", firstRightPinnedChangedListener); col.__addEventListener("lastLeftPinnedChanged", lastLeftPinnedChangedListener); col.__addEventListener("colDefChanged", colDefChangedListener); this.destroyFuncsForColumnListeners.push(() => { col.__removeEventListener("leftChanged", leftChangedListener); col.__removeEventListener("widthChanged", widthChangedListener); col.__removeEventListener("firstRightPinnedChanged", firstRightPinnedChangedListener); col.__removeEventListener("lastLeftPinnedChanged", lastLeftPinnedChangedListener); col.__removeEventListener("colDefChanged", colDefChangedListener); }); } } onDomLayoutChanged() { const printLayout = _isDomLayout(this.gos, "print"); const embedFullWidthRows = printLayout || this.gos.get("embedFullWidthRows"); const destroyRows = embedFullWidthRows !== this.embedFullWidthRows || this.printLayout !== printLayout; this.printLayout = printLayout; this.embedFullWidthRows = embedFullWidthRows; if (destroyRows) { this.redrawAfterModelUpdate({ domLayoutChanged: true }); } } datasourceChanged() { this.firstRenderedRow = 0; this.lastRenderedRow = -1; const rowIndexesToRemove = Object.keys(this.rowCtrlsByRowIndex); this.removeRowCtrls(rowIndexesToRemove); } onPageLoaded(event) { const params = { recycleRows: event.keepRenderedRows, animate: event.animate, newData: event.newData, newPage: event.newPage, onlyBody: true }; this.redrawAfterModelUpdate(params); } getAllCellsNotSpanningForColumn(column) { const res = []; for (const rowCtrl of this.getAllRowCtrls()) { const eCell = rowCtrl.getCellCtrl(column, true)?.eGui; if (eCell) { res.push(eCell); } } return res; } refreshFloatingRowComps(recycleRows = true) { this.refreshFloatingRows(this.topRowCtrls, "top", recycleRows); this.refreshFloatingRows(this.bottomRowCtrls, "bottom", recycleRows); } refreshFloatingRows(rowCtrls, floating, recycleRows) { const { pinnedRowModel, beans, printLayout } = this; const rowCtrlMap = Object.fromEntries(rowCtrls.map((ctrl) => [ctrl.rowNode.id, ctrl])); pinnedRowModel?.forEachPinnedRow(floating, (node, i) => { const rowCtrl = rowCtrls[i]; const rowCtrlDoesNotExist = rowCtrl && pinnedRowModel.getPinnedRowById(rowCtrl.rowNode.id, floating) === undefined; if (rowCtrlDoesNotExist) { rowCtrl.destroyFirstPass(); rowCtrl.destroySecondPass(); } if (node.id in rowCtrlMap && recycleRows) { rowCtrls[i] = rowCtrlMap[node.id]; delete rowCtrlMap[node.id]; } else { rowCtrls[i] = new RowCtrl(node, beans, false, false, printLayout); } }); const rowNodeCount = (floating === "top" ? pinnedRowModel?.getPinnedTopRowCount() : pinnedRowModel?.getPinnedBottomRowCount()) ?? 0; rowCtrls.length = rowNodeCount; } onPinnedRowDataChanged() { const params = { recycleRows: true }; this.redrawAfterModelUpdate(params); } onPinnedRowsChanged() { this.redrawAfterModelUpdate({ recycleRows: true }); } redrawRow(rowNode, suppressEvent = false) { if (rowNode.sticky) { this.stickyRowFeature?.refreshStickyNode(rowNode); } else if (this.cachedRowCtrls?.has(rowNode)) { this.cachedRowCtrls.removeRow(rowNode); return; } else { const destroyAndRecreateCtrl = (dataStruct) => { const ctrl = dataStruct[rowNode.rowIndex]; if (!ctrl) { return; } if (ctrl.rowNode !== rowNode) { return; } ctrl.destroyFirstPass(); ctrl.destroySecondPass(); dataStruct[rowNode.rowIndex] = this.createRowCon(rowNode, false, false); }; switch (rowNode.rowPinned) { case "top": destroyAndRecreateCtrl(this.topRowCtrls); break; case "bottom": destroyAndRecreateCtrl(this.bottomRowCtrls); break; default: destroyAndRecreateCtrl(this.rowCtrlsByRowIndex); this.updateAllRowCtrls(); } } if (!suppressEvent) { this.dispatchDisplayedRowsChanged(false); } } redrawRows(rowNodes) { const { editSvc } = this.beans; if (editSvc?.isEditing()) { if (editSvc.isBatchEditing()) { editSvc.cleanupEditors(); } else { editSvc.stopEditing(undefined, { source: "api" }); } } const partialRefresh = rowNodes != null; if (partialRefresh) { for (const node of rowNodes ?? []) { this.redrawRow(node, true); } this.dispatchDisplayedRowsChanged(false); return; } this.redrawAfterModelUpdate(); } redrawAfterModelUpdate(params = {}) { this.getLockOnRefresh(); const focusedCell = this.beans.focusSvc?.getFocusCellToUseAfterRefresh(); this.updateContainerHeights(); this.scrollToTopIfNewData(params); const recycleRows = !params.domLayoutChanged && !!params.recycleRows; const animate = params.animate && _isAnimateRows(this.gos); const rowsToRecycle = recycleRows ? this.getRowsToRecycle() : null; if (!recycleRows) { this.removeAllRowComps(); } this.workOutFirstAndLastRowsToRender(); const { stickyRowFeature, gos } = this; if (stickyRowFeature) { stickyRowFeature.checkStickyRows(); const extraHeight = stickyRowFeature.extraTopHeight + stickyRowFeature.extraBottomHeight; if (extraHeight) { this.updateContainerHeights(extraHeight); } } this.recycleRows(rowsToRecycle, animate); this.gridBodyCtrl.updateRowCount(); if (!params.onlyBody) { this.refreshFloatingRowComps(gos.get("enableRowPinning") ? recycleRows : undefined); } this.dispatchDisplayedRowsChanged(); if (focusedCell != null) { this.restoreFocusedCell(focusedCell); } this.releaseLockOnRefresh(); } scrollToTopIfNewData(params) { const scrollToTop = params.newData || params.newPage; const suppressScrollToTop = this.gos.get("suppressScrollOnNewData"); if (scrollToTop && !suppressScrollToTop) { this.gridBodyCtrl.scrollFeature.scrollToTop(); this.stickyRowFeature?.resetOffsets(); } } updateContainerHeights(additionalHeight = 0) { const { rowContainerHeight } = this; if (this.printLayout) { rowContainerHeight.setModelHeight(null); return; } let containerHeight = this.pageBounds.getCurrentPageHeight(); if (containerHeight === 0) { containerHeight = 1; } rowContainerHeight.setModelHeight(containerHeight + additionalHeight); } getLockOnRefresh() { if (this.refreshInProgress) { throw new Error(_errMsg(252)); } this.refreshInProgress = true; this.beans.frameworkOverrides.getLockOnRefresh?.(); } releaseLockOnRefresh() { this.refreshInProgress = false; this.beans.frameworkOverrides.releaseLockOnRefresh?.(); } isRefreshInProgress() { return this.refreshInProgress; } restoreFocusedCell(cellPosition) { if (!cellPosition) { return; } const focusSvc = this.beans.focusSvc; const cellToFocus = this.findPositionToFocus(cellPosition); if (!cellToFocus) { focusSvc.focusHeaderPosition({ headerPosition: { headerRowIndex: getFocusHeaderRowCount(this.beans) - 1, column: cellPosition.column } }); return; } if (cellPosition.rowIndex !== cellToFocus.rowIndex || cellPosition.rowPinned != cellToFocus.rowPinned) { focusSvc.setFocusedCell({ ...cellToFocus, preventScrollOnBrowserFocus: true, forceBrowserFocus: true }); return; } if (!focusSvc.doesRowOrCellHaveBrowserFocus()) { this.updateCellFocus(_addGridCommonParams(this.gos, { ...cellToFocus, forceBrowserFocus: true, preventScrollOnBrowserFocus: true, type: "cellFocused" })); } } findPositionToFocus(cellPosition) { const { pagination, pageBounds } = this.beans; let rowPosition = cellPosition; if (rowPosition.rowPinned == null && pagination && pageBounds && !pagination.isRowInPage(rowPosition.rowIndex)) { rowPosition = { rowPinned: null, rowIndex: pageBounds.getFirstRow() }; } while (rowPosition) { if (rowPosition.rowPinned == null && pageBounds) { if (rowPosition.rowIndex < pageBounds.getFirstRow()) { rowPosition = _getRowAbove(this.beans, { rowPinned: null, rowIndex: 0 }); if (!rowPosition) { return null; } } else if (rowPosition.rowIndex > pageBounds.getLastRow()) { rowPosition = { rowPinned: null, rowIndex: pageBounds.getLastRow() }; } } const row = this.getRowByPosition(rowPosition); if (row?.isAlive()) { return { ...row.getRowPosition(), column: cellPosition.column }; } rowPosition = _getRowAbove(this.beans, rowPosition); } return null; } getAllCellCtrls() { const res = []; const rowCtrls = this.getAllRowCtrls(); const rowCtrlsLength = rowCtrls.length; for (let i = 0;i < rowCtrlsLength; i++) { const cellCtrls = rowCtrls[i].getAllCellCtrls(); const cellCtrlsLength = cellCtrls.length; for (let j = 0;j < cellCtrlsLength; j++) { res.push(cellCtrls[j]); } } return res; } getAllRowCtrls() { const { spannedRowRenderer } = this.beans; const stickyTopRowCtrls = this.getStickyTopRowCtrls(); const stickyBottomRowCtrls = this.getStickyBottomRowCtrls(); const res = [ ...this.topRowCtrls, ...this.bottomRowCtrls, ...stickyTopRowCtrls, ...stickyBottomRowCtrls, ...spannedRowRenderer?.getCtrls("top") ?? [], ...spannedRowRenderer?.getCtrls("bottom") ?? [], ...spannedRowRenderer?.getCtrls("center") ?? [], ...Object.values(this.rowCtrlsByRowIndex) ]; return res; } addRenderedRowListener(eventName, rowIndex, callback) { const rowComp = this.rowCtrlsByRowIndex[rowIndex]; if (rowComp) { rowComp.addEventListener(eventName, callback); } } refreshCells({ rowNodes, columns, force, suppressFlash } = {}) { const refreshCellParams = { force, newData: false, suppressFlash }; for (const cellCtrl of this.getCellCtrls(rowNodes, columns)) { cellCtrl.refreshOrDestroyCell(refreshCellParams); } this.refreshFullWidth(rowNodes); } refreshRows(params = {}) { for (const rowCtrl of this.getRowCtrls(params.rowNodes)) { rowCtrl.refreshRow(params); } this.refreshFullWidth(params.rowNodes); } getRowCtrlByNode(node) { const rowIndex = node.rowIndex; if (rowIndex == null) { return; } const rowPinned = node.rowPinned; if (rowPinned === "top") { const ctrl2 = this.topRowCtrls[rowIndex]; return ctrl2?.rowNode === node ? ctrl2 : undefined; } if (rowPinned === "bottom") { const ctrl2 = this.bottomRowCtrls[rowIndex]; return ctrl2?.rowNode === node ? ctrl2 : undefined; } const ctrl = this.rowCtrlsByRowIndex[rowIndex]; if (ctrl?.rowNode === node) { return ctrl; } return this.getStickyRowCtrlByNode(node); } getStickyRowCtrlByNode(node) { const stickyRowFeature = this.stickyRowFeature; if (!stickyRowFeature) { return; } for (const c of stickyRowFeature.stickyTopRowCtrls) { if (c.rowNode === node) { return c; } } for (const c of stickyRowFeature.stickyBottomRowCtrls) { if (c.rowNode === node) { return c; } } return; } refreshRowByNode(node) { if (node) { this.getRowCtrlByNode(node)?.refreshRow(); } } refreshFullWidth(rowNodes) { if (!rowNodes) { return; } let rowRedrawn = false; for (const rowCtrl of this.getRowCtrls(rowNodes)) { if (!rowCtrl.isFullWidth()) { continue; } const refreshed = rowCtrl.refreshFullWidth(); if (!refreshed) { rowRedrawn = true; this.redrawRow(rowCtrl.rowNode, true); } } if (rowRedrawn) { this.dispatchDisplayedRowsChanged(false); } } getRowCtrls(rowNodes) { const rowIdsMap = mapRowNodes(rowNodes); const allRowCtrls = this.getAllRowCtrls(); if (!rowNodes || !rowIdsMap) { return allRowCtrls; } return allRowCtrls.filter((rowCtrl) => { const rowNode = rowCtrl.rowNode; return isRowInMap(rowNode, rowIdsMap); }); } getCellCtrls(rowNodes, columns) { let colIdsMap; if (_exists(columns)) { colIdsMap = {}; columns.forEach((colKey) => { const column = this.colModel.getCol(colKey); if (_exists(column)) { colIdsMap[column.getId()] = true; } }); } const res = []; for (const rowCtrl of this.getRowCtrls(rowNodes)) { for (const cellCtrl of rowCtrl.getAllCellCtrls()) { const colId = cellCtrl.column.getId(); const excludeColFromRefresh = colIdsMap && !colIdsMap[colId]; if (excludeColFromRefresh) { continue; } res.push(cellCtrl); } } return res; } destroy() { this.removeAllRowComps(true); super.destroy(); } removeAllRowComps(suppressAnimation = false) { const rowIndexesToRemove = Object.keys(this.rowCtrlsByRowIndex); this.removeRowCtrls(rowIndexesToRemove, suppressAnimation); this.stickyRowFeature?.destroyStickyCtrls(); } getRowsToRecycle() { const stubNodeIndexes = []; for (const index of Object.keys(this.rowCtrlsByRowIndex)) { const rowCtrl = this.rowCtrlsByRowIndex[index]; const stubNode = rowCtrl.rowNode.id == null; if (stubNode) { stubNodeIndexes.push(index); } } this.removeRowCtrls(stubNodeIndexes); const ctrlsByIdMap = {}; for (const rowCtrl of Object.values(this.rowCtrlsByRowIndex)) { const rowNode = rowCtrl.rowNode; ctrlsByIdMap[rowNode.id] = rowCtrl; } this.rowCtrlsByRowIndex = {}; return ctrlsByIdMap; } removeRowCtrls(rowsToRemove, suppressAnimation = false) { for (const indexToRemove of rowsToRemove) { const rowCtrl = this.rowCtrlsByRowIndex[indexToRemove]; if (rowCtrl) { rowCtrl.destroyFirstPass(suppressAnimation); rowCtrl.destroySecondPass(); } delete this.rowCtrlsByRowIndex[indexToRemove]; } } onBodyScroll(e) { if (e.direction !== "vertical") { return; } this.redraw({ afterScroll: true }); } redraw(params = {}) { const { focusSvc, animationFrameSvc } = this.beans; const { afterScroll } = params; let cellFocused; const stickyRowFeature = this.stickyRowFeature; if (stickyRowFeature) { cellFocused = focusSvc?.getFocusCellToUseAfterRefresh() || undefined; } const oldFirstRow = this.firstRenderedRow; const oldLastRow = this.lastRenderedRow; this.workOutFirstAndLastRowsToRender(); let hasStickyRowChanges = false; if (stickyRowFeature) { hasStickyRowChanges = stickyRowFeature.checkStickyRows(); const extraHeight = stickyRowFeature.extraTopHeight + stickyRowFeature.extraBottomHeight; if (extraHeight) { this.updateContainerHeights(extraHeight); } } const rangeChanged = this.firstRenderedRow !== oldFirstRow || this.lastRenderedRow !== oldLastRow; if (afterScroll && !hasStickyRowChanges && !rangeChanged) { return; } this.getLockOnRefresh(); this.recycleRows(null, false, afterScroll); this.releaseLockOnRefresh(); this.dispatchDisplayedRowsChanged(afterScroll && !hasStickyRowChanges); if (cellFocused != null) { const newFocusedCell = focusSvc?.getFocusCellToUseAfterRefresh(); if (cellFocused != null && newFocusedCell == null) { animationFrameSvc?.flushAllFrames(); this.restoreFocusedCell(cellFocused); } } } removeRowCompsNotToDraw(indexesToDraw, suppressAnimation) { const indexesToDrawMap = {}; for (const index of indexesToDraw) { indexesToDrawMap[index] = true; } const existingIndexes = Object.keys(this.rowCtrlsByRowIndex); const indexesNotToDraw = existingIndexes.filter((index) => !indexesToDrawMap[index]); this.removeRowCtrls(indexesNotToDraw, suppressAnimation); } calculateIndexesToDraw(rowsToRecycle) { const indexesToDraw = []; for (let i = this.firstRenderedRow;i <= this.lastRenderedRow; i++) { indexesToDraw.push(i); } const pagination = this.beans.pagination; const focusedRowIndex = this.beans.focusSvc?.getFocusedCell()?.rowIndex; if (focusedRowIndex != null && (focusedRowIndex < this.firstRenderedRow || focusedRowIndex > this.lastRenderedRow) && (!pagination || pagination.isRowInPage(focusedRowIndex)) && focusedRowIndex < this.rowModel.getRowCount()) { indexesToDraw.push(focusedRowIndex); } const checkRowToDraw = (rowComp) => { const index = rowComp.rowNode.rowIndex; if (index == null || index === focusedRowIndex) { return; } if (index < this.firstRenderedRow || index > this.lastRenderedRow) { if (this.doNotUnVirtualiseRow(rowComp)) { indexesToDraw.push(index); } } }; for (const rowCtrl of Object.values(this.rowCtrlsByRowIndex)) { checkRowToDraw(rowCtrl); } if (rowsToRecycle) { for (const rowCtrl of Object.values(rowsToRecycle)) { checkRowToDraw(rowCtrl); } } indexesToDraw.sort((a, b) => a - b); const ret = []; for (let i = 0;i < indexesToDraw.length; i++) { const currRow = indexesToDraw[i]; const rowNode = this.rowModel.getRow(currRow); if (rowNode && !rowNode.sticky) { ret.push(currRow); } } return ret; } recycleRows(rowsToRecycle, animate = false, afterScroll = false) { const indexesToDraw = this.calculateIndexesToDraw(rowsToRecycle); if (this.printLayout || afterScroll) { animate = false; } this.removeRowCompsNotToDraw(indexesToDraw, !animate); for (const rowIndex of indexesToDraw) { this.createOrUpdateRowCtrl(rowIndex, rowsToRecycle, animate, afterScroll); } if (rowsToRecycle) { const { animationFrameSvc } = this.beans; const useAnimationFrame = animationFrameSvc?.active && afterScroll && !this.printLayout; if (useAnimationFrame) { animationFrameSvc.addDestroyTask(() => { this.destroyRowCtrls(rowsToRecycle, animate); this.updateAllRowCtrls(); this.dispatchDisplayedRowsChanged(); }); } else { this.destroyRowCtrls(rowsToRecycle, animate); } } this.updateAllRowCtrls(); } dispatchDisplayedRowsChanged(afterScroll = false) { this.eventSvc.dispatchEvent({ type: "displayedRowsChanged", afterScroll }); } onDisplayedColumnsChanged() { const { visibleCols } = this.beans; const pinningLeft = visibleCols.isPinningLeft(); const pinningRight = visibleCols.isPinningRight(); const atLeastOneChanged = this.pinningLeft !== pinningLeft || pinningRight !== this.pinningRight; if (atLeastOneChanged) { this.pinningLeft = pinningLeft; this.pinningRight = pinningRight; if (this.embedFullWidthRows) { this.redrawFullWidthEmbeddedRows(); } } } redrawFullWidthEmbeddedRows() { const rowsToRemove = []; for (const fullWidthCtrl of this.getFullWidthRowCtrls()) { const rowIndex = fullWidthCtrl.rowNode.rowIndex; rowsToRemove.push(rowIndex.toString()); } this.refreshFloatingRowComps(); this.removeRowCtrls(rowsToRemove); this.redraw({ afterScroll: true }); } getFullWidthRowCtrls(rowNodes) { const rowNodesMap = mapRowNodes(rowNodes); return this.getAllRowCtrls().filter((rowCtrl) => { if (!rowCtrl.isFullWidth()) { return false; } const rowNode = rowCtrl.rowNode; if (rowNodesMap != null && !isRowInMap(rowNode, rowNodesMap)) { return false; } return true; }); } createOrUpdateRowCtrl(rowIndex, rowsToRecycle, animate, afterScroll) { let rowNode; let rowCtrl = this.rowCtrlsByRowIndex[rowIndex]; if (!rowCtrl) { rowNode = this.rowModel.getRow(rowIndex); if (_exists(rowNode) && _exists(rowsToRecycle) && rowsToRecycle[rowNode.id] && rowNode.alreadyRendered) { rowCtrl = rowsToRecycle[rowNode.id]; rowsToRecycle[rowNode.id] = null; } } const creatingNewRowCtrl = !rowCtrl; if (creatingNewRowCtrl) { if (!rowNode) { rowNode = this.rowModel.getRow(rowIndex); } if (_exists(rowNode)) { rowCtrl = this.createRowCon(rowNode, animate, afterScroll); } else { return; } } if (rowNode) { rowNode.alreadyRendered = true; } this.rowCtrlsByRowIndex[rowIndex] = rowCtrl; } destroyRowCtrls(rowCtrlsMap, animate) { const executeInAWhileFuncs = []; if (rowCtrlsMap) { for (const rowCtrl of Object.values(rowCtrlsMap)) { if (!rowCtrl) { continue; } if (this.cachedRowCtrls && rowCtrl.isCacheable()) { this.cachedRowCtrls.addRow(rowCtrl); continue; } rowCtrl.destroyFirstPass(!animate); if (animate) { const instanceId = rowCtrl.instanceId; this.zombieRowCtrls[instanceId] = rowCtrl; executeInAWhileFuncs.push(() => { rowCtrl.destroySecondPass(); delete this.zombieRowCtrls[instanceId]; }); } else { rowCtrl.destroySecondPass(); } } } if (animate) { executeInAWhileFuncs.push(() => { if (this.isAlive()) { this.updateAllRowCtrls(); this.dispatchDisplayedRowsChanged(); } }); window.setTimeout(() => { for (const func of executeInAWhileFuncs) { func(); } }, ROW_ANIMATION_TIMEOUT); } } getRowBuffer() { return this.gos.get("rowBuffer"); } getRowBufferInPixels() { const rowsToBuffer = this.getRowBuffer(); const defaultRowHeight = _getRowHeightAsNumber(this.beans); return rowsToBuffer * defaultRowHeight; } workOutFirstAndLastRowsToRender() { const { rowContainerHeight, pageBounds, rowModel } = this; rowContainerHeight.updateOffset(); let newFirst; let newLast; if (!rowModel.isRowsToRender()) { newFirst = 0; newLast = -1; } else if (this.printLayout) { this.beans.environment.refreshRowHeightVariable(); newFirst = pageBounds.getFirstRow(); newLast = pageBounds.getLastRow(); } else { const bufferPixels = this.getRowBufferInPixels(); const scrollFeature = this.ctrlsSvc.getScrollFeature(); const suppressRowVirtualisation = this.gos.get("suppressRowVirtualisation"); let rowHeightsChanged = false; let firstPixel; let lastPixel; do { const paginationOffset = pageBounds.getPixelOffset(); const { pageFirstPixel, pageLastPixel } = pageBounds.getCurrentPagePixelRange(); const divStretchOffset = rowContainerHeight.divStretchOffset; const bodyVRange = scrollFeature.getVScrollPosition(); const bodyTopPixel = bodyVRange.top; const bodyBottomPixel = bodyVRange.bottom; if (suppressRowVirtualisation) { firstPixel = pageFirstPixel + divStretchOffset; lastPixel = pageLastPixel + divStretchOffset; } else { firstPixel = Math.max(bodyTopPixel + paginationOffset - bufferPixels, pageFirstPixel) + divStretchOffset; lastPixel = Math.min(bodyBottomPixel + paginationOffset + bufferPixels, pageLastPixel) + divStretchOffset; } this.firstVisibleVPixel = Math.max(bodyTopPixel + paginationOffset, pageFirstPixel) + divStretchOffset; this.lastVisibleVPixel = Math.min(bodyBottomPixel + paginationOffset, pageLastPixel) + divStretchOffset; rowHeightsChanged = this.ensureAllRowsInRangeHaveHeightsCalculated(firstPixel, lastPixel); } while (rowHeightsChanged); let firstRowIndex = rowModel.getRowIndexAtPixel(firstPixel); let lastRowIndex = rowModel.getRowIndexAtPixel(lastPixel); const pageFirstRow = pageBounds.getFirstRow(); const pageLastRow = pageBounds.getLastRow(); if (firstRowIndex < pageFirstRow) { firstRowIndex = pageFirstRow; } if (lastRowIndex > pageLastRow) { lastRowIndex = pageLastRow; } newFirst = firstRowIndex; newLast = lastRowIndex; } const rowLayoutNormal = _isDomLayout(this.gos, "normal"); const suppressRowCountRestriction = this.gos.get("suppressMaxRenderedRowRestriction"); const rowBufferMaxSize = Math.max(this.getRowBuffer(), 500); if (rowLayoutNormal && !suppressRowCountRestriction) { if (newLast - newFirst > rowBufferMaxSize) { newLast = newFirst + rowBufferMaxSize; } } const firstDiffers = newFirst !== this.firstRenderedRow; const lastDiffers = newLast !== this.lastRenderedRow; if (firstDiffers || lastDiffers) { this.firstRenderedRow = newFirst; this.lastRenderedRow = newLast; this.eventSvc.dispatchEvent({ type: "viewportChanged", firstRow: newFirst, lastRow: newLast }); } } dispatchFirstDataRenderedEvent() { if (this.dataFirstRenderedFired) { return; } this.dataFirstRenderedFired = true; _requestAnimationFrame(this.beans, () => { this.beans.eventSvc.dispatchEvent({ type: "firstDataRendered", firstRow: this.firstRenderedRow, lastRow: this.lastRenderedRow }); }); } ensureAllRowsInRangeHaveHeightsCalculated(topPixel, bottomPixel) { const pinnedRowHeightsChanged = this.pinnedRowModel?.ensureRowHeightsValid(); const stickyHeightsChanged = this.stickyRowFeature?.ensureRowHeightsValid(); const { pageBounds, rowModel } = this; const rowModelHeightsChanged = rowModel.ensureRowHeightsValid(topPixel, bottomPixel, pageBounds.getFirstRow(), pageBounds.getLastRow()); if (rowModelHeightsChanged || stickyHeightsChanged) { this.eventSvc.dispatchEvent({ type: "recalculateRowBounds" }); } if (stickyHeightsChanged || rowModelHeightsChanged || pinnedRowHeightsChanged) { this.updateContainerHeights(); return true; } return false; } doNotUnVirtualiseRow(rowCtrl) { const REMOVE_ROW = false; const KEEP_ROW = true; const rowNode = rowCtrl.rowNode; const rowHasFocus = this.focusSvc.isRowFocused(rowNode.rowIndex, rowNode.rowPinned); const rowIsEditing = this.editSvc?.isEditing(rowCtrl); const rowIsDetail = rowNode.detail; const mightWantToKeepRow = rowHasFocus || rowIsEditing || rowIsDetail; if (!mightWantToKeepRow) { return REMOVE_ROW; } const rowNodePresent = this.isRowPresent(rowNode); return rowNodePresent ? KEEP_ROW : REMOVE_ROW; } isRowPresent(rowNode) { if (!this.rowModel.isRowPresent(rowNode)) { return false; } return this.beans.pagination?.isRowInPage(rowNode.rowIndex) ?? true; } createRowCon(rowNode, animate, afterScroll) { const rowCtrlFromCache = this.cachedRowCtrls?.getRow(rowNode) ?? null; if (rowCtrlFromCache) { return rowCtrlFromCache; } const useAnimationFrameForCreate = afterScroll && !this.printLayout && !!this.beans.animationFrameSvc?.active; const res = new RowCtrl(rowNode, this.beans, animate, useAnimationFrameForCreate, this.printLayout); return res; } getRenderedNodes() { const viewportRows = Object.values(this.rowCtrlsByRowIndex).map((rowCtrl) => rowCtrl.rowNode); const stickyTopRows = this.getStickyTopRowCtrls().map((rowCtrl) => rowCtrl.rowNode); const stickyBottomRows = this.getStickyBottomRowCtrls().map((rowCtrl) => rowCtrl.rowNode); return [...stickyTopRows, ...viewportRows, ...stickyBottomRows]; } getRowByPosition(rowPosition) { let rowCtrl; const { rowIndex } = rowPosition; switch (rowPosition.rowPinned) { case "top": rowCtrl = this.topRowCtrls[rowIndex]; break; case "bottom": rowCtrl = this.bottomRowCtrls[rowIndex]; break; default: rowCtrl = this.rowCtrlsByRowIndex[rowIndex]; if (!rowCtrl) { rowCtrl = this.getStickyTopRowCtrls().find((ctrl) => ctrl.rowNode.rowIndex === rowIndex) || null; if (!rowCtrl) { rowCtrl = this.getStickyBottomRowCtrls().find((ctrl) => ctrl.rowNode.rowIndex === rowIndex) || null; } } break; } return rowCtrl; } isRangeInRenderedViewport(startIndex, endIndex) { const parentClosed = startIndex == null || endIndex == null; if (parentClosed) { return false; } const blockAfterViewport = startIndex > this.lastRenderedRow; const blockBeforeViewport = endIndex < this.firstRenderedRow; const blockInsideViewport = !blockBeforeViewport && !blockAfterViewport; return blockInsideViewport; } }; var RowCtrlCache = class { constructor(maxCount) { this.entriesMap = {}; this.entriesList = []; this.maxCount = maxCount; } addRow(rowCtrl) { this.entriesMap[rowCtrl.rowNode.id] = rowCtrl; this.entriesList.push(rowCtrl); rowCtrl.setCached(true); if (this.entriesList.length > this.maxCount) { const rowCtrlToDestroy = this.entriesList[0]; rowCtrlToDestroy.destroyFirstPass(); rowCtrlToDestroy.destroySecondPass(); this.removeFromCache(rowCtrlToDestroy); } } getRow(rowNode) { if (rowNode?.id == null) { return null; } const res = this.entriesMap[rowNode.id]; if (!res) { return null; } this.removeFromCache(res); res.setCached(false); const rowNodeMismatch = res.rowNode != rowNode; return rowNodeMismatch ? null : res; } has(rowNode) { return this.entriesMap[rowNode.id] != null; } removeRow(rowNode) { const rowNodeId = rowNode.id; const ctrl = this.entriesMap[rowNodeId]; delete this.entriesMap[rowNodeId]; _removeFromArray(this.entriesList, ctrl); } removeFromCache(rowCtrl) { const rowNodeId = rowCtrl.rowNode.id; delete this.entriesMap[rowNodeId]; _removeFromArray(this.entriesList, rowCtrl); } getEntries() { return this.entriesList; } }; function mapRowNodes(rowNodes) { if (!rowNodes) { return; } const res = { top: {}, bottom: {}, normal: {} }; for (const rowNode of rowNodes) { const id = rowNode.id; switch (rowNode.rowPinned) { case "top": res.top[id] = rowNode; break; case "bottom": res.bottom[id] = rowNode; break; default: res.normal[id] = rowNode; break; } } return res; } function isRowInMap(rowNode, rowIdsMap) { const id = rowNode.id; const floating = rowNode.rowPinned; switch (floating) { case "top": return rowIdsMap.top[id] != null; case "bottom": return rowIdsMap.bottom[id] != null; default: return rowIdsMap.normal[id] != null; } } var RowNodeSorter = class extends BeanStub { constructor() { super(...arguments); this.beanName = "rowNodeSorter"; this.accentedSort = false; this.primaryColumnsSortGroups = false; this.pivotActive = false; } postConstruct() { this.firstLeaf = _isClientSideRowModel(this.gos) ? _csrmFirstLeaf : defaultGetLeaf; this.addManagedPropertyListeners(["accentedSort", "autoGroupColumnDef", "treeData"], this.updateOptions.bind(this)); const updatePivotModeState = this.updatePivotModeState.bind(this); this.addManagedEventListeners({ columnPivotModeChanged: updatePivotModeState, columnPivotChanged: updatePivotModeState }); this.updateOptions(); updatePivotModeState(); } updateOptions() { this.accentedSort = !!this.gos.get("accentedSort"); this.primaryColumnsSortGroups = _isColumnsSortingCoupledToGroup(this.gos); } updatePivotModeState() { this.pivotActive = this.beans.colModel.isPivotActive(); } doFullSortInPlace(rowNodes, sortOptions) { return rowNodes.sort((a, b) => this.compareRowNodes(sortOptions, a, b)); } compareRowNodes(sortOptions, nodeA, nodeB) { if (nodeA === nodeB) { return 0; } const accentedCompare = this.accentedSort; for (let i = 0, len = sortOptions.length;i < len; ++i) { const sortOption = sortOptions[i]; const isDescending = sortOption.sort === "desc"; let valueA = this.getValue(nodeA, sortOption.column); let valueB = this.getValue(nodeB, sortOption.column); let comparatorResult; const providedComparator = this.getComparator(sortOption, nodeA); if (providedComparator) { comparatorResult = providedComparator(valueA, valueB, nodeA, nodeB, isDescending); } else { if (sortOption.type === "absolute") { valueA = absoluteValueTransformer(valueA); valueB = absoluteValueTransformer(valueB); } comparatorResult = _defaultComparator(valueA, valueB, accentedCompare); } if (comparatorResult) { return sortOption.sort === "asc" ? comparatorResult : -comparatorResult; } } return 0; } getComparator(sortOption, rowNode) { const colDef = sortOption.column.getColDef(); const comparatorOnCol = this.getComparatorFromColDef(colDef, sortOption); if (comparatorOnCol) { return comparatorOnCol; } if (!colDef.showRowGroup) { return; } const groupLeafField = !rowNode.group && colDef.field; if (!groupLeafField) { return; } const primaryColumn = this.beans.colModel.getColDefCol(groupLeafField); if (!primaryColumn) { return; } return this.getComparatorFromColDef(primaryColumn.getColDef(), sortOption); } getComparatorFromColDef(colDef, sortOption) { const comparator = colDef.comparator; if (comparator == null) { return; } if (typeof comparator === "object") { return comparator[_normalizeSortType(sortOption.type)]; } return comparator; } getValue(node, column) { const beans = this.beans; if (this.primaryColumnsSortGroups) { if (node.rowGroupColumn === column) { return this.getGroupDataValue(node, column); } if (node.group && column.getColDef().showRowGroup) { return; } } const value = beans.valueSvc.getValue(column, node, "data"); if (column.isAllowFormula()) { const formula = beans.formula; if (formula?.isFormula(value)) { return formula.resolveValue(column, node); } } return value; } getGroupDataValue(node, column) { if (_isGroupUseEntireRow(this.gos, this.pivotActive)) { const leafChild = this.firstLeaf(node); return leafChild && this.beans.valueSvc.getValue(column, leafChild, "data"); } const displayCol = this.beans.showRowGroupCols?.getShowRowGroupCol(column.getId()); return displayCol ? node.groupData?.[displayCol.getId()] : undefined; } }; var defaultGetLeaf = (row) => { if (row.data) { return row; } let childrenAfterGroup = row.childrenAfterGroup; while (childrenAfterGroup?.length) { const node = childrenAfterGroup[0]; if (node.data) { return node; } childrenAfterGroup = node.childrenAfterGroup; } }; var absoluteValueTransformer = (value) => { if (!value) { return value; } if (typeof value === "bigint") { return value < 0n ? -value : value; } const numberValue = Number(value); return isNaN(numberValue) ? value : Math.abs(numberValue); }; function onSortChanged(beans) { beans.sortSvc?.onSortChanged("api"); } var makeIconParams = (dataRefSuffix, classSuffix) => ({ tag: "span", ref: `eSort${dataRefSuffix}`, cls: `ag-sort-indicator-icon ag-sort-${classSuffix} ag-hidden`, attrs: { "aria-hidden": "true" } }); var SortIndicatorElement = { tag: "span", cls: "ag-sort-indicator-container", children: [ makeIconParams("Order", "order"), makeIconParams("Asc", "ascending-icon"), makeIconParams("Desc", "descending-icon"), makeIconParams("Mixed", "mixed-icon"), makeIconParams("AbsoluteAsc", "absolute-ascending-icon"), makeIconParams("AbsoluteDesc", "absolute-descending-icon"), makeIconParams("None", "none-icon") ] }; var SortIndicatorComp = class extends Component { constructor(skipTemplate) { super(); this.eSortOrder = RefPlaceholder; this.eSortAsc = RefPlaceholder; this.eSortDesc = RefPlaceholder; this.eSortMixed = RefPlaceholder; this.eSortNone = RefPlaceholder; this.eSortAbsoluteAsc = RefPlaceholder; this.eSortAbsoluteDesc = RefPlaceholder; if (!skipTemplate) { this.setTemplate(SortIndicatorElement); } } attachCustomElements(eSortOrder, eSortAsc, eSortDesc, eSortMixed, eSortNone, eSortAbsoluteAsc, eSortAbsoluteDesc) { this.eSortOrder = eSortOrder; this.eSortAsc = eSortAsc; this.eSortDesc = eSortDesc; this.eSortMixed = eSortMixed; this.eSortNone = eSortNone; this.eSortAbsoluteAsc = eSortAbsoluteAsc; this.eSortAbsoluteDesc = eSortAbsoluteDesc; } setupSort(column, suppressOrder = false, getSortDefOverride) { this.column = column; this.suppressOrder = suppressOrder; this.getSortDefOverride = getSortDefOverride; this.setupMultiSortIndicator(); if (!column.isSortable() && !column.getColDef().showRowGroup) { return; } this.addInIcon("sortAscending", this.eSortAsc, column); this.addInIcon("sortDescending", this.eSortDesc, column); this.addInIcon("sortUnSort", this.eSortNone, column); this.addInIcon("sortAbsoluteAscending", this.eSortAbsoluteAsc, column); this.addInIcon("sortAbsoluteDescending", this.eSortAbsoluteDesc, column); const updateIcons = this.updateIcons.bind(this); const sortUpdated = this.onSortChanged.bind(this); this.addManagedPropertyListener("unSortIcon", updateIcons); this.addManagedEventListeners({ newColumnsLoaded: updateIcons, sortChanged: sortUpdated, columnRowGroupChanged: sortUpdated }); this.onSortChanged(); } addInIcon(iconName, eParent, column) { if (eParent == null) { return; } const eIcon = _createIconNoSpan(iconName, this.beans, column); if (eIcon) { eParent.appendChild(eIcon); } } onSortChanged() { this.updateIcons(); if (!this.suppressOrder) { this.updateSortOrder(); } } updateIcons() { const { eSortAsc, eSortDesc, eSortAbsoluteAsc, eSortAbsoluteDesc, eSortNone, column, gos, beans } = this; const displaySort = _getDisplaySortForColumn(column, beans, this.getSortDefOverride); const isDefaultSortAllowed = displaySort.isDefaultSortAllowed; const isAbsoluteSortAllowed = displaySort.isAbsoluteSortAllowed; const { isAbsoluteSort, isDefaultSort, isAscending, isDescending, direction } = displaySort; if (eSortAsc) { _setDisplayed(eSortAsc, isAscending && isDefaultSort && isDefaultSortAllowed, { skipAriaHidden: true }); } if (eSortDesc) { _setDisplayed(eSortDesc, isDescending && isDefaultSort && isDefaultSortAllowed, { skipAriaHidden: true }); } if (eSortNone) { const alwaysHideNoSort = !column.getColDef().unSortIcon && !gos.get("unSortIcon"); _setDisplayed(eSortNone, !alwaysHideNoSort && !direction, { skipAriaHidden: true }); } if (eSortAbsoluteAsc) { _setDisplayed(eSortAbsoluteAsc, isAscending && isAbsoluteSort && isAbsoluteSortAllowed, { skipAriaHidden: true }); } if (eSortAbsoluteDesc) { _setDisplayed(eSortAbsoluteDesc, isDescending && isAbsoluteSort && isAbsoluteSortAllowed, { skipAriaHidden: true }); } } setupMultiSortIndicator() { const { eSortMixed, column, gos } = this; this.addInIcon("sortUnSort", eSortMixed, column); const isColumnShowingRowGroup = column.getColDef().showRowGroup; const areGroupsCoupled = _isColumnsSortingCoupledToGroup(gos); if (areGroupsCoupled && isColumnShowingRowGroup) { this.addManagedEventListeners({ sortChanged: this.updateMultiSortIndicator.bind(this), columnRowGroupChanged: this.updateMultiSortIndicator.bind(this) }); this.updateMultiSortIndicator(); } } updateMultiSortIndicator() { const { eSortMixed, beans, column } = this; if (eSortMixed) { const isMixedSort = beans.sortSvc.getDisplaySortForColumn(column)?.direction === "mixed"; _setDisplayed(eSortMixed, isMixedSort, { skipAriaHidden: true }); } } updateSortOrder() { const { eSortOrder, column, beans: { sortSvc } } = this; if (!eSortOrder) { return; } const allColumnsWithSorting = sortSvc.getColumnsWithSortingOrdered(); const indexThisCol = sortSvc.getDisplaySortIndexForColumn(column) ?? -1; const moreThanOneColSorting = allColumnsWithSorting.some((col) => sortSvc.getDisplaySortIndexForColumn(col) ?? -1 >= 1); const showIndex = indexThisCol >= 0 && moreThanOneColSorting; _setDisplayed(eSortOrder, showIndex, { skipAriaHidden: true }); if (indexThisCol >= 0) { eSortOrder.textContent = (indexThisCol + 1).toString(); } else { _clearElement(eSortOrder); } } refresh() { this.onSortChanged(); } }; var SortIndicatorSelector = { selector: "AG-SORT-INDICATOR", component: SortIndicatorComp }; var SortService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "sortSvc"; } progressSort(column, multiSort, source) { const nextDirection = this.getNextSortDirection(column); this.setSortForColumn(column, nextDirection, multiSort, source); } progressSortFromEvent(column, event) { const sortUsingCtrl = this.gos.get("multiSortKey") === "ctrl"; const multiSort = sortUsingCtrl ? event.ctrlKey || event.metaKey : event.shiftKey; this.progressSort(column, multiSort, "uiColumnSorted"); } setSortForColumn(column, sortDef, multiSort, source) { const { gos, showRowGroupCols } = this.beans; const isColumnsSortingCoupledToGroup = _isColumnsSortingCoupledToGroup(gos); let columnsToUpdate = [column]; if (isColumnsSortingCoupledToGroup) { if (column.getColDef().showRowGroup) { const rowGroupColumns = showRowGroupCols?.getSourceColumnsForGroupColumn?.(column); const sortableRowGroupColumns = rowGroupColumns?.filter((col) => col.isSortable()); if (sortableRowGroupColumns) { columnsToUpdate = [column, ...sortableRowGroupColumns]; } } } for (const col of columnsToUpdate) { this.setColSort(col, sortDef, source); } const doingMultiSort = (multiSort || gos.get("alwaysMultiSort")) && !gos.get("suppressMultiSort"); const updatedColumns = []; if (!doingMultiSort) { const clearedColumns = this.clearSortBarTheseColumns(columnsToUpdate, source); updatedColumns.push(...clearedColumns); } this.updateSortIndex(column); updatedColumns.push(...columnsToUpdate); this.dispatchSortChangedEvents(source, updatedColumns); } updateSortIndex(lastColToChange) { const { gos, colModel, showRowGroupCols } = this.beans; const isCoupled = _isColumnsSortingCoupledToGroup(gos); const groupParent = showRowGroupCols?.getShowRowGroupCol(lastColToChange.getId()); const lastSortIndexCol = isCoupled ? groupParent || lastColToChange : lastColToChange; const allSortedCols = this.getColumnsWithSortingOrdered(); colModel.forAllCols((col) => this.setColSortIndex(col, null)); const allSortedColsWithoutChangesOrGroups = allSortedCols.filter((col) => { if (isCoupled && col.getColDef().showRowGroup) { return false; } return col !== lastSortIndexCol; }); const sortedColsWithIndices = lastSortIndexCol.getSortDef() ? [...allSortedColsWithoutChangesOrGroups, lastSortIndexCol] : allSortedColsWithoutChangesOrGroups; sortedColsWithIndices.forEach((col, idx) => this.setColSortIndex(col, idx)); } onSortChanged(source, columns) { this.dispatchSortChangedEvents(source, columns); } isSortActive() { let isSorting = false; this.beans.colModel.forAllCols((col) => { if (col.getSortDef()) { isSorting = true; return true; } }); return isSorting; } dispatchSortChangedEvents(source, columns) { const event = { type: "sortChanged", source }; if (columns) { event.columns = columns; } this.eventSvc.dispatchEvent(event); } clearSortBarTheseColumns(columnsToSkip, source) { const clearedColumns = []; this.beans.colModel.forAllCols((columnToClear) => { if (!columnsToSkip.includes(columnToClear)) { if (columnToClear.getSortDef()) { clearedColumns.push(columnToClear); } this.setColSort(columnToClear, undefined, source); } }); return clearedColumns; } getNextSortDirection(column, currentSort) { const sortingOrder = column.getSortingOrder(); const currentSortDef = currentSort === undefined ? column.getSortDef() : _getSortDefFromInput(currentSort); const currentIndex = sortingOrder.findIndex((e) => _areSortDefsEqual(e, currentSortDef)); let nextIndex = currentIndex + 1; if (nextIndex >= sortingOrder.length) { nextIndex = 0; } return _getSortDefFromInput(sortingOrder[nextIndex]); } getIndexedSortMap() { const { gos, colModel, showRowGroupCols, rowGroupColsSvc } = this.beans; let allSortedCols = []; colModel.forAllCols((col) => { if (col.getSortDef()) { allSortedCols.push(col); } }); if (colModel.isPivotMode()) { const isSortingLinked = _isColumnsSortingCoupledToGroup(gos); allSortedCols = allSortedCols.filter((col) => { const isAggregated = !!col.getAggFunc(); const isSecondary = !col.isPrimary(); const isGroup = isSortingLinked ? showRowGroupCols?.getShowRowGroupCol(col.getId()) : col.getColDef().showRowGroup; return isAggregated || isSecondary || isGroup; }); } const sortedRowGroupCols = rowGroupColsSvc?.columns.filter((col) => !!col.getSortDef()) ?? []; const allColsIndexes = {}; allSortedCols.forEach((col, index) => allColsIndexes[col.getId()] = index); allSortedCols.sort((a, b) => { const iA = a.getSortIndex(); const iB = b.getSortIndex(); if (iA != null && iB != null) { return iA - iB; } else if (iA == null && iB == null) { const posA = allColsIndexes[a.getId()]; const posB = allColsIndexes[b.getId()]; return posA > posB ? 1 : -1; } else if (iB == null) { return -1; } else { return 1; } }); const isSortLinked = _isColumnsSortingCoupledToGroup(gos) && !!sortedRowGroupCols.length; if (isSortLinked) { allSortedCols = [ ...new Set(allSortedCols.map((col) => showRowGroupCols?.getShowRowGroupCol(col.getId()) ?? col)) ]; } const indexMap = /* @__PURE__ */ new Map; allSortedCols.forEach((col, idx) => indexMap.set(col, idx)); if (isSortLinked) { for (const col of sortedRowGroupCols) { const groupDisplayCol = showRowGroupCols.getShowRowGroupCol(col.getId()); indexMap.set(col, indexMap.get(groupDisplayCol)); } } return indexMap; } getColumnsWithSortingOrdered() { return [...this.getIndexedSortMap().entries()].sort(([, idx1], [, idx2]) => idx1 - idx2).map(([col]) => col); } collectSortItems(asSortModel = false) { const sortItems = []; const columnsWithSortingOrdered = this.getColumnsWithSortingOrdered(); for (const column of columnsWithSortingOrdered) { const sort = column.getSortDef()?.direction; if (!sort) { continue; } const type = _normalizeSortType(column.getSortDef()?.type); const sortItem = { sort, type }; if (asSortModel) { sortItem.colId = column.getId(); } else { sortItem.column = column; } sortItems.push(sortItem); } return sortItems; } getSortModel() { return this.collectSortItems(true); } getSortOptions() { return this.collectSortItems(); } canColumnDisplayMixedSort(column) { const isColumnSortCouplingActive = _isColumnsSortingCoupledToGroup(this.gos); const isGroupDisplayColumn = !!column.getColDef().showRowGroup; return isColumnSortCouplingActive && isGroupDisplayColumn; } getDisplaySortForColumn(column) { const linkedColumns = this.beans.showRowGroupCols?.getSourceColumnsForGroupColumn(column); if (!this.canColumnDisplayMixedSort(column) || !linkedColumns?.length) { return column.getSortDef(); } const columnHasUniqueData = column.getColDef().field != null || !!column.getColDef().valueGetter; const sortableColumns = columnHasUniqueData ? [column, ...linkedColumns] : linkedColumns; const firstSort = sortableColumns[0].getSortDef(); const allMatch = sortableColumns.every((col) => _areSortDefsEqual(col.getSortDef(), firstSort)); if (!allMatch) { return { type: _normalizeSortType(column.getSortDef()?.type), direction: "mixed" }; } return firstSort; } getDisplaySortIndexForColumn(column) { return this.getIndexedSortMap().get(column); } setupHeader(comp, column) { const refreshStyles = () => { const { type, direction } = _getSortDefFromInput(column.getSortDef()); comp.toggleCss("ag-header-cell-sorted-asc", direction === "asc"); comp.toggleCss("ag-header-cell-sorted-desc", direction === "desc"); comp.toggleCss("ag-header-cell-sorted-abs-asc", type === "absolute" && direction === "asc"); comp.toggleCss("ag-header-cell-sorted-abs-desc", type === "absolute" && direction === "desc"); comp.toggleCss("ag-header-cell-sorted-none", !direction); if (column.getColDef().showRowGroup) { const sourceColumns = this.beans.showRowGroupCols?.getSourceColumnsForGroupColumn(column); const sortDirectionsMatch = sourceColumns?.every((sourceCol) => direction == sourceCol.getSortDef()?.direction); const isMultiSorting = !sortDirectionsMatch; comp.toggleCss("ag-header-cell-sorted-mixed", isMultiSorting); } }; comp.addManagedEventListeners({ sortChanged: refreshStyles, columnPinned: refreshStyles, columnRowGroupChanged: refreshStyles, displayedColumnsChanged: refreshStyles }); } initCol(column) { const { sortIndex, initialSortIndex } = column.colDef; const sortDef = _getSortDefFromColDef(column.colDef); if (sortDef) { column.setSortDef(sortDef, true); } if (sortIndex !== undefined) { if (sortIndex !== null) { column.sortIndex = sortIndex; } } else if (initialSortIndex !== null) { column.sortIndex = initialSortIndex; } } updateColSort(column, sortDefOrDirection, source) { if (sortDefOrDirection === undefined) { return; } this.setColSort(column, _getSortDefFromInput(sortDefOrDirection), source); } setColSort(column, sort, source) { if (!_areSortDefsEqual(column.getSortDef(), sort)) { column.setSortDef(_getSortDefFromInput(sort), sort === undefined); column.dispatchColEvent("sortChanged", source); } column.dispatchStateUpdatedEvent("sort"); } setColSortIndex(column, sortOrder) { column.sortIndex = sortOrder; column.dispatchStateUpdatedEvent("sortIndex"); } createSortIndicator(skipTemplate) { return new SortIndicatorComp(skipTemplate); } getSortIndicatorSelector() { return SortIndicatorSelector; } }; var SortModule = { moduleName: "Sort", version: VERSION, beans: [SortService, RowNodeSorter], apiFunctions: { onSortChanged }, userComponents: { agSortIndicator: SortIndicatorComp }, icons: { sortAscending: "asc", sortDescending: "desc", sortUnSort: "none", sortAbsoluteAscending: "aasc", sortAbsoluteDescending: "adesc" } }; var SyncService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "syncSvc"; this.waitingForColumns = false; } postConstruct() { this.addManagedPropertyListener("columnDefs", (event) => this.setColumnDefs(event)); } start() { this.beans.ctrlsSvc.whenReady(this, () => { const columnDefs = this.gos.get("columnDefs"); if (columnDefs) { this.setColumnsAndData(columnDefs); } else { this.waitingForColumns = true; } this.gridReady(); }); } setColumnsAndData(columnDefs) { const { colModel, rowModel } = this.beans; colModel.setColumnDefs(columnDefs ?? [], "gridInitializing"); rowModel.start(); } gridReady() { const { eventSvc, gos } = this; eventSvc.dispatchEvent({ type: "gridReady" }); _logIfDebug(gos, `initialised successfully, enterprise = ${gos.isModuleRegistered("EnterpriseCore")}`); } setColumnDefs(event) { const columnDefs = this.gos.get("columnDefs"); if (!columnDefs) { return; } if (this.waitingForColumns) { this.waitingForColumns = false; this.setColumnsAndData(columnDefs); return; } this.beans.colModel.setColumnDefs(columnDefs, _convertColumnEventSourceType(event.source)); } }; var SOURCE_PASTE = "paste"; var ChangeDetectionService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "changeDetectionSvc"; this.deferredDepth = 0; this.batchedPath = null; this.batchedNodes = null; } destroy() { super.destroy(); this.batchedPath = null; this.batchedNodes = null; } postConstruct() { this.csrm = _getClientSideRowModel(this.beans); this.addManagedEventListeners({ cellValueChanged: this.onCellValueChanged.bind(this) }); } beginDeferred() { this.deferredDepth++; } endDeferred() { if (this.deferredDepth === 0) { return; } if (--this.deferredDepth > 0) { return; } const path = this.batchedPath; const nodes = this.batchedNodes; this.batchedPath = null; this.batchedNodes = null; if (path) { this.csrm?.doAggregate(path); } const { rowRenderer } = this.beans; if (nodes) { for (const node of nodes) { refreshRowAndSiblings(rowRenderer, node); } } if (path) { const rows = path.getSortedRows(); for (let i = 0, len = rows.length;i < len; ++i) { refreshRowAndSiblings(rowRenderer, rows[i]); } } if (this.batchedPath || this.batchedNodes) { this.deferredDepth = 1; this.endDeferred(); } } onCellValueChanged(event) { const { gos, rowModel, changedPathFactory } = this.beans; if (event.source === SOURCE_PASTE || gos.get("suppressChangeDetection")) { return; } if (!rowModel.rootNode) { return; } const node = event.node.primaryRow; if (this.csrm) { let batchedPath = this.batchedPath; if (!batchedPath) { batchedPath = changedPathFactory?.newPath(gos.get("aggregateOnlyChangedColumns")) ?? null; this.batchedPath = batchedPath; } let pathNode = node; if (!node.group) { const nodes = this.batchedNodes ?? (this.batchedNodes = /* @__PURE__ */ new Set); nodes.add(node); pathNode = node.parent; } batchedPath?.addCell(pathNode, event.column.getColId()); } else { const nodes = this.batchedNodes ?? (this.batchedNodes = /* @__PURE__ */ new Set); nodes.add(node); } if (this.deferredDepth === 0) { this.deferredDepth = 1; this.endDeferred(); } } }; var refreshRowAndSiblings = (rowRenderer, node) => { const { sibling, pinnedSibling } = node; rowRenderer.refreshRowByNode(node); rowRenderer.refreshRowByNode(sibling); rowRenderer.refreshRowByNode(pinnedSibling); rowRenderer.refreshRowByNode(sibling?.pinnedSibling); rowRenderer.refreshRowByNode(pinnedSibling?.sibling); }; var ExpressionService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "expressionSvc"; this.cache = {}; } evaluate(expression, params) { if (typeof expression === "string") { return this.evaluateExpression(expression, params); } else { _error(15, { expression }); } } evaluateExpression(expression, params) { try { const javaScriptFunction = this.createExpressionFunction(expression); const result = javaScriptFunction(params.value, params.context, params.oldValue, params.newValue, params.value, params.node, params.data, params.colDef, params.rowIndex, params.api, params.getValue, params.column, params.columnGroup); return result; } catch (e) { _error(16, { expression, params, e }); return null; } } createExpressionFunction(expression) { const expressionToFunctionCache = this.cache; if (expressionToFunctionCache[expression]) { return expressionToFunctionCache[expression]; } const functionBody = this.createFunctionBody(expression); const theFunction = new Function("x, ctx, oldValue, newValue, value, node, data, colDef, rowIndex, api, getValue, column, columnGroup", functionBody); expressionToFunctionCache[expression] = theFunction; return theFunction; } createFunctionBody(expression) { if (expression.includes("return")) { return expression; } else { return "return " + expression + ";"; } } }; var ExpressionModule = { moduleName: "Expression", version: VERSION, beans: [ExpressionService] }; var ChangeDetectionModule = { moduleName: "ChangeDetection", version: VERSION, beans: [ChangeDetectionService] }; var ValueService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "valueSvc"; this.initialised = false; this.isSsrm = false; } wireBeans(beans) { this.expressionSvc = beans.expressionSvc; this.colModel = beans.colModel; this.valueCache = beans.valueCache; this.dataTypeSvc = beans.dataTypeSvc; this.editSvc = beans.editSvc; this.formulaDataSvc = beans.formulaDataSvc; this.rowGroupColsSvc = beans.rowGroupColsSvc; } postConstruct() { if (!this.initialised) { this.init(); } } init() { const { gos, valueCache } = this; this.executeValueGetter = valueCache ? this.executeValueGetterWithValueCache.bind(this) : this.executeValueGetterWithoutValueCache.bind(this); this.isSsrm = _isServerSideRowModel(gos); this.cellExpressions = gos.get("enableCellExpressions"); this.isTreeData = gos.get("treeData"); this.initialised = true; const listener = (event) => this.callColumnCellValueChangedHandler(event); this.eventSvc.addListener("cellValueChanged", listener, true); this.addDestroyFunc(() => this.eventSvc.removeListener("cellValueChanged", listener, true)); this.addManagedPropertyListener("treeData", (propChange) => this.isTreeData = propChange.currentValue); } getValueForDisplay(params) { const beans = this.beans; const column = params.column; const node = params.node; const showRowGroupColValueSvc = beans.showRowGroupColValueSvc; const isFullWidthGroup = !column && node.group; const isGroupCol = column?.colDef.showRowGroup; const processTreeDataAsGroup = !this.isTreeData || node.footer; if (showRowGroupColValueSvc && processTreeDataAsGroup && (isFullWidthGroup || isGroupCol)) { const groupValue = showRowGroupColValueSvc.getGroupValue(node, column, this.displayIgnoresAggData(node)); if (groupValue == null) { return { value: null, valueFormatted: null }; } return { value: groupValue.value, valueFormatted: params.includeValueFormatted ? showRowGroupColValueSvc.formatAndPrefixGroupColValue(groupValue, column, params.exporting) : null }; } if (!column) { return { value: node.key, valueFormatted: null }; } let value = this.getValue(column, node, params.from, this.displayIgnoresAggData(node)); let valueToFormat = value; const formula = beans.formula; if (column.isAllowFormula() && formula?.isFormula(value)) { if (params.useRawFormula) { value = formula.normaliseFormula(value, true); valueToFormat = formula.resolveValue(column, node); } else { value = formula.resolveValue(column, node); valueToFormat = value; } } const format = params.includeValueFormatted && !(params.exporting && column.colDef.useValueFormatterForExport === false); return { value, valueFormatted: format ? this.formatValue(column, node, valueToFormat) : null }; } getValue(column, rowNode, from, ignoreAggData = false) { if (!this.initialised) { this.init(); } if (!rowNode) { return; } const colDef = column.colDef; const isGroup = rowNode.group; if (!isGroup) { const pivotValueColumn = colDef.pivotValueColumn; if (pivotValueColumn) { column = pivotValueColumn; } } const pending = this.editSvc?.getPendingEditValue(rowNode, column, from); if (pending !== undefined) { return pending; } let result = this.resolveValue(column, rowNode, ignoreAggData, isGroup); if (result === undefined) { if (isGroup) { const rowGroupColId = colDef.showRowGroup; if (typeof rowGroupColId === "string") { const colRowGroupIndex = this.rowGroupColsSvc?.getColumnIndex(rowGroupColId); if (colRowGroupIndex != null && colRowGroupIndex > rowNode.level) { return null; } } } return; } if (this.cellExpressions && _isExpressionString(result)) { const cellValueGetter = result.substring(1); result = this.executeValueGetter(cellValueGetter, rowNode.data, column, rowNode); } return result; } displayIgnoresAggData(node) { if (!node.group || node.footer || node.level === -1) { return false; } if (!node.sibling || this.gos.get("groupSuppressBlankHeader")) { return false; } if (node.leafGroup && this.colModel.isPivotMode()) { return false; } return !!node.expanded; } resolveValue(column, rowNode, ignoreAggData, isGroup) { const colDef = column.colDef; const colId = column.colId; const formulaDataSvc = !isGroup && this.formulaDataSvc; if (formulaDataSvc && formulaDataSvc.hasDataSource() && colDef.allowFormula === true) { const formula = formulaDataSvc.getFormula({ column, rowNode }); if (_isExpressionString(formula)) { return formula; } } const aggData = isGroup && !ignoreAggData ? rowNode.aggData : undefined; const isTreeData = this.isTreeData; if (isTreeData && aggData?.[colId] !== undefined) { return aggData[colId]; } const data = rowNode.data; const field = colDef.field; const valueGetter = colDef.valueGetter; if (isTreeData) { if (valueGetter) { return this.executeValueGetter(valueGetter, data, column, rowNode); } if (field && data) { return _getValueUsingField(data, field, column.isFieldContainsDots()); } } const groupData = rowNode.groupData; if (groupData && colId in groupData) { return groupData[colId]; } if (aggData?.[colId] !== undefined) { return aggData[colId]; } const rowGroupColId = colDef.showRowGroup; const allowUserValuesForCell = typeof rowGroupColId !== "string" || !isGroup; const isSsrm = this.isSsrm; const ignoreSsrmAggData = isSsrm && ignoreAggData && !!colDef.aggFunc; if (valueGetter && !ignoreSsrmAggData) { return allowUserValuesForCell ? this.executeValueGetter(valueGetter, data, column, rowNode) : undefined; } const ssrmFooterGroupCol = isSsrm && rowNode.footer && rowNode.field && (rowGroupColId === true || rowGroupColId === rowNode.field); if (ssrmFooterGroupCol) { return _getValueUsingField(data, rowNode.field, column.isFieldContainsDots()); } if (field && data && !ignoreSsrmAggData) { return allowUserValuesForCell ? _getValueUsingField(data, field, column.isFieldContainsDots()) : undefined; } return; } parseValue(column, rowNode, newValue, oldValue) { const colDef = column.getColDef(); if (colDef.allowFormula && this.beans.formula?.isFormula(newValue)) { return newValue; } const valueParser = colDef.valueParser; if (_exists(valueParser)) { const params = _addGridCommonParams(this.gos, { node: rowNode, data: rowNode?.data, oldValue, newValue, colDef, column }); if (typeof valueParser === "function") { return valueParser(params); } return this.expressionSvc?.evaluate(valueParser, params); } return newValue; } getDeleteValue(column, rowNode) { if (_exists(column.getColDef().valueParser)) { return this.parseValue(column, rowNode, "", this.getValueForDisplay({ column, node: rowNode, from: "edit" }).value) ?? null; } return null; } formatValue(column, node, value, suppliedFormatter, useFormatterFromColumn = true) { const { expressionSvc } = this.beans; let result = null; let formatter; const colDef = column.getColDef(); if (suppliedFormatter) { formatter = suppliedFormatter; } else if (useFormatterFromColumn) { formatter = colDef.valueFormatter; } if (formatter) { const data = node ? node.data : null; const params = _addGridCommonParams(this.gos, { value, node, data, colDef, column }); if (typeof formatter === "function") { result = formatter(params); } else { result = expressionSvc ? expressionSvc.evaluate(formatter, params) : null; } } else if (colDef.refData) { return colDef.refData[value] || ""; } if (result == null && Array.isArray(value)) { result = value.join(", "); } return result; } setValue(rowNode, column, newValue, eventSource) { const colDef = column.getColDef(); if (!rowNode.data && this.canCreateRowNodeData(rowNode, colDef)) { rowNode.data = {}; } if (!this.isSetValueSupported(column, rowNode, newValue, colDef)) { return false; } const oldValue = this.getValue(column, rowNode, "data"); const params = _addGridCommonParams(this.gos, { node: rowNode, data: rowNode.data, oldValue, newValue, colDef, column }); let valueSetterChanged = false; if (rowNode.data) { const externalFormulaResult = this.handleExternalFormulaChange({ column, eventSource, newValue, setterParams: params, rowNode }); if (externalFormulaResult !== null) { return externalFormulaResult; } const result = this.computeValueChange({ column, rowNode, newValue, params, rowData: rowNode.data, valueSetter: colDef.valueSetter, field: colDef.field }); valueSetterChanged = result ?? true; } const changeDetectionSvc = this.beans.changeDetectionSvc; changeDetectionSvc?.beginDeferred(); try { if (rowNode.group) { const groupResult = this.beans.rowGroupingEditValueSvc?.setGroupDataValue(rowNode, column, newValue, oldValue, eventSource, valueSetterChanged || newValue !== oldValue); if (groupResult !== undefined) { if (!valueSetterChanged && !groupResult) { return false; } return this.finishValueChange(rowNode, column, params, eventSource, newValue); } } if (!valueSetterChanged) { return false; } return this.finishValueChange(rowNode, column, params, eventSource); } finally { changeDetectionSvc?.endDeferred(); } } canCreateRowNodeData(rowNode, colDef) { if (!rowNode.group) { return true; } if (colDef.groupRowValueSetter != null || colDef.groupRowEditable != null) { return false; } if (colDef.pivotValueColumn) { return false; } return true; } finishValueChange(rowNode, column, params, eventSource, savedValueOverride) { rowNode.resetQuickFilterAggregateText(); this.valueCache?.onDataChanged(); const savedValue = savedValueOverride === undefined ? this.getValue(column, rowNode, "data") : savedValueOverride; this.dispatchCellValueChangedEvent(rowNode, params, savedValue, eventSource); if (rowNode.pinnedSibling) { this.dispatchCellValueChangedEvent(rowNode.pinnedSibling, params, savedValue, eventSource); } return true; } isSetValueSupported(column, rowNode, newValue, colDef) { const { field, valueSetter } = colDef; const formulaSvc = this.beans.formula; const isFormulaValue = column.isAllowFormula() && formulaSvc?.isFormula(newValue); const hasExternalFormulaData = !!this.formulaDataSvc?.hasDataSource(); if (_missing(field) && _missing(valueSetter) && !(hasExternalFormulaData && isFormulaValue)) { if (rowNode.group && (colDef.groupRowValueSetter || colDef.groupRowEditable)) { return true; } _warn(17); return false; } if (this.dataTypeSvc && !this.dataTypeSvc.checkType(column, newValue)) { _warn(135); return false; } return true; } handleExternalFormulaChange(args) { const { column, rowNode, newValue, eventSource, setterParams } = args; const formulaSvc = this.beans.formula; const formulaDataSvc = this.formulaDataSvc; if (!formulaDataSvc?.hasDataSource() || !column.isAllowFormula()) { return null; } const isFormulaValue = formulaSvc?.isFormula(newValue); const existingFormula = formulaDataSvc.getFormula({ column, rowNode }); if (isFormulaValue) { const valueWasDifferent = existingFormula !== newValue; if (!valueWasDifferent) { return false; } formulaDataSvc.setFormula({ column, rowNode, formula: newValue }); const computedValue = formulaSvc?.resolveValue(column, rowNode); const colDef = column.getColDef(); if (_exists(colDef.valueSetter) || !_missing(colDef.field)) { const computedParams = { ...setterParams, newValue: computedValue }; this.computeValueChange({ column, rowNode, newValue: computedValue, params: computedParams, rowData: rowNode.data, valueSetter: colDef.valueSetter, field: colDef.field }); } return this.finishValueChange(rowNode, column, setterParams, eventSource); } if (existingFormula !== undefined) { formulaDataSvc.setFormula({ column, rowNode, formula: undefined }); } return null; } computeValueChange(params) { const { valueSetter, params: setterParams, rowData, field, column, newValue } = params; if (_exists(valueSetter)) { if (typeof valueSetter === "function") { return valueSetter(setterParams); } return this.expressionSvc?.evaluate(valueSetter, setterParams); } return !!rowData && this.setValueUsingField(rowData, field, newValue, column.isFieldContainsDots()); } dispatchCellValueChangedEvent(rowNode, params, value, source) { this.eventSvc.dispatchEvent({ type: "cellValueChanged", event: null, rowIndex: rowNode.rowIndex, rowPinned: rowNode.rowPinned, column: params.column, colDef: params.colDef, data: rowNode.data, node: rowNode, oldValue: params.oldValue, newValue: value, newRawValue: params.newValue, value, source }); } callColumnCellValueChangedHandler(event) { const onCellValueChanged = event.colDef.onCellValueChanged; if (typeof onCellValueChanged === "function") { this.beans.frameworkOverrides.wrapOutgoing(() => { onCellValueChanged(event); }); } } setValueUsingField(data, field, newValue, isFieldContainsDots) { if (!field) { return false; } let valuesAreSame = false; if (!isFieldContainsDots) { valuesAreSame = data[field] === newValue; if (!valuesAreSame) { data[field] = newValue; } } else { const fieldPieces = field.split("."); let currentObject = data; while (fieldPieces.length > 0 && currentObject) { const fieldPiece = fieldPieces.shift(); if (fieldPieces.length === 0) { valuesAreSame = currentObject[fieldPiece] === newValue; if (!valuesAreSame) { currentObject[fieldPiece] = newValue; } } else { currentObject = currentObject[fieldPiece]; } } } return !valuesAreSame; } executeValueGetterWithValueCache(valueGetter, data, column, rowNode) { const colId = column.getColId(); const valueFromCache = this.valueCache.getValue(rowNode, colId); if (valueFromCache !== undefined) { return valueFromCache; } const result = this.executeValueGetterWithoutValueCache(valueGetter, data, column, rowNode); this.valueCache.setValue(rowNode, colId, result); return result; } executeValueGetterWithoutValueCache(valueGetter, data, column, rowNode) { const params = _addGridCommonParams(this.gos, { data, node: rowNode, column, colDef: column.getColDef(), getValue: (field) => this.getValueCallback(rowNode, field) }); let result; if (typeof valueGetter === "function") { result = valueGetter(params); } else { result = this.expressionSvc?.evaluate(valueGetter, params); } return result; } getValueCallback(node, field) { const otherColumn = this.colModel.getColDefCol(field); if (otherColumn) { return this.getValue(otherColumn, node, "data"); } return null; } getKeyForNode(col, rowNode) { const value = this.getValue(col, rowNode, "data"); const keyCreator = col.getColDef().keyCreator; let result = value; if (keyCreator) { const keyParams = _addGridCommonParams(this.gos, { value, colDef: col.getColDef(), column: col, node: rowNode, data: rowNode.data }); result = keyCreator(keyParams); } if (typeof result === "string" || result == null) { return result; } result = String(result); if (result === "[object Object]") { _warn(121); } return result; } }; var CommunityCoreModule = { moduleName: "CommunityCore", version: VERSION, beans: [ GridDestroyService, ApiFunctionService, Registry, UserComponentFactory, RowContainerHeightService, VisibleColsService, EventService, GridOptionsService, ColumnModel, PageBoundsService, PageBoundsListener, RowRenderer, ValueService, FocusService, Environment, ScrollVisibleService, CtrlsService, SyncService, ColumnNameService, ColumnViewportService, IconService ], icons: { selectOpen: "small-down", smallDown: "small-down", colorPicker: "color-picker", smallUp: "small-up", checkboxChecked: "small-up", checkboxIndeterminate: "checkbox-indeterminate", checkboxUnchecked: "checkbox-unchecked", radioButtonOn: "radio-button-on", radioButtonOff: "radio-button-off", smallLeft: "small-left", smallRight: "small-right" }, apiFunctions: { getGridId, destroy, isDestroyed, getGridOption, setGridOption, updateGridOptions, isModuleRegistered }, dependsOn: [ DataTypeModule, ColumnMoveModule, ColumnResizeModule, SortModule, ColumnHeaderCompModule, ColumnGroupModule, ColumnGroupHeaderCompModule, OverlayModule, ChangeDetectionModule, AnimationFrameModule, KeyboardNavigationModule, PinnedColumnModule, AriaModule, TouchModule, CellRendererFunctionModule, ColumnFlexModule, ExpressionModule, SkeletonCellRendererModule, ColumnDelayRenderModule ] }; function _fuzzySuggestions(params) { const { inputValue, allSuggestions, hideIrrelevant, filterByPercentageOfBestMatch } = params; let thisSuggestions = (allSuggestions ?? []).map((text, idx) => ({ value: text, relevance: _getLevenshteinSimilarityDistance(inputValue, text), idx })); thisSuggestions.sort((a, b) => a.relevance - b.relevance); if (hideIrrelevant) { thisSuggestions = thisSuggestions.filter((suggestion) => suggestion.relevance < Math.max(suggestion.value.length, inputValue.length)); } if (thisSuggestions.length > 0 && filterByPercentageOfBestMatch && filterByPercentageOfBestMatch > 0) { const bestMatch = thisSuggestions[0].relevance; const limit = bestMatch * filterByPercentageOfBestMatch; thisSuggestions = thisSuggestions.filter((suggestion) => limit - suggestion.relevance < 0); } const values = []; const indices = []; for (const suggestion of thisSuggestions) { values.push(suggestion.value); indices.push(suggestion.idx); } return { values, indices }; } function _getLevenshteinSimilarityDistance(source, target) { const sourceLength = source.length; const targetLength = target.length; if (targetLength === 0) { return sourceLength ? sourceLength : 0; } let inputLower = source.toLocaleLowerCase(); let targetLower = target.toLocaleLowerCase(); let swapTmp; if (source.length < target.length) { swapTmp = targetLower; targetLower = inputLower; inputLower = swapTmp; swapTmp = target; target = source; source = swapTmp; } let previousRow = new Uint16Array(targetLength + 1); let currentRow = new Uint16Array(targetLength + 1); for (let j = 0;j <= targetLength; j++) { previousRow[j] = j; } let secondaryScore = 0; const earlyMatchLimit = sourceLength / 2 - 10; for (let i = 1;i <= sourceLength; i++) { const inputChar = source[i - 1]; const inputCharLower = inputLower[i - 1]; currentRow[0] = i; for (let j = 1;j <= targetLength; j++) { const targetChar = target[j - 1]; const targetCharLower = targetLower[j - 1]; if (inputCharLower !== targetCharLower) { const insertCost = currentRow[j - 1]; const deleteCost = previousRow[j]; const replaceCost = previousRow[j - 1]; let cost = insertCost < deleteCost ? insertCost : deleteCost; if (replaceCost < cost) { cost = replaceCost; } currentRow[j] = cost + 1 | 0; continue; } secondaryScore++; if (inputChar === targetChar) { secondaryScore++; } if (i > 1 && j > 1) { const prevSourceChar = source[i - 2]; const prevSourceCharLower = inputLower[i - 2]; const prevTargetChar = target[j - 2]; const prevTargetCharLower = targetLower[j - 2]; if (prevSourceCharLower === prevTargetCharLower) { secondaryScore++; if (prevSourceChar === prevTargetChar) { secondaryScore++; } } } if (i < earlyMatchLimit) { secondaryScore++; } currentRow[j] = previousRow[j - 1]; } swapTmp = previousRow; previousRow = currentRow; currentRow = swapTmp; } return previousRow[targetLength] / (secondaryScore + 1); } var ENTERPRISE_MODULE_NAMES = { AdvancedFilter: 1, AiToolkit: 1, AllEnterprise: 1, BatchEdit: 1, CellSelection: 1, Clipboard: 1, ColumnMenu: 1, ColumnsToolPanel: 1, ContextMenu: 1, ExcelExport: 1, FiltersToolPanel: 1, Find: 1, GridCharts: 1, IntegratedCharts: 1, GroupFilter: 1, MasterDetail: 1, Menu: 1, MultiFilter: 1, NewFiltersToolPanel: 1, Pivot: 1, RangeSelection: 1, RichSelect: 1, RowNumbers: 1, RowGrouping: 1, RowGroupingEdit: 1, RowGroupingPanel: 1, ServerSideRowModelApi: 1, ServerSideRowModel: 1, SetFilter: 1, SideBar: 1, Sparklines: 1, StatusBar: 1, TreeData: 1, ViewportRowModel: 1, Formula: 1 }; var ALL_COLUMN_FILTERS = [ "TextFilter", "NumberFilter", "BigIntFilter", "DateFilter", "SetFilter", "MultiFilter", "GroupFilter", "CustomFilter" ]; var RESOLVABLE_MODULE_NAMES = { EditCore: [ "TextEditor", "NumberEditor", "DateEditor", "CheckboxEditor", "LargeTextEditor", "SelectEditor", "RichSelect", "CustomEditor" ], CheckboxCellRenderer: ["AllCommunity"], ClientSideRowModelHierarchy: ["RowGrouping", "Pivot", "TreeData"], ColumnFilter: ALL_COLUMN_FILTERS, ColumnGroupHeaderComp: ["AllCommunity"], ColumnGroup: ["AllCommunity"], ColumnHeaderComp: ["AllCommunity"], ColumnMove: ["AllCommunity"], ColumnResize: ["AllCommunity"], CommunityCore: ["AllCommunity"], CsrmSsrmSharedApi: ["ClientSideRowModelApi", "ServerSideRowModelApi"], RowModelSharedApi: ["ClientSideRowModelApi", "ServerSideRowModelApi"], EnterpriseCore: ["AllEnterprise"], FilterCore: [...ALL_COLUMN_FILTERS, "QuickFilter", "ExternalFilter", "AdvancedFilter"], GroupCellRenderer: ["RowGrouping", "Pivot", "TreeData", "MasterDetail", "ServerSideRowModel"], KeyboardNavigation: ["AllCommunity"], LoadingCellRenderer: ["ServerSideRowModel"], MenuCore: ["ColumnMenu", "ContextMenu"], MenuItem: ["ColumnMenu", "ContextMenu", "MultiFilter", "IntegratedCharts", "ColumnsToolPanel"], Overlay: ["AllCommunity"], PinnedColumn: ["AllCommunity"], SharedAggregation: ["RowGrouping", "Pivot", "TreeData", "ServerSideRowModel"], SharedDragAndDrop: ["AllCommunity"], SharedMasterDetail: ["MasterDetail", "ServerSideRowModel"], SharedMenu: [...ALL_COLUMN_FILTERS, "ColumnMenu", "ContextMenu"], SharedPivot: ["Pivot", "ServerSideRowModel"], SharedRowGrouping: ["RowGrouping", "ServerSideRowModel"], SharedRowSelection: ["RowSelection", "ServerSideRowModel"], SkeletonCellRenderer: ["ServerSideRowModel"], Sort: ["AllCommunity"], SsrmInfiniteSharedApi: ["InfiniteRowModel", "ServerSideRowModelApi"], SharedTreeData: ["TreeData", "ServerSideRowModel"] }; var MODULES_FOR_ROW_MODELS = { InfiniteRowModel: "infinite", ClientSideRowModelApi: "clientSide", ClientSideRowModel: "clientSide", ServerSideRowModelApi: "serverSide", ServerSideRowModel: "serverSide", ViewportRowModel: "viewport" }; function resolveModuleNames(moduleName, rowModelType) { const resolvedModuleNames = []; for (const modName of Array.isArray(moduleName) ? moduleName : [moduleName]) { const resolved = RESOLVABLE_MODULE_NAMES[modName]; if (resolved) { for (const resolvedModName of resolved) { const rowModelForModule = MODULES_FOR_ROW_MODELS[resolvedModName]; if (!rowModelForModule || rowModelForModule === rowModelType) { resolvedModuleNames.push(resolvedModName); } } } else { resolvedModuleNames.push(modName); } } return resolvedModuleNames; } var NoModulesRegisteredError = () => `No AG Grid modules are registered! It is recommended to start with all Community features via the AllCommunityModule: import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community'; ModuleRegistry.registerModules([ AllCommunityModule ]); `; var moduleImportMsg = (moduleNames) => { const imports = moduleNames.map((moduleName) => `import { ${convertToUserModuleName(moduleName)} } from '${ENTERPRISE_MODULE_NAMES[moduleName] ? "ag-grid-enterprise" : "ag-grid-community"}';`); const includeCharts = moduleNames.some((m) => m === "IntegratedCharts" || m === "Sparklines"); if (includeCharts) { const chartImport = `import { AgChartsEnterpriseModule } from 'ag-charts-enterprise';`; imports.push(chartImport); } return `import { ModuleRegistry } from 'ag-grid-community'; ${imports.join(` `)} ModuleRegistry.registerModules([ ${moduleNames.map((m) => convertToUserModuleName(m, true)).join(", ")} ]); For more info see: ${baseDocLink}/modules/`; }; function convertToUserModuleName(moduleName, inModuleRegistration = false) { if (inModuleRegistration && (moduleName === "IntegratedCharts" || moduleName === "Sparklines")) { return `${moduleName}Module.with(AgChartsEnterpriseModule)`; } return `${moduleName}Module`; } function umdMissingModule(reasonOrId, moduleNames) { const chartModules = moduleNames.filter((m) => m === "IntegratedCharts" || m === "Sparklines"); let message = ""; const agChartsDynamic = globalThis?.agCharts; if (!agChartsDynamic && chartModules.length > 0) { message = `Unable to use ${reasonOrId} as either the ag-charts-community or ag-charts-enterprise script needs to be included alongside ag-grid-enterprise. `; } else if (moduleNames.some((m) => ENTERPRISE_MODULE_NAMES[m])) { message = message + `Unable to use ${reasonOrId} as that requires the ag-grid-enterprise script to be included. `; } return message; } function missingRowModelTypeError({ moduleName, rowModelType }) { return `To use the ${moduleName}Module you must set the gridOption "rowModelType='${rowModelType}'"`; } var missingModule = ({ reasonOrId, moduleName, gridScoped, gridId, rowModelType, additionalText, isUmd: isUmd2 }) => { const resolvedModuleNames = resolveModuleNames(moduleName, rowModelType); const reason = typeof reasonOrId === "string" ? reasonOrId : MISSING_MODULE_REASONS[reasonOrId]; if (isUmd2) { return umdMissingModule(reason, resolvedModuleNames); } const chartModules = resolvedModuleNames.filter((m) => m === "IntegratedCharts" || m === "Sparklines"); const chartImportRequired = chartModules.length > 0 ? `${chartModules.map((m) => convertToUserModuleName(m)).join()} must be initialised with an AG Charts module. One of 'AgChartsCommunityModule' / 'AgChartsEnterpriseModule'.` : ""; const explanation = `Unable to use ${reason} as ${resolvedModuleNames.length > 1 ? "one of " + resolvedModuleNames.map((m) => convertToUserModuleName(m)).join(", ") : convertToUserModuleName(resolvedModuleNames[0])} is not registered${gridScoped ? " for gridId: " + gridId : ""}. ${chartImportRequired} Check if you have registered the module: `; return `${explanation} ${moduleImportMsg(resolvedModuleNames)}` + (additionalText ? ` ${additionalText}` : ""); }; var missingChartsWithModule = (gridModule) => { return `${gridModule} must be initialised with an AG Charts module. One of 'AgChartsCommunityModule' / 'AgChartsEnterpriseModule'. import { AgChartsEnterpriseModule } from 'ag-charts-enterprise'; import { ModuleRegistry } from 'ag-grid-community'; import { ${gridModule} } from 'ag-grid-enterprise'; ModuleRegistry.registerModules([${gridModule}.with(AgChartsEnterpriseModule)]); `; }; var clipboardApiError = (method) => `AG Grid: Unable to use the Clipboard API (navigator.clipboard.${method}()). The reason why it could not be used has been logged in the previous line. For this reason the grid has defaulted to using a workaround which doesn't perform as well. Either fix why Clipboard API is blocked, OR stop this message from appearing by setting grid property suppressClipboardApi=true (which will default the grid to using the workaround rather than the API.`; var AG_GRID_ERRORS = { 1: () => "`rowData` must be an array", 2: ({ nodeId }) => `Duplicate node id '${nodeId}' detected from getRowId callback, this could cause issues in your grid.`, 3: () => "Calling gridApi.resetRowHeights() makes no sense when using Auto Row Height.", 4: ({ id }) => `Could not find row id=${id}, data item was not found for this id`, 5: ({ data }) => [ `Could not find data item as object was not found.`, data, " Consider using getRowId to help the Grid find matching row data" ], 6: () => `'groupHideOpenParents' only works when specifying specific columns for 'colDef.showRowGroup'`, 7: () => "Pivoting is not supported with aligned grids as it may produce different columns in each grid.", 8: ({ key }) => `Unknown key for navigation ${key}`, 9: ({ variable }) => `No value for ${variable?.cssName}. This usually means that the grid has been initialised before styles have been loaded. The default value of ${variable?.defaultValue} will be used and updated when styles load.`, 10: ({ eventType }) => `As of v33, the '${eventType}' event is deprecated. Use the global 'modelUpdated' event to determine when row children have changed.`, 11: () => "No gridOptions provided to createGrid", 12: ({ colKey }) => ["column ", colKey, " not found"], 13: () => "Could not find rowIndex, this means tasks are being executed on a rowNode that has been removed from the grid.", 14: ({ groupPrefix }) => `Row IDs cannot start with ${groupPrefix}, this is a reserved prefix for AG Grid's row grouping feature.`, 15: ({ expression }) => ["value should be either a string or a function", expression], 16: ({ expression, params, e }) => [ "Processing of the expression failed", "Expression = ", expression, "Params = ", params, "Exception = ", e ], 17: () => "you need either field or valueSetter set on colDef for editing to work", 18: () => `alignedGrids contains an undefined option.`, 19: () => `alignedGrids - No api found on the linked grid.`, 20: () => `You may want to configure via a callback to avoid setup race conditions: "alignedGrids: () => [linkedGrid]"`, 21: () => "pivoting is not supported with aligned grids. You can only use one of these features at a time in a grid.", 22: ({ key }) => `${key} is an initial property and cannot be updated.`, 23: () => "The return of `getRowHeight` cannot be zero. If the intention is to hide rows, use a filter instead.", 24: () => "row height must be a number if not using standard row model", 25: ({ id }) => [`The getRowId callback must return a string. The ID `, id, ` is being cast to a string.`], 26: ({ fnName, preDestroyLink }) => { return `Grid API function ${fnName}() cannot be called as the grid has been destroyed. Either clear local references to the grid api, when it is destroyed, or check gridApi.isDestroyed() to avoid calling methods against a destroyed grid. To run logic when the grid is about to be destroyed use the gridPreDestroy event. See: ${preDestroyLink}`; }, 27: ({ fnName, module }) => `API function '${fnName}' not registered to module '${module}'`, 28: () => "setRowCount cannot be used while using row grouping.", 29: () => "tried to call sizeColumnsToFit() but the grid is coming back with zero width, maybe the grid is not visible yet on the screen?", 30: ({ toIndex }) => [ "tried to insert columns in invalid location, toIndex = ", toIndex, "remember that you should not count the moving columns when calculating the new index" ], 31: () => "infinite loop in resizeColumnSets", 32: () => "applyColumnState() - the state attribute should be an array, however an array was not found. Please provide an array of items (one for each col you want to change) for state.", 33: () => "stateItem.aggFunc must be a string. if using your own aggregation functions, register the functions first before using them in get/set state. This is because it is intended for the column state to be stored and retrieved as simple JSON.", 34: ({ key }) => `the column type '${key}' is a default column type and cannot be overridden.`, 35: () => `Column type definitions 'columnTypes' with a 'type' attribute are not supported because a column type cannot refer to another column type. Only column definitions 'columnDefs' can use the 'type' attribute to refer to a column type.`, 36: ({ t }) => "colDef.type '" + t + "' does not correspond to defined gridOptions.columnTypes", 37: () => `Changing the column pinning status is not allowed with domLayout='print'`, 38: ({ iconName }) => `provided icon '${iconName}' needs to be a string or a function`, 39: () => "Applying column order broke a group where columns should be married together. Applying new order has been discarded.", 40: ({ e, method }) => `${e} ${clipboardApiError(method)}`, 41: () => "Browser did not allow document.execCommand('copy'). Ensure 'api.copySelectedRowsToClipboard() is invoked via a user event, i.e. button click, otherwise the browser will prevent it for security reasons.", 42: () => "Browser does not support document.execCommand('copy') for clipboard operations", 43: ({ iconName }) => `As of v33, icon '${iconName}' is deprecated. Use the icon CSS name instead.`, 44: () => 'Data type definition hierarchies (via the "extendsDataType" property) cannot contain circular references.', 45: ({ parentCellDataType }) => `The data type definition ${parentCellDataType} does not exist.`, 46: () => 'The "baseDataType" property of a data type definition must match that of its parent.', 47: ({ cellDataType }) => `Missing data type definition - "${cellDataType}"`, 48: ({ property, inferred, colId }) => { const inferredStr = inferred ? " (inferred)" : ""; const colIdStr = colId ? ` for column "${colId}"` : ""; const parserHint = inferred && property === "Parser" ? ` - "colDef.cellDataType = 'object'"` : ""; return `Cell data type is "object"${inferredStr} but no Value ${property} has been provided${colIdStr}. Please either provide an object data type definition with a Value ${property}, or set: - "colDef.value${property}"${parserHint}`; }, 49: ({ methodName }) => `Framework component is missing the method ${methodName}()`, 50: ({ compName }) => `Could not find component ${compName}, did you forget to configure this component?`, 51: () => `Export cancelled. Export is not allowed as per your configuration.`, 52: () => "There is no `window` associated with the current `document`", 53: () => `unknown value type during csv conversion`, 54: () => "Could not find document body, it is needed for drag and drop and context menu.", 55: () => "addRowDropZone - A container target needs to be provided", 56: () => "addRowDropZone - target already exists in the list of DropZones. Use `removeRowDropZone` before adding it again.", 57: () => "unable to show popup filter, filter instantiation failed", 58: () => "no values found for select cellEditor", 59: () => "cannot select pinned rows", 60: () => "cannot select node until it has finished loading", 61: () => "since version v32.2.0, rowNode.isFullWidthCell() has been deprecated. Instead check `rowNode.detail` followed by the user provided `isFullWidthRow` grid option.", 62: ({ colId }) => `setFilterModel() - no column found for colId: ${colId}`, 63: ({ colId }) => `setFilterModel() - unable to fully apply model, filtering disabled for colId: ${colId}`, 64: ({ colId }) => `setFilterModel() - unable to fully apply model, unable to create filter for colId: ${colId}`, 65: () => "filter missing setModel method, which is needed for setFilterModel", 66: () => "filter API missing getModel method, which is needed for getFilterModel", 67: () => "Filter is missing isFilterActive() method", 68: () => "Column Filter API methods have been disabled as Advanced Filters are enabled.", 69: ({ guiFromFilter }) => `getGui method from filter returned ${guiFromFilter}; it should be a DOM element.`, 70: ({ newFilter }) => `Grid option quickFilterText only supports string inputs, received: ${typeof newFilter}`, 71: () => "debounceMs is ignored when apply button is present", 72: ({ keys }) => [`ignoring FilterOptionDef as it doesn't contain one of `, keys], 73: () => `invalid FilterOptionDef supplied as it doesn't contain a 'displayKey'`, 74: () => "no filter options for filter", 75: () => "Unknown button type specified", 76: ({ filterModelType }) => [ 'Unexpected type of filter "', filterModelType, '", it looks like the filter was configured with incorrect Filter Options' ], 77: () => `Filter model is missing 'conditions'`, 78: () => 'Filter Model contains more conditions than "filterParams.maxNumConditions". Additional conditions have been ignored.', 79: () => '"filterParams.maxNumConditions" must be greater than or equal to zero.', 80: () => '"filterParams.numAlwaysVisibleConditions" must be greater than or equal to zero.', 81: () => '"filterParams.numAlwaysVisibleConditions" cannot be greater than "filterParams.maxNumConditions".', 82: ({ param }) => `DateFilter ${param} is not a number`, 83: () => `DateFilter minValidYear should be <= maxValidYear`, 84: () => `DateFilter minValidDate should be <= maxValidDate`, 85: () => "DateFilter should not have both minValidDate and minValidYear parameters set at the same time! minValidYear will be ignored.", 86: () => "DateFilter should not have both maxValidDate and maxValidYear parameters set at the same time! maxValidYear will be ignored.", 87: () => "DateFilter parameter minValidDate should always be lower than or equal to parameter maxValidDate.", 88: ({ index }) => `Invalid row index for ensureIndexVisible: ${index}`, 89: () => `A template was provided for Header Group Comp - templates are only supported for Header Comps (not groups)`, 90: () => `datasource is missing getRows method`, 91: () => "Filter is missing method doesFilterPass", 92: () => `AnimationFrameService called but animation frames are off`, 93: () => "cannot add multiple ranges when `cellSelection.suppressMultiRanges = true`", 94: ({ paginationPageSizeOption, pageSizeSet, pageSizesSet, pageSizeOptions }) => `'paginationPageSize=${paginationPageSizeOption}'${pageSizeSet ? "" : " (default value)"}, but ${paginationPageSizeOption} is not included in${pageSizesSet ? "" : " the default"} paginationPageSizeSelector=[${pageSizeOptions?.join(", ")}].`, 95: ({ paginationPageSizeOption, paginationPageSizeSelector: paginationPageSizeSelector2 }) => `Either set '${paginationPageSizeSelector2}' to an array that includes ${paginationPageSizeOption} or to 'false' to disable the page size selector.`, 96: ({ id, data }) => [ "Duplicate ID", id, "found for pinned row with data", data, "When `getRowId` is defined, it must return unique IDs for all pinned rows. Use the `rowPinned` parameter." ], 97: ({ colId }) => `cellEditor for column ${colId} is missing getGui() method`, 98: () => "popup cellEditor does not work with fullRowEdit - you cannot use them both - either turn off fullRowEdit, or stop using popup editors.", 99: () => "Since v32, `api.hideOverlay()` does not hide the loading overlay when `loading=true`. Set `loading=false` instead.", 101: ({ propertyName, componentName, agGridDefaults, jsComps }) => { const textOutput = []; const validComponents = [ ...Object.keys(agGridDefaults ?? []).filter((k) => !["agCellEditor", "agGroupRowRenderer", "agSortIndicator"].includes(k)), ...Object.keys(jsComps ?? []).filter((k) => !!jsComps[k]) ]; const suggestions = _fuzzySuggestions({ inputValue: componentName, allSuggestions: validComponents, hideIrrelevant: true, filterByPercentageOfBestMatch: 0.8 }).values; textOutput.push(`Could not find '${componentName}' component. It was configured as "${propertyName}: '${componentName}'" but it wasn't found in the list of registered components. `); if (suggestions.length > 0) { textOutput.push(` Did you mean: [${suggestions.slice(0, 3)}]? `); } textOutput.push(`If using a custom component check it has been registered correctly.`); return textOutput; }, 102: () => "selectAll: 'filtered' only works when gridOptions.rowModelType='clientSide'", 103: () => "Invalid selection state. When using client-side row model, the state must conform to `string[]`.", 104: ({ value, param }) => `Numeric value ${value} passed to ${param} param will be interpreted as ${value} seconds. If this is intentional use "${value}s" to silence this warning.`, 105: ({ e }) => [`chart rendering failed`, e], 106: () => `Theming API and Legacy Themes are both used in the same page. A Theming API theme has been provided to the 'theme' grid option, but the file (ag-grid.css) is also included and will cause styling issues. Remove ag-grid.css from the page. See the migration guide: ${baseDocLink}/theming-migration/`, 107: ({ key, value }) => `Invalid value for theme param ${key} - ${value}`, 108: ({ e }) => ["chart update failed", e], 109: ({ inputValue, allSuggestions }) => { const suggestions = _fuzzySuggestions({ inputValue, allSuggestions, hideIrrelevant: true, filterByPercentageOfBestMatch: 0.8 }).values; return [ `Could not find '${inputValue}' aggregate function. It was configured as "aggFunc: '${inputValue}'" but it wasn't found in the list of registered aggregations.`, suggestions.length > 0 ? ` Did you mean: [${suggestions.slice(0, 3)}]?` : "", `If using a custom aggregation function check it has been registered correctly.` ].join(` `); }, 110: () => "groupHideOpenParents only works when specifying specific columns for colDef.showRowGroup", 111: () => "Invalid selection state. When `groupSelects` is enabled, the state must conform to `IServerSideGroupSelectionState`.", 113: () => "Set Filter cannot initialise because you are using a row model that does not contain all rows in the browser. Either use a different filter type, or configure Set Filter such that you provide it with values", 114: ({ component }) => `Could not find component with name of ${component}. Is it in Vue.components?`, 116: () => "Invalid selection state. The state must conform to `IServerSideSelectionState`.", 117: () => "selectAll must be of boolean type.", 118: () => "Infinite scrolling must be enabled in order to set the row count.", 119: () => "Unable to instantiate filter", 120: () => "MultiFloatingFilterComp expects MultiFilter as its parent", 121: () => "a column you are grouping or pivoting by has objects as values. If you want to group by complex objects then either a) use a colDef.keyCreator (see AG Grid docs) or b) to toString() on the object to return a key", 122: () => "could not find the document, document is empty", 123: () => "Advanced Filter is only supported with the Client-Side Row Model or Server-Side Row Model.", 124: () => "No active charts to update.", 125: ({ chartId }) => `Unable to update chart. No active chart found with ID: ${chartId}.`, 126: () => "unable to restore chart as no chart model is provided", 127: ({ allRange }) => `unable to create chart as ${allRange ? "there are no columns in the grid" : "no range is selected"}.`, 128: ({ feature }) => `${feature} is only available if using 'multiRow' selection mode.`, 129: ({ feature, rowModel }) => `${feature} is only available if using 'clientSide' or 'serverSide' rowModelType, you are using ${rowModel}.`, 130: () => 'cannot multi select unless selection mode is "multiRow"', 132: () => "Row selection features are not available unless `rowSelection` is enabled.", 133: ({ iconName }) => `icon '${iconName}' function should return back a string or a dom object`, 134: ({ iconName }) => `Did not find icon '${iconName}'`, 135: () => `Data type of the new value does not match the cell data type of the column`, 136: () => `Unable to update chart as the 'type' is missing. It must be either 'rangeChartUpdate', 'pivotChartUpdate', or 'crossFilterChartUpdate'.`, 137: ({ type, currentChartType }) => `Unable to update chart as a '${type}' update type is not permitted on a ${currentChartType}.`, 138: ({ chartType }) => `invalid chart type supplied: ${chartType}`, 139: ({ customThemeName }) => `a custom chart theme with the name ${customThemeName} has been supplied but not added to the 'chartThemes' list`, 140: ({ name }) => `no stock theme exists with the name '${name}' and no custom chart theme with that name was supplied to 'customChartThemes'`, 141: () => "cross filtering with row grouping is not supported.", 142: () => "cross filtering is only supported in the client side row model.", 143: ({ panel }) => `'${panel}' is not a valid Chart Tool Panel name`, 144: ({ type }) => `Invalid charts data panel group name supplied: '${type}'`, 145: ({ group }) => `As of v32, only one charts customize panel group can be expanded at a time. '${group}' will not be expanded.`, 146: ({ comp }) => `Unable to instantiate component '${comp}' as its module hasn't been loaded. Add 'ValidationModule' to see which module is required.`, 147: ({ group }) => `Invalid charts customize panel group name supplied: '${group}'`, 148: ({ group }) => `invalid chartGroupsDef config '${group}'`, 149: ({ group, chartType }) => `invalid chartGroupsDef config '${group}.${chartType}'`, 150: () => `'seriesChartTypes' are required when the 'customCombo' chart type is specified.`, 151: ({ chartType }) => `invalid chartType '${chartType}' supplied in 'seriesChartTypes', converting to 'line' instead.`, 152: ({ colId }) => `no 'seriesChartType' found for colId = '${colId}', defaulting to 'line'.`, 153: ({ chartDataType }) => `unexpected chartDataType value '${chartDataType}' supplied, instead use 'category', 'series' or 'excluded'`, 154: ({ colId }) => `cross filtering requires a 'agSetColumnFilter' or 'agMultiColumnFilter' to be defined on the column with id: ${colId}`, 155: ({ option }) => `'${option}' is not a valid Chart Toolbar Option`, 156: ({ panel }) => `Invalid panel in chartToolPanelsDef.panels: '${panel}'`, 157: ({ unrecognisedGroupIds }) => ["unable to find group(s) for supplied groupIds:", unrecognisedGroupIds], 158: () => "can not expand a column item that does not represent a column group header", 159: () => "Invalid params supplied to createExcelFileForExcel() - `ExcelExportParams.data` is empty.", 160: () => `Export cancelled. Export is not allowed as per your configuration.`, 161: () => "The Excel Exporter is currently on Multi Sheet mode. End that operation by calling 'api.getMultipleSheetAsExcel()' or 'api.exportMultipleSheetsAsExcel()'", 162: ({ id, dataType }) => `Unrecognized data type for excel export [${id}.dataType=${dataType}]`, 163: ({ featureName }) => `Excel table export does not work with ${featureName}. The exported Excel file will not contain any Excel tables. Please turn off ${featureName} to enable Excel table exports.`, 164: () => "Unable to add data table to Excel sheet: A table already exists.", 165: () => "Unable to add data table to Excel sheet: Missing required parameters.", 166: ({ unrecognisedGroupIds }) => ["unable to find groups for these supplied groupIds:", unrecognisedGroupIds], 167: ({ unrecognisedColIds }) => ["unable to find columns for these supplied colIds:", unrecognisedColIds], 168: () => "detailCellRendererParams.template should be function or string", 169: () => 'Reference to eDetailGrid was missing from the details template. Please add data-ref="eDetailGrid" to the template.', 170: ({ providedStrategy }) => `invalid cellRendererParams.refreshStrategy = ${providedStrategy} supplied, defaulting to refreshStrategy = 'rows'.`, 171: () => "could not find detail grid options for master detail, please set gridOptions.detailCellRendererParams.detailGridOptions", 172: () => "could not find getDetailRowData for master / detail, please set gridOptions.detailCellRendererParams.getDetailRowData", 173: ({ group }) => `invalid chartGroupsDef config '${group}'`, 174: ({ group, chartType }) => `invalid chartGroupsDef config '${group}.${chartType}'`, 175: ({ menuTabName, itemsToConsider }) => [ `Trying to render an invalid menu item '${menuTabName}'. Check that your 'menuTabs' contains one of `, itemsToConsider ], 176: ({ key }) => `unknown menu item type ${key}`, 177: () => `valid values for cellSelection.handle.direction are 'x', 'y' and 'xy'. Default to 'xy'.`, 178: ({ colId }) => `column ${colId} is not visible`, 179: () => "totalValueGetter should be either a function or a string (expression)", 180: () => "agRichSelectCellEditor requires cellEditorParams.values to be set", 181: () => "agRichSelectCellEditor cannot have `multiSelect` and `allowTyping` set to `true`. AllowTyping has been turned off.", 182: () => 'you cannot mix groupDisplayType = "multipleColumns" with treeData, only one column can be used to display groups when doing tree data', 183: () => "Group Column Filter only works on group columns. Please use a different filter.", 184: ({ parentGroupData, childNodeData }) => [`duplicate group keys for row data, keys should be unique`, [parentGroupData, childNodeData]], 185: ({ data }) => [`getDataPath() should not return an empty path`, [data]], 186: ({ rowId, rowData, duplicateRowsData }) => [ `duplicate group keys for row data, keys should be unique`, rowId, rowData, ...duplicateRowsData ?? [] ], 187: ({ rowId, firstData, secondData }) => [ `Duplicate node id ${rowId}. Row IDs are provided via the getRowId() callback. Please modify the getRowId() callback code to provide unique row id values.`, "first instance", firstData, "second instance", secondData ], 188: (props) => `getRowId callback must be provided for Server Side Row Model ${props?.feature || "selection"} to work correctly.`, 189: ({ startRow }) => `invalid value ${startRow} for startRow, the value should be >= 0`, 190: ({ rowGroupId, data }) => [ `null and undefined values are not allowed for server side row model keys`, rowGroupId ? `column = ${rowGroupId}` : ``, `data is `, data ], 194: ({ method }) => `calling gridApi.${method}() is only possible when using rowModelType=\`clientSide\`.`, 195: ({ justCurrentPage }) => `selecting just ${justCurrentPage ? "current page" : "filtered"} only works when gridOptions.rowModelType='clientSide'`, 196: ({ key }) => `Provided ids must be of string type. Invalid id provided: ${key}`, 197: () => "`toggledNodes` must be an array of string ids.", 199: () => `getSelectedNodes and getSelectedRows functions cannot be used with select all functionality with the server-side row model. Use \`api.getServerSideSelectionState()\` instead.`, 200: missingModule, 201: ({ rowModelType }) => `Could not find row model for rowModelType = ${rowModelType}`, 202: () => `\`getSelectedNodes\` and \`getSelectedRows\` functions cannot be used with \`groupSelectsChildren\` and the server-side row model. Use \`api.getServerSideSelectionState()\` instead.`, 203: () => "Server Side Row Model does not support Dynamic Row Height and Cache Purging. Either a) remove getRowHeight() callback or b) remove maxBlocksInCache property. Purging has been disabled.", 204: () => "Server Side Row Model does not support Auto Row Height and Cache Purging. Either a) remove colDef.autoHeight or b) remove maxBlocksInCache property. Purging has been disabled.", 205: ({ duplicateIdText }) => `Unable to display rows as duplicate row ids (${duplicateIdText}) were returned by the getRowId callback. Please modify the getRowId callback to provide unique ids.`, 206: () => "getRowId callback must be implemented for transactions to work. Transaction was ignored.", 207: () => 'The Set Filter Parameter "defaultToNothingSelected" value was ignored because it does not work when "excelMode" is used.', 208: () => `Set Filter Value Formatter must return string values. Please ensure the Set Filter Value Formatter returns string values for complex objects.`, 209: () => `Set Filter Key Creator is returning null for provided values and provided values are primitives. Please provide complex objects. See ${baseDocLink}/filter-set-filter-list/#filter-value-types`, 210: () => "Set Filter has a Key Creator, but provided values are primitives. Did you mean to provide complex objects?", 211: () => "property treeList=true for Set Filter params, but you did not provide a treeListPathGetter or values of type Date.", 212: () => `please review all your toolPanel components, it seems like at least one of them doesn't have an id`, 213: () => "Advanced Filter does not work with Filters Tool Panel. Filters Tool Panel has been disabled.", 214: ({ key }) => `unable to lookup Tool Panel as invalid key supplied: ${key}`, 215: ({ key, defaultByKey }) => `the key ${key} is not a valid key for specifying a tool panel, valid keys are: ${Object.keys(defaultByKey ?? {}).join(",")}`, 216: ({ name }) => `Missing component for '${name}'`, 217: ({ invalidColIds }) => ["unable to find grid columns for the supplied colDef(s):", invalidColIds], 218: ({ property, defaultOffset }) => `${property} must be a number, the value you provided is not a valid number. Using the default of ${defaultOffset}px.`, 219: ({ property }) => `Property ${property} does not exist on the target object.`, 220: ({ lineDash }) => `'${lineDash}' is not a valid 'lineDash' option.`, 221: () => `agAggregationComponent should only be used with the client and server side row model.`, 222: () => `agFilteredRowCountComponent should only be used with the client side row model.`, 223: () => `agSelectedRowCountComponent should only be used with the client and server side row model.`, 224: () => `agTotalAndFilteredRowCountComponent should only be used with the client side row model.`, 225: () => "agTotalRowCountComponent should only be used with the client side row model.", 226: () => "viewport is missing init method.", 227: () => "menu item icon must be DOM node or string", 228: ({ menuItemOrString }) => `unrecognised menu item ${menuItemOrString}`, 230: () => "detailCellRendererParams.template is not supported by AG Grid React. To change the template, provide a Custom Detail Cell Renderer. See https://www.ag-grid.com/react-data-grid/master-detail-custom-detail/", 231: () => "As of v32, using custom components with `reactiveCustomComponents = false` is deprecated.", 232: () => "Using both rowData and v-model. rowData will be ignored.", 233: ({ methodName }) => `Framework component is missing the method ${methodName}()`, 234: () => 'Group Column Filter does not work with the colDef property "field". This property will be ignored.', 235: () => 'Group Column Filter does not work with the colDef property "filterValueGetter". This property will be ignored.', 236: () => 'Group Column Filter does not work with the colDef property "filterParams". This property will be ignored.', 237: () => "Group Column Filter does not work with Tree Data enabled. Please disable Tree Data, or use a different filter.", 238: () => "setRowCount can only accept a positive row count.", 239: () => 'Theming API and CSS File Themes are both used in the same page. In v33 we released the Theming API as the new default method of styling the grid. See the migration docs https://www.ag-grid.com/react-data-grid/theming-migration/. Because no value was provided to the `theme` grid option it defaulted to themeQuartz. But the file (ag-grid.css) is also included and will cause styling issues. Either pass the string "legacy" to the theme grid option to use v32 style themes, or remove ag-grid.css from the page to use Theming API.', 240: ({ theme }) => `theme grid option must be a Theming API theme object or the string "legacy", received: ${theme}`, 243: () => "Failed to deserialize state - each provided state object must be an object.", 244: () => "Failed to deserialize state - `selectAllChildren` must be a boolean value or undefined.", 245: () => "Failed to deserialize state - `toggledNodes` must be an array.", 246: () => "Failed to deserialize state - Every `toggledNode` requires an associated string id.", 247: () => `Row selection state could not be parsed due to invalid data. Ensure all child state has toggledNodes or does not conform with the parent rule. Please rebuild the selection state and reapply it.`, 248: () => "SetFloatingFilter expects SetFilter as its parent", 249: () => "Must supply a Value Formatter in Set Filter params when using a Key Creator", 250: () => "Must supply a Key Creator in Set Filter params when `treeList = true` on a group column, and Tree Data or Row Grouping is enabled.", 251: ({ chartType }) => `AG Grid: Unable to create chart as an invalid chartType = '${chartType}' was supplied.`, 252: () => `cannot get grid to draw rows when it is in the middle of drawing rows. Your code probably called a grid API method while the grid was in the render stage. To overcome this, put the API call into a timeout, e.g. instead of api.redrawRows(), call setTimeout(function() { api.redrawRows(); }, 0). To see what part of your code that caused the refresh check this stacktrace.`, 253: ({ version }) => ["Illegal version string: ", version], 254: () => "Cannot create chart: no chart themes available.", 255: ({ point }) => `Lone surrogate U+${point?.toString(16).toUpperCase()} is not a scalar value`, 256: () => "Unable to initialise. See validation error, or load ValidationModule if missing.", 257: () => missingChartsWithModule("IntegratedChartsModule"), 258: () => missingChartsWithModule("SparklinesModule"), 259: ({ part }) => `the argument to theme.withPart must be a Theming API part object, received: ${part}`, 260: ({ propName, compName, gridScoped, gridId, rowModelType }) => missingModule({ reasonOrId: `AG Grid '${propName}' component: ${compName}`, moduleName: USER_COMP_MODULES[compName], gridId, gridScoped, rowModelType }), 261: () => "As of v33, `column.isHovered()` is deprecated. Use `api.isColumnHovered(column)` instead.", 262: () => 'As of v33, icon key "smallDown" is deprecated. Use "advancedFilterBuilderSelect" for Advanced Filter Builder dropdown, "selectOpen" for Select cell editor and dropdowns (e.g. Integrated Charts menu), "richSelectOpen" for Rich Select cell editor.', 263: () => 'As of v33, icon key "smallLeft" is deprecated. Use "panelDelimiterRtl" for Row Group Panel / Pivot Panel, "subMenuOpenRtl" for sub-menus.', 264: () => 'As of v33, icon key "smallRight" is deprecated. Use "panelDelimiter" for Row Group Panel / Pivot Panel, "subMenuOpen" for sub-menus.', 265: ({ colId }) => `Unable to infer chart data type for column '${colId}' if first data entry is null. Please specify "chartDataType", or a "cellDataType" in the column definition. For more information, see ${baseDocLink}/integrated-charts-range-chart#coldefchartdatatype .`, 266: () => 'As of v33.1, using "keyCreator" with the Rich Select Editor has been deprecated. It now requires the "formatValue" callback to convert complex data to strings.', 267: () => "Detail grids can not use a different theme to the master grid, the `theme` detail grid option will be ignored.", 268: () => "Transactions aren't supported with tree data when using treeDataChildrenField", 269: () => "When `masterSelects: 'detail'`, detail grids must be configured with multi-row selection", 270: ({ id, parentId }) => `Cycle detected for row with id='${id}' and parent id='${parentId}'. Resetting the parent for row with id='${id}' and showing it as a root-level node.`, 271: ({ id, parentId }) => `Parent row not found for row with id='${id}' and parent id='${parentId}'. Showing row with id='${id}' as a root-level node.`, 272: () => NoModulesRegisteredError(), 273: ({ providedId, usedId }) => `Provided column id '${providedId}' was already in use, ensure all column and group ids are unique. Using '${usedId}' instead.`, 274: ({ prop }) => { let msg = `Since v33, ${prop} has been deprecated.`; switch (prop) { case "maxComponentCreationTimeMs": msg += " This property is no longer required and so will be removed in a future version."; break; case "setGridApi": msg += ` This method is not called by AG Grid. To access the GridApi see: https://ag-grid.com/react-data-grid/grid-interface/#grid-api `; break; case "children": msg += ` For multiple versions AgGridReact does not support children.`; break; } return msg; }, 275: missingRowModelTypeError, 276: () => "Row Numbers Row Resizer cannot be used when Grid Columns have `autoHeight` enabled.", 277: ({ colId }) => `'enableFilterHandlers' is set to true, but column '${colId}' does not have 'filter.doesFilterPass' or 'filter.handler' set.`, 278: ({ colId }) => `Unable to create filter handler for column '${colId}'`, 279: (_) => {}, 280: ({ colId }) => `'name' must be provided for custom filter components for column '${colId}`, 281: ({ colId }) => `Filter for column '${colId}' does not have 'filterParams.buttons', but the new Filters Tool Panel has buttons configured. Either configure buttons for the filter, or disable buttons on the Filters Tool Panel.`, 282: () => "New filter tool panel requires `enableFilterHandlers: true`.", 283: () => "As of v34, use the same method on the filter handler (`api.getColumnFilterHandler(colKey)`) instead.", 284: () => "As of v34, filters are active when they have a model. Use `api.getColumnFilterModel()` instead.", 285: () => "As of v34, use (`api.getColumnFilterModel()`) instead.", 286: () => "As of v34, use (`api.setColumnFilterModel()`) instead.", 287: () => "`api.doFilterAction()` requires `enableFilterHandlers = true", 288: () => "`api.getColumnFilterModel(key, true)` requires `enableFilterHandlers = true", 289: ({ rowModelType }) => `Row Model '${rowModelType}' is not supported with Batch Editing`, 290: ({ rowIndex, rowPinned }) => `Row with index '${rowIndex}' and pinned state '${rowPinned}' not found`, 291: () => "License Key being set multiple times with different values. This can result in an incorrect license key being used,", 292: ({ colId }) => `The Multi Filter for column '${colId}' has buttons configured against the child filters. When 'enableFilterHandlers=true', buttons must instead be provided against the parent Multi Filter params. The child filter buttons will be ignored.`, 293: () => `The grid was initialised detached from the DOM and was then inserted into a Shadow Root. Theme styles are probably broken. Pass the themeStyleContainer grid option to let the grid know where in the document to insert theme CSS.`, 294: () => `When using the \`agRichSelectCellEditor\` setting \`filterListAsync = true\` requires \`allowTyping = true\` and the \`values()\` callback must return a Promise of filtered values.`, 295: ({ blockedService }) => `colDef.allowFormula is not supported with ${blockedService}. Formulas has been turned off.`, 296: () => "Since v35, `api.hideOverlay()` does not hide the overlay when `activeOverlay` is set. Set `activeOverlay=null` instead.", 297: () => '`api.hideOverlay()` does not hide the no matching rows overlay as it is only controlled by grid state. Set `suppressOverlays=["noMatchingRows"] to not show it.', 298: () => `Columns Tool Panel 'buttons' requires 'apply' to enable Deferred Updates.` }; function getError(errorId, args) { const msgOrFunc = AG_GRID_ERRORS[errorId]; if (!msgOrFunc) { return [`Missing error text for error id ${errorId}!`]; } const errorBody = msgOrFunc(args); const errorLink = getErrorLink(errorId, args); const errorSuffix = ` See ${errorLink}`; return Array.isArray(errorBody) ? errorBody.concat(errorSuffix) : [errorBody, errorSuffix]; } var MISSING_MODULE_REASONS = { 1: "Charting Aggregation", 2: "pivotResultFields", 3: "setTooltip" }; var VanillaFrameworkOverrides = class { constructor(frameworkName = "javascript") { this.frameworkName = frameworkName; this.renderingEngine = "vanilla"; this.batchFrameworkComps = false; this.wrapIncoming = (callback) => callback(); this.wrapOutgoing = (callback) => callback(); this.baseDocLink = `${BASE_URL}/${this.frameworkName}-data-grid`; setValidationDocLink(this.baseDocLink); } frameworkComponent(_) { return null; } isFrameworkComponent(_) { return false; } getDocLink(path) { return this.baseDocLink + (path ? "/" + path : ""); } }; var _gridApiCache = /* @__PURE__ */ new WeakMap; var _gridElementCache = /* @__PURE__ */ new WeakMap; function createGrid(eGridDiv, gridOptions, params) { if (!gridOptions) { _error(11); return {}; } const gridParams = params; let destroyCallback; if (!gridParams?.setThemeOnGridDiv) { const newGridDiv = _createElement({ tag: "div" }); newGridDiv.style.height = "100%"; eGridDiv.appendChild(newGridDiv); eGridDiv = newGridDiv; destroyCallback = () => eGridDiv.remove(); } const api = new GridCoreCreator().create(eGridDiv, gridOptions, (context) => { const gridComp = new GridComp(eGridDiv); context.createBean(gridComp); }, undefined, params, destroyCallback); return api; } var nextGridId = 1; var GridCoreCreator = class { create(eGridDiv, providedOptions, createUi, acceptChanges, params, _destroyCallback) { const gridOptions = GlobalGridOptions.applyGlobalGridOptions(providedOptions); const gridId = gridOptions.gridId ?? String(nextGridId++); const registeredModules = this.getRegisteredModules(params, gridId, gridOptions.rowModelType); const beanClasses = this.createBeansList(gridOptions.rowModelType, registeredModules, gridId); const providedBeanInstances = this.createProvidedBeans(eGridDiv, gridOptions, params); if (!beanClasses) { return; } const destroyCallback = () => { _gridElementCache.delete(api); _gridApiCache.delete(eGridDiv); _unRegisterGridModules(gridId); _destroyCallback?.(); }; const contextParams = { providedBeanInstances, beanClasses, id: gridId, beanInitComparator: gridBeanInitComparator, beanDestroyComparator: gridBeanDestroyComparator, derivedBeans: [createGridApi], destroyCallback }; const context = new AgContext(contextParams); this.registerModuleFeatures(context, registeredModules); createUi(context); context.getBean("syncSvc").start(); acceptChanges?.(context); const api = context.getBean("gridApi"); _gridApiCache.set(eGridDiv, api); _gridElementCache.set(api, eGridDiv); return api; } getRegisteredModules(params, gridId, rowModelType) { _registerModule(CommunityCoreModule, undefined, true); params?.modules?.forEach((m) => _registerModule(m, gridId)); return _getRegisteredModules(gridId, getDefaultRowModelType(rowModelType)); } registerModuleFeatures(context, registeredModules) { const registry = context.getBean("registry"); const apiFunctionSvc = context.getBean("apiFunctionSvc"); for (const module of registeredModules) { registry.registerModule(module); const apiFunctions = module.apiFunctions; if (apiFunctions) { const names = Object.keys(apiFunctions); for (const name of names) { apiFunctionSvc?.addFunction(name, apiFunctions[name]); } } } } createProvidedBeans(eGridDiv, gridOptions, params) { let frameworkOverrides = params ? params.frameworkOverrides : null; if (_missing(frameworkOverrides)) { frameworkOverrides = new VanillaFrameworkOverrides; } const seed = { gridOptions, eGridDiv, eRootDiv: eGridDiv, globalListener: params ? params.globalListener : null, globalSyncListener: params ? params.globalSyncListener : null, frameworkOverrides, withinStudio: params?.withinStudio }; if (params?.providedBeanInstances) { Object.assign(seed, params.providedBeanInstances); } return seed; } createBeansList(userProvidedRowModelType, registeredModules, gridId) { const rowModelModuleNames = { clientSide: "ClientSideRowModel", infinite: "InfiniteRowModel", serverSide: "ServerSideRowModel", viewport: "ViewportRowModel" }; const rowModelType = getDefaultRowModelType(userProvidedRowModelType); const rowModuleModelName = rowModelModuleNames[rowModelType]; if (!rowModuleModelName) { _logPreInitErr(201, { rowModelType }, `Unknown rowModelType ${rowModelType}.`); return; } if (!_hasUserRegistered()) { _logPreInitErr(272, undefined, NoModulesRegisteredError()); return; } if (!userProvidedRowModelType) { const registeredRowModelModules = Object.entries(rowModelModuleNames).filter(([rowModelType2, module]) => _isModuleRegistered(module, gridId, rowModelType2)); if (registeredRowModelModules.length == 1) { const [userRowModelType, moduleName] = registeredRowModelModules[0]; if (userRowModelType !== rowModelType) { const params = { moduleName, rowModelType: userRowModelType }; _logPreInitErr(275, params, missingRowModelTypeError(params)); return; } } } if (!_isModuleRegistered(rowModuleModelName, gridId, rowModelType)) { const isUmd2 = _isUmd(); const reasonOrId = `rowModelType = '${rowModelType}'`; const message = isUmd2 ? `Unable to use ${reasonOrId} as that requires the ag-grid-enterprise script to be included. ` : `Missing module ${rowModuleModelName}Module for rowModelType ${rowModelType}.`; _logPreInitErr(200, { reasonOrId, moduleName: rowModuleModelName, gridScoped: _areModulesGridScoped(), gridId, rowModelType, isUmd: isUmd2 }, message); return; } const beans = /* @__PURE__ */ new Set; for (const module of registeredModules) { for (const bean of module.beans ?? []) { beans.add(bean); } } return Array.from(beans); } }; function getDefaultRowModelType(passedRowModelType) { return passedRowModelType ?? "clientSide"; } function ensureColumnVisible(beans, key, position = "auto") { beans.frameworkOverrides.wrapIncoming(() => beans.ctrlsSvc.getScrollFeature().ensureColumnVisible(key, position), "ensureVisible"); } function ensureIndexVisible(beans, index, position) { beans.frameworkOverrides.wrapIncoming(() => beans.ctrlsSvc.getScrollFeature().ensureIndexVisible(index, position), "ensureVisible"); } var forEachGroupDepthFirst = (children, callback) => { for (let i = 0, len = children.length;i < len; ++i) { const child = children[i]; const grandChildren = child.childrenAfterGroup; if (grandChildren !== null) { forEachGroupDepthFirst(grandChildren, callback); callback(child); } } }; var _forEachChangedGroupDepthFirst = (rootNode, hierarchical, changedPath, callback) => { if (changedPath != null) { const rows = changedPath.getSortedRows(); for (let i = 0, len = rows.length;i < len; ++i) { const row = rows[i]; if (row.childrenAfterGroup !== null && !row.destroyed) { callback(row); } } return; } if (rootNode == null) { return; } const children = rootNode.childrenAfterGroup; if (children === null) { return; } if (hierarchical) { forEachGroupDepthFirst(children, callback); } callback(rootNode); }; var ClientSideNodeManager = class extends BeanStub { constructor(rootNode) { super(); this.rootNode = rootNode; this.nextId = 0; this.allNodesMap = {}; initRootNode(rootNode); } getRowNode(id) { return this.allNodesMap[id]; } setNewRowData(rowData) { this.dispatchRowDataUpdateStarted(rowData); this.destroyAllNodes(); const rootNode = initRootNode(this.rootNode); const allLeafs = new Array(rowData.length); rootNode._leafs = allLeafs; let writeIdx = 0; const nestedDataGetter = this.beans.groupStage?.getNestedDataGetter(); const processedNested = nestedDataGetter ? /* @__PURE__ */ new Set : null; const processChildren = (parent, childrenData) => { const level = parent.level + 1; for (let i = 0, len = childrenData.length;i < len; ++i) { const data = childrenData[i]; if (!data) { continue; } const node = this.createRowNode(data, level, writeIdx); allLeafs[writeIdx++] = node; if (processedNested && !processedNested.has(data)) { processedNested.add(data); node.treeParent = parent; const children = nestedDataGetter(data); if (children) { processChildren(node, children); } } } }; processChildren(rootNode, rowData); allLeafs.length = writeIdx; } destroyAllNodes() { const { selectionSvc, pinnedRowModel, groupStage } = this.beans; selectionSvc?.reset("rowDataChanged"); if (pinnedRowModel?.isManual()) { pinnedRowModel.reset(); } groupStage?.clearNonLeafs(); const existingLeafs = this.rootNode._leafs; if (existingLeafs) { for (let i = 0, len = existingLeafs.length;i < len; ++i) { existingLeafs[i]._destroy(false); } } this.allNodesMap = /* @__PURE__ */ Object.create(null); this.nextId = 0; } setImmutableRowData(params, rowData) { const { rootNode, gos } = this; this.dispatchRowDataUpdateStarted(rowData); const getRowIdFunc = _getRowIdCallback(gos); const changedRowNodes = params.changedRowNodes; const { adds, updates } = changedRowNodes; const processedNodes = /* @__PURE__ */ new Set; const nodesToUnselect = []; const nestedDataGetter = this.beans.groupStage?.getNestedDataGetter(); let reorder = gos.get("suppressMaintainUnsortedOrder") ? undefined : false; let prevIndex = -1; let treeUpdated = false; const updateNode = (node, data) => { if (!reorder && reorder !== undefined) { const oldIndex = node.sourceRowIndex; reorder = oldIndex <= prevIndex; prevIndex = oldIndex; } if (node.data !== data) { node.updateData(data); if (!adds.has(node)) { updates.add(node); } if (!node.selectable && node.isSelected()) { nodesToUnselect.push(node); } } }; const processChildren = (parent, childrenData, level) => { for (let i = 0, len = childrenData.length;i < len; ++i) { const data = childrenData[i]; if (!data) { continue; } let node = this.getRowNode(getRowIdFunc({ data, level })); if (node) { updateNode(node, data); treeUpdated || (treeUpdated = !!nestedDataGetter && node.treeParent !== parent); } else { node = this.createRowNode(data, level); adds.add(node); } if (!nestedDataGetter || processedNodes.has(node)) { processedNodes.add(node); continue; } processedNodes.add(node); node.treeParent = parent; const children = nestedDataGetter(data); if (children) { processChildren(node, children, level + 1); } } }; processChildren(rootNode, rowData, 0); const changed = this.deleteUnusedNodes(processedNodes, changedRowNodes, nodesToUnselect, !!params.animate) || reorder || adds.size > 0; if (changed) { const allLeafs = rootNode._leafs ?? (rootNode._leafs = []); if (reorder === undefined) { updateRootLeafsKeepOrder(allLeafs, processedNodes, changedRowNodes); } else if (updateRootLeafsOrdered(allLeafs, processedNodes)) { changedRowNodes.reordered = true; } } if (changed || treeUpdated || updates.size) { params.rowDataUpdated = true; this.deselect(nodesToUnselect); } } deleteUnusedNodes(processedNodes, { removals }, nodesToUnselect, animate) { const allLeafs = this.rootNode._leafs; for (let i = 0, len = allLeafs.length;i < len; i++) { const node = allLeafs[i]; if (!processedNodes.has(node)) { if (this.destroyNode(node, animate)) { removals.push(node); if (node.isSelected()) { nodesToUnselect.push(node); } } } } return removals.length > 0; } updateRowData(rowDataTran, changedRowNodes, animate) { this.dispatchRowDataUpdateStarted(rowDataTran.add); if (this.beans.groupStage?.getNestedDataGetter()) { _warn(268); return { remove: [], update: [], add: [] }; } const nodesToUnselect = []; const getRowIdFunc = _getRowIdCallback(this.gos); const remove = this.executeRemove(getRowIdFunc, rowDataTran, changedRowNodes, nodesToUnselect, animate); const update = this.executeUpdate(getRowIdFunc, rowDataTran, changedRowNodes, nodesToUnselect); const add = this.executeAdd(rowDataTran, changedRowNodes); this.deselect(nodesToUnselect); return { remove, update, add }; } executeRemove(getRowIdFunc, { remove }, { adds, updates, removals }, nodesToUnselect, animate) { const allLeafs = this.rootNode._leafs; const allLeafsLen = allLeafs?.length; const removeLen = remove?.length; if (!removeLen || !allLeafsLen) { return []; } let removeCount = 0; let filterIdx = allLeafsLen; let filterEndIdx = 0; const removedResult = new Array(removeLen); for (let i = 0;i < removeLen; ++i) { const rowNode = this.lookupNode(getRowIdFunc, remove[i]); if (!rowNode) { continue; } const sourceRowIndex = rowNode.sourceRowIndex; if (sourceRowIndex < filterIdx) { filterIdx = sourceRowIndex; } if (sourceRowIndex > filterEndIdx) { filterEndIdx = sourceRowIndex; } removedResult[removeCount++] = rowNode; if (!this.destroyNode(rowNode, animate)) { continue; } if (rowNode.isSelected()) { nodesToUnselect.push(rowNode); } if (!adds.delete(rowNode)) { updates.delete(rowNode); removals.push(rowNode); } } removedResult.length = removeCount; if (removeCount) { filterRemovedRowNodes(allLeafs, filterIdx, filterEndIdx); } return removedResult; } executeUpdate(getRowIdFunc, { update }, { adds, updates }, nodesToUnselect) { const updateLen = update?.length; if (!updateLen) { return []; } const updateResult = new Array(updateLen); let writeIdx = 0; for (let i = 0;i < updateLen; i++) { const item = update[i]; const rowNode = this.lookupNode(getRowIdFunc, item); if (rowNode) { rowNode.updateData(item); if (!rowNode.selectable && rowNode.isSelected()) { nodesToUnselect.push(rowNode); } updateResult[writeIdx++] = rowNode; if (!adds.has(rowNode)) { updates.add(rowNode); } } } updateResult.length = writeIdx; return updateResult; } executeAdd(rowDataTran, changedRowNodes) { var _a; const allLeafs = (_a = this.rootNode)._leafs ?? (_a._leafs = []); const allLeafsLen = allLeafs.length; const add = rowDataTran.add; const addLength = add?.length; if (!addLength) { return []; } const newLen = allLeafsLen + addLength; let addIndex = this.sanitizeAddIndex(allLeafs, rowDataTran.addIndex); if (addIndex < allLeafsLen) { for (let readIdx = allLeafsLen - 1, writeIdx = newLen - 1;readIdx >= addIndex; --readIdx) { const node = allLeafs[readIdx]; node.sourceRowIndex = writeIdx; allLeafs[writeIdx--] = node; } changedRowNodes.reordered = true; } allLeafs.length = newLen; const addedNodes = new Array(addLength); const adds = changedRowNodes.adds; for (let i = 0;i < addLength; i++) { const node = this.createRowNode(add[i], 0, addIndex); adds.add(node); allLeafs[addIndex] = node; addedNodes[i] = node; addIndex++; } return addedNodes; } dispatchRowDataUpdateStarted(data) { this.eventSvc.dispatchEvent({ type: "rowDataUpdateStarted", firstRowData: data?.length ? data[0] : null }); } deselect(nodes) { const source = "rowDataChanged"; const selectionSvc = this.beans.selectionSvc; if (nodes.length) { selectionSvc?.setNodesSelected({ newValue: false, nodes, suppressFinishActions: true, source }); } selectionSvc?.updateGroupsFromChildrenSelections?.(source); if (nodes.length) { this.eventSvc.dispatchEvent({ type: "selectionChanged", source, selectedNodes: selectionSvc?.getSelectedNodes() ?? null, serverSideState: null }); } } createRowNode(data, level, sourceRowIndex) { const node = new RowNode(this.beans); node.parent = this.rootNode; node.level = level; node.group = false; if (sourceRowIndex != null) { node.sourceRowIndex = sourceRowIndex; } node.setDataAndId(data, String(this.nextId++)); const id = node.id; const allNodesMap = this.allNodesMap; if (allNodesMap[id]) { _warn(2, { nodeId: id }); } allNodesMap[id] = node; return node; } destroyNode(node, animate) { if (!node._destroy(animate)) { return false; } const id = node.id; const allNodesMap = this.allNodesMap; if (allNodesMap[id] === node) { delete allNodesMap[id]; } return true; } lookupNode(getRowIdFunc, data) { if (!getRowIdFunc) { return lookupNodeByData(this.rootNode._leafs, data); } const id = getRowIdFunc({ data, level: 0 }); const rowNode = this.allNodesMap[id]; if (!rowNode) { _error(4, { id }); return null; } return rowNode; } sanitizeAddIndex(allLeafs, addIndex) { const allLeafsLen = allLeafs.length; if (typeof addIndex !== "number") { return allLeafsLen; } if (addIndex < 0 || addIndex >= allLeafsLen || Number.isNaN(addIndex)) { return allLeafsLen; } addIndex = Math.ceil(addIndex); const gos = this.gos; if (addIndex > 0 && gos.get("treeData") && gos.get("getDataPath")) { addIndex = adjustAddIndexForDataPath(allLeafs, addIndex); } return addIndex; } }; var adjustAddIndexForDataPath = (allLeafs, addIndex) => { for (let i = 0, len = allLeafs.length;i < len; i++) { const node = allLeafs[i]; if (node?.rowIndex == addIndex - 1) { return i + 1; } } return addIndex; }; var initRootNode = (rootNode) => { rootNode.group = true; rootNode.level = -1; rootNode._expanded = true; rootNode.id = "ROOT_NODE_ID"; if (rootNode._leafs?.length !== 0) { rootNode._leafs = []; } const childrenAfterGroup = []; const childrenAfterSort = []; const childrenAfterAggFilter = []; const childrenAfterFilter = []; rootNode.childrenAfterGroup = childrenAfterGroup; rootNode.childrenAfterSort = childrenAfterSort; rootNode.childrenAfterAggFilter = childrenAfterAggFilter; rootNode.childrenAfterFilter = childrenAfterFilter; const sibling = rootNode.sibling; if (sibling) { sibling.childrenAfterGroup = childrenAfterGroup; sibling.childrenAfterSort = childrenAfterSort; sibling.childrenAfterAggFilter = childrenAfterAggFilter; sibling.childrenAfterFilter = childrenAfterFilter; sibling.childrenMapped = rootNode.childrenMapped; } rootNode.updateHasChildren(); return rootNode; }; var lookupNodeByData = (nodes, data) => { if (nodes) { for (let i = 0, len = nodes.length;i < len; i++) { const node = nodes[i]; if (node.data === data) { return node; } } } _error(5, { data }); return null; }; var filterRemovedRowNodes = (allLeafs, filterIdx, filterEndIdx) => { filterIdx = Math.max(0, filterIdx); for (let readIdx = filterIdx, len = allLeafs.length;readIdx < len; ++readIdx) { const node = allLeafs[readIdx]; if (readIdx <= filterEndIdx && node.destroyed) { continue; } node.sourceRowIndex = filterIdx; allLeafs[filterIdx++] = node; } allLeafs.length = filterIdx; }; var updateRootLeafsOrdered = (allLeafs, processedNodes) => { const newSize = processedNodes.size; allLeafs.length = newSize; let writeIdx = 0; let added = false; let reordered = false; for (const node of processedNodes) { const sourceRowIndex = node.sourceRowIndex; if (sourceRowIndex === writeIdx) { reordered || (reordered = added); } else { if (sourceRowIndex >= 0) { reordered = true; } else { added = true; } node.sourceRowIndex = writeIdx; allLeafs[writeIdx] = node; } ++writeIdx; } return reordered; }; var updateRootLeafsKeepOrder = (allLeafs, processedNodes, { adds }) => { const allLeafsLen = allLeafs.length; const newAllLeafsLen = processedNodes.size; if (newAllLeafsLen > allLeafsLen) { allLeafs.length = newAllLeafsLen; } let writeIdx = 0; for (let readIdx = 0;readIdx < allLeafsLen; ++readIdx) { const node = allLeafs[readIdx]; if (!node.destroyed) { if (writeIdx !== readIdx) { node.sourceRowIndex = writeIdx; allLeafs[writeIdx] = node; } ++writeIdx; } } for (const node of adds) { if (node.sourceRowIndex < 0) { node.sourceRowIndex = writeIdx; allLeafs[writeIdx++] = node; } } allLeafs.length = writeIdx; }; function updateRowNodeAfterFilter(rowNode) { const sibling = rowNode.sibling; if (sibling) { sibling.childrenAfterFilter = rowNode.childrenAfterFilter; } } var FilterStage = class extends BeanStub { constructor() { super(...arguments); this.beanName = "filterStage"; this.step = "filter"; this.refreshProps = ["excludeChildrenWhenTreeDataFiltering"]; } wireBeans(beans) { this.filterManager = beans.filterManager; } execute(changedPath) { const filterActive = !!this.filterManager?.isChildFilterPresent(); if (this.beans.formula?.active) { this.softFilter(filterActive, changedPath); } else { this.filterNodes(filterActive, changedPath); } } filterNodes(filterActive, changedPath) { const filterCallback = (rowNode, includeChildNodes) => { if (rowNode.hasChildren()) { if (filterActive && !includeChildNodes) { rowNode.childrenAfterFilter = rowNode.childrenAfterGroup.filter((childNode) => { const passBecauseChildren = childNode.childrenAfterFilter && childNode.childrenAfterFilter.length > 0; const passBecauseDataPasses = childNode.data && this.filterManager.doesRowPassFilter({ rowNode: childNode }); return passBecauseChildren || passBecauseDataPasses; }); } else { rowNode.childrenAfterFilter = rowNode.childrenAfterGroup; } } else { rowNode.childrenAfterFilter = rowNode.childrenAfterGroup; } updateRowNodeAfterFilter(rowNode); }; if (this.doingTreeDataFiltering()) { const treeDataDepthFirstFilter = (rowNode, alreadyFoundInParent) => { if (rowNode.childrenAfterGroup) { for (let i = 0;i < rowNode.childrenAfterGroup.length; i++) { const childNode = rowNode.childrenAfterGroup[i]; const foundInParent = alreadyFoundInParent || this.filterManager.doesRowPassFilter({ rowNode: childNode }); if (childNode.childrenAfterGroup) { treeDataDepthFirstFilter(rowNode.childrenAfterGroup[i], foundInParent); } else { filterCallback(childNode, foundInParent); } } } filterCallback(rowNode, alreadyFoundInParent); }; treeDataDepthFirstFilter(this.beans.rowModel.rootNode, false); } else { const defaultFilterCallback = (rowNode) => filterCallback(rowNode, false); _forEachChangedGroupDepthFirst(this.beans.rowModel.rootNode, this.beans.rowModel.hierarchical, changedPath, defaultFilterCallback); } } softFilter(filterActive, changedPath) { const filterCallback = (rowNode) => { rowNode.childrenAfterFilter = rowNode.childrenAfterGroup; if (rowNode.hasChildren()) { for (const childNode of rowNode.childrenAfterGroup) { childNode.softFiltered = filterActive && !(childNode.data && this.filterManager.doesRowPassFilter({ rowNode: childNode })); } } updateRowNodeAfterFilter(rowNode); }; const rowModel = this.beans.rowModel; _forEachChangedGroupDepthFirst(rowModel.rootNode, rowModel.hierarchical, changedPath, filterCallback); } doingTreeDataFiltering() { const { gos } = this; return !!this.beans.groupStage?.treeData && !gos.get("excludeChildrenWhenTreeDataFiltering"); } }; var MIN_DELTA_SORT_ROWS = 4; var doDeltaSort = (rowNodeSorter, rowNode, changedRowNodes, changedPath, sortOptions) => { const oldSortedRows = rowNode.childrenAfterSort; const unsortedRows = rowNode.childrenAfterAggFilter; if (!unsortedRows) { return oldSortedRows && oldSortedRows.length > 0 ? oldSortedRows : []; } const unsortedRowsLen = unsortedRows.length; if (unsortedRowsLen <= 1) { if (oldSortedRows?.length === unsortedRowsLen && (unsortedRowsLen === 0 || oldSortedRows[0] === unsortedRows[0])) { return oldSortedRows; } return unsortedRows.slice(); } if (!oldSortedRows || unsortedRowsLen <= MIN_DELTA_SORT_ROWS) { return rowNodeSorter.doFullSortInPlace(unsortedRows.slice(), sortOptions); } const indexByNode = /* @__PURE__ */ new Map; const { updates, adds } = changedRowNodes; const touchedRows = []; for (let i = 0;i < unsortedRowsLen; ++i) { const node = unsortedRows[i]; if (updates.has(node) || adds.has(node) || changedPath?.hasRow(node)) { indexByNode.set(node, ~i); touchedRows.push(node); } else { indexByNode.set(node, i); } } const touchedRowsLen = touchedRows.length; if (touchedRowsLen === 0) { return unsortedRowsLen === oldSortedRows.length ? oldSortedRows : filterRemovedNodes(oldSortedRows, indexByNode, touchedRows); } touchedRows.sort((a, b) => rowNodeSorter.compareRowNodes(sortOptions, a, b) || ~indexByNode.get(a) - ~indexByNode.get(b)); if (touchedRowsLen === unsortedRowsLen) { return touchedRows; } return mergeDeltaSortedArrays(rowNodeSorter, sortOptions, touchedRows, oldSortedRows, indexByNode, unsortedRowsLen); }; var mergeDeltaSortedArrays = (rowNodeSorter, sortOptions, touchedRows, oldSortedRows, indexByNode, resultSize) => { const result = new Array(resultSize); let touchedIdx = 0; let touchedNode = touchedRows[touchedIdx]; let untouchedNode; let untouchedIdx = -1; let oldIdx = 0; let resultIdx = 0; const touchedLength = touchedRows.length; const oldSortedLength = oldSortedRows.length; while (true) { if (untouchedIdx < 0) { if (oldIdx >= oldSortedLength) { break; } untouchedNode = oldSortedRows[oldIdx++]; untouchedIdx = indexByNode.get(untouchedNode) ?? -1; if (untouchedIdx < 0) { continue; } } const orderDelta = rowNodeSorter.compareRowNodes(sortOptions, touchedNode, untouchedNode) || ~indexByNode.get(touchedNode) - untouchedIdx; if (orderDelta < 0) { result[resultIdx++] = touchedNode; if (++touchedIdx >= touchedLength) { break; } touchedNode = touchedRows[touchedIdx]; } else { result[resultIdx++] = untouchedNode; untouchedIdx = -1; } } while (touchedIdx < touchedLength) { result[resultIdx++] = touchedRows[touchedIdx++]; } if (untouchedIdx < 0) { return result; } result[resultIdx++] = untouchedNode; while (oldIdx < oldSortedLength) { const node = oldSortedRows[oldIdx++]; if (indexByNode.get(node) >= 0) { result[resultIdx++] = node; } } return result; }; var filterRemovedNodes = (rows, map, result) => { let count = 0; result.length = map.size; for (let i = 0, len = rows.length;i < len; ++i) { const node = rows[i]; if (map.has(node)) { result[count++] = node; } } result.length = count; return result; }; var updateRowNodeAfterSort = (rowNode) => { const childrenAfterSort = rowNode.childrenAfterSort; const sibling = rowNode.sibling; if (sibling) { sibling.childrenAfterSort = childrenAfterSort; } if (!childrenAfterSort) { return; } for (let i = 0, lastIdx = childrenAfterSort.length - 1;i <= lastIdx; i++) { const child = childrenAfterSort[i]; const first = i === 0; const last = i === lastIdx; if (child.firstChild !== first) { child.firstChild = first; child.dispatchRowEvent("firstChildChanged"); } if (child.lastChild !== last) { child.lastChild = last; child.dispatchRowEvent("lastChildChanged"); } if (child.childIndex !== i) { child.childIndex = i; child.dispatchRowEvent("childIndexChanged"); } } }; var SortStage = class extends BeanStub { constructor() { super(...arguments); this.beanName = "sortStage"; this.step = "sort"; this.refreshProps = ["postSortRows", "groupDisplayType", "accentedSort"]; } execute(changedPath, changedRowNodes) { const sortOptions = this.beans.sortSvc.getSortOptions(); const useDeltaSort = sortOptions.length > 0 && !!changedRowNodes && this.gos.get("deltaSort"); const { gos, colModel, rowGroupColsSvc, rowNodeSorter, rowRenderer, showRowGroupCols } = this.beans; const groupMaintainOrder = gos.get("groupMaintainOrder"); const groupColumnsPresent = colModel.getCols().some((c) => c.isRowGroupActive()); const groupCols = rowGroupColsSvc?.columns; const isPivotMode = colModel.isPivotMode(); const postSortFunc = gos.getCallback("postSortRows"); let hasAnyFirstChildChanged = false; let sortContainsGroupColumns; const callback = (rowNode) => { const skipSortingPivotLeafs = isPivotMode && rowNode.leafGroup; let skipSortingGroups = groupMaintainOrder && groupColumnsPresent && !rowNode.leafGroup; if (skipSortingGroups) { sortContainsGroupColumns ?? (sortContainsGroupColumns = this.shouldSortContainsGroupCols(sortOptions)); skipSortingGroups && (skipSortingGroups = !sortContainsGroupColumns); } let newChildrenAfterSort = null; if (skipSortingGroups) { let wasSortExplicitlyRemoved = false; if (groupCols) { const nextGroupIndex = rowNode.level + 1; if (nextGroupIndex < groupCols.length) { wasSortExplicitlyRemoved = groupCols[nextGroupIndex].wasSortExplicitlyRemoved; } } if (!wasSortExplicitlyRemoved) { newChildrenAfterSort = preserveGroupOrder(rowNode); } } else if (!sortOptions.length || skipSortingPivotLeafs) {} else if (useDeltaSort && changedRowNodes) { newChildrenAfterSort = doDeltaSort(rowNodeSorter, rowNode, changedRowNodes, changedPath, sortOptions); } else { newChildrenAfterSort = rowNodeSorter.doFullSortInPlace(rowNode.childrenAfterAggFilter.slice(), sortOptions); } newChildrenAfterSort || (newChildrenAfterSort = rowNode.childrenAfterAggFilter?.slice() ?? []); hasAnyFirstChildChanged || (hasAnyFirstChildChanged = rowNode.childrenAfterSort?.[0] !== newChildrenAfterSort[0]); rowNode.childrenAfterSort = newChildrenAfterSort; updateRowNodeAfterSort(rowNode); if (postSortFunc) { const params = { nodes: rowNode.childrenAfterSort }; postSortFunc(params); } }; _forEachChangedGroupDepthFirst(this.beans.rowModel.rootNode, this.beans.rowModel.hierarchical, changedPath, callback); if (hasAnyFirstChildChanged && gos.get("groupHideOpenParents")) { const columns = showRowGroupCols?.columns; if (columns?.length) { rowRenderer.refreshCells({ columns, force: true }); } } } shouldSortContainsGroupCols(sortOptions) { const sortOptionsLen = sortOptions.length; if (!sortOptionsLen) { return false; } if (_isColumnsSortingCoupledToGroup(this.gos)) { for (let i = 0;i < sortOptionsLen; ++i) { const column = sortOptions[i].column; if (column.isPrimary() && column.isRowGroupActive()) { return true; } } return false; } for (let i = 0;i < sortOptionsLen; ++i) { if (sortOptions[i].column.getColDef().showRowGroup) { return true; } } return false; } }; var preserveGroupOrder = (node) => { const childrenAfterSort = node.childrenAfterSort; const childrenAfterAggFilter = node.childrenAfterAggFilter; const childrenAfterSortLen = childrenAfterSort?.length; const childrenAfterAggFilterLen = childrenAfterAggFilter?.length; if (!childrenAfterSortLen || !childrenAfterAggFilterLen) { return null; } const result = new Array(childrenAfterAggFilterLen); const processed = /* @__PURE__ */ new Set; for (let i = 0;i < childrenAfterAggFilterLen; ++i) { processed.add(childrenAfterAggFilter[i]); } let writeIdx = 0; for (let i = 0;i < childrenAfterSortLen; ++i) { const node2 = childrenAfterSort[i]; if (processed.delete(node2)) { result[writeIdx++] = node2; } } if (processed.size === 0 && writeIdx === childrenAfterSortLen) { return childrenAfterSort; } for (const newNode of processed) { result[writeIdx++] = newNode; } result.length = writeIdx; return result; }; var ClientSideRowModel = class extends BeanStub { constructor() { super(...arguments); this.beanName = "rowModel"; this.rootNode = null; this.rowCountReady = false; this.hierarchical = false; this.nodeManager = undefined; this.rowsToDisplay = []; this.formulaRows = []; this.stages = null; this.asyncTransactions = null; this.asyncTransactionsTimer = 0; this.started = false; this.refreshingData = false; this.rowDataUpdatedPending = false; this.refreshingModel = false; this.pendingNewData = false; this.noKeepRenderedRows = false; this.noKeepUndoRedoStack = false; this.noAnimate = false; this.rowNodesCountReady = false; this.stagesRefreshProps = /* @__PURE__ */ new Map; this.onRowHeightChanged_debounced = _debounce(this, this.onRowHeightChanged.bind(this), 100); } postConstruct() { const beans = this.beans; const rootNode = new RowNode(beans); this.rootNode = rootNode; this.nodeManager = this.createBean(new ClientSideNodeManager(rootNode)); const onColumnsChanged = () => { this.beans.groupStage?.invalidateGroupCols(); this.refreshModel({ step: "group", afterColumnsChanged: true, keepRenderedRows: true, animate: !this.gos.get("suppressAnimationFrame") }); }; this.addManagedEventListeners({ newColumnsLoaded: onColumnsChanged, columnRowGroupChanged: onColumnsChanged, columnValueChanged: this.onValueChanged.bind(this), columnPivotChanged: () => this.refreshModel({ step: "pivot" }), columnPivotModeChanged: () => this.refreshModel({ step: "group" }), filterChanged: this.onFilterChanged.bind(this), sortChanged: this.onSortChanged.bind(this), stylesChanged: this.onGridStylesChanges.bind(this), gridReady: this.onGridReady.bind(this), rowExpansionStateChanged: this.onRowGroupOpened.bind(this) }); this.addPropertyListeners(); } addPropertyListeners() { const { beans, stagesRefreshProps } = this; const orderedStages = [ beans.groupStage, beans.filterStage, beans.pivotStage, beans.aggStage, beans.sortStage, beans.filterAggStage, beans.flattenStage ].filter((stage) => !!stage); this.stages = orderedStages; for (let i = orderedStages.length - 1;i >= 0; --i) { const stage = orderedStages[i]; for (const prop of stage.refreshProps) { stagesRefreshProps.set(prop, i); } } this.addManagedPropertyListeners([...stagesRefreshProps.keys(), "rowData"], (params) => { const properties = params.changeSet?.properties; if (properties) { this.onPropChange(properties); } }); this.addManagedPropertyListener("rowHeight", () => this.resetRowHeights()); } start() { this.started = true; if (this.rowNodesCountReady) { this.refreshModel({ step: "group", rowDataUpdated: true, newData: true }); } else { this.setInitialData(); } } setInitialData() { const rowData = this.gos.get("rowData"); if (rowData) { this.onPropChange(["rowData"]); } } ensureRowHeightsValid(startPixel, endPixel, startLimitIndex, endLimitIndex) { let atLeastOneChange; let res = false; do { atLeastOneChange = false; const rowAtStartPixel = this.getRowIndexAtPixel(startPixel); const rowAtEndPixel = this.getRowIndexAtPixel(endPixel); const firstRow = Math.max(rowAtStartPixel, startLimitIndex); const lastRow = Math.min(rowAtEndPixel, endLimitIndex); for (let rowIndex = firstRow;rowIndex <= lastRow; rowIndex++) { const rowNode = this.getRow(rowIndex); if (rowNode.rowHeightEstimated) { const rowHeight = _getRowHeightForNode(this.beans, rowNode); rowNode.setRowHeight(rowHeight.height); atLeastOneChange = true; res = true; } } if (atLeastOneChange) { this.setRowTopAndRowIndex(); } } while (atLeastOneChange); return res; } onPropChange(properties) { const { nodeManager, gos, beans } = this; const groupStage = beans.groupStage; if (!nodeManager) { return; } const changedProps = new Set(properties); const extractData = groupStage?.onPropChange(changedProps); let newRowData; if (changedProps.has("rowData")) { newRowData = gos.get("rowData"); } else if (extractData) { newRowData = groupStage?.extractData(); } if (newRowData && !Array.isArray(newRowData)) { newRowData = null; _warn(1); } const params = { step: "nothing", changedProps }; if (newRowData) { const immutable = !extractData && !this.isEmpty() && newRowData.length > 0 && gos.exists("getRowId") && !gos.get("resetRowDataOnUpdate"); this.refreshingData = true; if (immutable) { params.keepRenderedRows = true; params.animate = !gos.get("suppressAnimationFrame"); params.changedRowNodes = new ChangedRowNodes; nodeManager.setImmutableRowData(params, newRowData); } else { params.rowDataUpdated = true; params.newData = true; nodeManager.setNewRowData(newRowData); this.rowNodesCountReady = true; } } const step = params.rowDataUpdated ? "group" : this.getRefreshedStage(properties); if (step) { params.step = step; this.refreshModel(params); } } getRefreshedStage(properties) { const { stages, stagesRefreshProps } = this; if (!stages) { return null; } const stagesLen = stages.length; let minIndex = stagesLen; for (let i = 0, len = properties.length;i < len && minIndex; ++i) { minIndex = Math.min(minIndex, stagesRefreshProps.get(properties[i]) ?? minIndex); } return minIndex < stagesLen ? stages[minIndex].step : null; } setRowTopAndRowIndex(outputDisplayedRowsMapped) { const { beans, rowsToDisplay } = this; const defaultRowHeight = beans.environment.getDefaultRowHeight(); let nextRowTop = 0; const allowEstimate = _isDomLayout(this.gos, "normal"); for (let i = 0, len = rowsToDisplay.length;i < len; ++i) { const rowNode = rowsToDisplay[i]; const id = rowNode.id; if (id != null) { outputDisplayedRowsMapped?.add(id); } if (rowNode.rowHeight == null) { const rowHeight = _getRowHeightForNode(beans, rowNode, allowEstimate, defaultRowHeight); rowNode.setRowHeight(rowHeight.height, rowHeight.estimated); } rowNode.setRowTop(nextRowTop); rowNode.setRowIndex(i); nextRowTop += rowNode.rowHeight; } if (this.beans.formula?.active) { const formulaRows = this.formulaRows; for (let i = 0, len = formulaRows.length;i < len; ++i) { const rowNode = formulaRows[i]; rowNode.formulaRowIndex = i; } } } clearRowTopAndRowIndex(changedPath, displayedRowsMapped) { const clearIfNotDisplayed = (rowNode) => { if (rowNode?.id != null && !displayedRowsMapped.has(rowNode.id)) { rowNode.clearRowTopAndRowIndex(); } }; const recurse = (rowNode) => { clearIfNotDisplayed(rowNode); clearIfNotDisplayed(rowNode.detailNode); clearIfNotDisplayed(rowNode.sibling); const childrenAfterGroup = rowNode.childrenAfterGroup; if (!rowNode.hasChildren() || !childrenAfterGroup) { return; } if (changedPath && rowNode.level !== -1 && !rowNode.expanded) { return; } for (let i = 0, len = childrenAfterGroup.length;i < len; ++i) { recurse(childrenAfterGroup[i]); } }; const rootNode = this.rootNode; if (rootNode) { recurse(rootNode); } } isLastRowIndexKnown() { return true; } getRowCount() { return this.rowsToDisplay.length; } getTopLevelRowCount() { const { rootNode, rowsToDisplay } = this; if (!rootNode || !rowsToDisplay.length) { return 0; } const showingRootNode = rowsToDisplay[0] === rootNode; if (showingRootNode) { return 1; } const totalFooterInc = rootNode.sibling?.displayed ? 1 : 0; return (rootNode.childrenAfterSort?.length ?? 0) + totalFooterInc; } getTopLevelRowDisplayedIndex(topLevelIndex) { const { beans, rootNode, rowsToDisplay } = this; const showingRootNode = !rootNode || !rowsToDisplay.length || rowsToDisplay[0] === rootNode; if (showingRootNode) { return topLevelIndex; } const childrenAfterSort = rootNode.childrenAfterSort; const getDefaultIndex = (adjustedIndex) => { let rowNode = childrenAfterSort[adjustedIndex]; if (this.gos.get("groupHideOpenParents")) { while (rowNode.expanded && rowNode.childrenAfterSort && rowNode.childrenAfterSort.length > 0) { rowNode = rowNode.childrenAfterSort[0]; } } return rowNode.rowIndex; }; const footerSvc = beans.footerSvc; if (footerSvc) { return footerSvc?.getTopDisplayIndex(rowsToDisplay, topLevelIndex, childrenAfterSort, getDefaultIndex); } return getDefaultIndex(topLevelIndex); } getTopLevelIndexFromDisplayedIndex(displayedIndex) { const { rootNode, rowsToDisplay } = this; const showingRootNode = !rootNode || !rowsToDisplay.length || rowsToDisplay[0] === rootNode; if (showingRootNode) { return displayedIndex; } let node = this.getRow(displayedIndex); if (node.footer) { node = node.sibling; } let parent = node.parent; while (parent && parent !== rootNode) { node = parent; parent = node.parent; } const topLevelIndex = rootNode.childrenAfterSort?.indexOf(node) ?? -1; return topLevelIndex >= 0 ? topLevelIndex : displayedIndex; } getRowBounds(index) { const rowNode = this.rowsToDisplay[index]; return rowNode ? { rowTop: rowNode.rowTop, rowHeight: rowNode.rowHeight } : null; } onRowGroupOpened() { this.refreshModel({ step: "map", keepRenderedRows: true, animate: _isAnimateRows(this.gos) }); } onFilterChanged({ afterDataChange, columns }) { if (!afterDataChange) { const primaryOrQuickFilterChanged = columns.length === 0 || columns.some((col) => col.isPrimary()); const step = primaryOrQuickFilterChanged ? "filter" : "filter_aggregates"; this.refreshModel({ step, keepRenderedRows: true, animate: _isAnimateRows(this.gos) }); } } onSortChanged() { this.refreshModel({ step: "sort", keepRenderedRows: true, animate: _isAnimateRows(this.gos) }); } getType() { return "clientSide"; } onValueChanged() { this.refreshModel({ step: this.beans.colModel.isPivotActive() ? "pivot" : "aggregate" }); } isSuppressModelUpdateAfterUpdateTransaction(params) { if (!this.gos.get("suppressModelUpdateAfterUpdateTransaction")) { return false; } const { changedRowNodes, newData, rowDataUpdated } = params; if (!changedRowNodes || newData || !rowDataUpdated) { return false; } if (changedRowNodes.removals.length || changedRowNodes.adds.size) { return false; } return true; } reMapRows() { if (this.refreshingModel || this.refreshingData) { this.noKeepRenderedRows = true; this.noKeepUndoRedoStack = true; this.noAnimate = true; return; } this.refreshModel({ step: "map", keepRenderedRows: false, keepUndoRedoStack: false, animate: false }); } refreshModel(params) { const { nodeManager, eventSvc, started } = this; if (!nodeManager) { return; } const rowDataUpdated = !!params.rowDataUpdated; if (started && rowDataUpdated) { eventSvc.dispatchEvent({ type: "rowDataUpdated" }); } if (this.deferRefresh(params)) { this.setPendingRefreshFlags(params); this.rowDataUpdatedPending || (this.rowDataUpdatedPending = rowDataUpdated); return; } if (this.rowDataUpdatedPending) { this.rowDataUpdatedPending = false; params.step = "group"; } this.updateRefreshParams(params); let succeeded = false; this.refreshingModel = true; try { this.executeRefresh(params, rowDataUpdated); succeeded = true; } finally { this.refreshingData = false; this.refreshingModel = false; if (!succeeded) { this.setPendingRefreshFlags(params); } } this.clearPendingRefreshFlags(); eventSvc.dispatchEvent({ type: "modelUpdated", animate: params.animate, keepRenderedRows: params.keepRenderedRows, newData: params.newData, newPage: false, keepUndoRedoStack: params.keepUndoRedoStack }); } executeRefresh(params, rowDataUpdated) { const { beans, rootNode } = this; beans.masterDetailSvc?.refreshModel(params); if (rowDataUpdated && params.step !== "group") { beans.colFilter?.refreshModel(); } let changedPath = params.changedPath; changedPath?.addRow(rootNode); if (params.step === "group") { this.doGrouping(rootNode, params); changedPath ?? (changedPath = params.changedPath); } changedPath ?? (changedPath = beans.changedPathFactory?.ensureRowsPath(params, rootNode)); switch (params.step) { case "group": case "filter": this.doFilter(changedPath); case "pivot": if (this.doPivot(changedPath)) { changedPath = undefined; params.changedPath = undefined; } case "aggregate": this.doAggregate(changedPath); case "filter_aggregates": this.doFilterAggregates(changedPath); case "sort": this.doSort(changedPath, params.changedRowNodes); case "map": this.doRowsToDisplay(); } const displayedNodesMapped = /* @__PURE__ */ new Set; this.setRowTopAndRowIndex(displayedNodesMapped); this.clearRowTopAndRowIndex(changedPath, displayedNodesMapped); this.updateRefreshParams(params); } deferRefresh(params) { if (this.refreshingModel) { return true; } if (this.beans.colModel.changeEventsDispatching) { return true; } if (this.isSuppressModelUpdateAfterUpdateTransaction(params)) { if (this.started) { this.refreshingData = false; } return true; } if (!this.started) { return true; } return false; } setPendingRefreshFlags(params) { this.pendingNewData || (this.pendingNewData = !!params.newData); this.noKeepRenderedRows || (this.noKeepRenderedRows = !params.keepRenderedRows); this.noKeepUndoRedoStack || (this.noKeepUndoRedoStack = !params.keepUndoRedoStack); this.noAnimate || (this.noAnimate = !params.animate); } clearPendingRefreshFlags() { this.pendingNewData = false; this.noKeepRenderedRows = false; this.noKeepUndoRedoStack = false; this.noAnimate = false; } updateRefreshParams(params) { params.newData = this.pendingNewData || !!params.newData; params.keepRenderedRows = !this.noKeepRenderedRows && !!params.keepRenderedRows; params.keepUndoRedoStack = !this.noKeepUndoRedoStack && !!params.keepUndoRedoStack; params.animate = !this.noAnimate && !!params.animate; } isEmpty() { return !this.rootNode?._leafs?.length || !this.beans.colModel?.ready; } isRowsToRender() { return this.rowsToDisplay.length > 0; } getOverlayType() { const { beans, gos } = this; if (this.rootNode?._leafs?.length) { if (beans.filterManager?.isAnyFilterPresent() && this.getRowCount() === 0) { return "noMatchingRows"; } } else if (this.rowCountReady || (gos.get("rowData")?.length ?? 0) == 0) { return "noRows"; } return null; } getNodesInRangeForSelection(firstInRange, lastInRange) { let started = false; let finished = false; const result = []; const groupsSelectChildren = _getGroupSelectsDescendants(this.gos); this.forEachNodeAfterFilterAndSort((rowNode) => { if (finished) { return; } if (started) { if (rowNode === lastInRange || rowNode === firstInRange) { finished = true; if (groupsSelectChildren && rowNode.group) { addAllLeafs(result, rowNode); return; } } } if (!started) { if (rowNode !== lastInRange && rowNode !== firstInRange) { return; } started = true; if (lastInRange === firstInRange) { finished = true; } } const includeThisNode = !rowNode.group || !groupsSelectChildren; if (includeThisNode) { result.push(rowNode); } }); return result; } getTopLevelNodes() { return this.rootNode?.childrenAfterGroup ?? null; } getRow(index) { return this.rowsToDisplay[index]; } getFormulaRow(index) { return this.formulaRows[index]; } isRowPresent(rowNode) { return this.rowsToDisplay.indexOf(rowNode) >= 0; } getRowIndexAtPixel(pixelToMatch) { const rowsToDisplay = this.rowsToDisplay; const rowsToDisplayLen = rowsToDisplay.length; if (this.isEmpty() || rowsToDisplayLen === 0) { return -1; } let bottomPointer = 0; let topPointer = rowsToDisplayLen - 1; if (pixelToMatch <= 0) { return 0; } const lastNode = rowsToDisplay[topPointer]; if (lastNode.rowTop <= pixelToMatch) { return topPointer; } let oldBottomPointer = -1; let oldTopPointer = -1; while (true) { const midPointer = Math.floor((bottomPointer + topPointer) / 2); const currentRowNode = rowsToDisplay[midPointer]; if (this.isRowInPixel(currentRowNode, pixelToMatch)) { return midPointer; } if (currentRowNode.rowTop < pixelToMatch) { bottomPointer = midPointer + 1; } else if (currentRowNode.rowTop > pixelToMatch) { topPointer = midPointer - 1; } const caughtInInfiniteLoop = oldBottomPointer === bottomPointer && oldTopPointer === topPointer; if (caughtInInfiniteLoop) { return midPointer; } oldBottomPointer = bottomPointer; oldTopPointer = topPointer; } } isRowInPixel(rowNode, pixelToMatch) { const topPixel = rowNode.rowTop; const bottomPixel = topPixel + rowNode.rowHeight; return topPixel <= pixelToMatch && bottomPixel > pixelToMatch; } forEachLeafNode(callback) { const allLeafs = this.rootNode?._leafs; if (allLeafs) { for (let i = 0, len = allLeafs.length;i < len; ++i) { callback(allLeafs[i], i); } } } forEachNode(callback, includeFooterNodes = false) { this.depthFirstSearchRowNodes(callback, includeFooterNodes); } forEachDisplayedNode(callback) { const rowsToDisplay = this.rowsToDisplay; for (let i = 0, len = rowsToDisplay.length;i < len; ++i) { callback(rowsToDisplay[i], i); } } forEachNodeAfterFilter(callback, includeFooterNodes = false) { this.depthFirstSearchRowNodes(callback, includeFooterNodes, (node) => node.childrenAfterAggFilter); } forEachNodeAfterFilterAndSort(callback, includeFooterNodes = false) { this.depthFirstSearchRowNodes(callback, includeFooterNodes, (node) => node.childrenAfterSort); } forEachPivotNode(callback, includeFooterNodes, afterSort) { const { colModel, rowGroupColsSvc } = this.beans; if (!colModel.isPivotMode()) { return; } if (!rowGroupColsSvc?.columns.length) { callback(this.rootNode, 0); return; } const childrenField = afterSort ? "childrenAfterSort" : "childrenAfterGroup"; this.depthFirstSearchRowNodes(callback, includeFooterNodes, (node) => !node.leafGroup ? node[childrenField] : null); } depthFirstSearchRowNodes(callback, includeFooterNodes = false, getChildren = (node2) => node2.childrenAfterGroup, node = this.rootNode, startIndex = 0) { let index = startIndex; if (!node) { return index; } const isRootNode = node === this.rootNode; if (!isRootNode) { callback(node, index++); } if (node.hasChildren() && !node.footer) { const children = isRootNode || this.hierarchical ? getChildren(node) : null; if (children) { const footerSvc = this.beans.footerSvc; index = footerSvc?.addTotalRows(index, node, callback, includeFooterNodes, isRootNode, "top") ?? index; for (const node2 of children) { index = this.depthFirstSearchRowNodes(callback, includeFooterNodes, getChildren, node2, index); } return footerSvc?.addTotalRows(index, node, callback, includeFooterNodes, isRootNode, "bottom") ?? index; } } return index; } doAggregate(changedPath) { const rootNode = this.rootNode; if (rootNode) { this.beans.aggStage?.execute(changedPath); } } doFilterAggregates(changedPath) { const rootNode = this.rootNode; const filterAggStage = this.beans.filterAggStage; if (filterAggStage && this.hierarchical) { filterAggStage.execute(changedPath); return; } rootNode.childrenAfterAggFilter = rootNode.childrenAfterFilter; const sibling = rootNode.sibling; if (sibling) { sibling.childrenAfterAggFilter = rootNode.childrenAfterFilter; } } doSort(changedPath, changedRowNodes) { const sortStage = this.beans.sortStage; if (sortStage) { sortStage.execute(changedPath, changedRowNodes); return; } _forEachChangedGroupDepthFirst(this.rootNode, this.hierarchical, changedPath, (rowNode) => { rowNode.childrenAfterSort = rowNode.childrenAfterAggFilter.slice(0); updateRowNodeAfterSort(rowNode); }); } doGrouping(rootNode, params) { const groupStage = this.beans.groupStage; const groupingChanged = groupStage?.execute(params); if (groupingChanged === undefined) { const allLeafs = rootNode._leafs; rootNode.childrenAfterGroup = allLeafs; rootNode.updateHasChildren(); const sibling = rootNode.sibling; if (sibling) { sibling.childrenAfterGroup = allLeafs; } } if (groupingChanged || params.rowDataUpdated) { this.beans.colFilter?.refreshModel(); } if (!this.rowCountReady && this.rowNodesCountReady) { this.rowCountReady = true; this.eventSvc.dispatchEventOnce({ type: "rowCountReady" }); } } doFilter(changedPath) { const filterStage = this.beans.filterStage; if (filterStage) { filterStage.execute(changedPath); return; } _forEachChangedGroupDepthFirst(this.rootNode, this.hierarchical, changedPath, (rowNode) => { rowNode.childrenAfterFilter = rowNode.childrenAfterGroup; updateRowNodeAfterFilter(rowNode); }); } doPivot(changedPath) { return this.beans.pivotStage?.execute(changedPath) ?? false; } getRowNode(id) { const found = this.nodeManager?.getRowNode(id); if (typeof found === "object") { return found; } return this.beans.groupStage?.getNonLeaf(id); } batchUpdateRowData(rowDataTransaction, callback) { if (!this.asyncTransactionsTimer) { this.asyncTransactions = []; const waitMilliseconds = this.gos.get("asyncTransactionWaitMillis"); this.asyncTransactionsTimer = setTimeout(() => this.executeBatchUpdateRowData(), waitMilliseconds); } this.asyncTransactions.push({ rowDataTransaction, callback }); } flushAsyncTransactions() { const asyncTransactionsTimer = this.asyncTransactionsTimer; if (asyncTransactionsTimer) { clearTimeout(asyncTransactionsTimer); this.executeBatchUpdateRowData(); } } executeBatchUpdateRowData() { const { nodeManager, beans, eventSvc, asyncTransactions } = this; if (!nodeManager) { return; } beans.valueCache?.onDataChanged(); const rowNodeTrans = []; const callbackFuncsBound = []; const changedRowNodes = new ChangedRowNodes; const animate = !this.gos.get("suppressAnimationFrame"); for (const { rowDataTransaction, callback } of asyncTransactions ?? []) { this.rowNodesCountReady = true; this.refreshingData = true; const rowNodeTransaction = nodeManager.updateRowData(rowDataTransaction, changedRowNodes, animate); rowNodeTrans.push(rowNodeTransaction); if (callback) { callbackFuncsBound.push(callback.bind(null, rowNodeTransaction)); } } this.commitTransactions(changedRowNodes, animate); if (callbackFuncsBound.length > 0) { setTimeout(() => { for (let i = 0, len = callbackFuncsBound.length;i < len; i++) { callbackFuncsBound[i](); } }, 0); } if (rowNodeTrans.length > 0) { eventSvc.dispatchEvent({ type: "asyncTransactionsFlushed", results: rowNodeTrans }); } this.asyncTransactionsTimer = 0; this.asyncTransactions = null; } updateRowData(rowDataTran) { const nodeManager = this.nodeManager; if (!nodeManager) { return null; } this.beans.valueCache?.onDataChanged(); this.rowNodesCountReady = true; const changedRowNodes = new ChangedRowNodes; const animate = !this.gos.get("suppressAnimationFrame"); this.refreshingData = true; const rowNodeTransaction = nodeManager.updateRowData(rowDataTran, changedRowNodes, animate); this.commitTransactions(changedRowNodes, animate); return rowNodeTransaction; } commitTransactions(changedRowNodes, animate) { this.refreshModel({ step: "group", rowDataUpdated: true, keepRenderedRows: true, animate, changedRowNodes }); } doRowsToDisplay() { const { rootNode, beans } = this; if (beans.formula?.active) { const unfilteredRows = rootNode?.childrenAfterSort ?? []; this.formulaRows = unfilteredRows; this.rowsToDisplay = unfilteredRows.filter((row) => !row.softFiltered); for (const row of this.rowsToDisplay) { row.setUiLevel(0); } return; } const flattenStage = beans.flattenStage; if (flattenStage) { this.rowsToDisplay = flattenStage.execute(); return; } const rowsToDisplay = this.rootNode.childrenAfterSort ?? []; for (const row of rowsToDisplay) { row.setUiLevel(0); } this.rowsToDisplay = rowsToDisplay; } onRowHeightChanged() { this.refreshModel({ step: "map", keepRenderedRows: true, keepUndoRedoStack: true }); } resetRowHeights() { const rootNode = this.rootNode; if (!rootNode) { return; } const atLeastOne = this.resetRowHeightsForAllRowNodes(); rootNode.setRowHeight(rootNode.rowHeight, true); const sibling = rootNode.sibling; sibling?.setRowHeight(sibling.rowHeight, true); if (atLeastOne) { this.onRowHeightChanged(); } } resetRowHeightsForAllRowNodes() { let atLeastOne = false; this.forEachNode((rowNode) => { rowNode.setRowHeight(rowNode.rowHeight, true); const detailNode = rowNode.detailNode; detailNode?.setRowHeight(detailNode.rowHeight, true); const sibling = rowNode.sibling; sibling?.setRowHeight(sibling.rowHeight, true); atLeastOne = true; }); return atLeastOne; } onGridStylesChanges(e) { if (e.rowHeightChanged && !this.beans.rowAutoHeight?.active) { this.resetRowHeights(); } } onGridReady() { if (!this.started) { this.setInitialData(); } } destroy() { super.destroy(); this.nodeManager = this.destroyBean(this.nodeManager); this.started = false; this.rootNode = null; this.rowsToDisplay = []; this.asyncTransactions = null; this.stages = null; this.stagesRefreshProps.clear(); clearTimeout(this.asyncTransactionsTimer); } onRowHeightChangedDebounced() { this.onRowHeightChanged_debounced(); } }; var addAllLeafs = (result, node) => { const childrenAfterGroup = node.childrenAfterGroup; if (childrenAfterGroup) { for (let i = 0, len = childrenAfterGroup.length;i < len; ++i) { const child = childrenAfterGroup[i]; if (child.data) { result.push(child); } if (child.group) { addAllLeafs(result, child); } } } }; var ClientSideRowModelModule = { moduleName: "ClientSideRowModel", version: VERSION, rowModels: ["clientSide"], beans: [ClientSideRowModel, SortStage], dependsOn: [SortModule] }; var columnAutoSize_default = ":where(.ag-ltr) :where(.ag-animate-autosize){.ag-cell,.ag-header-cell,.ag-header-group-cell{transition:width .2s ease-in-out,left .2s ease-in-out}}:where(.ag-rtl) :where(.ag-animate-autosize){.ag-cell,.ag-header-cell,.ag-header-group-cell{transition:width .2s ease-in-out,right .2s ease-in-out}}"; function sizeColumnsToFit(beans, paramsOrGridWidth) { if (typeof paramsOrGridWidth === "number") { beans.colAutosize?.sizeColumnsToFit(paramsOrGridWidth, "api"); } else { beans.colAutosize?.sizeColumnsToFitGridBody(paramsOrGridWidth); } } function autoSizeColumns({ colAutosize, visibleCols }, keysOrParams, skipHeader) { if (Array.isArray(keysOrParams)) { colAutosize?.autoSizeCols({ colKeys: keysOrParams, skipHeader, source: "api" }); } else { colAutosize?.autoSizeCols({ ...keysOrParams, colKeys: keysOrParams.colIds ?? visibleCols.allCols, source: "api" }); } } function autoSizeAllColumns(beans, paramsOrSkipHeader) { if (paramsOrSkipHeader && typeof paramsOrSkipHeader === "object") { autoSizeColumns(beans, paramsOrSkipHeader); } else { beans.colAutosize?.autoSizeAllColumns({ source: "api", skipHeader: paramsOrSkipHeader }); } } var ColumnAutosizeService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colAutosize"; this.timesDelayed = 0; this.shouldQueueResizeOperations = false; this.resizeOperationQueue = []; } postConstruct() { const { gos } = this; const autoSizeStrategy = gos.get("autoSizeStrategy"); if (autoSizeStrategy) { let shouldHideColumns = false; const type = autoSizeStrategy.type; if (type === "fitGridWidth" || type === "fitProvidedWidth") { shouldHideColumns = true; } else if (type === "fitCellContents") { this.addManagedEventListeners({ firstDataRendered: () => this.onFirstDataRendered(autoSizeStrategy) }); const rowData = gos.get("rowData"); shouldHideColumns = rowData != null && rowData.length > 0 && _isClientSideRowModel(gos); } if (shouldHideColumns) { this.beans.colDelayRenderSvc?.hideColumns(type); } } } autoSizeCols(params) { const { eventSvc, visibleCols, colModel } = this.beans; setWidthAnimation(this.beans, true); this.innerAutoSizeCols(params).then((columnsAutoSized) => { const dispatch = (cols) => dispatchColumnResizedEvent(eventSvc, Array.from(cols), true, "autosizeColumns"); if (!params.scaleUpToFitGridWidth) { setWidthAnimation(this.beans, false); return dispatch(columnsAutoSized); } const availableGridWidth = getAvailableWidth(this.beans); const isLeftCol = (col) => visibleCols.leftCols.some((leftCol) => _columnsMatch(leftCol, col)); const isRightCol = (col) => visibleCols.rightCols.some((rightCol) => _columnsMatch(rightCol, col)); const colKeys = params.colKeys.filter((col) => { const allowAutoSize = !colModel.getCol(col)?.getColDef().suppressAutoSize; return allowAutoSize && !isRowNumberCol(col) && !isLeftCol(col) && !isRightCol(col); }); this.sizeColumnsToFit(availableGridWidth, params.source, true, { defaultMaxWidth: params.defaultMaxWidth, defaultMinWidth: params.defaultMinWidth, columnLimits: params.columnLimits?.map((limit) => ({ ...limit, key: limit.colId })), colKeys, onlyScaleUp: true, animate: false }); setWidthAnimation(this.beans, false); dispatch(columnsAutoSized); }); } innerAutoSizeCols(params) { return new Promise((resolve, reject) => { if (this.shouldQueueResizeOperations) { return this.pushResizeOperation(() => this.innerAutoSizeCols(params).then(resolve, reject)); } const { colKeys, skipHeader, skipHeaderGroups, stopAtGroup, defaultMaxWidth, defaultMinWidth, columnLimits = [], source = "api" } = params; const { animationFrameSvc, renderStatus, colModel, autoWidthCalc, visibleCols } = this.beans; animationFrameSvc?.flushAllFrames(); if (this.timesDelayed < 5 && renderStatus && (!renderStatus.areHeaderCellsRendered() || !renderStatus.areCellsRendered())) { this.timesDelayed++; setTimeout(() => { if (this.isAlive()) { this.innerAutoSizeCols(params).then(resolve, reject); } }); return; } this.timesDelayed = 0; const columnsAutoSized = /* @__PURE__ */ new Set; let changesThisTimeAround = -1; const columnLimitsIndex = Object.fromEntries(columnLimits.map(({ colId, ...dimensions }) => [colId, dimensions])); const shouldSkipHeader = skipHeader ?? this.gos.get("skipHeaderOnAutoSize"); const shouldSkipHeaderGroups = skipHeaderGroups ?? shouldSkipHeader; while (changesThisTimeAround !== 0) { changesThisTimeAround = 0; const updatedColumns = []; for (const key of colKeys) { if (!key || isSpecialCol(key)) { continue; } const column = colModel.getCol(key); if (!column || columnsAutoSized.has(column) || column.getColDef().suppressAutoSize) { continue; } const preferredWidth = autoWidthCalc.getPreferredWidthForColumn(column, shouldSkipHeader); if (preferredWidth > 0) { const columnLimit = columnLimitsIndex[column.colId] ?? {}; columnLimit.minWidth ?? (columnLimit.minWidth = defaultMinWidth); columnLimit.maxWidth ?? (columnLimit.maxWidth = defaultMaxWidth); const newWidth = normaliseColumnWidth(column, preferredWidth, columnLimit); column.setActualWidth(newWidth, source); columnsAutoSized.add(column); changesThisTimeAround++; } updatedColumns.push(column); } if (updatedColumns.length) { visibleCols.refresh(source); } } if (!shouldSkipHeaderGroups) { this.autoSizeColumnGroupsByColumns(colKeys, source, stopAtGroup); } resolve(columnsAutoSized); }); } autoSizeColumn(key, source, skipHeader) { this.autoSizeCols({ colKeys: [key], skipHeader, skipHeaderGroups: true, source }); } autoSizeColumnGroupsByColumns(keys, source, stopAtGroup) { const { colModel, ctrlsSvc } = this.beans; const columnGroups = /* @__PURE__ */ new Set; const columns = colModel.getColsForKeys(keys); for (const col of columns) { let parent = col.getParent(); while (parent && parent != stopAtGroup) { if (!parent.isPadding()) { columnGroups.add(parent); } parent = parent.getParent(); } } let headerGroupCtrl; for (const columnGroup of columnGroups) { for (const headerContainerCtrl of ctrlsSvc.getHeaderRowContainerCtrls()) { headerGroupCtrl = headerContainerCtrl.getHeaderCtrlForColumn(columnGroup); if (headerGroupCtrl) { break; } } headerGroupCtrl?.resizeLeafColumnsToFit(source); } } autoSizeAllColumns(params) { if (this.shouldQueueResizeOperations) { this.pushResizeOperation(() => this.autoSizeAllColumns(params)); return; } this.autoSizeCols({ colKeys: this.beans.visibleCols.allCols, ...params }); } addColumnAutosizeListeners(element, column) { const skipHeaderOnAutoSize = this.gos.get("skipHeaderOnAutoSize"); const autoSizeColListener = () => { this.autoSizeColumn(column, "uiColumnResized", skipHeaderOnAutoSize); }; element.addEventListener("dblclick", autoSizeColListener); const touchListener = new TouchListener(element); touchListener.addEventListener("doubleTap", autoSizeColListener); return () => { element.removeEventListener("dblclick", autoSizeColListener); touchListener.destroy(); }; } addColumnGroupResize(element, columnGroup, callback) { const skipHeaderOnAutoSize = this.gos.get("skipHeaderOnAutoSize"); const listener = () => { const keys = []; const leafCols = columnGroup.getDisplayedLeafColumns(); for (const column of leafCols) { if (!column.getColDef().suppressAutoSize) { keys.push(column.getColId()); } } if (keys.length > 0) { this.autoSizeCols({ colKeys: keys, skipHeader: skipHeaderOnAutoSize, stopAtGroup: columnGroup, source: "uiColumnResized" }); } callback(); }; element.addEventListener("dblclick", listener); return () => element.removeEventListener("dblclick", listener); } sizeColumnsToFitGridBody(params, nextTimeout) { if (!this.isAlive()) { return; } const availableWidth = getAvailableWidth(this.beans); if (availableWidth > 0) { this.sizeColumnsToFit(availableWidth, "sizeColumnsToFit", false, params); return; } if (nextTimeout === undefined) { window.setTimeout(() => { this.sizeColumnsToFitGridBody(params, 100); }, 0); } else if (nextTimeout === 100) { window.setTimeout(() => { this.sizeColumnsToFitGridBody(params, 500); }, 100); } else if (nextTimeout === 500) { window.setTimeout(() => { this.sizeColumnsToFitGridBody(params, -1); }, 500); } else { _warn(29); } } sizeColumnsToFit(gridWidth, source = "sizeColumnsToFit", silent, params) { if (this.shouldQueueResizeOperations) { this.pushResizeOperation(() => this.sizeColumnsToFit(gridWidth, source, silent, params)); return; } const { beans } = this; const animate = params?.animate ?? true; if (animate) { setWidthAnimation(beans, true); } const limitsMap = {}; for (const { key, ...dimensions } of params?.columnLimits ?? []) { limitsMap[typeof key === "string" ? key : key.getColId()] = dimensions; } const allDisplayedColumns = beans.visibleCols.allCols; if (gridWidth <= 0 || !allDisplayedColumns.length) { return; } const currentTotalColumnWidth = getWidthOfColsInList(allDisplayedColumns); if (params?.onlyScaleUp && currentTotalColumnWidth > gridWidth) { return; } const doColumnsAlreadyFit = gridWidth === currentTotalColumnWidth; if (doColumnsAlreadyFit) { const doAllColumnsSatisfyConstraints = allDisplayedColumns.every((column) => { if (column.colDef.suppressSizeToFit) { return true; } const widthOverride = limitsMap?.[column.getId()]; const minWidth = widthOverride?.minWidth ?? params?.defaultMinWidth; const maxWidth = widthOverride?.maxWidth ?? params?.defaultMaxWidth; const colWidth = column.getActualWidth(); return (minWidth == null || colWidth >= minWidth) && (maxWidth == null || colWidth <= maxWidth); }); if (doAllColumnsSatisfyConstraints) { return; } } const colsToSpread = []; const colsToNotSpread = []; for (const column of allDisplayedColumns) { const isIncluded = params?.colKeys?.some((key) => _columnsMatch(column, key)) ?? true; if (column.getColDef().suppressSizeToFit || !isIncluded) { colsToNotSpread.push(column); } else { colsToSpread.push(column); } } const colsToDispatchEventFor = colsToSpread.slice(0); let finishedResizing = false; const moveToNotSpread = (column) => { _removeFromArray(colsToSpread, column); colsToNotSpread.push(column); }; const currentWidths = {}; for (const column of colsToSpread) { if (params?.onlyScaleUp) { currentWidths[column.getColId()] = column.getActualWidth(); } column.resetActualWidth(source); const widthOverride = limitsMap?.[column.getId()]; const minOverride = widthOverride?.minWidth ?? params?.defaultMinWidth ?? -Infinity; const maxOverride = widthOverride?.maxWidth ?? params?.defaultMaxWidth ?? Infinity; const colWidth = column.getActualWidth(); const targetWidth = Math.max(Math.min(colWidth, maxOverride), minOverride); if (targetWidth != colWidth) { column.setActualWidth(targetWidth, source, true); } } while (!finishedResizing) { finishedResizing = true; const availablePixels = gridWidth - getWidthOfColsInList(colsToNotSpread); if (availablePixels <= 0) { for (const column of colsToSpread) { const newWidth = limitsMap?.[column.getId()]?.minWidth ?? params?.defaultMinWidth ?? column.minWidth; column.setActualWidth(newWidth, source, true); } } else { const scale = availablePixels / getWidthOfColsInList(colsToSpread); let pixelsForLastCol = availablePixels; for (let i = colsToSpread.length - 1;i >= 0; i--) { const column = colsToSpread[i]; const id = column.getColId(); const prevWidth = currentWidths[id]; const widthOverride = limitsMap?.[id]; const minOverride = widthOverride?.minWidth ?? params?.defaultMinWidth ?? prevWidth; const maxOverride = widthOverride?.maxWidth ?? params?.defaultMaxWidth; const minWidth = Math.max(minOverride ?? -Infinity, column.getMinWidth()); const maxWidth = Math.min(maxOverride ?? Infinity, column.getMaxWidth()); let newWidth = Math.round(column.getActualWidth() * scale); if (newWidth < minWidth) { newWidth = minWidth; moveToNotSpread(column); finishedResizing = false; } else if (newWidth > maxWidth) { newWidth = maxWidth; moveToNotSpread(column); finishedResizing = false; } else if (i === 0) { newWidth = pixelsForLastCol; } column.setActualWidth(newWidth, source, true); pixelsForLastCol -= newWidth; } } } for (const col of colsToDispatchEventFor) { col.fireColumnWidthChangedEvent(source); } const visibleCols = beans.visibleCols; visibleCols.setLeftValues(source); visibleCols.updateBodyWidths(); if (silent) { return; } dispatchColumnResizedEvent(this.eventSvc, colsToDispatchEventFor, true, source); if (animate) { setWidthAnimation(beans, false); } } applyAutosizeStrategy() { const { gos, colDelayRenderSvc } = this.beans; const autoSizeStrategy = gos.get("autoSizeStrategy"); if (autoSizeStrategy?.type !== "fitGridWidth" && autoSizeStrategy?.type !== "fitProvidedWidth") { return; } setTimeout(() => { if (!this.isAlive()) { return; } const type = autoSizeStrategy.type; if (type === "fitGridWidth") { const { columnLimits: propColumnLimits, defaultMinWidth, defaultMaxWidth } = autoSizeStrategy; const columnLimits = propColumnLimits?.map(({ colId: key, minWidth, maxWidth }) => ({ key, minWidth, maxWidth })); this.sizeColumnsToFitGridBody({ defaultMinWidth, defaultMaxWidth, columnLimits }); } else if (type === "fitProvidedWidth") { this.sizeColumnsToFit(autoSizeStrategy.width, "sizeColumnsToFit"); } colDelayRenderSvc?.revealColumns(type); }); } onFirstDataRendered({ colIds: colKeys, ...params }) { setTimeout(() => { if (!this.isAlive()) { return; } const source = "autosizeColumns"; if (colKeys) { this.autoSizeCols({ ...params, source, colKeys }); } else { this.autoSizeAllColumns({ ...params, source }); } this.beans.colDelayRenderSvc?.revealColumns(params.type); }); } processResizeOperations() { this.shouldQueueResizeOperations = false; for (const resizeOperation of this.resizeOperationQueue) { resizeOperation(); } this.resizeOperationQueue = []; } pushResizeOperation(func) { this.resizeOperationQueue.push(func); } destroy() { this.resizeOperationQueue.length = 0; super.destroy(); } }; function normaliseColumnWidth(column, newWidth, limits = {}) { const minWidth = limits.minWidth ?? column.getMinWidth(); if (newWidth < minWidth) { newWidth = minWidth; } const maxWidth = limits.maxWidth ?? column.getMaxWidth(); if (newWidth > maxWidth) { newWidth = maxWidth; } return newWidth; } function getAvailableWidth({ ctrlsSvc, scrollVisibleSvc }) { const gridBodyCtrl = ctrlsSvc.getGridBodyCtrl(); const removeScrollWidth = gridBodyCtrl.isVerticalScrollShowing(); const scrollWidthToRemove = removeScrollWidth ? scrollVisibleSvc.getScrollbarWidth() : 0; const bodyViewportWidth = _getInnerWidth(gridBodyCtrl.eGridBody); return bodyViewportWidth - scrollWidthToRemove; } var WIDTH_ANIMATION_CLASS = "ag-animate-autosize"; function setWidthAnimation({ ctrlsSvc, gos }, enable) { if (!gos.get("animateColumnResizing") || gos.get("enableRtl") || !ctrlsSvc.isAlive()) { return; } const classList = ctrlsSvc.getGridBodyCtrl().eGridBody.classList; if (enable) { classList.add(WIDTH_ANIMATION_CLASS); } else { classList.remove(WIDTH_ANIMATION_CLASS); } } var ColumnAutoSizeModule = { moduleName: "ColumnAutoSize", version: VERSION, beans: [ColumnAutosizeService], apiFunctions: { sizeColumnsToFit, autoSizeColumns, autoSizeAllColumns }, dependsOn: [AutoWidthModule], css: [columnAutoSize_default] }; var GridSerializer = class extends BeanStub { constructor() { super(...arguments); this.beanName = "gridSerializer"; } wireBeans(beans) { this.visibleCols = beans.visibleCols; this.colModel = beans.colModel; this.rowModel = beans.rowModel; this.pinnedRowModel = beans.pinnedRowModel; } serialize(gridSerializingSession, params = {}) { const { allColumns, columnKeys, skipRowGroups, exportRowNumbers } = params; const columnsToExport = this.getColumnsToExport({ allColumns, skipRowGroups, columnKeys, exportRowNumbers }); return [ this.prepareSession(columnsToExport), this.prependContent(params), this.exportColumnGroups(params, columnsToExport), this.exportHeaders(params, columnsToExport), this.processPinnedTopRows(params, columnsToExport), this.processRows(params, columnsToExport), this.processPinnedBottomRows(params, columnsToExport), this.appendContent(params) ].reduce((composed, f) => f(composed), gridSerializingSession).parse(); } processRow(gridSerializingSession, params, columnsToExport, node) { const rowSkipper = params.shouldRowBeSkipped || (() => false); const isClipboardExport = params.rowPositions != null; const isExplicitExportSelection = isClipboardExport || !!params.onlySelected; const hideOpenParents = this.gos.get("groupHideOpenParents") && !isExplicitExportSelection; const isLeafNode = this.colModel.isPivotMode() ? node.leafGroup : !node.group; const isFooter = !!node.footer; const shouldSkipCurrentGroup = node.allChildrenCount === 1 && node.childrenAfterGroup?.length === 1 && _canSkipShowingRowGroup(this.gos, node); if (!isLeafNode && !isFooter && (params.skipRowGroups || shouldSkipCurrentGroup || hideOpenParents) || params.onlySelected && !node.isSelected() || params.skipPinnedTop && node.rowPinned === "top" || params.skipPinnedBottom && node.rowPinned === "bottom" || node.stub) { return; } const nodeIsRootNode = node.level === -1; if (nodeIsRootNode && !isLeafNode && !isFooter) { return; } const shouldRowBeSkipped = rowSkipper(_addGridCommonParams(this.gos, { node })); if (shouldRowBeSkipped) { return; } const rowAccumulator = gridSerializingSession.onNewBodyRow(node); columnsToExport.forEach((column, index) => { rowAccumulator.onColumn(column, index, node); }); if (params.getCustomContentBelowRow) { const content = params.getCustomContentBelowRow(_addGridCommonParams(this.gos, { node })); if (content) { gridSerializingSession.addCustomContent(content); } } } appendContent(params) { return (gridSerializingSession) => { const appendContent = params.appendContent; if (appendContent) { gridSerializingSession.addCustomContent(appendContent); } return gridSerializingSession; }; } prependContent(params) { return (gridSerializingSession) => { const prependContent = params.prependContent; if (prependContent) { gridSerializingSession.addCustomContent(prependContent); } return gridSerializingSession; }; } prepareSession(columnsToExport) { return (gridSerializingSession) => { gridSerializingSession.prepare(columnsToExport); return gridSerializingSession; }; } exportColumnGroups(params, columnsToExport) { return (gridSerializingSession) => { if (!params.skipColumnGroupHeaders) { const idCreator = new GroupInstanceIdCreator; const { colGroupSvc } = this.beans; const displayedGroups = colGroupSvc ? colGroupSvc.createColumnGroups({ columns: columnsToExport, idCreator, pinned: null, isStandaloneStructure: true }) : columnsToExport; this.recursivelyAddHeaderGroups(displayedGroups, gridSerializingSession, params.processGroupHeaderCallback); } return gridSerializingSession; }; } exportHeaders(params, columnsToExport) { return (gridSerializingSession) => { if (!params.skipColumnHeaders) { const gridRowIterator = gridSerializingSession.onNewHeaderRow(); columnsToExport.forEach((column, index) => { gridRowIterator.onColumn(column, index, undefined); }); } return gridSerializingSession; }; } processPinnedTopRows(params, columnsToExport) { return (gridSerializingSession) => { const processRow = this.processRow.bind(this, gridSerializingSession, params, columnsToExport); if (params.rowPositions) { params.rowPositions.filter((position) => position.rowPinned === "top").sort((a, b) => a.rowIndex - b.rowIndex).map((position) => this.pinnedRowModel?.getPinnedTopRow(position.rowIndex)).forEach(processRow); } else if (!this.pinnedRowModel?.isManual()) { this.pinnedRowModel?.forEachPinnedRow("top", processRow); } return gridSerializingSession; }; } processRows(params, columnsToExport) { return (gridSerializingSession) => { const rowModel = this.rowModel; const usingCsrm = _isClientSideRowModel(this.gos, rowModel); const usingSsrm = _isServerSideRowModel(this.gos, rowModel); const onlySelectedNonStandardModel = !usingCsrm && params.onlySelected; const processRow = this.processRow.bind(this, gridSerializingSession, params, columnsToExport); const { exportedRows = "filteredAndSorted" } = params; if (params.rowPositions) { params.rowPositions.filter((position) => position.rowPinned == null).sort((a, b) => a.rowIndex - b.rowIndex).map((position) => rowModel.getRow(position.rowIndex)).forEach(processRow); } else if (this.colModel.isPivotMode()) { if (usingCsrm) { rowModel.forEachPivotNode(processRow, true, exportedRows === "filteredAndSorted"); } else if (usingSsrm) { rowModel.forEachNodeAfterFilterAndSort(processRow, true); } else { rowModel.forEachNode(processRow); } } else if (params.onlySelectedAllPages || onlySelectedNonStandardModel) { const selectedNodes = this.beans.selectionSvc?.getSelectedNodes() ?? []; this.replicateSortedOrder(selectedNodes); selectedNodes.forEach(processRow); } else if (exportedRows === "all") { rowModel.forEachNode(processRow); } else if (usingCsrm || usingSsrm) { rowModel.forEachNodeAfterFilterAndSort(processRow, true); } else { rowModel.forEachNode(processRow); } return gridSerializingSession; }; } replicateSortedOrder(rows) { const { sortSvc, rowNodeSorter } = this.beans; if (!sortSvc || !rowNodeSorter) { return; } const sortOptions = sortSvc.getSortOptions(); const compareNodes = (rowA, rowB) => { if (rowA.rowIndex != null && rowB.rowIndex != null) { return rowA.rowIndex - rowB.rowIndex; } if (rowA.level === rowB.level) { if (rowA.parent?.id === rowB.parent?.id) { return rowNodeSorter.compareRowNodes(sortOptions, rowA, rowB) || (rowA.rowIndex ?? -1) - (rowB.rowIndex ?? -1); } return compareNodes(rowA.parent, rowB.parent); } if (rowA.level > rowB.level) { return compareNodes(rowA.parent, rowB); } return compareNodes(rowA, rowB.parent); }; rows.sort(compareNodes); } processPinnedBottomRows(params, columnsToExport) { return (gridSerializingSession) => { const processRow = this.processRow.bind(this, gridSerializingSession, params, columnsToExport); if (params.rowPositions) { params.rowPositions.filter((position) => position.rowPinned === "bottom").sort((a, b) => a.rowIndex - b.rowIndex).map((position) => this.pinnedRowModel?.getPinnedBottomRow(position.rowIndex)).forEach(processRow); } else if (!this.pinnedRowModel?.isManual()) { this.pinnedRowModel?.forEachPinnedRow("bottom", processRow); } return gridSerializingSession; }; } getColumnsToExport(params) { const { allColumns = false, skipRowGroups = false, exportRowNumbers = false, columnKeys } = params; const { colModel, gos, visibleCols } = this; const isPivotMode = colModel.isPivotMode(); const filterSpecialColumns = (col) => { if (isColumnSelectionCol(col)) { return false; } return !isRowNumberCol(col) || exportRowNumbers; }; if (columnKeys?.length) { return colModel.getColsForKeys(columnKeys).filter(filterSpecialColumns); } const isTreeData = gos.get("treeData"); let columnsToExport = []; if (allColumns && !isPivotMode) { columnsToExport = colModel.getCols(); } else { columnsToExport = visibleCols.allCols; } columnsToExport = columnsToExport.filter((column) => filterSpecialColumns(column) && (skipRowGroups && !isTreeData ? !isColumnGroupAutoCol(column) : true)); return columnsToExport; } recursivelyAddHeaderGroups(displayedGroups, gridSerializingSession, processGroupHeaderCallback) { const directChildrenHeaderGroups = []; for (const columnGroupChild of displayedGroups) { const columnGroup = columnGroupChild; if (!columnGroup.getChildren) { continue; } for (const it of columnGroup.getChildren() ?? []) { directChildrenHeaderGroups.push(it); } } if (displayedGroups.length > 0 && isColumnGroup(displayedGroups[0])) { this.doAddHeaderHeader(gridSerializingSession, displayedGroups, processGroupHeaderCallback); } if (directChildrenHeaderGroups && directChildrenHeaderGroups.length > 0) { this.recursivelyAddHeaderGroups(directChildrenHeaderGroups, gridSerializingSession, processGroupHeaderCallback); } } doAddHeaderHeader(gridSerializingSession, displayedGroups, processGroupHeaderCallback) { const gridRowIterator = gridSerializingSession.onNewHeaderGroupingRow(); let columnIndex = 0; for (const columnGroupChild of displayedGroups) { const columnGroup = columnGroupChild; let name; if (processGroupHeaderCallback) { name = processGroupHeaderCallback(_addGridCommonParams(this.gos, { columnGroup })); } else { name = this.beans.colNames.getDisplayNameForColumnGroup(columnGroup, "header"); } const columnsToCalculateRange = columnGroup.isExpandable() ? columnGroup.getLeafColumns() : []; const collapsibleGroupRanges = columnsToCalculateRange.reduce((collapsibleGroups, currentColumn, currentIdx, arr) => { let lastGroup = _last(collapsibleGroups); const groupShow = currentColumn.getColumnGroupShow() === "open"; if (!groupShow) { if (lastGroup && lastGroup[1] == null) { lastGroup[1] = currentIdx - 1; } } else if (!lastGroup || lastGroup[1] != null) { lastGroup = [currentIdx]; collapsibleGroups.push(lastGroup); } if (currentIdx === arr.length - 1 && lastGroup && lastGroup[1] == null) { lastGroup[1] = currentIdx; } return collapsibleGroups; }, []); gridRowIterator.onColumn(columnGroup, name || "", columnIndex++, columnGroup.getLeafColumns().length - 1, collapsibleGroupRanges); } } }; var SharedExportModule = { moduleName: "SharedExport", version: VERSION, beans: [GridSerializer] }; var BaseCreator = class extends BeanStub { getFileName(fileName) { const extension = this.getDefaultFileExtension(); if (!fileName?.length) { fileName = this.getDefaultFileName(); } return fileName.includes(".") ? fileName : `${fileName}.${extension}`; } getData(params) { return this.beans.gridSerializer.serialize(this.createSerializingSession(params), params); } getDefaultFileName() { return `export.${this.getDefaultFileExtension()}`; } }; function _downloadFile(fileName, content) { const win = document.defaultView || window; if (!win) { _warn(52); return; } const element = document.createElement("a"); const url = win.URL.createObjectURL(content); element.setAttribute("href", url); element.setAttribute("download", fileName); element.style.display = "none"; document.body.appendChild(element); element.dispatchEvent(new MouseEvent("click", { bubbles: false, cancelable: true, view: win })); element.remove(); win.setTimeout(() => { win.URL.revokeObjectURL(url); }, 0); } var BaseGridSerializingSession = class { constructor(config) { this.valueFrom = "data"; const { colModel, rowGroupColsSvc, colNames, valueSvc, gos, processCellCallback, processHeaderCallback, processGroupHeaderCallback, processRowGroupCallback, valueFrom } = config; this.colModel = colModel; this.rowGroupColsSvc = rowGroupColsSvc; this.colNames = colNames; this.valueSvc = valueSvc; this.gos = gos; this.processCellCallback = processCellCallback; this.processHeaderCallback = processHeaderCallback; this.processGroupHeaderCallback = processGroupHeaderCallback; this.processRowGroupCallback = processRowGroupCallback; if (valueFrom) { this.valueFrom = valueFrom; } } prepare(_columnsToExport) {} extractHeaderValue(column) { const value = this.getHeaderName(this.processHeaderCallback, column); return value ?? ""; } extractRowCellValue(params) { const { column, node, currentColumnIndex, accumulatedRowIndex, type, useRawFormula } = params; const isFullWidthGroup = currentColumnIndex === 0 && _isFullWidthGroupRow(this.gos, node, this.colModel.isPivotMode()); if (this.processRowGroupCallback && (this.gos.get("treeData") || node.group) && (column.isRowGroupDisplayed(node.rowGroupColumn?.getColId() ?? "") || isFullWidthGroup)) { return { value: this.processRowGroupCallback(_addGridCommonParams(this.gos, { column, node })) ?? "" }; } if (this.processCellCallback) { return { value: this.processCellCallback(_addGridCommonParams(this.gos, { accumulatedRowIndex, column, node, value: this.valueSvc.getValueForDisplay({ column, node, from: this.valueFrom }).value, type, parseValue: (valueToParse) => this.valueSvc.parseValue(column, node, valueToParse, this.valueSvc.getValue(column, node, this.valueFrom)), formatValue: (valueToFormat) => this.valueSvc.formatValue(column, node, valueToFormat) ?? valueToFormat })) ?? "" }; } const isTreeData = this.gos.get("treeData"); const valueService = this.valueSvc; const isGrandTotalRow = node.level === -1 && node.footer; const isMultiAutoCol = column.colDef.showRowGroup === true && (node.group || isTreeData); if (!isGrandTotalRow && (isFullWidthGroup || isMultiAutoCol)) { let concatenatedGroupValue = ""; let pointer = node; while (pointer && pointer.level !== -1) { const { value: value2, valueFormatted: valueFormatted2 } = valueService.getValueForDisplay({ column: isFullWidthGroup ? undefined : column, node: pointer, includeValueFormatted: true, exporting: true, from: this.valueFrom }); concatenatedGroupValue = ` -> ${valueFormatted2 ?? value2 ?? ""}${concatenatedGroupValue}`; pointer = pointer.parent; } return { value: concatenatedGroupValue, valueFormatted: concatenatedGroupValue }; } const { value, valueFormatted } = valueService.getValueForDisplay({ column, node, includeValueFormatted: true, exporting: true, useRawFormula, from: this.valueFrom }); return { value: value ?? "", valueFormatted }; } getHeaderName(callback, column) { if (callback) { return callback(_addGridCommonParams(this.gos, { column })); } return this.colNames.getDisplayNameForColumn(column, "csv", true); } }; var LINE_SEPARATOR = `\r `; var CsvSerializingSession = class extends BaseGridSerializingSession { constructor(config) { super(config); this.config = config; this.isFirstLine = true; this.result = ""; const { suppressQuotes, columnSeparator } = config; this.suppressQuotes = suppressQuotes; this.columnSeparator = columnSeparator; } addCustomContent(content) { if (!content) { return; } if (typeof content === "string") { if (!/^\s*\n/.test(content)) { this.beginNewLine(); } content = content.replace(/\r?\n/g, LINE_SEPARATOR); this.result += content; } else { content.forEach((row) => { this.beginNewLine(); row.forEach((cell, index) => { if (index !== 0) { this.result += this.columnSeparator; } this.result += this.putInQuotes(cell.data.value || ""); if (cell.mergeAcross) { this.appendEmptyCells(cell.mergeAcross); } }); }); } } onNewHeaderGroupingRow() { this.beginNewLine(); return { onColumn: this.onNewHeaderGroupingRowColumn.bind(this) }; } onNewHeaderGroupingRowColumn(columnGroup, header, index, span) { if (index != 0) { this.result += this.columnSeparator; } this.result += this.putInQuotes(header); this.appendEmptyCells(span); } appendEmptyCells(count) { for (let i = 1;i <= count; i++) { this.result += this.columnSeparator + this.putInQuotes(""); } } onNewHeaderRow() { this.beginNewLine(); return { onColumn: this.onNewHeaderRowColumn.bind(this) }; } onNewHeaderRowColumn(column, index) { if (index != 0) { this.result += this.columnSeparator; } this.result += this.putInQuotes(this.extractHeaderValue(column)); } onNewBodyRow() { this.beginNewLine(); return { onColumn: this.onNewBodyRowColumn.bind(this) }; } onNewBodyRowColumn(column, index, node) { if (index != 0) { this.result += this.columnSeparator; } const rowCellValue = this.extractRowCellValue({ column, node, currentColumnIndex: index, accumulatedRowIndex: index, type: "csv", useRawFormula: false }); this.result += this.putInQuotes(rowCellValue.valueFormatted ?? rowCellValue.value); } putInQuotes(value) { if (this.suppressQuotes) { return value; } if (value === null || value === undefined) { return '""'; } let stringValue; if (typeof value === "string") { stringValue = value; } else if (typeof value.toString === "function") { stringValue = value.toString(); } else { _warn(53); stringValue = ""; } const valueEscaped = stringValue.replace(/"/g, '""'); return '"' + valueEscaped + '"'; } parse() { return this.result; } beginNewLine() { if (!this.isFirstLine) { this.result += LINE_SEPARATOR; } this.isFirstLine = false; } }; var CsvCreator = class extends BaseCreator { constructor() { super(...arguments); this.beanName = "csvCreator"; } getMergedParams(params) { const baseParams6 = this.gos.get("defaultCsvExportParams"); return Object.assign({}, baseParams6, params); } export(userParams) { if (this.isExportSuppressed()) { _warn(51); return; } const exportFunc = () => { const mergedParams = this.getMergedParams(userParams); const data = this.getData(mergedParams); const packagedFile = new Blob(["\uFEFF", data], { type: "text/plain" }); const fileNameParams = mergedParams.fileName; const fileName = typeof fileNameParams === "function" ? fileNameParams(_addGridCommonParams(this.gos, {})) : fileNameParams; _downloadFile(this.getFileName(fileName), packagedFile); }; const { overlays } = this.beans; if (overlays) { overlays.showExportOverlay(exportFunc); } else { exportFunc(); } } exportDataAsCsv(params) { this.export(params); } getDataAsCsv(params, skipDefaultParams = false) { const mergedParams = skipDefaultParams ? Object.assign({}, params) : this.getMergedParams(params); return this.getData(mergedParams); } getDefaultFileExtension() { return "csv"; } createSerializingSession(params) { const { colModel, colNames, rowGroupColsSvc, valueSvc, gos } = this.beans; const { processCellCallback, processHeaderCallback, processGroupHeaderCallback, processRowGroupCallback, suppressQuotes, columnSeparator, valueFrom } = params; return new CsvSerializingSession({ colModel, colNames, valueSvc, gos, processCellCallback: processCellCallback || undefined, processHeaderCallback: processHeaderCallback || undefined, processGroupHeaderCallback: processGroupHeaderCallback || undefined, processRowGroupCallback: processRowGroupCallback || undefined, suppressQuotes: suppressQuotes || false, columnSeparator: columnSeparator || ",", rowGroupColsSvc, valueFrom }); } isExportSuppressed() { return this.gos.get("suppressCsvExport"); } }; function getDataAsCsv(beans, params) { return beans.csvCreator?.getDataAsCsv(params); } function exportDataAsCsv(beans, params) { beans.csvCreator?.exportDataAsCsv(params); } var CsvExportModule = { moduleName: "CsvExport", version: VERSION, beans: [CsvCreator], apiFunctions: { getDataAsCsv, exportDataAsCsv }, dependsOn: [SharedExportModule] }; var AgTooltipFeature = class extends AgBeanStub { constructor(ctrl, beans) { super(); this.ctrl = ctrl; if (beans) { this.beans = beans; } } postConstruct() { this.refreshTooltip(); } setBrowserTooltip(tooltip, allowEmptyString) { const name = "title"; const eGui = this.ctrl.getGui(); if (!eGui) { return; } if (tooltip != null && (tooltip != "" || allowEmptyString)) { eGui.setAttribute(name, tooltip); } else { eGui.removeAttribute(name); } } updateTooltipText() { const { getTooltipValue } = this.ctrl; if (getTooltipValue) { this.tooltip = getTooltipValue(); } } createTooltipFeatureIfNeeded() { if (this.tooltipManager == null) { const tooltipManager = this.beans.registry.createDynamicBean("tooltipStateManager", true, this.ctrl, () => this.tooltip); if (tooltipManager) { this.tooltipManager = this.createBean(tooltipManager, this.beans.context); } } } attemptToShowTooltip() { this.tooltipManager?.prepareToShowTooltip(); } attemptToHideTooltip() { this.tooltipManager?.hideTooltip(); } setTooltipAndRefresh(tooltip) { this.tooltip = tooltip; this.refreshTooltip(); } refreshTooltip(clearWithEmptyString) { this.browserTooltips = this.beans.gos.get("enableBrowserTooltips"); this.updateTooltipText(); if (this.browserTooltips) { this.setBrowserTooltip(this.tooltip); this.tooltipManager = this.destroyBean(this.tooltipManager, this.beans.context); } else { this.setBrowserTooltip(clearWithEmptyString ? "" : null, clearWithEmptyString); this.createTooltipFeatureIfNeeded(); } } destroy() { this.tooltipManager = this.destroyBean(this.tooltipManager, this.beans.context); super.destroy(); } }; var SHOW_SWITCH_TOOLTIP_DIFF = 1000; var FADE_OUT_TOOLTIP_TIMEOUT = 1000; var INTERACTIVE_HIDE_DELAY = 100; var lastTooltipHideTime; var isLocked = false; var BaseTooltipStateManager = class extends AgBeanStub { constructor(tooltipCtrl, getTooltipValue) { super(); this.tooltipCtrl = tooltipCtrl; this.getTooltipValue = getTooltipValue; this.interactionEnabled = false; this.isInteractingWithTooltip = false; this.state = 0; this.tooltipInstanceCount = 0; this.tooltipMouseTrack = false; } wireBeans(beans) { this.popupSvc = beans.popupSvc; } postConstruct() { if (this.gos.get("tooltipInteraction")) { this.interactionEnabled = true; } this.tooltipTrigger = this.getTooltipTrigger(); this.tooltipMouseTrack = this.gos.get("tooltipMouseTrack"); const el = this.tooltipCtrl.getGui(); if (this.tooltipTrigger === 0) { this.addManagedListeners(el, { mouseenter: this.onMouseEnter.bind(this), mouseleave: this.onMouseLeave.bind(this) }); } if (this.tooltipTrigger === 1) { this.addManagedListeners(el, { focusin: this.onFocusIn.bind(this), focusout: this.onFocusOut.bind(this) }); } this.addManagedListeners(el, { mousemove: this.onMouseMove.bind(this) }); if (!this.interactionEnabled) { this.addManagedListeners(el, { mousedown: this.onMouseDown.bind(this), keydown: this.onKeyDown.bind(this) }); } } getGridOptionsTooltipDelay(delayOption) { const delay = this.gos.get(delayOption); return Math.max(200, delay); } getTooltipDelay(type) { return this.tooltipCtrl[`getTooltip${type}DelayOverride`]?.() ?? this.getGridOptionsTooltipDelay(`tooltip${type}Delay`); } destroy() { this.setToDoNothing(); super.destroy(); } getTooltipTrigger() { const trigger = this.gos.get("tooltipTrigger"); if (!trigger || trigger === "hover") { return 0; } return 1; } onMouseEnter(e) { if (this.interactionEnabled && this.interactiveTooltipTimeoutId) { this.unlockService(); this.startHideTimeout(); } if (_isIOSUserAgent()) { return; } if (isLocked) { this.showTooltipTimeoutId = window.setTimeout(() => { this.prepareToShowTooltip(e); }, INTERACTIVE_HIDE_DELAY); } else { this.prepareToShowTooltip(e); } } onMouseMove(e) { if (this.lastMouseEvent) { this.lastMouseEvent = e; } if (this.tooltipMouseTrack && this.state === 2 && this.tooltipComp) { this.positionTooltip(); } } onMouseDown() { this.setToDoNothing(); } onMouseLeave() { if (this.interactionEnabled) { this.lockService(); } else { this.setToDoNothing(); } } onFocusIn() { this.prepareToShowTooltip(); } onFocusOut(e) { const relatedTarget = e.relatedTarget; const parentCompGui = this.tooltipCtrl.getGui(); const tooltipGui = this.tooltipComp?.getGui(); if (this.isInteractingWithTooltip || parentCompGui.contains(relatedTarget) || this.interactionEnabled && tooltipGui?.contains(relatedTarget)) { return; } this.setToDoNothing(); } onKeyDown() { if (this.isInteractingWithTooltip) { this.isInteractingWithTooltip = false; } this.setToDoNothing(); } prepareToShowTooltip(mouseEvent) { if (this.state != 0 || isLocked) { return; } let delay = 0; if (mouseEvent) { delay = this.isLastTooltipHiddenRecently() ? this.getTooltipDelay("SwitchShow") : this.getTooltipDelay("Show"); } this.lastMouseEvent = mouseEvent || null; this.showTooltipTimeoutId = window.setTimeout(this.showTooltip.bind(this), delay); this.state = 1; } isLastTooltipHiddenRecently() { const now = Date.now(); const then = lastTooltipHideTime; return now - then < SHOW_SWITCH_TOOLTIP_DIFF; } setToDoNothing(fromHideTooltip) { if (!fromHideTooltip && this.state === 2) { this.hideTooltip(); } if (this.onBodyScrollEventCallback) { this.onBodyScrollEventCallback(); this.onBodyScrollEventCallback = undefined; } this.clearEventHandlers(); if (this.onDocumentKeyDownCallback) { this.onDocumentKeyDownCallback(); this.onDocumentKeyDownCallback = undefined; } this.clearTimeouts(); this.state = 0; this.lastMouseEvent = null; } showTooltip() { const value = this.getTooltipValue(); const ctrl = this.tooltipCtrl; if (!_exists(value) || ctrl.shouldDisplayTooltip && !ctrl.shouldDisplayTooltip()) { this.setToDoNothing(); return; } const params = this.gos.addCommon({ location: ctrl.getLocation?.() ?? "UNKNOWN", value, hideTooltipCallback: () => this.hideTooltip(true), ...ctrl.getAdditionalParams?.() }); this.state = 2; this.tooltipInstanceCount++; const callback = this.newTooltipComponentCallback.bind(this, this.tooltipInstanceCount); this.createTooltipComp(params, callback); } hideTooltip(forceHide) { if (!forceHide && this.isInteractingWithTooltip) { return; } if (this.tooltipComp) { this.destroyTooltipComp(); lastTooltipHideTime = Date.now(); } this.eventSvc.dispatchEvent({ type: "tooltipHide", parentGui: this.tooltipCtrl.getGui() }); if (forceHide) { this.isInteractingWithTooltip = false; } this.setToDoNothing(true); } newTooltipComponentCallback(tooltipInstanceCopy, tooltipComp) { const compNoLongerNeeded = this.state !== 2 || this.tooltipInstanceCount !== tooltipInstanceCopy; if (compNoLongerNeeded) { this.destroyBean(tooltipComp); return; } const eGui = tooltipComp.getGui(); this.tooltipComp = tooltipComp; if (!eGui.classList.contains("ag-tooltip")) { eGui.classList.add("ag-tooltip-custom"); } if (this.tooltipTrigger === 0) { eGui.classList.add("ag-tooltip-animate"); } if (this.interactionEnabled) { eGui.classList.add("ag-tooltip-interactive"); } const translate = this.getLocaleTextFunc(); const addPopupRes = this.popupSvc?.addPopup({ eChild: eGui, ariaLabel: translate("ariaLabelTooltip", "Tooltip") }); if (addPopupRes) { this.tooltipPopupDestroyFunc = addPopupRes.hideFunc; } this.positionTooltip(); if (this.tooltipTrigger === 1) { const listener = () => this.setToDoNothing(); [this.onBodyScrollEventCallback] = this.addManagedEventListeners({ bodyScroll: listener }); this.setEventHandlers(listener); } if (this.interactionEnabled) { [this.tooltipMouseEnterListener, this.tooltipMouseLeaveListener] = this.addManagedElementListeners(eGui, { mouseenter: this.onTooltipMouseEnter.bind(this), mouseleave: this.onTooltipMouseLeave.bind(this) }); [this.onDocumentKeyDownCallback] = this.addManagedElementListeners(_getDocument(this.beans), { keydown: (e) => { if (!eGui.contains(e?.target)) { this.onKeyDown(); } } }); if (this.tooltipTrigger === 1) { [this.tooltipFocusInListener, this.tooltipFocusOutListener] = this.addManagedElementListeners(eGui, { focusin: this.onTooltipFocusIn.bind(this), focusout: this.onTooltipFocusOut.bind(this) }); } } this.eventSvc.dispatchEvent({ type: "tooltipShow", tooltipGui: eGui, parentGui: this.tooltipCtrl.getGui() }); this.startHideTimeout(); } onTooltipMouseEnter() { this.isInteractingWithTooltip = true; this.unlockService(); } onTooltipMouseLeave() { if (this.isTooltipFocused()) { return; } this.isInteractingWithTooltip = false; this.lockService(); } onTooltipFocusIn() { this.isInteractingWithTooltip = true; } isTooltipFocused() { const tooltipGui = this.tooltipComp?.getGui(); const activeEl = _getActiveDomElement(this.beans); return !!tooltipGui && tooltipGui.contains(activeEl); } onTooltipFocusOut(e) { const parentGui = this.tooltipCtrl.getGui(); if (this.isTooltipFocused()) { return; } this.isInteractingWithTooltip = false; if (parentGui.contains(e.relatedTarget)) { this.startHideTimeout(); } else { this.hideTooltip(); } } positionTooltip() { const params = { type: "tooltip", ePopup: this.tooltipComp.getGui(), nudgeY: 18, skipObserver: this.tooltipMouseTrack }; if (this.lastMouseEvent) { this.popupSvc?.positionPopupUnderMouseEvent({ ...params, mouseEvent: this.lastMouseEvent }); } else { this.popupSvc?.positionPopupByComponent({ ...params, eventSource: this.tooltipCtrl.getGui(), position: "under", keepWithinBounds: true, nudgeY: 5 }); } } destroyTooltipComp() { this.tooltipComp.getGui().classList.add("ag-tooltip-hiding"); const tooltipPopupDestroyFunc = this.tooltipPopupDestroyFunc; const tooltipComp = this.tooltipComp; const delay = this.tooltipTrigger === 0 ? FADE_OUT_TOOLTIP_TIMEOUT : 0; window.setTimeout(() => { tooltipPopupDestroyFunc(); this.destroyBean(tooltipComp); }, delay); this.clearTooltipListeners(); this.tooltipPopupDestroyFunc = undefined; this.tooltipComp = undefined; } clearTooltipListeners() { for (const listener of [ this.tooltipMouseEnterListener, this.tooltipMouseLeaveListener, this.tooltipFocusInListener, this.tooltipFocusOutListener ]) { if (listener) { listener(); } } this.tooltipMouseEnterListener = this.tooltipMouseLeaveListener = this.tooltipFocusInListener = this.tooltipFocusOutListener = null; } lockService() { isLocked = true; this.interactiveTooltipTimeoutId = window.setTimeout(() => { this.unlockService(); this.setToDoNothing(); }, INTERACTIVE_HIDE_DELAY); } unlockService() { isLocked = false; this.clearInteractiveTimeout(); } startHideTimeout() { this.clearHideTimeout(); this.hideTooltipTimeoutId = window.setTimeout(this.hideTooltip.bind(this), this.getTooltipDelay("Hide")); } clearShowTimeout() { if (!this.showTooltipTimeoutId) { return; } window.clearTimeout(this.showTooltipTimeoutId); this.showTooltipTimeoutId = undefined; } clearHideTimeout() { if (!this.hideTooltipTimeoutId) { return; } window.clearTimeout(this.hideTooltipTimeoutId); this.hideTooltipTimeoutId = undefined; } clearInteractiveTimeout() { if (!this.interactiveTooltipTimeoutId) { return; } window.clearTimeout(this.interactiveTooltipTimeoutId); this.interactiveTooltipTimeoutId = undefined; } clearTimeouts() { this.clearShowTimeout(); this.clearHideTimeout(); this.clearInteractiveTimeout(); } }; var AgHighlightTooltipFeature = class extends AgTooltipFeature { constructor(ctrl, highlightTracker, beans) { super(ctrl, beans); this.highlightTracker = highlightTracker; this.onHighlight = this.onHighlight.bind(this); } postConstruct() { super.postConstruct(); this.wireHighlightListeners(); } wireHighlightListeners() { this.addManagedPropertyListener("tooltipTrigger", ({ currentValue }) => { this.setTooltipMode(currentValue); }); this.setTooltipMode(this.gos.get("tooltipTrigger")); this.highlightTracker.addEventListener("itemHighlighted", this.onHighlight); } onHighlight(event) { if (this.tooltipMode !== 1) { return; } if (event.highlighted) { this.attemptToShowTooltip(); } else { this.attemptToHideTooltip(); } } setTooltipMode(tooltipTriggerMode = "focus") { this.tooltipMode = tooltipTriggerMode === "focus" ? 1 : 0; } destroy() { this.highlightTracker.removeEventListener("itemHighlighted", this.onHighlight); super.destroy(); } }; var AgTooltipComponent = class extends AgPopupComponent { constructor() { super({ tag: "div", cls: "ag-tooltip" }); } init(params) { const { value } = params; const eGui = this.getGui(); eGui.textContent = _toString(value); const locationKebabCase = params.location.replace(/([a-z])([A-Z0-9])/g, "$1-$2").toLowerCase(); eGui.classList.add(`ag-${locationKebabCase}-tooltip`); } }; var tooltip_default = ".ag-tooltip{background-color:var(--ag-tooltip-background-color);border:var(--ag-tooltip-border);border-radius:var(--ag-border-radius);color:var(--ag-tooltip-text-color);padding:var(--ag-widget-container-vertical-padding) var(--ag-widget-container-horizontal-padding);position:absolute;white-space:normal;z-index:99999;&:where(.ag-cell-editor-tooltip),&:where(.ag-cell-formula-tooltip){background-color:var(--ag-tooltip-error-background-color);border:var(--ag-tooltip-error-border);color:var(--ag-tooltip-error-text-color);font-weight:500}}.ag-tooltip-custom{position:absolute;z-index:99999}.ag-tooltip-custom:where(:not(.ag-tooltip-interactive)),.ag-tooltip:where(:not(.ag-tooltip-interactive)){pointer-events:none}.ag-tooltip-animate{transition:opacity 1s;&:where(.ag-tooltip-hiding){opacity:0}}"; var instanceIdSeq = 0; var WAIT_FOR_POPUP_CONTENT_RESIZE = 200; var BasePopupService = class extends AgBeanStub { constructor() { super(...arguments); this.beanName = "popupSvc"; this.popupList = []; } postConstruct() { this.addManagedEventListeners({ stylesChanged: this.handleThemeChange.bind(this) }); } getPopupParent() { const ePopupParent = this.gos.get("popupParent"); if (ePopupParent) { return ePopupParent; } return this.getDefaultPopupParent(); } positionPopupUnderMouseEvent(params) { const { ePopup, nudgeX, nudgeY, skipObserver } = params; this.positionPopup({ ePopup, nudgeX, nudgeY, keepWithinBounds: true, skipObserver, updatePosition: () => this.calculatePointerAlign(params.mouseEvent), postProcessCallback: () => this.callPostProcessPopup(params.additionalParams, params.type, params.ePopup, null, params.mouseEvent) }); } calculatePointerAlign(e) { const parentRect = this.getParentRect(); return { x: e.clientX - parentRect.left, y: e.clientY - parentRect.top }; } positionPopupByComponent(params) { const { ePopup, nudgeX, nudgeY, keepWithinBounds, eventSource, alignSide = "left", position = "over", type } = params; const sourceRect = eventSource.getBoundingClientRect(); const parentRect = this.getParentRect(); this.setAlignedTo(eventSource, ePopup); const updatePosition = () => { let x = sourceRect.left - parentRect.left; if (alignSide === "right") { x -= ePopup.offsetWidth - sourceRect.width; } let y; if (position === "over") { y = sourceRect.top - parentRect.top; this.setAlignedStyles(ePopup, "over"); } else { this.setAlignedStyles(ePopup, "under"); const alignSide2 = this.shouldRenderUnderOrAbove(ePopup, sourceRect, parentRect, params.nudgeY || 0); if (alignSide2 === "under") { y = sourceRect.top - parentRect.top + sourceRect.height; } else { y = sourceRect.top - ePopup.offsetHeight - (nudgeY || 0) * 2 - parentRect.top; } } return { x, y }; }; this.positionPopup({ ePopup, nudgeX, nudgeY, keepWithinBounds, updatePosition, postProcessCallback: () => this.callPostProcessPopup(params.additionalParams, type, ePopup, eventSource, null) }); } positionPopupForMenu(params) { const { eventSource, ePopup, event } = params; const sourceRect = eventSource.getBoundingClientRect(); const parentRect = this.getParentRect(); this.setAlignedTo(eventSource, ePopup); let minWidthSet = false; const updatePosition = () => { const y = this.keepXYWithinBounds(ePopup, sourceRect.top - parentRect.top, 0); const minWidth = ePopup.clientWidth > 0 ? ePopup.clientWidth : 200; if (!minWidthSet) { ePopup.style.minWidth = `${minWidth}px`; minWidthSet = true; } const widthOfParent = parentRect.right - parentRect.left; const maxX = widthOfParent - minWidth; let x; if (this.gos.get("enableRtl")) { x = xLeftPosition(); if (x < 0) { x = xRightPosition(); this.setAlignedStyles(ePopup, "left"); } if (x > maxX) { x = 0; this.setAlignedStyles(ePopup, "right"); } } else { x = xRightPosition(); if (x > maxX) { x = xLeftPosition(); this.setAlignedStyles(ePopup, "right"); } if (x < 0) { x = 0; this.setAlignedStyles(ePopup, "left"); } } return { x, y }; function xRightPosition() { return sourceRect.right - parentRect.left - 2; } function xLeftPosition() { return sourceRect.left - parentRect.left - minWidth; } }; this.positionPopup({ ePopup, keepWithinBounds: true, updatePosition, postProcessCallback: () => this.callPostProcessPopup(params.additionalParams, "subMenu", ePopup, eventSource, event instanceof MouseEvent ? event : undefined) }); } shouldRenderUnderOrAbove(ePopup, targetCompRect, parentRect, nudgeY) { const spaceAvailableUnder = parentRect.bottom - targetCompRect.bottom; const spaceAvailableAbove = targetCompRect.top - parentRect.top; const spaceRequired = ePopup.offsetHeight + nudgeY; if (spaceAvailableUnder > spaceRequired) { return "under"; } if (spaceAvailableAbove > spaceRequired || spaceAvailableAbove > spaceAvailableUnder) { return "above"; } return "under"; } setAlignedStyles(ePopup, positioned) { const popupIdx = this.getPopupIndex(ePopup); if (popupIdx === -1) { return; } const popup = this.popupList[popupIdx]; const { alignedToElement } = popup; if (!alignedToElement) { return; } const positions = ["right", "left", "over", "above", "under"]; for (const position of positions) { alignedToElement.classList.remove(`ag-has-popup-positioned-${position}`); ePopup.classList.remove(`ag-popup-positioned-${position}`); } if (!positioned) { return; } alignedToElement.classList.add(`ag-has-popup-positioned-${positioned}`); ePopup.classList.add(`ag-popup-positioned-${positioned}`); } setAlignedTo(eventSource, ePopup) { const popupIdx = this.getPopupIndex(ePopup); if (popupIdx !== -1) { const popup = this.popupList[popupIdx]; popup.alignedToElement = eventSource; } } positionPopup(params) { const { ePopup, keepWithinBounds, nudgeX, nudgeY, skipObserver, updatePosition } = params; const lastSize = { width: 0, height: 0 }; const updatePopupPosition = (fromResizeObserver = false) => { let { x, y } = updatePosition(); if (fromResizeObserver && ePopup.clientWidth === lastSize.width && ePopup.clientHeight === lastSize.height) { return; } lastSize.width = ePopup.clientWidth; lastSize.height = ePopup.clientHeight; if (nudgeX) { x += nudgeX; } if (nudgeY) { y += nudgeY; } if (keepWithinBounds) { x = this.keepXYWithinBounds(ePopup, x, 1); y = this.keepXYWithinBounds(ePopup, y, 0); } ePopup.style.left = `${x}px`; ePopup.style.top = `${y}px`; if (params.postProcessCallback) { params.postProcessCallback(); } }; updatePopupPosition(); if (!skipObserver) { const resizeObserverDestroyFunc = _observeResize(this.beans, ePopup, () => updatePopupPosition(true)); setTimeout(() => resizeObserverDestroyFunc(), WAIT_FOR_POPUP_CONTENT_RESIZE); } } getParentRect() { const eDocument = _getDocument(this.beans); let popupParent = this.getPopupParent(); if (popupParent === eDocument.body) { popupParent = eDocument.documentElement; } else if (getComputedStyle(popupParent).position === "static") { popupParent = popupParent.offsetParent; } return _getElementRectWithOffset(popupParent); } keepXYWithinBounds(ePopup, position, direction) { const isVertical = direction === 0; const sizeProperty = isVertical ? "clientHeight" : "clientWidth"; const anchorProperty = isVertical ? "top" : "left"; const offsetProperty = isVertical ? "height" : "width"; const scrollPositionProperty = isVertical ? "scrollTop" : "scrollLeft"; const eDocument = _getDocument(this.beans); const docElement = eDocument.documentElement; const popupParent = this.getPopupParent(); const popupRect = ePopup.getBoundingClientRect(); const parentRect = popupParent.getBoundingClientRect(); const documentRect = eDocument.documentElement.getBoundingClientRect(); const isBody = popupParent === eDocument.body; const offsetSize = Math.ceil(popupRect[offsetProperty]); const getSize2 = isVertical ? _getAbsoluteHeight : _getAbsoluteWidth; let sizeOfParent = isBody ? getSize2(docElement) + docElement[scrollPositionProperty] : popupParent[sizeProperty]; if (isBody) { sizeOfParent -= Math.abs(documentRect[anchorProperty] - parentRect[anchorProperty]); } const max = sizeOfParent - offsetSize; return Math.min(Math.max(position, 0), Math.max(max, 0)); } addPopup(params) { const { eChild, ariaLabel, ariaOwns, alwaysOnTop, positionCallback, anchorToElement } = params; const pos = this.getPopupIndex(eChild); if (pos !== -1) { const popup = this.popupList[pos]; return { hideFunc: popup.hideFunc }; } this.initialisePopupPosition(eChild); const wrapperEl = this.createPopupWrapper(eChild, !!alwaysOnTop, ariaLabel, ariaOwns); const removeListeners = this.addEventListenersToPopup({ ...params, wrapperEl }); if (positionCallback) { positionCallback(); } this.addPopupToPopupList(eChild, wrapperEl, removeListeners, anchorToElement); return { hideFunc: removeListeners }; } initialisePopupPosition(element) { const ePopupParent = this.getPopupParent(); const ePopupParentRect = ePopupParent.getBoundingClientRect(); if (!_exists(element.style.top)) { element.style.top = `${ePopupParentRect.top * -1}px`; } if (!_exists(element.style.left)) { element.style.left = `${ePopupParentRect.left * -1}px`; } } createPopupWrapper(element, alwaysOnTop, ariaLabel, ariaOwns) { const ePopupParent = this.getPopupParent(); const { environment, gos } = this.beans; const eWrapper = _createAgElement({ tag: "div" }); environment.applyThemeClasses(eWrapper); eWrapper.classList.add("ag-popup"); element.classList.add(gos.get("enableRtl") ? "ag-rtl" : "ag-ltr", "ag-popup-child"); if (!element.hasAttribute("role")) { _setAriaRole(element, "dialog"); } if (ariaLabel) { _setAriaLabel(element, ariaLabel); } else if (ariaOwns) { element.id || (element.id = `popup-component-${instanceIdSeq}`); _setAriaOwns(ariaOwns, element.id); } eWrapper.appendChild(element); ePopupParent.appendChild(eWrapper); if (alwaysOnTop) { this.setAlwaysOnTop(element, true); } else { this.bringPopupToFront(element); } return eWrapper; } addEventListenersToPopup(params) { const beans = this.beans; const eDocument = _getDocument(beans); const { wrapperEl, eChild: popupEl, closedCallback, afterGuiAttached, closeOnEsc, modal, ariaOwns } = params; let popupHidden = false; const hidePopupOnKeyboardEvent = (event) => { if (!wrapperEl.contains(_getActiveDomElement(beans))) { return; } const key = event.key; if (key === KeyCode.ESCAPE && !this.isStopPropagation(event)) { removeListeners({ keyboardEvent: event }); } }; const hidePopupOnMouseEvent = (event) => removeListeners({ mouseEvent: event }); const hidePopupOnTouchEvent = (event) => removeListeners({ touchEvent: event }); const removeListeners = (popupParams = {}) => { const { mouseEvent, touchEvent, keyboardEvent, forceHide } = popupParams; if (!forceHide && (this.isEventFromCurrentPopup({ mouseEvent, touchEvent }, popupEl) || popupHidden)) { return; } popupHidden = true; wrapperEl.remove(); eDocument.removeEventListener("keydown", hidePopupOnKeyboardEvent); eDocument.removeEventListener("mousedown", hidePopupOnMouseEvent); eDocument.removeEventListener("touchstart", hidePopupOnTouchEvent); eDocument.removeEventListener("contextmenu", hidePopupOnMouseEvent); this.eventSvc.removeListener("dragStarted", hidePopupOnMouseEvent); if (closedCallback) { closedCallback(mouseEvent || touchEvent || keyboardEvent); } this.removePopupFromPopupList(popupEl, ariaOwns); }; if (afterGuiAttached) { afterGuiAttached({ hidePopup: removeListeners }); } window.setTimeout(() => { if (closeOnEsc) { eDocument.addEventListener("keydown", hidePopupOnKeyboardEvent); } if (modal) { eDocument.addEventListener("mousedown", hidePopupOnMouseEvent); this.eventSvc.addListener("dragStarted", hidePopupOnMouseEvent); eDocument.addEventListener("touchstart", hidePopupOnTouchEvent); eDocument.addEventListener("contextmenu", hidePopupOnMouseEvent); } }, 0); return removeListeners; } addPopupToPopupList(element, wrapperEl, removeListeners, anchorToElement) { this.popupList.push({ element, wrapper: wrapperEl, hideFunc: removeListeners, instanceId: instanceIdSeq, isAnchored: !!anchorToElement }); if (anchorToElement) { this.setPopupPositionRelatedToElement(element, anchorToElement); } instanceIdSeq = instanceIdSeq + 1; } getPopupIndex(el) { return this.popupList.findIndex((p) => p.element === el); } setPopupPositionRelatedToElement(popupEl, relativeElement) { const popupIndex = this.getPopupIndex(popupEl); if (popupIndex === -1) { return; } const popup = this.popupList[popupIndex]; if (popup.stopAnchoringPromise) { popup.stopAnchoringPromise.then((destroyFunc) => destroyFunc && destroyFunc()); } popup.stopAnchoringPromise = undefined; popup.isAnchored = false; if (!relativeElement) { return; } const destroyPositionTracker = this.keepPopupPositionedRelativeTo({ element: relativeElement, ePopup: popupEl, hidePopup: popup.hideFunc }); popup.stopAnchoringPromise = destroyPositionTracker; popup.isAnchored = true; return destroyPositionTracker; } removePopupFromPopupList(element, ariaOwns) { this.setAlignedStyles(element, null); this.setPopupPositionRelatedToElement(element, null); if (ariaOwns) { _setAriaOwns(ariaOwns, null); } this.popupList = this.popupList.filter((p) => p.element !== element); } keepPopupPositionedRelativeTo(params) { const eParent = this.getPopupParent(); const parentRect = eParent.getBoundingClientRect(); const { element, ePopup } = params; const sourceRect = element.getBoundingClientRect(); const extractFromPixelValue = (pxSize) => Number.parseInt(pxSize.substring(0, pxSize.length - 1), 10); const createPosition = (prop, direction) => { const initialDiff = parentRect[prop] - sourceRect[prop]; const initial = extractFromPixelValue(ePopup.style[prop]); return { initialDiff, lastDiff: initialDiff, initial, last: initial, direction }; }; const topPosition = createPosition("top", 0); const leftPosition = createPosition("left", 1); const fwOverrides = this.beans.frameworkOverrides; return new AgPromise((resolve) => { fwOverrides.wrapIncoming(() => { _wrapInterval(() => { const pRect = eParent.getBoundingClientRect(); const sRect = element.getBoundingClientRect(); const elementNotInDom = sRect.top == 0 && sRect.left == 0 && sRect.height == 0 && sRect.width == 0; if (elementNotInDom) { params.hidePopup(); return; } const calculateNewPosition = (position, prop) => { const current = extractFromPixelValue(ePopup.style[prop]); if (position.last !== current) { position.initial = current; position.last = current; } const currentDiff = pRect[prop] - sRect[prop]; if (currentDiff != position.lastDiff) { const newValue = this.keepXYWithinBounds(ePopup, position.initial + position.initialDiff - currentDiff, position.direction); ePopup.style[prop] = `${newValue}px`; position.last = newValue; } position.lastDiff = currentDiff; }; calculateNewPosition(topPosition, "top"); calculateNewPosition(leftPosition, "left"); }, 200).then((intervalId) => { const result = () => { if (intervalId != null) { window.clearInterval(intervalId); } }; resolve(result); }); }, "popupPositioning"); }); } isEventFromCurrentPopup(params, target) { const { mouseEvent, touchEvent } = params; const event = mouseEvent ? mouseEvent : touchEvent; if (!event) { return false; } const indexOfThisChild = this.getPopupIndex(target); if (indexOfThisChild === -1) { return false; } for (let i = indexOfThisChild;i < this.popupList.length; i++) { const popup = this.popupList[i]; if (_isElementInEventPath(popup.element, event)) { return true; } } return this.isElementWithinCustomPopup(event.target); } isElementWithinCustomPopup(el) { const eDocument = _getDocument(this.beans); while (el && el !== eDocument.body) { if (el.classList.contains("ag-custom-component-popup") || el.parentElement === null) { return true; } el = el.parentElement; } return false; } getWrapper(ePopup) { while (!ePopup.classList.contains("ag-popup") && ePopup.parentElement) { ePopup = ePopup.parentElement; } return ePopup.classList.contains("ag-popup") ? ePopup : null; } setAlwaysOnTop(ePopup, alwaysOnTop) { const eWrapper = this.getWrapper(ePopup); if (!eWrapper) { return; } eWrapper.classList.toggle("ag-always-on-top", !!alwaysOnTop); if (alwaysOnTop) { this.bringPopupToFront(eWrapper); } } bringPopupToFront(ePopup) { const parent = this.getPopupParent(); const popupList = Array.prototype.slice.call(parent.querySelectorAll(".ag-popup")); const popupLen = popupList.length; const eWrapper = this.getWrapper(ePopup); if (!eWrapper || popupLen <= 1 || !parent.contains(ePopup)) { return; } const standardPopupList = []; const alwaysOnTopList = []; for (const popup of popupList) { if (popup === eWrapper) { continue; } if (popup.classList.contains("ag-always-on-top")) { alwaysOnTopList.push(popup); } else { standardPopupList.push(popup); } } const innerElsScrollMap = []; const onTopLength = alwaysOnTopList.length; const isPopupAlwaysOnTop = eWrapper.classList.contains("ag-always-on-top"); const shouldBeLast = isPopupAlwaysOnTop || !onTopLength; const targetList = shouldBeLast ? [...standardPopupList, ...alwaysOnTopList, eWrapper] : [...standardPopupList, eWrapper, ...alwaysOnTopList]; for (let i = 0;i <= popupLen; i++) { const currentPopup = targetList[i]; if (popupList[i] === targetList[i] || currentPopup === eWrapper) { continue; } const innerEls = currentPopup.querySelectorAll("div"); for (const el of innerEls) { if (el.scrollTop !== 0) { innerElsScrollMap.push([el, el.scrollTop]); } } if (i === 0) { parent.prepend(currentPopup); } else { targetList[i - 1].after(currentPopup); } } while (innerElsScrollMap.length) { const currentEl = innerElsScrollMap.pop(); currentEl[0].scrollTop = currentEl[1]; } } handleThemeChange(e) { if (e.themeChanged) { const environment = this.beans.environment; for (const popup of this.popupList) { environment.applyThemeClasses(popup.wrapper); } } } }; var PopupService = class extends BasePopupService { getDefaultPopupParent() { return this.beans.ctrlsSvc.get("gridCtrl").getGui(); } callPostProcessPopup(params, type, ePopup, eventSource, mouseEvent) { const callback = this.gos.getCallback("postProcessPopup"); if (callback) { const { column, rowNode } = params ?? {}; const postProcessParams = { column, rowNode, ePopup, type, eventSource, mouseEvent }; callback(postProcessParams); } } getActivePopups() { return this.popupList.map((popup) => popup.element); } hasAnchoredPopup() { return this.popupList.some((popup) => popup.isAnchored); } isStopPropagation(event) { return _isStopPropagationForAgGrid(event); } }; var PopupModule = { moduleName: "Popup", version: VERSION, beans: [PopupService] }; function _isShowTooltipWhenTruncated(gos) { return gos.get("tooltipShowMode") === "whenTruncated"; } function _getShouldDisplayTooltip(gos, getElement2) { return _isShowTooltipWhenTruncated(gos) ? _isElementOverflowingCallback(getElement2) : undefined; } var getErrorTooltipMessage = (error, translate) => { const localisable = error; if (typeof localisable.getTranslatedMessage === "function") { return localisable.getTranslatedMessage(translate); } return error.message; }; var getEditErrorsForPosition = (beans, cellCtrl, translate) => { const { editModelSvc } = beans; const cellValidationErrors = editModelSvc?.getCellValidationModel()?.getCellValidation(cellCtrl)?.errorMessages; const rowValidationErrors = editModelSvc?.getRowValidationModel().getRowValidation(cellCtrl)?.errorMessages; const errors = cellValidationErrors || rowValidationErrors; return errors?.length ? errors.join(translate("tooltipValidationErrorSeparator", ". ")) : undefined; }; var getCellTruncationCheck = (beans, ctrl) => { const isTooltipWhenTruncated = _isShowTooltipWhenTruncated(beans.gos); if (!isTooltipWhenTruncated) { return; } if (ctrl.isCellRenderer()) { const colDef = ctrl.column.getColDef(); const isGroupCellRenderer = !!colDef.showRowGroup || colDef.cellRenderer === "agGroupCellRenderer"; if (!isGroupCellRenderer) { return; } return _isElementOverflowingCallback(() => { const eCell = ctrl.eGui; return eCell.querySelector(".ag-group-value") || eCell.querySelector(".ag-cell-value") || eCell; }); } return _isElementOverflowingCallback(() => { const eCell = ctrl.eGui; return eCell.children.length === 0 ? eCell : eCell.querySelector(".ag-cell-value"); }); }; var buildCellTooltipDisplayFunctions = (beans, ctrl, shouldDisplayTooltip) => { const { editSvc } = beans; const { column } = ctrl; const isCellTruncated = getCellTruncationCheck(beans, ctrl); const shouldDisplayCellTooltip = () => { if (editSvc?.isEditing(ctrl)) { return false; } if (!isCellTruncated) { return true; } if (!column.isTooltipEnabled()) { return false; } return isCellTruncated(); }; return { shouldDisplayDefault: shouldDisplayCellTooltip, shouldDisplayColumnTooltip: shouldDisplayCellTooltip, shouldDisplayCustomTooltip: shouldDisplayTooltip ?? shouldDisplayCellTooltip }; }; var resolveCellTooltip = ({ beans, ctrl, value, displayFunctions, translate }) => { const { editSvc, formula, gos } = beans; const { column, rowNode } = ctrl; if (formula?.active && column.isAllowFormula()) { const error = formula.getFormulaError(column, rowNode); if (error) { return { value: getErrorTooltipMessage(error, translate), location: "cellFormula", shouldDisplay: () => !!formula?.getFormulaError(column, rowNode) }; } } const isEditing2 = !!editSvc?.isEditing(ctrl); if (!isEditing2) { const errorMessages = getEditErrorsForPosition(beans, ctrl, translate); if (errorMessages) { return { value: errorMessages, location: "cellEditor", shouldDisplay: () => !editSvc?.isEditing(ctrl) && !!getEditErrorsForPosition(beans, ctrl, translate) }; } } const { shouldDisplayCustomTooltip, shouldDisplayColumnTooltip } = displayFunctions; if (value != null) { return { value, location: "cell", shouldDisplay: shouldDisplayCustomTooltip }; } const colDef = column.getColDef(); const data = rowNode.data; if (colDef.tooltipField && _exists(data)) { return { value: _getValueUsingField(data, colDef.tooltipField, column.isTooltipFieldContainsDots()), location: "cell", shouldDisplay: shouldDisplayColumnTooltip }; } const valueGetter = colDef.tooltipValueGetter; if (valueGetter) { return { value: valueGetter(_addGridCommonParams(gos, { location: "cell", colDef: column.getColDef(), column, rowIndex: ctrl.cellPosition.rowIndex, node: rowNode, data: rowNode.data, value: ctrl.value, valueFormatted: ctrl.valueFormatted })), location: "cell", shouldDisplay: shouldDisplayColumnTooltip }; } return null; }; var TooltipService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "tooltipSvc"; } setupHeaderTooltip(existingTooltipFeature, ctrl, passedValue, shouldDisplayTooltip) { if (existingTooltipFeature) { ctrl.destroyBean(existingTooltipFeature); } const gos = this.gos; const isTooltipWhenTruncated = _isShowTooltipWhenTruncated(gos); const { column, eGui } = ctrl; const colDef = column.getColDef(); if (!shouldDisplayTooltip && isTooltipWhenTruncated && !colDef.headerComponent) { shouldDisplayTooltip = _isElementOverflowingCallback(() => eGui.querySelector(".ag-header-cell-text")); } const location = "header"; const headerLocation = "header"; const valueFormatted = this.beans.colNames.getDisplayNameForColumn(column, headerLocation, true); const value = passedValue ?? valueFormatted; const tooltipCtrl = { getGui: () => eGui, getLocation: () => location, getTooltipValue: () => passedValue ?? colDef?.headerTooltipValueGetter?.(_addGridCommonParams(gos, { location, colDef, column, value, valueFormatted })) ?? colDef?.headerTooltip, shouldDisplayTooltip, getAdditionalParams: () => ({ column, colDef: column.getColDef() }) }; let tooltipFeature = this.createTooltipFeature(tooltipCtrl); if (tooltipFeature) { tooltipFeature = ctrl.createBean(tooltipFeature); ctrl.setRefreshFunction("tooltip", () => tooltipFeature.refreshTooltip()); } return tooltipFeature; } setupHeaderGroupTooltip(existingTooltipFeature, ctrl, passedValue, shouldDisplayTooltip) { if (existingTooltipFeature) { ctrl.destroyBean(existingTooltipFeature); } const gos = this.gos; const isTooltipWhenTruncated = _isShowTooltipWhenTruncated(gos); const { column, eGui } = ctrl; const colDef = column.getColGroupDef(); if (!shouldDisplayTooltip && isTooltipWhenTruncated && !colDef?.headerGroupComponent) { shouldDisplayTooltip = _isElementOverflowingCallback(() => eGui.querySelector(".ag-header-group-text")); } const location = "headerGroup"; const headerLocation = "header"; const valueFormatted = this.beans.colNames.getDisplayNameForColumnGroup(column, headerLocation); const value = passedValue ?? valueFormatted; const tooltipCtrl = { getGui: () => eGui, getLocation: () => location, getTooltipValue: () => passedValue ?? colDef?.headerTooltipValueGetter?.(_addGridCommonParams(gos, { location, colDef, column, value, valueFormatted })) ?? colDef?.headerTooltip, shouldDisplayTooltip, getAdditionalParams: () => { const additionalParams = { column }; if (colDef) { additionalParams.colDef = colDef; } return additionalParams; } }; const tooltipFeature = this.createTooltipFeature(tooltipCtrl); return tooltipFeature ? ctrl.createBean(tooltipFeature) : tooltipFeature; } enableCellTooltipFeature(ctrl, value, shouldDisplayTooltip) { const { beans } = this; const { column, rowNode } = ctrl; const displayFunctions = buildCellTooltipDisplayFunctions(beans, ctrl, shouldDisplayTooltip); const translate = this.getLocaleTextFunc(); let resolvedTooltip = null; const resolveAndStore = () => { resolvedTooltip = resolveCellTooltip({ beans, ctrl, value, displayFunctions, translate }); return resolvedTooltip; }; const getTooltipValue = () => resolveAndStore()?.value; const tooltipCtrl = { getGui: () => ctrl.eGui, getLocation: () => resolvedTooltip?.location ?? "cell", getTooltipValue, shouldDisplayTooltip: () => { const tooltip = resolvedTooltip ?? resolveAndStore(); if (!tooltip) { return false; } return tooltip.shouldDisplay ? tooltip.shouldDisplay() : true; }, getAdditionalParams: () => ({ column, colDef: column.getColDef(), rowIndex: ctrl.cellPosition.rowIndex, node: rowNode, data: rowNode.data, valueFormatted: ctrl.valueFormatted }) }; return this.createTooltipFeature(tooltipCtrl, beans); } setupFullWidthRowTooltip(existingTooltipFeature, ctrl, value, shouldDisplayTooltip) { const tooltipParams = { getGui: () => ctrl.getFullWidthElement(), getTooltipValue: () => value, getLocation: () => "fullWidthRow", shouldDisplayTooltip }; const beans = this.beans; const context = beans.context; if (existingTooltipFeature) { ctrl.destroyBean(existingTooltipFeature, context); } const tooltipFeature = this.createTooltipFeature(tooltipParams, beans); if (!tooltipFeature) { return; } return ctrl.createBean(tooltipFeature, context); } setupCellEditorTooltip(cellCtrl, editor) { const { beans } = this; const { context } = beans; const el = editor.getValidationElement?.(true) || !editor.isPopup?.() && cellCtrl.eGui; if (!el) { return; } const tooltipParams = { getGui: () => el, getTooltipValue: () => getEditErrorsForPosition(beans, cellCtrl, this.getLocaleTextFunc()), getLocation: () => "cellEditor", shouldDisplayTooltip: () => { const { editModelSvc } = beans; const rowValidationMap = editModelSvc?.getRowValidationModel()?.getRowValidationMap(); const cellValidationMap = editModelSvc?.getCellValidationModel()?.getCellValidationMap(); const hasRowValidationErrors = !!rowValidationMap && rowValidationMap.size > 0; const hasCellValidationErrors = !!cellValidationMap && cellValidationMap.size > 0; return hasRowValidationErrors || hasCellValidationErrors; } }; const tooltipFeature = this.createTooltipFeature(tooltipParams, beans); if (!tooltipFeature) { return; } return cellCtrl.createBean(tooltipFeature, context); } initCol(column) { const { colDef } = column; column.tooltipEnabled = _exists(colDef.tooltipField) || _exists(colDef.tooltipValueGetter) || _exists(colDef.tooltipComponent); } createTooltipFeature(tooltipCtrl, beans) { return this.beans.registry.createDynamicBean("tooltipFeature", false, tooltipCtrl, beans); } }; var TooltipStateManager = class extends BaseTooltipStateManager { createTooltipComp(params, callback) { const userDetails = _getTooltipCompDetails(this.beans.userCompFactory, params); userDetails?.newAgStackInstance().then(callback); } setEventHandlers(listener) { [this.onColumnMovedEventCallback] = this.addManagedEventListeners({ columnMoved: listener }); } clearEventHandlers() { this.onColumnMovedEventCallback?.(); this.onColumnMovedEventCallback = undefined; } }; var TooltipModule = { moduleName: "Tooltip", version: VERSION, beans: [TooltipService], dynamicBeans: { tooltipFeature: AgTooltipFeature, highlightTooltipFeature: AgHighlightTooltipFeature, tooltipStateManager: TooltipStateManager }, userComponents: { agTooltipComponent: AgTooltipComponent }, dependsOn: [PopupModule], css: [tooltip_default] }; var cell_editing_default = ".ag-cell-inline-editing{border:var(--ag-cell-editing-border)!important;border-radius:var(--ag-border-radius);box-shadow:var(--ag-cell-editing-shadow);padding:0;z-index:1;.ag-cell-edit-wrapper,.ag-cell-editor,.ag-cell-wrapper,:where(.ag-cell-editor) .ag-input-field-input,:where(.ag-cell-editor) .ag-wrapper{height:100%;line-height:normal;min-height:100%;width:100%}&.ag-cell-editing-error{border-color:var(--ag-invalid-color)!important}}:where(.ag-popup-editor) .ag-large-text{background-color:var(--ag-background-color);border-radius:var(--ag-border-radius);box-shadow:var(--ag-dropdown-shadow);padding:0}.ag-large-text-input{display:block;height:auto;padding:var(--ag-cell-horizontal-padding)}:where(.ag-rtl .ag-large-text-input) .ag-text-area-input{resize:none}:where(.ag-ltr) .ag-checkbox-edit{padding-left:var(--ag-cell-horizontal-padding)}:where(.ag-rtl) .ag-checkbox-edit{padding-right:var(--ag-cell-horizontal-padding)}:where(.ag-row.ag-row-editing-invalid .ag-cell-inline-editing){opacity:.8}.ag-popup-editor{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none}"; var AgInputTextField = class extends AgAbstractInputField { constructor(config, className = "ag-text-field", inputType = "text") { super(config, className, inputType); } postConstruct() { super.postConstruct(); if (this.config.allowedCharPattern) { this.preventDisallowedCharacters(); } } setValue(value, silent) { const eInput = this.eInput; if (eInput.value !== value) { eInput.value = _exists(value) ? value : ""; } return super.setValue(value, silent); } setStartValue(value) { this.setValue(value, true); } setCustomValidity(message) { const eInput = this.eInput; const isInvalid = message.length > 0; eInput.setCustomValidity(message); if (isInvalid) { eInput.reportValidity(); } _setAriaInvalid(eInput, isInvalid); } preventDisallowedCharacters() { const pattern = new RegExp(`[${this.config.allowedCharPattern}]`); const preventCharacters = (event) => { if (!_isEventFromPrintableCharacter(event)) { return; } if (event.key && !pattern.test(event.key)) { event.preventDefault(); } }; this.addManagedListeners(this.eInput, { keydown: preventCharacters, paste: (e) => { const text = e.clipboardData?.getData("text"); if (text?.split("").some((c) => !pattern.test(c))) { e.preventDefault(); } } }); } }; var AgInputTextFieldSelector = { selector: "AG-INPUT-TEXT-FIELD", component: AgInputTextField }; var SimpleCellEditor = class extends AgAbstractCellEditor { constructor(cellEditorInput) { super(); this.cellEditorInput = cellEditorInput; this.eEditor = RefPlaceholder; } initialiseEditor(params) { const { cellEditorInput } = this; this.setTemplate({ tag: "div", cls: "ag-cell-edit-wrapper", children: [cellEditorInput.getTemplate()] }, cellEditorInput.getAgComponents()); const { eEditor } = this; const { cellStartedEdit, eventKey, suppressPreventDefault } = params; eEditor.getInputElement().setAttribute("title", ""); cellEditorInput.init(eEditor, params); let startValue; let shouldSetStartValue = true; if (cellStartedEdit) { this.focusAfterAttached = true; if (eventKey === KeyCode.BACKSPACE || eventKey === KeyCode.DELETE) { startValue = ""; } else if (eventKey && eventKey.length === 1) { if (suppressPreventDefault) { shouldSetStartValue = false; } else { startValue = eventKey; } } else { startValue = cellEditorInput.getStartValue(); if (eventKey !== KeyCode.F2) { this.highlightAllOnFocus = true; } } } else { this.focusAfterAttached = false; startValue = cellEditorInput.getStartValue(); } if (shouldSetStartValue && startValue != null) { eEditor.setStartValue(startValue); } this.addGuiEventListener("keydown", (event) => { const { key } = event; if (key === KeyCode.PAGE_UP || key === KeyCode.PAGE_DOWN) { event.preventDefault(); } }); } afterGuiAttached() { const translate = this.getLocaleTextFunc(); const eInput = this.eEditor; eInput.setInputAriaLabel(translate("ariaInputEditor", "Input Editor")); if (!this.focusAfterAttached) { return; } if (!_isBrowserSafari()) { eInput.getFocusableElement().focus(); } const inputEl = eInput.getInputElement(); if (this.highlightAllOnFocus) { inputEl.select(); } else { this.cellEditorInput.setCaret?.(); } } focusIn() { const { eEditor } = this; const focusEl = eEditor.getFocusableElement(); const inputEl = eEditor.getInputElement(); focusEl.focus(); inputEl.select(); } getValue() { return this.cellEditorInput.getValue(); } agSetEditValue(value) { this.params.value = value; const startValue = this.cellEditorInput.getStartValue(); this.eEditor.setStartValue(startValue ?? null); } isPopup() { return false; } getValidationElement() { return this.eEditor.getInputElement(); } getValidationErrors() { return this.cellEditorInput.getValidationErrors(); } }; var AgInputNumberField = class extends AgInputTextField { constructor(config) { super(config, "ag-number-field", "number"); } postConstruct() { super.postConstruct(); const eInput = this.eInput; this.addManagedListeners(eInput, { blur: () => { const floatedValue = Number.parseFloat(eInput.value); const value = isNaN(floatedValue) ? "" : this.normalizeValue(floatedValue.toString()); if (this.value !== value) { this.setValue(value); } }, wheel: this.onWheel.bind(this) }); eInput.step = "any"; const { precision, min, max, step } = this.config; if (typeof precision === "number") { this.setPrecision(precision); } if (typeof min === "number") { this.setMin(min); } if (typeof max === "number") { this.setMax(max); } if (typeof step === "number") { this.setStep(step); } } onWheel(e) { if (_getActiveDomElement(this.beans) === this.eInput) { e.preventDefault(); } } normalizeValue(value) { if (value === "") { return ""; } if (this.precision != null) { value = this.adjustPrecision(value); } return value; } adjustPrecision(value, isScientificNotation) { const precision = this.precision; if (precision == null) { return value; } if (isScientificNotation) { const floatString = Number.parseFloat(value).toFixed(precision); return Number.parseFloat(floatString).toString(); } const parts = String(value).split("."); if (parts.length > 1) { if (parts[1].length <= precision) { return value; } else if (precision > 0) { return `${parts[0]}.${parts[1].slice(0, precision)}`; } } return parts[0]; } setMin(min) { if (this.min === min) { return this; } this.min = min; _addOrRemoveAttribute(this.eInput, "min", min); return this; } setMax(max) { if (this.max === max) { return this; } this.max = max; _addOrRemoveAttribute(this.eInput, "max", max); return this; } setPrecision(precision) { this.precision = precision; return this; } setStep(step) { if (this.step === step) { return this; } this.step = step; _addOrRemoveAttribute(this.eInput, "step", step); return this; } setValue(value, silent) { return this.setValueOrInputValue((v) => super.setValue(v, silent), () => this, value); } setStartValue(value) { return this.setValueOrInputValue((v) => super.setValue(v, true), (v) => { this.eInput.value = v; }, value); } setValueOrInputValue(setValueFunc, setInputValueOnlyFunc, value) { if (_exists(value)) { let setInputValueOnly = this.isScientificNotation(value); if (setInputValueOnly && this.eInput.validity.valid) { return setValueFunc(value); } if (!setInputValueOnly) { value = this.adjustPrecision(value); const normalizedValue = this.normalizeValue(value); setInputValueOnly = value != normalizedValue; } if (setInputValueOnly) { return setInputValueOnlyFunc(value); } } return setValueFunc(value); } getValue(ignoreValidity = false) { const eInput = this.eInput; if (!eInput.validity.valid && !ignoreValidity) { return; } const inputValue = eInput.value; if (this.isScientificNotation(inputValue)) { return this.adjustPrecision(inputValue, true); } return super.getValue(); } isScientificNotation(value) { return typeof value === "string" && value.includes("e"); } }; var agList_default = ".ag-list-item{align-items:center;display:flex;height:var(--ag-list-item-height);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;&.ag-active-item{background-color:var(--ag-row-hover-color)}}"; var ACTIVE_CLASS = "ag-active-item"; var getAgListElement = (cssIdentifier, label) => ({ tag: "div", cls: `ag-list-item ag-${cssIdentifier}-list-item`, attrs: { role: "option" }, children: [ { tag: "span", cls: `ag-list-item-text ag-${cssIdentifier}-list-item-text`, ref: "eText", children: label } ] }); var AgListItem = class extends AgComponentStub { constructor(cssIdentifier, label, value) { super(getAgListElement(cssIdentifier, label)); this.label = label; this.value = value; this.eText = RefPlaceholder; } postConstruct() { this.createTooltip(); this.addEventListeners(); } setHighlighted(highlighted) { const eGui = this.getGui(); eGui.classList.toggle(ACTIVE_CLASS, highlighted); _setAriaSelected(eGui, highlighted); this.dispatchLocalEvent({ type: "itemHighlighted", highlighted }); } getHeight() { return this.getGui().clientHeight; } setIndex(idx, setSize) { const eGui = this.getGui(); _setAriaPosInSet(eGui, idx); _setAriaSetSize(eGui, setSize); } createTooltip() { const tooltipCtrl = { getTooltipValue: () => this.label, getGui: () => this.getGui(), getLocation: () => "UNKNOWN", shouldDisplayTooltip: () => _isHorizontalScrollShowing(this.eText) }; const tooltipFeature = this.createOptionalManagedBean(this.beans.registry.createDynamicBean("highlightTooltipFeature", false, tooltipCtrl, this)); if (tooltipFeature) { this.tooltipFeature = tooltipFeature; } } addEventListeners() { const parentComponent = this.getParentComponent(); if (!parentComponent) { return; } this.addGuiEventListener("mouseover", () => { parentComponent.highlightItem(this); }); this.addGuiEventListener("mousedown", (e) => { e.preventDefault(); e.stopPropagation(); parentComponent.setValue(this.value); }); } }; var AgList = class extends AgComponentStub { constructor(cssIdentifier = "default") { super({ tag: "div", cls: `ag-list ag-${cssIdentifier}-list` }); this.cssIdentifier = cssIdentifier; this.options = []; this.listItems = []; this.highlightedItem = null; this.registerCSS(agList_default); } postConstruct() { const eGui = this.getGui(); this.addManagedElementListeners(eGui, { mouseleave: () => this.clearHighlighted() }); } handleKeyDown(e) { const key = e.key; switch (key) { case KeyCode.ENTER: if (!this.highlightedItem) { this.setValue(this.getValue()); } else { const pos = this.listItems.indexOf(this.highlightedItem); this.setValueByIndex(pos); } break; case KeyCode.DOWN: case KeyCode.UP: e.preventDefault(); this.navigate(key); break; case KeyCode.PAGE_DOWN: case KeyCode.PAGE_UP: case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: e.preventDefault(); this.navigateToPage(key); break; } } addOptions(listOptions) { for (const listOption of listOptions) { this.addOption(listOption); } return this; } addOption(listOption) { const { value, text } = listOption; const valueToRender = text ?? value; this.options.push({ value, text: valueToRender }); this.renderOption(value, valueToRender); this.updateIndices(); return this; } clearOptions() { this.options = []; this.reset(true); for (const item of this.listItems) { item.destroy(); } _clearElement(this.getGui()); this.listItems = []; this.refreshAriaRole(); } updateOptions(listOptions) { const needsUpdate = this.options !== listOptions; if (needsUpdate) { this.clearOptions(); this.addOptions(listOptions); } return needsUpdate; } setValue(value, silent) { if (this.value === value) { this.fireItemSelected(); return this; } if (value == null) { this.reset(silent); return this; } const idx = this.options.findIndex((option) => option.value === value); if (idx !== -1) { const option = this.options[idx]; this.value = option.value; this.displayValue = option.text; this.highlightItem(this.listItems[idx]); if (!silent) { this.fireChangeEvent(); } } return this; } setValueByIndex(idx) { return this.setValue(this.options[idx].value); } getValue() { return this.value; } getDisplayValue() { return this.displayValue; } refreshHighlighted() { this.clearHighlighted(); const idx = this.options.findIndex((option) => option.value === this.value); if (idx !== -1) { this.highlightItem(this.listItems[idx]); } } highlightItem(item) { const itemEl = item.getGui(); if (!_isVisible(itemEl)) { return; } this.clearHighlighted(); item.setHighlighted(true); this.highlightedItem = item; const eGui = this.getGui(); const { scrollTop, clientHeight } = eGui; const { offsetTop, offsetHeight } = itemEl; if (offsetTop + offsetHeight > scrollTop + clientHeight || offsetTop < scrollTop) { itemEl.scrollIntoView({ block: "nearest" }); } } hideItemTooltip() { this.highlightedItem?.tooltipFeature?.attemptToHideTooltip(); } destroy() { this.hideItemTooltip(); super.destroy(); } reset(silent) { this.value = null; this.displayValue = null; this.clearHighlighted(); if (!silent) { this.fireChangeEvent(); } } clearHighlighted() { this.highlightedItem?.setHighlighted(false); this.highlightedItem = null; } renderOption(value, text) { const item = new AgListItem(this.cssIdentifier, text, value); item.setParentComponent(this); const listItem = this.createManagedBean(item); this.listItems.push(listItem); this.getGui().appendChild(listItem.getGui()); } navigate(key) { const isDown = key === KeyCode.DOWN; let itemToHighlight; const { listItems, highlightedItem } = this; if (!highlightedItem) { itemToHighlight = isDown ? listItems[0] : _last(listItems); } else { const currentIdx = listItems.indexOf(highlightedItem); let nextPos = currentIdx + (isDown ? 1 : -1); nextPos = Math.min(Math.max(nextPos, 0), listItems.length - 1); itemToHighlight = listItems[nextPos]; } this.highlightItem(itemToHighlight); } navigateToPage(key) { const { listItems, highlightedItem } = this; if (!highlightedItem || listItems.length === 0) { return; } const currentIdx = listItems.indexOf(highlightedItem); const rowCount = this.options.length - 1; const itemHeight = listItems[0].getHeight(); const pageSize = Math.floor(this.getGui().clientHeight / itemHeight); let newIndex = -1; if (key === KeyCode.PAGE_HOME) { newIndex = 0; } else if (key === KeyCode.PAGE_END) { newIndex = rowCount; } else if (key === KeyCode.PAGE_DOWN) { newIndex = Math.min(currentIdx + pageSize, rowCount); } else if (key === KeyCode.PAGE_UP) { newIndex = Math.max(currentIdx - pageSize, 0); } if (newIndex === -1) { return; } this.highlightItem(listItems[newIndex]); } refreshAriaRole() { _setAriaRole(this.getGui(), this.options.length === 0 ? "presentation" : "listbox"); } updateIndices() { this.refreshAriaRole(); const listItems = this.listItems; const len = listItems.length; listItems.forEach((item, idx) => { item.setIndex(idx + 1, len); }); } fireChangeEvent() { this.dispatchLocalEvent({ type: "fieldValueChanged" }); this.fireItemSelected(); } fireItemSelected() { this.dispatchLocalEvent({ type: "selectedItem" }); } }; var agPickerField_default = ".ag-picker-field-display{flex:1 1 auto}.ag-picker-field{align-items:center;display:flex}.ag-picker-field-icon{border:0;cursor:pointer;display:flex;margin:0;padding:0}.ag-picker-field-wrapper{background-color:var(--ag-picker-button-background-color);border:var(--ag-picker-button-border);border-radius:5px;min-height:max(var(--ag-list-item-height),calc(var(--ag-spacing)*4));overflow:hidden;&:where(.invalid){background-color:var(--ag-input-invalid-background-color);border:var(--ag-input-invalid-border);color:var(--ag-input-invalid-text-color)}}.ag-picker-field-wrapper:where(.ag-picker-has-focus),.ag-picker-field-wrapper:where(:focus-within){background-color:var(--ag-picker-button-focus-background-color);border:var(--ag-picker-button-focus-border);box-shadow:var(--ag-focus-shadow);&:where(.invalid){box-shadow:var(--ag-focus-error-shadow)}}.ag-picker-field-wrapper:disabled{opacity:.5}"; var AgPickerFieldElement = { tag: "div", cls: "ag-picker-field", role: "presentation", children: [ { tag: "div", ref: "eLabel" }, { tag: "div", ref: "eWrapper", cls: "ag-wrapper ag-picker-field-wrapper ag-picker-collapsed", children: [ { tag: "div", ref: "eDisplayField", cls: "ag-picker-field-display" }, { tag: "div", ref: "eIcon", cls: "ag-picker-field-icon", attrs: { "aria-hidden": "true" } } ] } ] }; var AgPickerField = class extends AgAbstractField { constructor(config) { super(config, config?.template || AgPickerFieldElement, config?.agComponents || [], config?.className); this.isPickerDisplayed = false; this.skipClick = false; this.pickerGap = 4; this.hideCurrentPicker = null; this.eLabel = RefPlaceholder; this.eWrapper = RefPlaceholder; this.eDisplayField = RefPlaceholder; this.eIcon = RefPlaceholder; this.registerCSS(agPickerField_default); this.ariaRole = config?.ariaRole; this.onPickerFocusIn = this.onPickerFocusIn.bind(this); this.onPickerFocusOut = this.onPickerFocusOut.bind(this); if (!config) { return; } const { pickerGap, maxPickerHeight, variableWidth, minPickerWidth, maxPickerWidth } = config; if (pickerGap != null) { this.pickerGap = pickerGap; } this.variableWidth = !!variableWidth; if (maxPickerHeight != null) { this.setPickerMaxHeight(maxPickerHeight); } if (minPickerWidth != null) { this.setPickerMinWidth(minPickerWidth); } if (maxPickerWidth != null) { this.setPickerMaxWidth(maxPickerWidth); } } postConstruct() { super.postConstruct(); this.setupAria(); const displayId = `ag-${this.getCompId()}-display`; this.eDisplayField.setAttribute("id", displayId); const ariaEl = this.getAriaElement(); this.addManagedElementListeners(ariaEl, { keydown: this.onKeyDown.bind(this) }); this.addManagedElementListeners(this.eLabel, { mousedown: this.onLabelOrWrapperMouseDown.bind(this) }); this.addManagedElementListeners(this.eWrapper, { mousedown: this.onLabelOrWrapperMouseDown.bind(this) }); const { pickerIcon, inputWidth } = this.config; if (pickerIcon) { const icon = this.beans.iconSvc.createIconNoSpan(pickerIcon); if (icon) { this.eIcon.appendChild(icon); } } if (inputWidth != null) { this.setInputWidth(inputWidth); } } setupAria() { const ariaEl = this.getAriaElement(); ariaEl.setAttribute("tabindex", this.gos.get("tabIndex").toString()); _setAriaExpanded(ariaEl, false); if (this.ariaRole) { _setAriaRole(ariaEl, this.ariaRole); } } onLabelOrWrapperMouseDown(e) { if (e) { const focusableEl = this.getFocusableElement(); if (focusableEl !== this.eWrapper && e?.target === focusableEl) { return; } e.preventDefault(); this.getFocusableElement().focus(); } if (this.skipClick) { this.skipClick = false; return; } if (this.isDisabled()) { return; } if (this.isPickerDisplayed) { this.hidePicker(); } else { this.showPicker(); } } onKeyDown(e) { switch (e.key) { case KeyCode.UP: case KeyCode.DOWN: case KeyCode.ENTER: case KeyCode.SPACE: e.preventDefault(); this.onLabelOrWrapperMouseDown(); break; case KeyCode.ESCAPE: if (this.isPickerDisplayed) { e.preventDefault(); e.stopPropagation(); if (this.hideCurrentPicker) { this.hideCurrentPicker(); } } break; } } showPicker() { this.isPickerDisplayed = true; if (!this.pickerComponent) { this.pickerComponent = this.createPickerComponent(); } const pickerGui = this.pickerComponent.getGui(); pickerGui.addEventListener("focusin", this.onPickerFocusIn); pickerGui.addEventListener("focusout", this.onPickerFocusOut); this.hideCurrentPicker = this.renderAndPositionPicker(); this.toggleExpandedStyles(true); } renderAndPositionPicker() { const ePicker = this.pickerComponent.getGui(); if (!this.gos.get("suppressScrollWhenPopupsAreOpen")) { [this.destroyMouseWheelFunc] = this.addManagedEventListeners({ bodyScroll: () => { this.hidePicker(); } }); } const translate = this.getLocaleTextFunc(); const { config: { pickerAriaLabelKey, pickerAriaLabelValue, modalPicker = true }, maxPickerHeight, minPickerWidth, maxPickerWidth, variableWidth, beans, eWrapper } = this; const popupParams = { modal: modalPicker, eChild: ePicker, closeOnEsc: true, closedCallback: () => { const shouldRestoreFocus = _isNothingFocused(beans); this.beforeHidePicker(); if (shouldRestoreFocus && this.isAlive()) { this.getFocusableElement().focus(); } }, ariaLabel: translate(pickerAriaLabelKey, pickerAriaLabelValue), anchorToElement: eWrapper }; ePicker.style.position = "absolute"; const popupSvc = beans.popupSvc; const addPopupRes = popupSvc.addPopup(popupParams); if (variableWidth) { if (minPickerWidth) { ePicker.style.minWidth = minPickerWidth; } ePicker.style.width = _formatSize(_getAbsoluteWidth(eWrapper)); if (maxPickerWidth) { ePicker.style.maxWidth = maxPickerWidth; } } else { _setElementWidth(ePicker, maxPickerWidth ?? _getAbsoluteWidth(eWrapper)); } const maxHeight = maxPickerHeight ?? `${_getInnerHeight(popupSvc.getPopupParent())}px`; ePicker.style.setProperty("max-height", maxHeight); this.alignPickerToComponent(); return addPopupRes.hideFunc; } alignPickerToComponent() { if (!this.pickerComponent) { return; } const { pickerGap, config: { pickerType }, beans: { popupSvc, gos }, eWrapper, pickerComponent } = this; const alignSide = gos.get("enableRtl") ? "right" : "left"; popupSvc.positionPopupByComponent({ type: pickerType, eventSource: eWrapper, ePopup: pickerComponent.getGui(), position: "under", alignSide, keepWithinBounds: true, nudgeY: pickerGap }); } beforeHidePicker() { if (this.destroyMouseWheelFunc) { this.destroyMouseWheelFunc(); this.destroyMouseWheelFunc = undefined; } this.toggleExpandedStyles(false); const pickerGui = this.pickerComponent.getGui(); pickerGui.removeEventListener("focusin", this.onPickerFocusIn); pickerGui.removeEventListener("focusout", this.onPickerFocusOut); this.isPickerDisplayed = false; this.pickerComponent = undefined; this.hideCurrentPicker = null; } toggleExpandedStyles(expanded) { if (!this.isAlive()) { return; } const ariaEl = this.getAriaElement(); _setAriaExpanded(ariaEl, expanded); const classList = this.eWrapper.classList; classList.toggle("ag-picker-expanded", expanded); classList.toggle("ag-picker-collapsed", !expanded); } onPickerFocusIn() { this.togglePickerHasFocus(true); } onPickerFocusOut(e) { if (!this.pickerComponent?.getGui().contains(e.relatedTarget)) { this.togglePickerHasFocus(false); } } togglePickerHasFocus(focused) { if (!this.pickerComponent) { return; } this.eWrapper.classList.toggle("ag-picker-has-focus", focused); } hidePicker() { if (this.hideCurrentPicker) { this.hideCurrentPicker(); this.dispatchLocalEvent({ type: "pickerHidden" }); } } setInputWidth(width) { _setElementWidth(this.eWrapper, width); return this; } getFocusableElement() { return this.eWrapper; } setPickerGap(gap) { this.pickerGap = gap; return this; } setPickerMinWidth(width) { if (typeof width === "number") { width = `${width}px`; } this.minPickerWidth = width == null ? undefined : width; return this; } setPickerMaxWidth(width) { if (typeof width === "number") { width = `${width}px`; } this.maxPickerWidth = width == null ? undefined : width; return this; } setPickerMaxHeight(height) { if (typeof height === "number") { height = `${height}px`; } this.maxPickerHeight = height == null ? undefined : height; return this; } destroy() { this.hidePicker(); super.destroy(); } }; var agSelect_default = ".ag-select{align-items:center;display:flex;&.ag-disabled{opacity:.5}}.ag-select:where(:not(.ag-cell-editor,.ag-label-align-top)){min-height:var(--ag-list-item-height)}:where(.ag-select){.ag-picker-field-wrapper{cursor:default;padding-left:var(--ag-spacing);padding-right:var(--ag-spacing)}&.ag-disabled .ag-picker-field-wrapper:focus{box-shadow:none}.ag-picker-field-display{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-picker-field-icon{align-items:center;display:flex}}.ag-select-list{background-color:var(--ag-picker-list-background-color);border:var(--ag-picker-list-border);border-radius:var(--ag-border-radius);box-shadow:var(--ag-dropdown-shadow);overflow:hidden auto}.ag-select-list-item{cursor:default;-webkit-user-select:none;-moz-user-select:none;user-select:none}:where(.ag-ltr) .ag-select-list-item{padding-left:var(--ag-spacing)}:where(.ag-rtl) .ag-select-list-item{padding-right:var(--ag-spacing)}.ag-select-list-item-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}"; var AgSelect = class extends AgPickerField { constructor(config) { super({ pickerAriaLabelKey: "ariaLabelSelectField", pickerAriaLabelValue: "Select Field", pickerType: "ag-list", className: "ag-select", pickerIcon: "selectOpen", ariaRole: "combobox", ...config }); this.registerCSS(agSelect_default); } postConstruct() { this.tooltipFeature = this.createOptionalManagedBean(this.beans.registry.createDynamicBean("tooltipFeature", false, { shouldDisplayTooltip: _isElementOverflowingCallback(() => this.eDisplayField), getGui: () => this.getGui() })); super.postConstruct(); this.createListComponent(); this.eWrapper.tabIndex = this.gos.get("tabIndex"); const { options, value, placeholder } = this.config; if (options != null) { this.addOptions(options); } if (value != null) { this.setValue(value, true); } if (placeholder && value == null) { this.eDisplayField.textContent = placeholder; } this.addManagedElementListeners(this.eWrapper, { focusout: this.onWrapperFocusOut.bind(this) }); } onWrapperFocusOut(e) { if (!this.eWrapper.contains(e.relatedTarget)) { this.hidePicker(); } } createListComponent() { const listComponent = this.createBean(new AgList("select")); this.listComponent = listComponent; listComponent.setParentComponent(this); const eListAriaEl = listComponent.getAriaElement(); const listId = `ag-select-list-${listComponent.getCompId()}`; eListAriaEl.setAttribute("id", listId); _setAriaControlsAndLabel(this.getAriaElement(), eListAriaEl); listComponent.addManagedElementListeners(listComponent.getGui(), { mousedown: (e) => { e?.preventDefault(); } }); listComponent.addManagedListeners(listComponent, { selectedItem: () => { this.hidePicker(); this.dispatchLocalEvent({ type: "selectedItem" }); }, fieldValueChanged: () => { if (!this.listComponent) { return; } this.setValue(this.listComponent.getValue(), false, true); this.hidePicker(); } }); } createPickerComponent() { return this.listComponent; } beforeHidePicker() { this.listComponent?.hideItemTooltip(); super.beforeHidePicker(); } onKeyDown(e) { const { key } = e; if (key === KeyCode.TAB) { this.hidePicker(); } switch (key) { case KeyCode.ENTER: case KeyCode.UP: case KeyCode.DOWN: case KeyCode.PAGE_UP: case KeyCode.PAGE_DOWN: case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: e.preventDefault(); if (this.isPickerDisplayed) { this.listComponent?.handleKeyDown(e); } else { super.onKeyDown(e); } break; case KeyCode.ESCAPE: super.onKeyDown(e); break; case KeyCode.SPACE: if (this.isPickerDisplayed) { e.preventDefault(); } else { super.onKeyDown(e); } break; } } showPicker() { const listComponent = this.listComponent; if (!listComponent) { return; } super.showPicker(); listComponent.refreshHighlighted(); } addOptions(options) { for (const option of options) { this.addOption(option); } return this; } addOption(option) { this.listComponent.addOption(option); return this; } clearOptions() { this.listComponent?.clearOptions(); this.setValue(undefined, true); return this; } updateOptions(options) { if (this.listComponent?.updateOptions(options)) { this.setValue(undefined, true); } return this; } setValue(value, silent, fromPicker) { const { listComponent, config: { placeholder }, eDisplayField, tooltipFeature } = this; if (this.value === value || !listComponent) { return this; } if (!fromPicker) { listComponent.setValue(value, true); } const newValue = listComponent.getValue(); if (newValue === this.getValue()) { return this; } let displayValue = listComponent.getDisplayValue(); if (displayValue == null && placeholder) { displayValue = placeholder; } eDisplayField.textContent = displayValue; tooltipFeature?.setTooltipAndRefresh(displayValue ?? null); return super.setValue(value, silent); } destroy() { this.listComponent = this.destroyBean(this.listComponent); super.destroy(); } }; var TextCellEditorElement = { tag: "ag-input-text-field", ref: "eEditor", cls: "ag-cell-editor" }; var TextCellEditorInput = class { constructor(getLocaleTextFunc) { this.getLocaleTextFunc = getLocaleTextFunc; } getTemplate() { return TextCellEditorElement; } getAgComponents() { return [AgInputTextFieldSelector]; } init(eEditor, params) { this.eEditor = eEditor; this.params = params; const maxLength = params.maxLength; if (maxLength != null) { eEditor.setMaxLength(maxLength); } } getValidationErrors() { const { params } = this; const { maxLength, getValidationErrors } = params; const value = this.getValue(); const translate = this.getLocaleTextFunc(); let internalErrors = []; if (maxLength != null && typeof value === "string" && value.length > maxLength) { internalErrors.push(translate("maxLengthValidation", `Must be ${maxLength} characters or fewer.`, [String(maxLength)])); } if (!internalErrors.length) { internalErrors = null; } if (getValidationErrors) { return getValidationErrors({ value, cellEditorParams: params, internalErrors }); } return internalErrors; } getValue() { const { eEditor, params } = this; const value = eEditor.getValue(); if (!_exists(value) && !_exists(params.value)) { return params.value; } return params.parseValue(value); } getStartValue() { const params = this.params; const formatValue = params.useFormatter || params.column.getColDef().refData; return formatValue ? params.formatValue(params.value) : params.value; } setCaret() { if (_isBrowserSafari()) { this.eEditor.getInputElement().focus({ preventScroll: true }); } const eInput = this.eEditor; const value = eInput.getValue(); const len = _exists(value) && value.length || 0; if (len) { eInput.getInputElement().setSelectionRange(len, len); } } }; var TextCellEditor = class extends SimpleCellEditor { constructor() { super(new TextCellEditorInput(() => this.getLocaleTextFunc())); } }; function getEditRowValues(beans, rowNode) { return beans.editModelSvc?.getEditRowDataValue(rowNode, { checkSiblings: true }); } function getEditingCells(beans) { const edits = beans.editModelSvc?.getEditMap(); const positions = []; edits?.forEach((editRow, rowNode) => { const { rowIndex, rowPinned } = rowNode; editRow.forEach((editValue, column) => { const { editorValue, pendingValue, sourceValue: oldValue, state } = editValue; const diff = _sourceAndPendingDiffer(editValue); let newValue = editorValue ?? pendingValue; if (newValue === UNEDITED) { newValue = undefined; } const edit = { newValue, oldValue, state, column, colId: column.getColId(), colKey: column.getColId(), rowIndex, rowPinned }; const editing = state === "editing"; const changed = !editing && diff; if (editing || changed) { positions.push(edit); } }); }); return positions; } function stopEditing(beans, cancel = false) { const { editSvc } = beans; if (editSvc?.isBatchEditing()) { if (cancel) { for (const cellPosition of beans.editModelSvc?.getEditPositions() ?? []) { if (cellPosition.state === "editing") { editSvc.revertSingleCellEdit(cellPosition); } } } else { _syncFromEditors(beans, { persist: true }); } _destroyEditors(beans, undefined, { cancel }); } else { editSvc?.stopEditing(undefined, { cancel, source: "edit", forceStop: !cancel, forceCancel: cancel }); } } function isEditing(beans, cellPosition) { const cellCtrl = _getCellCtrl(beans, cellPosition); return !!beans.editSvc?.isEditing(cellCtrl); } function startEditingCell(beans, params) { const { key, colKey, rowIndex, rowPinned } = params; const { editSvc, colModel } = beans; const column = colModel.getCol(colKey); if (!column) { _warn(12, { colKey }); return; } const cellPosition = { rowIndex, rowPinned: rowPinned || null, column }; const rowNode = _getRowNode(beans, cellPosition); if (!rowNode) { _warn(290, { rowIndex, rowPinned }); return; } if (!editSvc?.isCellEditable({ rowNode, column }, "api")) { return; } const notPinned = rowPinned == null; if (notPinned) { ensureIndexVisible(beans, rowIndex); } ensureColumnVisible(beans, colKey); editSvc?.startEditing({ rowNode, column }, { event: key ? new KeyboardEvent("keydown", { key }) : undefined, source: "api", editable: true }); } function validateEdit(beans) { return beans.editSvc?.validateEdit() || null; } var PopupEditorElement = { tag: "div", cls: "ag-popup-editor", attrs: { tabindex: "-1" } }; var PopupEditorWrapper = class extends AgPopupComponent { constructor(params) { super(PopupEditorElement); this.params = params; } postConstruct() { _setDomData(this.gos, this.getGui(), "popupEditorWrapper", true); this.addKeyDownListener(); } addKeyDownListener() { const eGui = this.getGui(); const params = this.params; const listener = (event) => { if (!_isUserSuppressingKeyboardEvent(this.gos, event, params.node, params.column, true)) { params.onKeyDown(event); } }; this.addManagedElementListeners(eGui, { keydown: listener }); } }; function shouldStartEditing(beans, { column }, event, cellStartedEdit, source = "ui") { if (event instanceof KeyboardEvent && (event.key === KeyCode.TAB || event.key === KeyCode.ENTER || event.key === KeyCode.F2 || event.key === KeyCode.BACKSPACE && cellStartedEdit)) { return true; } const extendingRange = event?.shiftKey && beans.rangeSvc?.getCellRanges().length != 0; if (extendingRange) { return false; } const colDef = column?.getColDef(); const clickCount = deriveClickCount(beans.gos, colDef); const type = event?.type; if (type === "click" && event?.detail === 1 && clickCount === 1) { return true; } if (type === "dblclick" && event?.detail === 2 && clickCount === 2) { return true; } if (source === "api") { return !!cellStartedEdit; } return false; } function deriveClickCount(gos, colDef) { if (gos.get("suppressClickEdit") === true) { return 0; } if (gos.get("singleClickEdit") === true) { return 1; } if (colDef?.singleClickEdit) { return 1; } return 2; } function existingEditing(beans, editPosition) { return beans.editModelSvc?.hasEdits(editPosition, { withOpenEditor: true }) ?? false; } function isCellEditable(beans, editPosition) { const column = editPosition.column; const rowNode = editPosition.rowNode; const colDef = column.getColDef(); if (!rowNode) { return existingEditing(beans, editPosition); } const editable = colDef.editable; if (rowNode.group && colDef.groupRowEditable != null) { if (beans.rowGroupingEditValueSvc?.isGroupCellEditable(rowNode, column)) { return true; } return existingEditing(beans, editPosition); } if (column.isColumnFunc(rowNode, editable)) { return true; } return existingEditing(beans, editPosition); } function isFullRowCellEditable(beans, position, source = "ui") { const editable = isCellEditable(beans, position); if (editable || source === "ui") { return editable; } const { rowNode, column } = position; for (const col of beans.colModel.getCols()) { if (col !== column && isCellEditable(beans, { rowNode, column: col })) { return true; } } return false; } var editHighlightFn = (edit, includeEditing = false) => { if (edit !== undefined) { return _sourceAndPendingDiffer(edit) || includeEditing && edit.state === "editing"; } }; function _hasEdits(beans, position, includeEditing = false) { return editHighlightFn(beans.editModelSvc?.getEdit(position), includeEditing); } var nodeHasLeafEdit = (children, editModelSvc, column) => { if (!children) { return; } for (let i = 0, len = children.length;i < len; ++i) { const child = children[i]; if (child.data) { const highlight = editHighlightFn(editModelSvc?.getEdit({ rowNode: child, column })) || editHighlightFn(editModelSvc?.getEdit({ rowNode: child.pinnedSibling, column })); if (highlight) { return true; } } if (nodeHasLeafEdit(child.childrenAfterGroup, editModelSvc, column)) { return true; } } }; function _hasLeafEdits(beans, position) { const { column, rowNode } = position; if (beans.gos.get("groupTotalRow") && !rowNode?.footer) { return false; } return nodeHasLeafEdit(rowNode?.childrenAfterGroup, beans.editModelSvc, column); } function _hasPinnedEdits(beans, { rowNode, column }) { rowNode = rowNode.pinnedSibling; if (!rowNode) { return; } return editHighlightFn(beans.editModelSvc?.getEdit({ rowNode, column })); } var CellEditStyleFeature = class extends BeanStub { constructor(cellCtrl, beans) { super(); this.cellCtrl = cellCtrl; this.beans = beans; this.editSvc = beans.editSvc; this.editModelSvc = beans.editModelSvc; } setComp(comp) { this.cellComp = comp; this.applyCellStyles(); } applyCellStyles() { const { cellCtrl, editSvc, beans } = this; if (editSvc?.isBatchEditing() && editSvc.isEditing()) { const state = _hasEdits(beans, cellCtrl) || _hasLeafEdits(beans, cellCtrl) || _hasPinnedEdits(beans, cellCtrl); this.applyBatchingStyle(state); } else { this.applyBatchingStyle(false); } const hasErrors = !!this.editModelSvc?.getCellValidationModel().hasCellValidation(this.cellCtrl); this.cellComp.toggleCss("ag-cell-editing-error", hasErrors); } applyBatchingStyle(newState) { this.cellComp.toggleCss("ag-cell-editing", newState ?? false); this.cellComp.toggleCss("ag-cell-batch-edit", (newState && this.editSvc?.isBatchEditing()) ?? false); } }; var RowEditStyleFeature = class extends BeanStub { constructor(rowCtrl, beans) { super(); this.rowCtrl = rowCtrl; this.beans = beans; this.gos = beans.gos; this.editSvc = beans.editSvc; this.editModelSvc = beans.editModelSvc; } applyRowStyles() { const { rowCtrl, editModelSvc, beans } = this; let rowNode = rowCtrl.rowNode; let edits = editModelSvc?.getEditRow(rowNode); const hasErrors = this.editModelSvc?.getRowValidationModel().hasRowValidation({ rowNode }); if (!edits && rowNode.pinnedSibling) { rowNode = rowNode.pinnedSibling; edits = editModelSvc?.getEditRow(rowNode); } if (edits) { const editing = Array.from(edits.keys()).some((column) => { const position = { rowNode, column }; return _hasEdits(beans, position, true) || _hasLeafEdits(beans, position) || _hasPinnedEdits(beans, position); }); this.applyStyle(hasErrors, editing); return; } this.applyStyle(hasErrors); } applyStyle(hasErrors = false, editing = false) { const batchEdit = !!this.editSvc?.isBatchEditing(); const fullRow = this.gos.get("editType") === "fullRow"; this.rowCtrl?.forEachGui(undefined, ({ rowComp }) => { rowComp.toggleCss("ag-row-editing", fullRow && editing); rowComp.toggleCss("ag-row-batch-edit", fullRow && editing && batchEdit); rowComp.toggleCss("ag-row-inline-editing", editing); rowComp.toggleCss("ag-row-not-inline-editing", !editing); rowComp.toggleCss("ag-row-editing-invalid", fullRow && editing && hasErrors); }); } }; var purgeRows = ({ rowModel, pinnedRowModel, editModelSvc }, rowNodes) => { const found = /* @__PURE__ */ new Set; rowModel.forEachNode((node) => rowNodes.has(node) && found.add(node)); pinnedRowModel?.forEachPinnedRow("top", (node) => rowNodes.has(node) && found.add(node)); pinnedRowModel?.forEachPinnedRow("bottom", (node) => rowNodes.has(node) && found.add(node)); for (const rowNode of rowNodes) { if (!found.has(rowNode)) { editModelSvc.removeEdits({ rowNode }); } } return found; }; var purgeCells = ({ editModelSvc }, rowNodes, columns) => { for (const rowNode of rowNodes) { editModelSvc?.getEditRow(rowNode)?.forEach((_, column) => !columns.has(column) && editModelSvc.removeEdits({ rowNode, column })); } }; var _refreshEditCells = (beans) => () => { const columns = new Set(beans.colModel.getCols()); const updates = beans.editModelSvc.getEditMap(true); const rowNodes = new Set(updates.keys()); purgeCells(beans, purgeRows(beans, rowNodes), columns); }; var KEEP_EDITOR_SOURCES = /* @__PURE__ */ new Set(["undo", "redo", "paste", "bulk", "rangeSvc"]); var INTERNAL_EDITOR_SOURCES = /* @__PURE__ */ new Set(["ui", "api"]); var STOP_EDIT_SOURCE_TRANSFORM = { paste: "api", rangeSvc: "api", fillHandle: "api", cellClear: "api", bulk: "api" }; var STOP_EDIT_SOURCE_TRANSFORM_KEYS = new Set(Object.keys(STOP_EDIT_SOURCE_TRANSFORM)); var SET_DATA_SOURCE_AS_API = /* @__PURE__ */ new Set(["paste", "rangeSvc", "cellClear", "redo", "undo"]); var CANCEL_PARAMS = { cancel: true, source: "api" }; var COMMIT_PARAMS = { cancel: false, source: "api" }; var CHECK_SIBLING = { checkSiblings: true }; var FORCE_REFRESH = { force: true, suppressFlash: true }; var FORCE_REFRESH_FLASH = { force: true }; var EditService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "editSvc"; this.committing = false; this.batch = false; this.batchStartDispatched = false; this.stopping = false; this.rangeSelectionWhileEditing = 0; } postConstruct() { const { beans } = this; this.model = beans.editModelSvc; this.valueSvc = beans.valueSvc; this.rangeSvc = beans.rangeSvc; this.addManagedPropertyListener("editType", ({ currentValue }) => { this.stopEditing(undefined, CANCEL_PARAMS); this.createStrategy(currentValue); }); const handler = _refreshEditCells(beans); const stopInvalidEdits = () => { const hasCellValidation = this.model.getCellValidationModel().getCellValidationMap().size > 0; const hasRowValidation = this.model.getRowValidationModel().getRowValidationMap().size > 0; if (hasCellValidation || hasRowValidation) { this.stopEditing(undefined, CANCEL_PARAMS); } else if (this.isEditing()) { if (this.batch) { _destroyEditors(beans, this.model.getEditPositions()); } else { this.stopEditing(undefined, COMMIT_PARAMS); } } return false; }; this.addManagedEventListeners({ columnPinned: handler, columnVisible: handler, columnRowGroupChanged: handler, rowExpansionStateChanged: handler, pinnedRowsChanged: handler, displayedRowsChanged: handler, sortChanged: stopInvalidEdits, filterChanged: stopInvalidEdits, cellFocused: this.onCellFocused.bind(this) }); } isBatchEditing() { return this.batch; } startBatchEditing() { if (this.batch) { return; } this.batch = true; this.batchStartDispatched = false; this.stopEditing(undefined, CANCEL_PARAMS); } stopBatchEditing(params) { if (!this.batch) { return; } if (params) { this.stopEditing(undefined, params); } if (this.batchStartDispatched) { this.dispatchBatchStopped(/* @__PURE__ */ new Map, false); } this.batch = false; this.batchStartDispatched = false; } ensureBatchStarted() { if (!this.batch || this.batchStartDispatched) { return; } this.batchStartDispatched = true; this.dispatchBatchEvent("batchEditingStarted", /* @__PURE__ */ new Map); } createStrategy(editType) { const { beans, gos, strategy } = this; const name = getEditType(gos, editType); if (strategy) { if (strategy.beanName === name) { return strategy; } this.destroyStrategy(); } return this.strategy = this.createOptionalManagedBean(beans.registry.createDynamicBean(name, true)); } destroyStrategy() { if (!this.strategy) { return; } this.strategy.destroy(); this.strategy = this.destroyBean(this.strategy); } shouldStartEditing(position, event, cellStartedEdit, source = "ui") { const shouldStart = shouldStartEditing(this.beans, position, event, cellStartedEdit, source); if (shouldStart) { this.strategy ?? (this.strategy = this.createStrategy()); } return shouldStart; } shouldStopEditing(position, event, source = "ui") { return this.strategy?.shouldStop(position, event, source) ?? null; } shouldCancelEditing(position, event, source = "ui") { return this.strategy?.shouldCancel(position, event, source) ?? null; } validateEdit() { return _validateEdit(this.beans); } isEditing(position, params) { return this.model.hasEdits(position ?? undefined, params ?? CHECK_SIBLING); } isRowEditing(rowNode, params) { return !!rowNode && this.model.hasRowEdits(rowNode, params); } enableRangeSelectionWhileEditing() { if (this.beans.rangeSvc && this.gos.get("cellSelection")) { this.rangeSelectionWhileEditing++; } } disableRangeSelectionWhileEditing() { this.rangeSelectionWhileEditing = Math.max(0, this.rangeSelectionWhileEditing - 1); } isRangeSelectionEnabledWhileEditing() { return this.rangeSelectionWhileEditing > 0; } startEditing(position, params) { const { startedEdit = true, event = null, source = "ui", ignoreEventKey = false, silent } = params; this.strategy ?? (this.strategy = this.createStrategy()); const editable = params.editable ?? this.isCellEditable(position, "api"); if (!editable) { return; } const cellCtrl = _getCellCtrl(this.beans, position); if (cellCtrl && !cellCtrl.comp) { params.editable = undefined; cellCtrl.onCompAttachedFuncs.push(() => this.startEditing(position, params)); return; } const res = this.shouldStartEditing(position, event, startedEdit, source); if (res === false && source !== "api") { if (this.isEditing(position)) { this.stopEditing(); } return; } if (!this.batch && this.shouldStopEditing(position, undefined, source) && !params.continueEditing) { this.stopEditing(undefined, { source }); } if (res) { this.ensureBatchStarted(); } this.strategy.start({ position, event, source, ignoreEventKey, startedEdit, silent }); } stopEditing(position, params) { const context = this.prepareStopContext(position, params); if (!context) { return false; } this.stopping = true; let res = false; let { edits } = context; try { const outcome = this.processStopRequest(context); res || (res = outcome.res); edits = outcome.edits; this.finishStopEditing({ ...context, edits, params, position, res }); return res; } finally { this.rangeSelectionWhileEditing = 0; this.stopping = false; } } prepareStopContext(position, params) { const { event = null, cancel = false, source = "ui", forceCancel = false, forceStop = false, commit = false } = params || {}; if (STOP_EDIT_SOURCE_TRANSFORM_KEYS.has(source) && this.batch) { if (position?.rowNode && position?.column) { this.bulkRefreshCell(position); } return null; } const treatAsSource = this.committing ? STOP_EDIT_SOURCE_TRANSFORM[source] : source; const isEditingOrBatchWithEdits = this.committing || this.isEditing(position) || this.batch && this.model.hasEdits(position, CHECK_SIBLING); if (!isEditingOrBatchWithEdits || !this.strategy || this.stopping) { return null; } const cellCtrl = _getCellCtrl(this.beans, position); if (cellCtrl) { cellCtrl.onEditorAttachedFuncs = []; } const willStop = !cancel && (!!this.shouldStopEditing(position, event, treatAsSource) || (this.committing || source === "paste") && !this.batch) || forceStop; const willCancel = cancel && !!this.shouldCancelEditing(position, event, treatAsSource) || forceCancel; return { cancel, cellCtrl, edits: this.model.getEditMap(true), event: event ?? null, forceCancel, forceStop, commit, position, source, treatAsSource, willCancel, willStop }; } processStopRequest(context) { const { event, position, willCancel, willStop } = context; if (willStop || willCancel) { return this.handleStopOrCancel(context); } if (this.shouldHandleMidBatchKey(event, position)) { return { res: false, edits: this.handleMidBatchKey(event, position, context) }; } _syncFromEditors(this.beans, { persist: true }); if (this.batch) { this.strategy?.cleanupEditors(position); } return { res: false, edits: this.model.getEditMap() }; } handleStopOrCancel(context) { const { beans, model } = this; const { cancel, commit, edits, event, source, willCancel, willStop } = context; const persist = !this.batch || !willCancel; _syncFromEditors(beans, { persist, isCancelling: willCancel || cancel, isStopping: willStop }); const freshEdits = model.getEditMap(); const shouldCommit = !willCancel && (!this.batch || commit); const editsToDelete = shouldCommit ? this.processEdits(freshEdits, source) : []; if (cancel) { this.strategy?.stopCancelled(context.forceCancel); } else { this.strategy?.stopCommitted(event, commit); } this.clearValidationIfNoOpenEditors(); for (const position of editsToDelete) { model.clearEditValue(position); } this.bulkRefreshMap(edits); for (const pos of model.getEditPositions(freshEdits)) { const cellCtrl = _getCellCtrl(beans, pos); const valueChanged = _sourceAndPendingDiffer(pos); cellCtrl?.refreshCell({ force: true, suppressFlash: !valueChanged }); } return { res: willStop, edits: freshEdits }; } shouldHandleMidBatchKey(event, position) { return event instanceof KeyboardEvent && this.batch && !!this.strategy?.midBatchInputsAllowed(position) && this.isEditing(position, { withOpenEditor: true }); } handleMidBatchKey(event, position, context) { const { beans, model } = this; const { cellCtrl, edits } = context; const { key } = event; const isEnter = key === KeyCode.ENTER; const isEscape = key === KeyCode.ESCAPE; const isTab = key === KeyCode.TAB; if (isEnter || isTab || isEscape) { if (isEnter || isTab) { _syncFromEditors(beans, { persist: true }); } else if (isEscape && cellCtrl) { const { rowNode, column } = cellCtrl; if (this.batch && rowNode && column) { const pos = { rowNode, column }; _destroyEditors(beans, [pos], { silent: true }); this.model.stop(pos, true, true); _getCellCtrl(beans, pos)?.refreshCell(FORCE_REFRESH); } else { this.revertSingleCellEdit(cellCtrl); } } if (this.batch) { this.strategy?.cleanupEditors(); } else { _destroyEditors(beans, model.getEditPositions(), { event, cancel: isEscape }); } event.preventDefault(); this.bulkRefreshMap(edits, { suppressFlash: true }); return model.getEditMap(); } return edits; } finishStopEditing({ cellCtrl, edits, params, position, res, commit, forceCancel, willCancel, willStop }) { const beans = this.beans; if (res && position) { if (!this.batch || commit) { this.model.removeEdits(position); } } this.navigateAfterEdit(params, cellCtrl?.cellPosition); _purgeUnchangedEdits(beans); this.clearValidationIfNoOpenEditors(); const { rowRenderer, formula } = beans; if (willCancel) { rowRenderer.refreshRows({ rowNodes: Array.from(edits.keys()) }); } if (this.batch) { if (formula) { formula.refreshFormulas(true); } else { rowRenderer.refreshRows({ suppressFlash: true, force: true }); } const batchCommit = willStop && commit; const batchCancel = willCancel && forceCancel; if (batchCommit || batchCancel) { this.dispatchBatchStopped(edits, batchCommit); } } } dispatchBatchStopped(edits, commit) { let eventEdits; if (commit) { eventEdits = _filterChangedEdits(edits); if (eventEdits.size > 0) { this.ensureBatchStarted(); } } if (this.batchStartDispatched) { this.batchStartDispatched = false; this.dispatchBatchEvent("batchEditingStopped", eventEdits ?? /* @__PURE__ */ new Map); } } clearValidationIfNoOpenEditors() { const hasOpenEditors = this.model.hasEdits(undefined, { withOpenEditor: true }); if (!hasOpenEditors) { this.model.getCellValidationModel().clearCellValidationMap(); this.model.getRowValidationModel().clearRowValidationMap(); } } navigateAfterEdit(params, cellPosition) { if (!params || !cellPosition) { return; } const { event, suppressNavigateAfterEdit } = params; const isKeyBoardEvent = event instanceof KeyboardEvent; if (!isKeyBoardEvent || suppressNavigateAfterEdit) { return; } const { key, shiftKey } = event; const navAfterEdit = this.gos.get("enterNavigatesVerticallyAfterEdit"); if (key !== KeyCode.ENTER || !navAfterEdit) { return; } const direction = shiftKey ? KeyCode.UP : KeyCode.DOWN; this.beans.navigation?.navigateToNextCell(null, direction, cellPosition, false); } processEdits(edits, source) { const rowNodes = Array.from(edits.keys()); const hasValidationErrors = this.model.getCellValidationModel().getCellValidationMap().size > 0 || this.model.getRowValidationModel().getRowValidationMap().size > 0; const editsToDelete = []; const { changeDetectionSvc } = this.beans; changeDetectionSvc?.beginDeferred(); try { for (const rowNode of rowNodes) { const editRow = edits.get(rowNode); for (const column of editRow.keys()) { const editValue = editRow.get(column); const position = { rowNode, column }; if (_sourceAndPendingDiffer(editValue) && !hasValidationErrors) { const cellCtrl = _getCellCtrl(this.beans, position); const success = this.setNodeDataValue(rowNode, column, editValue.pendingValue, cellCtrl, source); if (!success) { editsToDelete.push(position); } } } } } finally { changeDetectionSvc?.endDeferred(); } return editsToDelete; } setNodeDataValue(rowNode, column, newValue, cellCtrl, originalSource = "edit") { const translatedSource = INTERNAL_EDITOR_SOURCES.has(originalSource) ? "edit" : originalSource; if (cellCtrl) { cellCtrl.suppressRefreshCell = true; } this.committing = true; try { return rowNode.setDataValue(column, newValue, translatedSource); } finally { this.committing = false; if (cellCtrl) { cellCtrl.suppressRefreshCell = false; } } } syncEditAfterCommit(position, success) { const edit = this.model.getEdit(position); if (edit && edit.state !== "editing") { if (success) { this.beans.editModelSvc?.setEdit(position, { sourceValue: edit.pendingValue }); } else { this.model.clearEditValue(position); } } } setEditMap(edits, params) { this.strategy ?? (this.strategy = this.createStrategy()); this.strategy?.setEditMap(edits, params); this.bulkRefreshMap(edits); let refreshParams = FORCE_REFRESH; if (params?.forceRefreshOfEditCellsOnly) { refreshParams = { ...getRowColumnsFromMap(edits), ...FORCE_REFRESH }; } this.beans.rowRenderer.refreshCells(refreshParams); } dispatchEditValuesChanged({ rowNode, column }, edit = {}) { if (!rowNode || !column || !edit) { return; } const { pendingValue, sourceValue } = edit; const { rowIndex, rowPinned, data } = rowNode; this.beans.eventSvc.dispatchEvent({ type: "cellEditValuesChanged", node: rowNode, rowIndex, rowPinned, column, source: "api", data, newValue: pendingValue, oldValue: sourceValue, value: pendingValue, colDef: column.getColDef() }); } bulkRefreshCell(position, params) { if (_isClientSideRowModel(this.gos, this.beans.rowModel)) { this.refCell(position, this.model.getEdit(position), params); } } bulkRefreshMap(editMap, params) { if (_isClientSideRowModel(this.gos, this.beans.rowModel)) { editMap.forEach((editRow, rowNode) => { for (const column of editRow.keys()) { this.refCell({ rowNode, column }, editRow.get(column), params); } }); } } refCell({ rowNode, column }, edit, params = {}) { const { beans, gos } = this; const updatedNodes = /* @__PURE__ */ new Set([rowNode]); const refreshNodes = /* @__PURE__ */ new Set; const pinnedSibling = rowNode.pinnedSibling; if (pinnedSibling) { updatedNodes.add(pinnedSibling); } const sibling = rowNode.sibling; if (sibling) { refreshNodes.add(sibling); } let parent = rowNode.parent; while (parent) { if (parent.sibling?.footer && gos.get("groupTotalRow")) { refreshNodes.add(parent.sibling); } else if (!parent.parent && parent.sibling && gos.get("grandTotalRow")) { refreshNodes.add(parent.sibling); } else { refreshNodes.add(parent); } parent = parent.parent; } for (const node of updatedNodes) { this.dispatchEditValuesChanged({ rowNode: node, column }, edit); } for (const node of updatedNodes) { _getCellCtrl(beans, { rowNode: node, column })?.refreshCell(params); } for (const node of refreshNodes) { const cellCtrl = _getCellCtrl(beans, { rowNode: node, column }); if (cellCtrl) { cellCtrl.refreshCell(params); if (!params.force && this.batch) { cellCtrl.editStyleFeature?.applyCellStyles?.(); } } } } stopAllEditing(cancel = false, source = "ui") { if (this.isEditing()) { this.stopEditing(undefined, { cancel, source }); } } isCellEditable(position, source = "ui") { const { gos, beans } = this; const rowNode = position.rowNode; if (rowNode.group && position.column.getColDef().groupRowEditable == null) { if (gos.get("treeData")) { if (!rowNode.data && !gos.get("enableGroupEdit")) { return false; } } else if (!gos.get("enableGroupEdit")) { return false; } } const isEditable = getEditType(gos) === "fullRow" ? isFullRowCellEditable(beans, position, source) : isCellEditable(beans, position); if (isEditable) { this.strategy ?? (this.strategy = this.createStrategy()); } return isEditable; } cellEditingInvalidCommitBlocks() { return this.gos.get("invalidEditValueMode") === "block"; } checkNavWithValidation(position, event, focus = true) { if (this.hasValidationErrors(position)) { const cellCtrl = _getCellCtrl(this.beans, position); if (this.cellEditingInvalidCommitBlocks()) { event?.preventDefault?.(); if (focus) { if (cellCtrl && !cellCtrl.hasBrowserFocus()) { cellCtrl.focusCell(); } cellCtrl?.comp?.getCellEditor()?.focusIn?.(); } return "block-stop"; } if (cellCtrl) { this.revertSingleCellEdit(cellCtrl); } return "revert-continue"; } return "continue"; } revertSingleCellEdit(cellPosition, focus = false) { const cellCtrl = _getCellCtrl(this.beans, cellPosition); if (!cellCtrl?.comp?.getCellEditor()) { return; } _destroyEditors(this.beans, [cellPosition], { silent: true }); this.model.clearEditValue(cellPosition); _setupEditor(this.beans, cellPosition, { silent: true }); _populateModelValidationErrors(this.beans); cellCtrl?.refreshCell(FORCE_REFRESH); if (!focus) { return; } cellCtrl?.focusCell(); cellCtrl?.comp?.getCellEditor()?.focusIn?.(); } hasValidationErrors(position) { _populateModelValidationErrors(this.beans); const cellCtrl = _getCellCtrl(this.beans, position); if (cellCtrl) { cellCtrl.refreshCell(FORCE_REFRESH); cellCtrl.rowCtrl.rowEditStyleFeature?.applyRowStyles(); } let invalid = false; if (position?.rowNode) { invalid || (invalid = this.model.getRowValidationModel().hasRowValidation({ rowNode: position.rowNode })); if (position.column) { invalid || (invalid = this.model.getCellValidationModel().hasCellValidation({ rowNode: position.rowNode, column: position.column })); } } else { invalid || (invalid = this.model.getCellValidationModel().getCellValidationMap().size > 0); invalid || (invalid = this.model.getRowValidationModel().getRowValidationMap().size > 0); } return invalid; } moveToNextCell(prev, backwards, event, source = "ui") { let res; const editing = this.isEditing(); const preventNavigation = editing && this.checkNavWithValidation(undefined, event) === "block-stop"; if (prev instanceof CellCtrl && editing) { res = this.strategy?.moveToNextEditingCell(prev, backwards, event, source, preventNavigation); } if (res === null) { return res; } res = res || !!this.beans.focusSvc.focusedHeader; if (res === false && !preventNavigation) { this.stopEditing(); } return res; } getPendingEditValue(rowNode, column, from) { if (from === "data") { return; } if (from === "batch" && !this.batch) { return; } const edit = this.model.getEdit({ rowNode, column }, CHECK_SIBLING); if (!edit) { return; } if (this.stopping && !this.batch && !edit.editorState?.cellStartedEditing) { return; } if (from === "edit") { const editorValue = edit.editorValue; if (editorValue != null && editorValue !== UNEDITED) { return editorValue; } } const pendingValue = edit.pendingValue; if (pendingValue !== UNEDITED) { return pendingValue; } return; } getCellDataValue(position) { const edit = this.model.getEdit(position, CHECK_SIBLING); if (edit) { const newValue = edit.pendingValue; if (newValue !== UNEDITED) { return newValue; } const sourceValue = edit.sourceValue; if (sourceValue != null) { return sourceValue; } } return this.valueSvc.getValue(position.column, position.rowNode, "data"); } addStopEditingWhenGridLosesFocus(viewports) { _addStopEditingWhenGridLosesFocus(this, this.beans, viewports); } createPopupEditorWrapper(params) { return new PopupEditorWrapper(params); } batchResetToSourceValue(position) { if (!this.batch) { return false; } const existing = this.model.getEdit(position); if (!existing) { return false; } const { pendingValue, sourceValue, state } = existing; if (pendingValue === sourceValue) { return false; } if (state === "editing") { return false; } this.dispatchEditValuesChanged(position, { ...existing, pendingValue: sourceValue }); this.beans.editModelSvc?.removeEdits(position); _getCellCtrl(this.beans, position)?.refreshCell(FORCE_REFRESH); return true; } setDataValue(position, newValue, eventSource) { try { const batch = this.batch; const editing = this.isEditing(batch ? undefined : position); if ((!editing || this.committing) && !batch && !SET_DATA_SOURCE_AS_API.has(eventSource)) { return; } if (!editing && !batch && eventSource === "paste") { return; } if (eventSource === "batch" && !batch) { return; } if (eventSource === "edit") { if (editing && this.applyEditorValue(position, newValue)) { return true; } if (!batch) { return; } } this.strategy ?? (this.strategy = this.createStrategy()); if (eventSource === "batch" || eventSource === "edit") { return this.applyDirectValue(position, newValue, eventSource); } const beans = this.beans; let source; if (batch) { source = "ui"; } else if (this.committing) { source = eventSource ?? "api"; } else { source = "api"; } if (!eventSource || KEEP_EDITOR_SOURCES.has(eventSource)) { return this.applyDirectValue(position, newValue, eventSource); } const result = this.applyExistingEdit(position, newValue, eventSource, source); if (result !== undefined) { return result; } _syncFromEditor(beans, position, newValue, eventSource, undefined, { persist: true }); this.ensureBatchStarted(); this.stopEditing(position, { source, suppressNavigateAfterEdit: true }); return true; } finally { this.committing = false; } } applyExistingEdit(position, newValue, eventSource, source) { const existing = this.model.getEdit(position); if (!existing) { return; } if (existing.pendingValue === newValue) { return false; } if (existing.sourceValue !== newValue) { _syncFromEditor(this.beans, position, newValue, eventSource, undefined, { persist: true }); this.ensureBatchStarted(); this.stopEditing(position, { source, suppressNavigateAfterEdit: true }); return true; } this.beans.editModelSvc?.removeEdits(position); this.ensureBatchStarted(); this.dispatchEditValuesChanged(position, { ...existing, pendingValue: newValue }); return true; } applyEditorValue(position, newValue) { const beans = this.beans; const cellCtrl = _getCellCtrl(beans, position); const editor = cellCtrl?.comp?.getCellEditor(); if (!cellCtrl || !editor) { return false; } _syncFromEditor(beans, position, newValue, "edit", undefined, { persist: true }); cellCtrl.editStyleFeature?.applyCellStyles?.(); if ("agSetEditValue" in editor) { editor.agSetEditValue(newValue); return true; } if (editor.refresh && cellCtrl.editCompDetails) { editor.refresh({ ...cellCtrl.editCompDetails.params, value: newValue }); return true; } const restoreFocus = cellCtrl.hasBrowserFocus(); if (restoreFocus) { cellCtrl.onEditorAttachedFuncs.push(() => { const latestCellCtrl = _getCellCtrl(this.beans, position); latestCellCtrl?.focusCell(true); latestCellCtrl?.comp?.getCellEditor()?.focusIn?.(); }); } _destroyEditors(beans, [position], { silent: true, cancel: true }); _setupEditor(beans, position, { silent: true }); _populateModelValidationErrors(beans); _getCellCtrl(beans, position)?.refreshCell(FORCE_REFRESH); return true; } applyDirectValue(position, newValue, eventSource) { const beans = this.beans; if (this.batch) { if (eventSource === "batch" && _getCellCtrl(beans, position)?.comp?.getCellEditor()) { const { editModelSvc, valueSvc } = beans; const { rowNode, column } = position; const existingEdit = editModelSvc?.getEdit(position); if (existingEdit?.sourceValue === undefined) { editModelSvc?.setEdit(position, { sourceValue: valueSvc.getValue(column, rowNode, "data") }); } editModelSvc?.setEdit(position, { pendingValue: newValue }); } else { _syncFromEditor(beans, position, newValue, eventSource, undefined, { persist: true }); if (eventSource !== "batch") { this.cleanupEditors(); } } _purgeUnchangedEdits(beans); this.ensureBatchStarted(); this.bulkRefreshCell(position); return true; } _syncFromEditor(beans, position, newValue, eventSource, undefined, { persist: true }); const cellCtrl = _getCellCtrl(beans, position); const success = this.setNodeDataValue(position.rowNode, position.column, newValue, cellCtrl, eventSource); this.syncEditAfterCommit(position, success); _purgeUnchangedEdits(beans); _getCellCtrl(beans, position)?.refreshCell(success ? FORCE_REFRESH_FLASH : FORCE_REFRESH); return success; } handleColDefChanged(cellCtrl) { _refreshEditorOnColDefChanged(this.beans, cellCtrl); } destroy() { this.model.clear(); this.destroyStrategy(); super.destroy(); } prepDetailsDuringBatch(position, params) { const { model } = this; if (!this.batch) { return; } const hasEdits = model.hasRowEdits(position.rowNode, CHECK_SIBLING); if (!hasEdits) { return; } const { rowNode } = position; const { compDetails, valueToDisplay } = params; if (compDetails) { const { params: params2 } = compDetails; params2.data = model.getEditRowDataValue(rowNode, CHECK_SIBLING); return { compDetails }; } return { valueToDisplay }; } cleanupEditors() { this.strategy?.cleanupEditors(); } dispatchCellEvent(position, event, type, payload) { this.strategy?.dispatchCellEvent(position, event, type, payload); } dispatchBatchEvent(type, edits) { this.eventSvc.dispatchEvent(this.createBatchEditEvent(type, edits)); } createBatchEditEvent(type, edits) { return _addGridCommonParams(this.gos, { type, ...type === "batchEditingStopped" ? { changes: this.toEventChangeList(edits) } : {} }); } toEventChangeList(edits) { return this.model.getEditPositions(edits).map((edit) => ({ rowIndex: edit.rowNode.rowIndex, rowPinned: edit.rowNode.rowPinned, columnId: edit.column.getColId(), newValue: edit.pendingValue, oldValue: edit.sourceValue })); } applyBulkEdit({ rowNode, column }, ranges) { if (!ranges || ranges.length === 0) { return; } const { beans, rangeSvc, valueSvc } = this; const { formula } = beans; _syncFromEditors(beans, { persist: true }); const edits = this.model.getEditMap(true); let editValue = edits.get(rowNode)?.get(column)?.pendingValue; let bulkStartDispatched = false; if (!this.batch) { this.eventSvc.dispatchEvent({ type: "bulkEditingStarted" }); bulkStartDispatched = true; } const isFormula = formula?.isFormula(editValue) ?? false; ranges.forEach((range) => { const hasFormulaColumnsInRange = range.columns.some((col) => col?.isAllowFormula()); rangeSvc?.forEachRowInRange(range, (position) => { const rowNode2 = _getRowNode(beans, position); if (rowNode2 === undefined) { return; } const editRow = edits.get(rowNode2) ?? /* @__PURE__ */ new Map; let valueForColumn = editValue; for (const column2 of range.columns) { if (!column2) { continue; } const isFormulaForColumn = !!isFormula && column2.isAllowFormula(); if (this.isCellEditable({ rowNode: rowNode2, column: column2 }, "api")) { const sourceValue = valueSvc.getValue(column2, rowNode2, "data", true); let pendingValue = valueSvc.parseValue(column2, rowNode2 ?? null, valueForColumn, sourceValue); if (Number.isNaN(pendingValue)) { pendingValue = null; } editRow.set(column2, { editorValue: undefined, pendingValue, sourceValue, state: "changed", editorState: { isCancelAfterEnd: undefined, isCancelBeforeStart: undefined } }); } if (isFormulaForColumn) { valueForColumn = formula?.updateFormulaByOffset({ value: valueForColumn, columnDelta: 1 }); } } if (editRow.size > 0) { edits.set(rowNode2, editRow); } if (isFormula && hasFormulaColumnsInRange) { editValue = formula?.updateFormulaByOffset({ value: editValue, rowDelta: 1 }); } }); this.setEditMap(edits); if (this.batch) { this.cleanupEditors(); _purgeUnchangedEdits(beans); this.ensureBatchStarted(); return; } this.committing = true; try { this.stopEditing(undefined, { source: "bulk" }); } finally { this.committing = false; if (bulkStartDispatched) { this.eventSvc.dispatchEvent({ type: "bulkEditingStopped", changes: this.toEventChangeList(edits) }); } } }); const cellCtrl = _getCellCtrl(beans, { rowNode, column }); if (cellCtrl) { cellCtrl.focusCell(true); } } createCellStyleFeature(cellCtrl) { return new CellEditStyleFeature(cellCtrl, this.beans); } createRowStyleFeature(rowCtrl) { return new RowEditStyleFeature(rowCtrl, this.beans); } setEditingCells(cells, params) { const { beans } = this; const { colModel, valueSvc } = beans; const edits = /* @__PURE__ */ new Map; for (let { colId, column, colKey, rowIndex, rowPinned, newValue: pendingValue, state } of cells) { const col = colId ? colModel.getCol(colId) : colKey ? colModel.getCol(colKey) : column; if (!col) { continue; } const rowNode = _getRowNode(beans, { rowIndex, rowPinned }); if (!rowNode) { continue; } const sourceValue = valueSvc.getValue(col, rowNode, "data", true); if (!params?.forceRefreshOfEditCellsOnly && !_sourceAndPendingDiffer({ pendingValue, sourceValue }) && state !== "editing") { continue; } let editRow = edits.get(rowNode); if (!editRow) { editRow = /* @__PURE__ */ new Map; edits.set(rowNode, editRow); } if (pendingValue === undefined) { pendingValue = UNEDITED; } editRow.set(col, { editorValue: undefined, pendingValue, sourceValue, state: state ?? "changed", editorState: { isCancelAfterEnd: undefined, isCancelBeforeStart: undefined } }); } this.setEditMap(edits, params); } onCellFocused(event) { const cellCtrl = _getCellCtrl(this.beans, event); if (!cellCtrl || !this.isEditing(cellCtrl, CHECK_SIBLING)) { return; } const edit = this.model.getEdit(cellCtrl); if (!edit || !_sourceAndPendingDiffer(edit)) { return; } const translate = this.getLocaleTextFunc(); const label = translate("ariaPendingChange", "Pending Change"); this.beans.ariaAnnounce?.announceValue(label, "pendingChange"); } allowedFocusTargetOnValidation(cellPosition) { return _getCellCtrl(this.beans, cellPosition); } }; function getRowColumnsFromMap(edits) { return { rowNodes: edits ? Array.from(edits.keys()) : undefined, columns: edits ? [...new Set(Array.from(edits.values()).flatMap((er) => Array.from(er.keys())))] : undefined }; } function getEditType(gos, editType) { return editType ?? gos.get("editType") ?? "singleCell"; } var BaseEditStrategy = class extends BeanStub { postConstruct() { this.model = this.beans.editModelSvc; this.editSvc = this.beans.editSvc; this.addManagedEventListeners({ cellFocused: this.onCellFocusChanged?.bind(this), cellFocusCleared: this.onCellFocusChanged?.bind(this) }); } clearEdits(position) { this.model.clearEditValue(position); } onCellFocusChanged(event) { let cellCtrl; const previous = event["previousParams"]; const { editSvc, beans } = this; const sourceEvent = event.type === "cellFocused" ? event.sourceEvent : null; if (previous) { cellCtrl = _getCellCtrl(beans, previous); } const { gos, editModelSvc } = beans; const isFocusCleared = event.type === "cellFocusCleared"; if (editSvc.isEditing(undefined, { withOpenEditor: true })) { const { column, rowIndex, rowPinned } = event; const cellPositionFromEvent = { column, rowNode: _getRowNode(beans, { rowIndex, rowPinned }) }; const isBlock = gos.get("invalidEditValueMode") === "block"; if (isBlock) { return; } const shouldRevert = !isBlock; const hasError = !!editModelSvc?.getCellValidationModel().hasCellValidation(cellPositionFromEvent); const shouldCancel = shouldRevert && hasError; const result = previous || isFocusCleared ? editSvc.stopEditing(undefined, { cancel: shouldCancel, source: isFocusCleared && shouldRevert ? "api" : undefined, event: sourceEvent }) : true; if (!result) { if (editSvc.isBatchEditing()) { editSvc.cleanupEditors(); } else { editSvc.stopEditing(undefined, { source: "api" }); } } } cellCtrl?.refreshCell({ suppressFlash: true, force: true }); } stopCancelled(forceCancel) { const preserveBatch = this.editSvc.isBatchEditing() && !forceCancel; for (const cell of this.model.getEditPositions()) { _destroyEditor(this.beans, cell, { cancel: true }, _getCellCtrl(this.beans, cell)); this.model.stop(cell, preserveBatch, true); } return true; } stopCommitted(event, commit) { const editingCells = this.model.getEditPositions(); const results = { all: [], pass: [], fail: [] }; for (const cell of editingCells) { results.all.push(cell); if ((this.model.getCellValidationModel().getCellValidation(cell)?.errorMessages?.length ?? 0) > 0) { results.fail.push(cell); } else { results.pass.push(cell); } } const actions = this.processValidationResults(results); const preserveBatch = this.editSvc.isBatchEditing() && !commit; for (const cell of actions.destroy) { _destroyEditor(this.beans, cell, { event }, _getCellCtrl(this.beans, cell)); this.model.stop(cell, preserveBatch, false); } for (const cell of actions.keep) { const cellCtrl = _getCellCtrl(this.beans, cell); if (!this.editSvc.cellEditingInvalidCommitBlocks() && cellCtrl) { this.editSvc.revertSingleCellEdit(cellCtrl); } } return true; } cleanupEditors({ rowNode } = {}, includeEditing) { _syncFromEditors(this.beans, { persist: false }); const positions = this.model.getEditPositions(); const discard = []; if (rowNode) { for (const pos of positions) { if (pos.rowNode !== rowNode) { discard.push(pos); } } } else { for (const pos of positions) { discard.push(pos); } } _destroyEditors(this.beans, discard); _purgeUnchangedEdits(this.beans, includeEditing); } setFocusOutOnEditor(cellCtrl) { cellCtrl.comp?.getCellEditor()?.focusOut?.(); } setFocusInOnEditor(cellCtrl) { const comp = cellCtrl.comp; const editor = comp?.getCellEditor(); if (editor?.focusIn) { editor.focusIn(); } else { const isFullRow = this.beans.gos.get("editType") === "fullRow"; cellCtrl.focusCell(isFullRow); cellCtrl.onEditorAttachedFuncs.push(() => comp?.getCellEditor()?.focusIn?.()); } } setupEditors(params) { const { event, ignoreEventKey = false, startedEdit, position, cells = this.model.getEditPositions() } = params; const key = event instanceof KeyboardEvent && !ignoreEventKey && event.key || undefined; _setupEditors(this.beans, cells, position, key, event, startedEdit); } dispatchCellEvent(position, event, type, payload) { const cellCtrl = _getCellCtrl(this.beans, position); if (cellCtrl) { this.eventSvc.dispatchEvent({ ...cellCtrl.createEvent(event ?? null, type), ...payload }); } } dispatchRowEvent(position, type, silent) { if (silent) { return; } const rowCtrl = _getRowCtrl(this.beans, position); if (rowCtrl) { this.eventSvc.dispatchEvent(rowCtrl.createRowEvent(type)); } } shouldStop(_position, event, source = "ui") { const batch = this.editSvc.isBatchEditing(); if (batch && source === "api") { return true; } if (batch && (source === "ui" || source === "edit")) { return false; } if (source === "api") { return true; } if (event instanceof KeyboardEvent && !batch) { return event.key === KeyCode.ENTER; } return null; } shouldCancel(_position, event, source = "ui") { const batch = this.editSvc.isBatchEditing(); if (event instanceof KeyboardEvent && !batch) { const result = event.key === KeyCode.ESCAPE; if (result) { return true; } } if (batch && source === "api") { return true; } if (source === "api") { return true; } return false; } setEditMap(edits, params) { if (!params?.update) { this.editSvc.stopEditing(undefined, { cancel: true, source: "api" }); } const cells = []; edits.forEach((editRow, rowNode) => { editRow.forEach((cellData, column) => { if (cellData.state === "editing") { cells.push({ ...cellData, rowNode, column }); } }); }); if (params?.update) { edits = new Map([...this.model.getEditMap(), ...edits]); } this.model?.setEditMap(edits); if (cells.length > 0) { const position = cells.at(-1); const key = position.pendingValue === UNEDITED ? undefined : position.pendingValue; this.start({ position, event: new KeyboardEvent("keydown", { key }), source: "api" }); const cellCtrl = _getCellCtrl(this.beans, position); if (cellCtrl) { this.setFocusInOnEditor(cellCtrl); } } } destroy() { this.cleanupEditors(); super.destroy(); } }; var FullRowEditStrategy = class extends BaseEditStrategy { constructor() { super(...arguments); this.beanName = "fullRow"; this.startedRows = /* @__PURE__ */ new Set; } shouldStop(position, event, _source = "ui") { const { rowNode: currentRowNode, beans } = this; const { rowNode } = position || {}; const oldRowCtrl = _getRowCtrl(beans, { rowNode: currentRowNode }); if (!oldRowCtrl) { return true; } const res = super.shouldStop({ rowNode: currentRowNode }, event, _source); if (res !== null) { return res; } if (!currentRowNode) { return false; } return rowNode !== currentRowNode; } midBatchInputsAllowed({ rowNode }) { if (!rowNode) { return false; } return this.model.hasEdits({ rowNode }); } clearEdits(position) { this.model.clearEditValue(position); } start(params) { const { position, silent, startedEdit, event, ignoreEventKey } = params; const { rowNode } = position; const { beans, model, startedRows } = this; if (this.rowNode !== rowNode) { super.cleanupEditors(position); } const columns = beans.visibleCols.allCols; const cells = []; const editableColumns = []; for (const column of columns) { if (column.isCellEditable(rowNode)) { editableColumns.push(column); } } if (editableColumns.length == 0) { return; } if (!startedRows.has(rowNode)) { this.dispatchRowEvent({ rowNode }, "rowEditingStarted", silent); startedRows.add(rowNode); } for (const column of editableColumns) { const position2 = { rowNode, column }; cells.push(position2); model.start(position2); } this.rowNode = rowNode; this.setupEditors({ cells, position, startedEdit, event, ignoreEventKey }); } processValidationResults(results) { const anyFailed = results.fail.length > 0; if (anyFailed && this.editSvc.cellEditingInvalidCommitBlocks()) { return { destroy: [], keep: results.all }; } return { destroy: results.all, keep: [] }; } stopCancelled(forceCancel) { const { rowNode, model } = this; if (rowNode && !model.hasRowEdits(rowNode)) { return false; } super.stopCancelled(forceCancel); this.cleanupEditors({ rowNode }, true); this.rowNode = undefined; return true; } stopCommitted(event, commit) { const { rowNode, beans, model, editSvc } = this; if (rowNode && !model.hasRowEdits(rowNode)) { return false; } const changedRows = []; model.getEditMap().forEach((rowEdits, rowNode2) => { if (!rowEdits || rowEdits.size === 0) { return; } for (const edit of rowEdits.values()) { if (_sourceAndPendingDiffer(edit)) { changedRows.push(rowNode2); break; } } }); _populateModelValidationErrors(beans); if (editSvc.checkNavWithValidation({ rowNode }) === "block-stop") { return false; } super.stopCommitted(event, commit); if (commit || !editSvc.isBatchEditing()) { for (const rowNode2 of changedRows) { this.dispatchRowEvent({ rowNode: rowNode2 }, "rowValueChanged"); } } this.cleanupEditors({ rowNode }, true); this.rowNode = undefined; return true; } onCellFocusChanged(event) { const { rowIndex } = event; const prev = event["previousParams"]; if (prev?.rowIndex === rowIndex || event.sourceEvent instanceof KeyboardEvent) { return; } const { beans, gos, model } = this; if (beans.editSvc?.isRangeSelectionEnabledWhileEditing()) { return; } const prevCell = _getCellCtrl(beans, prev); const isBlock = gos.get("invalidEditValueMode") === "block"; if (isBlock && prevCell && (model.getCellValidationModel().getCellValidation(prevCell) || model.getRowValidationModel().getRowValidation(prevCell))) { return; } super.onCellFocusChanged(event); } cleanupEditors(position = {}, includeEditing) { super.cleanupEditors(position, includeEditing); const { startedRows } = this; for (const rowNode of startedRows) { this.dispatchRowEvent({ rowNode }, "rowEditingStopped"); this.destroyEditorsForRow(rowNode); } startedRows.clear(); } destroyEditorsForRow(rowNode) { const rowCtrl = _getRowCtrl(this.beans, { rowNode }); if (!rowCtrl) { return; } const destroyParams = {}; for (const cellCtrl of rowCtrl.getAllCellCtrls()) { if (cellCtrl.comp?.getCellEditor()) { _destroyEditor(this.beans, cellCtrl, destroyParams, cellCtrl); } } } moveToNextEditingCell(prevCell, backwards, event, source = "ui", preventNavigation = false) { const { beans, model, gos, editSvc } = this; const prevPos = prevCell.cellPosition; let nextCell; model.suspend(true); try { nextCell = beans.navigation?.findNextCellToFocusOn(prevPos, { backwards, startEditing: true, skipToNextEditableCell: false }); } finally { model.suspend(false); } if (nextCell === false) { return null; } if (nextCell == null) { return false; } const nextPos = nextCell.cellPosition; const prevEditable = prevCell.isCellEditable(); const nextEditable = nextCell.isCellEditable(); const rowsMatch = nextPos && prevPos.rowIndex === nextPos.rowIndex && prevPos.rowPinned === nextPos.rowPinned; if (prevEditable) { this.setFocusOutOnEditor(prevCell); } this.restoreEditors(); const suppressStartEditOnTab = gos.get("suppressStartEditOnTab"); if (nextEditable && !preventNavigation) { if (suppressStartEditOnTab) { nextCell.focusCell(true, event); } else { if (!nextCell.comp?.getCellEditor()) { _setupEditor(beans, nextCell, { event, cellStartedEdit: true }); } this.setFocusInOnEditor(nextCell); nextCell.focusCell(false, event); } } else { if (nextEditable && preventNavigation) { this.setFocusInOnEditor(nextCell); } nextCell.focusCell(true, event); } if (!rowsMatch && !preventNavigation) { editSvc?.stopEditing({ rowNode: prevCell.rowNode }, { event, forceStop: true }); if (editSvc?.isRowEditing(prevCell.rowNode, { withOpenEditor: true })) { this.cleanupEditors(nextCell, true); } if (suppressStartEditOnTab) { nextCell.focusCell(true, event); } else { editSvc.startEditing(nextCell, { startedEdit: true, event, source, ignoreEventKey: true, editable: nextEditable || undefined }); } } prevCell.rowCtrl?.refreshRow({ suppressFlash: true, force: true }); return true; } restoreEditors() { const { beans, model } = this; model.getEditMap().forEach((rowEdits, rowNode) => rowEdits.forEach(({ state }, column) => { if (state !== "editing") { return; } const cellCtrl = _getCellCtrl(beans, { rowNode, column }); if (cellCtrl && !cellCtrl.comp?.getCellEditor()) { _setupEditor(beans, cellCtrl, { silent: true }); } })); } destroy() { super.destroy(); this.rowNode = undefined; this.startedRows.clear(); } }; var SingleCellEditStrategy = class extends BaseEditStrategy { constructor() { super(...arguments); this.beanName = "singleCell"; } shouldStop(position, event, source = "ui") { const res = super.shouldStop(position, event, source); if (res !== null) { return res; } const rowNode = position?.rowNode; const column = position?.column; const trackedRowNode = this.rowNode; const trackedColumn = this.column; if ((!trackedRowNode || !trackedColumn) && rowNode && column) { return null; } if (trackedRowNode !== rowNode || trackedColumn !== column) { return true; } if (!trackedRowNode && !trackedColumn) { return this.model.hasEdits(undefined, { withOpenEditor: true }); } return false; } midBatchInputsAllowed(position) { return this.model.hasEdits(position); } start(params) { const { position, startedEdit, event, ignoreEventKey } = params; if (this.rowNode !== position.rowNode || this.column !== position.column) { super.cleanupEditors(); } this.rowNode = position.rowNode; this.column = position.column; this.model.start(position); this.setupEditors({ cells: [position], position, startedEdit, event, ignoreEventKey }); } dispatchRowEvent(_position, _type, _silent) {} processValidationResults(results) { const anyFailed = results.fail.length > 0; if (anyFailed && this.editSvc.cellEditingInvalidCommitBlocks()) { return { destroy: [], keep: results.all }; } return { destroy: results.all, keep: [] }; } stopCancelled(forceCancel) { super.stopCancelled(forceCancel); return this.clearPosition(); } stopCommitted(event, commit) { super.stopCommitted(event, commit); return this.clearPosition(); } clearPosition() { this.rowNode = undefined; this.column = undefined; return true; } onCellFocusChanged(event) { const { colModel, editSvc } = this.beans; const { rowIndex, column, rowPinned } = event; const rowNode = _getRowNode(this.beans, { rowIndex, rowPinned }); const curColId = _getColId(column); const curCol = colModel.getCol(curColId); const previous = event["previousParams"]; if (previous) { const prevColId = _getColId(previous.column); if (previous?.rowIndex === rowIndex && prevColId === curColId && previous?.rowPinned === rowPinned) { return; } } if (event.type == "cellFocused" && (editSvc?.isRangeSelectionEnabledWhileEditing() || editSvc?.isEditing({ rowNode, column: curCol }, { withOpenEditor: true }))) { return; } super.onCellFocusChanged(event); } moveToNextEditingCell(prevCell, backwards, event, source = "ui", preventNavigation = false) { const focusedCell = this.beans.focusSvc.getFocusedCell(); if (focusedCell) { prevCell = _getCellByPosition(this.beans, focusedCell) ?? prevCell; } const prevPos = prevCell.cellPosition; let nextCell; const shouldSuspend = this.beans.gos.get("editType") === "fullRow"; if (shouldSuspend) { this.model.suspend(true); } if (!preventNavigation) { prevCell.eGui.focus(); this.editSvc?.stopEditing(prevCell, { source: this.editSvc?.isBatchEditing() ? "ui" : "api", event }); } try { nextCell = this.beans.navigation?.findNextCellToFocusOn(prevPos, { backwards, startEditing: true }); } finally { if (shouldSuspend) { this.model.suspend(false); } } if (nextCell === false) { return null; } if (nextCell == null) { return false; } const nextPos = nextCell.cellPosition; const prevEditable = prevCell.isCellEditable(); const nextEditable = nextCell.isCellEditable(); const rowsMatch = nextPos && prevPos.rowIndex === nextPos.rowIndex && prevPos.rowPinned === nextPos.rowPinned; if (prevEditable && !preventNavigation) { this.setFocusOutOnEditor(prevCell); } const suppressStartEditOnTab = this.gos.get("suppressStartEditOnTab"); let startEditingCalled = false; if (!rowsMatch && !preventNavigation) { super.cleanupEditors(nextCell, true); if (suppressStartEditOnTab) { nextCell.focusCell(true, event); } else { startEditingCalled = true; this.editSvc.startEditing(nextCell, { startedEdit: true, event, source, ignoreEventKey: true, editable: nextEditable }); } } if (nextEditable && !preventNavigation) { nextCell.focusCell(false, event); if (suppressStartEditOnTab) { nextCell.focusCell(true, event); } else if (!nextCell.comp?.getCellEditor()) { if (!startEditingCalled) { const alreadyEditing = this.editSvc?.isEditing(nextCell, { withOpenEditor: true }); _setupEditor(this.beans, nextCell, { event, cellStartedEdit: true, silent: alreadyEditing }); } this.setFocusInOnEditor(nextCell); this.cleanupEditors(nextCell); } } else { if (nextEditable && preventNavigation) { this.setFocusInOnEditor(nextCell); } nextCell.focusCell(true, event); } prevCell.rowCtrl?.refreshRow({ suppressFlash: true, force: true }); return true; } destroy() { super.destroy(); this.rowNode = undefined; this.column = undefined; } }; var EditCoreModule = { moduleName: "EditCore", version: VERSION, beans: [EditModelService, EditService], apiFunctions: { getEditingCells, getEditRowValues, getCellEditorInstances, startEditingCell, stopEditing, isEditing, validateEdit }, dynamicBeans: { singleCell: SingleCellEditStrategy, fullRow: FullRowEditStrategy }, dependsOn: [PopupModule, TooltipModule], css: [cell_editing_default] }; var TextEditorModule = { moduleName: "TextEditor", version: VERSION, userComponents: { agCellEditor: TextCellEditor, agTextCellEditor: TextCellEditor }, dependsOn: [EditCoreModule] }; var FILTER_HANDLER_MAP = { agSetColumnFilter: "agSetColumnFilterHandler", agMultiColumnFilter: "agMultiColumnFilterHandler", agGroupColumnFilter: "agGroupColumnFilterHandler", agNumberColumnFilter: "agNumberColumnFilterHandler", agBigIntColumnFilter: "agBigIntColumnFilterHandler", agDateColumnFilter: "agDateColumnFilterHandler", agTextColumnFilter: "agTextColumnFilterHandler" }; var FILTER_HANDLERS = new Set(Object.values(FILTER_HANDLER_MAP)); function getFilterUiFromWrapper(filterWrapper, skipCreate) { const filterUi = filterWrapper.filterUi; if (!filterUi) { return null; } if (filterUi.created) { return filterUi.promise; } if (skipCreate) { return null; } const promise = filterUi.create(filterUi.refreshed); const createdFilterUi = filterUi; createdFilterUi.created = true; createdFilterUi.promise = promise; return promise; } function _refreshHandlerAndUi(getFilterUi, handler, handlerParams, model, state, source, additionalEventAttributes) { handler.refresh?.({ ...handlerParams, model, source, additionalEventAttributes }); return getFilterUi().then((filterUi) => { if (filterUi) { const { filter, filterParams } = filterUi; _refreshFilterUi(filter, filterParams, model, state, source, additionalEventAttributes); } }); } function _refreshFilterUi(filter, filterParams, model, state, source, additionalEventAttributes) { filter?.refresh?.({ ...filterParams, model, state, source, additionalEventAttributes }); } function getAndRefreshFilterUi(getFilterUi, getModel, getState2, additionalEventAttributes) { const filterUi = getFilterUi(); if (filterUi?.created) { filterUi.promise.then((filter) => { const model = getModel(); _refreshFilterUi(filter, filterUi.filterParams, model, getState2() ?? { model }, "ui", additionalEventAttributes); }); } } function _updateFilterModel(params) { let state; let shouldUpdateModel = false; let model; const { action, filterParams, getFilterUi, getModel, getState: getState2, updateState, updateModel, processModelToApply } = params; switch (action) { case "apply": { const oldState = getState2(); model = oldState?.model ?? null; if (processModelToApply) { model = processModelToApply(model); } state = { state: oldState?.state, model }; shouldUpdateModel = true; break; } case "clear": { state = { model: null }; if (!filterParams?.buttons?.includes("apply")) { shouldUpdateModel = true; model = null; } break; } case "reset": { state = { model: null }; shouldUpdateModel = true; model = null; break; } case "cancel": { state = { model: getModel() }; break; } } updateState(state); if (shouldUpdateModel) { updateModel(model); } else { getAndRefreshFilterUi(getFilterUi, getModel, getState2, { fromAction: action }); } } function _getFilterModel(model, colId) { return model[colId] ?? null; } var HeaderFilterCellCtrl = class extends AbstractHeaderCellCtrl { constructor() { super(...arguments); this.iconCreated = false; } wireComp(comp, eGui, eButtonShowMainFilter, eFloatingFilterBody, compBeanInput) { this.comp = comp; const compBean = setupCompBean(this, this.beans.context, compBeanInput); this.eButtonShowMainFilter = eButtonShowMainFilter; this.eFloatingFilterBody = eFloatingFilterBody; this.setGui(eGui, compBean); this.setupActive(); this.refreshHeaderStyles(); this.setupWidth(compBean); this.setupLeft(compBean); this.setupHover(compBean); this.setupFocus(compBean); this.setupAria(); this.setupFilterButton(); this.setupUserComp(); this.setupSyncWithFilter(compBean); this.setupUi(); compBean.addManagedElementListeners(this.eButtonShowMainFilter, { click: this.showParentFilter.bind(this) }); this.setupFilterChangedListener(compBean); const colDefChanged = () => this.onColDefChanged(compBean); compBean.addManagedListeners(this.column, { colDefChanged }); compBean.addManagedEventListeners({ filterSwitched: ({ column }) => { if (column === this.column) { colDefChanged(); } } }); compBean.addDestroyFunc(() => { this.eButtonShowMainFilter = null; this.eFloatingFilterBody = null; this.userCompDetails = null; this.clearComponent(); }); } resizeHeader() {} moveHeader() {} getHeaderClassParams() { const { column, beans } = this; const colDef = column.colDef; return _addGridCommonParams(beans.gos, { colDef, column, floatingFilter: true }); } setupActive() { const colDef = this.column.getColDef(); const filterExists = !!colDef.filter; const floatingFilterExists = !!colDef.floatingFilter; this.active = filterExists && floatingFilterExists; } setupUi() { this.comp.setButtonWrapperDisplayed(!this.suppressFilterButton && this.active); this.comp.addOrRemoveBodyCssClass("ag-floating-filter-full-body", this.suppressFilterButton); this.comp.addOrRemoveBodyCssClass("ag-floating-filter-body", !this.suppressFilterButton); if (!this.active || this.iconCreated) { return; } const eMenuIcon = _createIconNoSpan("filter", this.beans, this.column); if (eMenuIcon) { this.iconCreated = true; this.eButtonShowMainFilter.appendChild(eMenuIcon); } } setupFocus(compBean) { compBean.createManagedBean(new ManagedFocusFeature(this.eGui, { shouldStopEventPropagation: this.shouldStopEventPropagation.bind(this), onTabKeyDown: this.onTabKeyDown.bind(this), handleKeyDown: this.handleKeyDown.bind(this), onFocusIn: this.onFocusIn.bind(this) })); } setupAria() { const localeTextFunc = this.getLocaleTextFunc(); _setAriaLabel(this.eButtonShowMainFilter, localeTextFunc("ariaFilterMenuOpen", "Open Filter Menu")); } onTabKeyDown(e) { const { beans } = this; const activeEl = _getActiveDomElement(beans); const wrapperHasFocus = activeEl === this.eGui; if (wrapperHasFocus) { return; } const nextFocusableEl = _findNextFocusableElement(beans, this.eGui, null, e.shiftKey); if (nextFocusableEl) { beans.headerNavigation?.scrollToColumn(this.column); e.preventDefault(); nextFocusableEl.focus(); return; } const nextFocusableColumn = this.findNextColumnWithFloatingFilter(e.shiftKey); if (!nextFocusableColumn) { return; } if (beans.focusSvc.focusHeaderPosition({ headerPosition: { headerRowIndex: this.rowCtrl.rowIndex, column: nextFocusableColumn }, event: e })) { e.preventDefault(); } } findNextColumnWithFloatingFilter(backwards) { const presentedColsService = this.beans.visibleCols; let nextCol = this.column; do { nextCol = backwards ? presentedColsService.getColBefore(nextCol) : presentedColsService.getColAfter(nextCol); if (!nextCol) { break; } } while (!nextCol.getColDef().filter || !nextCol.getColDef().floatingFilter); return nextCol; } handleKeyDown(e) { super.handleKeyDown(e); const wrapperHasFocus = this.getWrapperHasFocus(); switch (e.key) { case KeyCode.UP: case KeyCode.DOWN: case KeyCode.LEFT: case KeyCode.RIGHT: if (wrapperHasFocus) { return; } _stopPropagationForAgGrid(e); case KeyCode.ENTER: if (wrapperHasFocus) { if (_focusInto(this.eGui)) { e.preventDefault(); } } break; case KeyCode.ESCAPE: if (!wrapperHasFocus) { this.eGui.focus(); } } } onFocusIn(e) { const isRelatedWithin = this.eGui.contains(e.relatedTarget); if (isRelatedWithin) { return; } const notFromHeaderWrapper = !!e.relatedTarget && !e.relatedTarget.classList.contains("ag-floating-filter"); const fromWithinHeader = !!e.relatedTarget && _isElementChildOfClass(e.relatedTarget, "ag-floating-filter"); if (notFromHeaderWrapper && fromWithinHeader && e.target === this.eGui) { const lastFocusEvent = this.lastFocusEvent; const fromTab = !!(lastFocusEvent && lastFocusEvent.key === KeyCode.TAB); if (lastFocusEvent && fromTab) { const shouldFocusLast = lastFocusEvent.shiftKey; _focusInto(this.eGui, shouldFocusLast); } } this.focusThis(); } setupHover(compBean) { this.beans.colHover?.addHeaderFilterColumnHoverListener(compBean, this.comp, this.column, this.eGui); } setupLeft(compBean) { const setLeftFeature = new SetLeftFeature(this.column, this.eGui, this.beans); compBean.createManagedBean(setLeftFeature); } setupFilterButton() { this.suppressFilterButton = !this.beans.menuSvc?.isFloatingFilterButtonEnabled(this.column); this.highlightFilterButtonWhenActive = !_isLegacyMenuEnabled(this.gos); } setupUserComp() { if (!this.active) { return; } const compDetails = this.beans.colFilter?.getFloatingFilterCompDetails(this.column, () => this.showParentFilter()); if (compDetails) { this.setCompDetails(compDetails); } } setCompDetails(compDetails) { this.userCompDetails = compDetails; this.comp.setCompDetails(compDetails); } showParentFilter() { const eventSource = this.suppressFilterButton ? this.eFloatingFilterBody : this.eButtonShowMainFilter; this.beans.menuSvc?.showFilterMenu({ column: this.column, buttonElement: eventSource, containerType: "floatingFilter", positionBy: "button" }); } setupSyncWithFilter(compBean) { if (!this.active) { return; } const { beans: { colFilter }, column, gos } = this; const syncWithFilter = (event) => { if (event?.source === "filterDestroyed" && (!this.isAlive() || !colFilter?.isAlive())) { return; } const compPromise = this.comp.getFloatingFilterComp(); if (!compPromise) { return; } compPromise.then((comp) => { if (comp) { if (gos.get("enableFilterHandlers")) { const eventWithParams = event; let source = "filter"; if (eventWithParams?.afterFloatingFilter) { source = "ui"; } else if (eventWithParams?.afterDataChange) { source = "dataChanged"; } else if (event?.source === "api") { source = "api"; } this.updateFloatingFilterParams(this.userCompDetails, source); return; } const parentModel = colFilter?.getCurrentFloatingFilterParentModel(column); const filterChangedEvent = event ? { ...event, columns: event.columns ?? [], source: event.source === "api" ? "api" : "columnFilter" } : null; comp.onParentModelChanged(parentModel, filterChangedEvent); } }); }; [this.destroySyncListener] = compBean.addManagedListeners(column, { filterChanged: syncWithFilter }); if (colFilter?.isFilterActive(column)) { syncWithFilter(null); } } setupWidth(compBean) { const listener = () => { const width = `${this.column.getActualWidth()}px`; this.comp.setWidth(width); }; compBean.addManagedListeners(this.column, { widthChanged: listener }); listener(); } setupFilterChangedListener(compBean) { if (this.active) { [this.destroyFilterChangedListener] = compBean.addManagedListeners(this.column, { filterChanged: this.updateFilterButton.bind(this) }); this.updateFilterButton(); } } updateFilterButton() { if (!this.suppressFilterButton && this.comp) { const isFilterAllowed = !!this.beans.filterManager?.isFilterAllowed(this.column); this.comp.setButtonWrapperDisplayed(isFilterAllowed); if (this.highlightFilterButtonWhenActive && isFilterAllowed) { this.eButtonShowMainFilter.classList.toggle("ag-filter-active", this.column.isFilterActive()); } } } onColDefChanged(compBean) { const wasActive = this.active; this.setupActive(); const becomeActive = !wasActive && this.active; if (wasActive && !this.active) { this.destroySyncListener(); this.destroyFilterChangedListener(); } const colFilter = this.beans.colFilter; const newCompDetails = this.active ? colFilter?.getFloatingFilterCompDetails(this.column, () => this.showParentFilter()) : null; const compPromise = this.comp.getFloatingFilterComp(); if (!compPromise || !newCompDetails) { this.updateCompDetails(compBean, newCompDetails, becomeActive); } else { compPromise.then((compInstance) => { if (!compInstance || colFilter?.areFilterCompsDifferent(this.userCompDetails ?? null, newCompDetails)) { this.updateCompDetails(compBean, newCompDetails, becomeActive); } else { this.updateFloatingFilterParams(newCompDetails, "colDef"); } }); } } updateCompDetails(compBean, compDetails, becomeActive) { if (!this.isAlive()) { return; } this.setCompDetails(compDetails); this.setupFilterButton(); this.setupUi(); if (becomeActive) { this.setupSyncWithFilter(compBean); this.setupFilterChangedListener(compBean); } } updateFloatingFilterParams(userCompDetails, source) { if (!userCompDetails) { return; } let params = userCompDetails.params; this.comp.getFloatingFilterComp()?.then((floatingFilter) => { if (typeof floatingFilter?.refresh === "function") { if (this.gos.get("enableFilterHandlers")) { params = { ...params, model: _getFilterModel(this.beans.colFilter?.model ?? {}, this.column.getColId()), source }; } floatingFilter.refresh(params); } }); } addResizeAndMoveKeyboardListeners() {} destroy() { super.destroy(); this.destroySyncListener = null; this.destroyFilterChangedListener = null; } }; function showColumnMenu(beans, colKey) { const column = beans.colModel.getCol(colKey); if (!column) { _error(12, { colKey }); return; } beans.menuSvc?.showColumnMenu({ column, positionBy: "auto" }); } function hidePopupMenu(beans) { beans.menuSvc?.hidePopupMenu(); } var MenuService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "menuSvc"; } postConstruct() { const { enterpriseMenuFactory, filterMenuFactory } = this.beans; this.activeMenuFactory = enterpriseMenuFactory ?? filterMenuFactory; } showColumnMenu(params) { this.showColumnMenuCommon(this.activeMenuFactory, params, "columnMenu"); } showFilterMenu(params) { this.showColumnMenuCommon(getFilterMenuFactory(this.beans), params, params.containerType, true); } showHeaderContextMenu(column, mouseEvent, touchEvent) { this.activeMenuFactory?.showMenuAfterContextMenuEvent(column, mouseEvent, touchEvent); } hidePopupMenu() { this.beans.contextMenuSvc?.hideActiveMenu(); this.activeMenuFactory?.hideActiveMenu(); } hideFilterMenu() { getFilterMenuFactory(this.beans)?.hideActiveMenu(); } isColumnMenuInHeaderEnabled(column) { const { suppressHeaderMenuButton } = column.getColDef(); return !suppressHeaderMenuButton && !!this.activeMenuFactory?.isMenuEnabled(column) && (_isLegacyMenuEnabled(this.gos) || !!this.beans.enterpriseMenuFactory); } isFilterMenuInHeaderEnabled(column) { return !column.getColDef().suppressHeaderFilterButton && !!this.beans.filterManager?.isFilterAllowed(column); } isHeaderContextMenuEnabled(column) { const colDef = column && isColumn(column) ? column.getColDef() : column?.getColGroupDef(); return !colDef?.suppressHeaderContextMenu && this.gos.get("columnMenu") === "new"; } isHeaderMenuButtonAlwaysShowEnabled() { return this.isSuppressMenuHide(); } isHeaderMenuButtonEnabled() { const menuHides = !this.isSuppressMenuHide(); const onIpadAndMenuHides = _isIOSUserAgent() && menuHides; return !onIpadAndMenuHides; } isHeaderFilterButtonEnabled(column) { return this.isFilterMenuInHeaderEnabled(column) && !_isLegacyMenuEnabled(this.gos) && !this.isFloatingFilterButtonDisplayed(column); } isFilterMenuItemEnabled(column) { return !!this.beans.filterManager?.isFilterAllowed(column) && !_isLegacyMenuEnabled(this.gos) && !this.isFilterMenuInHeaderEnabled(column) && !this.isFloatingFilterButtonDisplayed(column); } isFloatingFilterButtonEnabled(column) { return !column.getColDef().suppressFloatingFilterButton; } isFloatingFilterButtonDisplayed(column) { return !!column.getColDef().floatingFilter && this.isFloatingFilterButtonEnabled(column); } isSuppressMenuHide() { const gos = this.gos; const suppressMenuHide = gos.get("suppressMenuHide"); if (_isLegacyMenuEnabled(gos)) { return gos.exists("suppressMenuHide") ? suppressMenuHide : false; } return suppressMenuHide; } showColumnMenuCommon(menuFactory, params, containerType, filtersOnly) { const { positionBy, onClosedCallback } = params; const column = params.column; if (positionBy === "button") { const { buttonElement } = params; menuFactory?.showMenuAfterButtonClick(column, buttonElement, containerType, onClosedCallback, filtersOnly); } else if (positionBy === "mouse") { const { mouseEvent } = params; menuFactory?.showMenuAfterMouseEvent(column, mouseEvent, containerType, onClosedCallback, filtersOnly); } else if (column) { const beans = this.beans; const ctrlsSvc = beans.ctrlsSvc; ctrlsSvc.getScrollFeature().ensureColumnVisible(column, "auto"); _requestAnimationFrame(beans, () => { const headerCellCtrl = ctrlsSvc.getHeaderRowContainerCtrl(column.getPinned())?.getHeaderCtrlForColumn(column); if (headerCellCtrl) { menuFactory?.showMenuAfterButtonClick(column, headerCellCtrl.getAnchorElementForMenu(filtersOnly), containerType, onClosedCallback, filtersOnly); } }); } } }; function _setColMenuVisible(column, visible, source) { if (column.menuVisible !== visible) { column.menuVisible = visible; column.dispatchColEvent("menuVisibleChanged", source); } } function getFilterMenuFactory(beans) { const { enterpriseMenuFactory, filterMenuFactory, gos } = beans; return enterpriseMenuFactory && _isLegacyMenuEnabled(gos) ? enterpriseMenuFactory : filterMenuFactory; } var SharedMenuModule = { moduleName: "SharedMenu", version: VERSION, beans: [MenuService], apiFunctions: { showColumnMenu, hidePopupMenu } }; var column_filters_default = ".ag-set-filter{--ag-indentation-level:0}.ag-set-filter-item{align-items:center;display:flex;height:100%}:where(.ag-ltr) .ag-set-filter-item{padding-left:calc(var(--ag-widget-container-horizontal-padding) + var(--ag-indentation-level)*var(--ag-set-filter-indent-size))}:where(.ag-rtl) .ag-set-filter-item{padding-right:calc(var(--ag-widget-container-horizontal-padding) + var(--ag-indentation-level)*var(--ag-set-filter-indent-size))}.ag-set-filter-item-checkbox{display:flex;height:100%;width:100%}.ag-set-filter-group-icons{display:block;:where(.ag-set-filter-group-closed-icon),:where(.ag-set-filter-group-indeterminate-icon),:where(.ag-set-filter-group-opened-icon){cursor:pointer}}:where(.ag-ltr) .ag-set-filter-group-icons{margin-right:var(--ag-widget-container-horizontal-padding)}:where(.ag-rtl) .ag-set-filter-group-icons{margin-left:var(--ag-widget-container-horizontal-padding)}.ag-filter-body-wrapper{display:flex;flex-direction:column}:where(.ag-menu:not(.ag-tabs) .ag-filter) .ag-filter-body-wrapper{min-width:180px}.ag-filter-filter{flex:1 1 0px}.ag-filter-condition{display:flex;justify-content:center}.ag-floating-filter-body{display:flex;flex:1 1 auto;height:100%;position:relative}.ag-floating-filter-full-body{align-items:center;display:flex;flex:1 1 auto;height:100%;overflow:hidden;width:100%}.ag-floating-filter-input{align-items:center;display:flex;width:100%;>:where(.ag-date-floating-filter-wrapper),>:where(.ag-floating-filter-input),>:where(.ag-input-field){flex:1 1 auto}:where(.ag-input-field-input[type=date]),:where(.ag-input-field-input[type=datetime-local]){width:1px}}.ag-floating-filter-button{display:flex;flex:none}.ag-date-floating-filter-wrapper{display:flex}.ag-set-floating-filter-input :where(.ag-input-field-input)[disabled]{pointer-events:none}.ag-floating-filter-button-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;height:var(--ag-icon-size);width:var(--ag-icon-size)}.ag-filter-loading{align-items:unset;background-color:var(--ag-chrome-background-color);height:100%;padding:var(--ag-widget-container-vertical-padding) var(--ag-widget-container-horizontal-padding);position:absolute;width:100%;z-index:1;:where(.ag-menu) &{background-color:var(--ag-menu-background-color)}}.ag-filter-separator{border-top:solid var(--ag-border-width) var(--menu-separator-color)}:where(.ag-filter-select) .ag-picker-field-wrapper{width:0}.ag-filter-condition-operator{height:17px}:where(.ag-ltr) .ag-filter-condition-operator-or{margin-left:calc(var(--ag-spacing)*2)}:where(.ag-rtl) .ag-filter-condition-operator-or{margin-right:calc(var(--ag-spacing)*2)}.ag-set-filter-select-all{padding-top:var(--ag-widget-container-vertical-padding)}.ag-filter-no-matches,.ag-set-filter-list{height:calc(var(--ag-list-item-height)*6)}.ag-filter-no-matches{padding:var(--ag-widget-container-vertical-padding) var(--ag-widget-container-horizontal-padding)}.ag-set-filter-tree-list{height:calc(var(--ag-list-item-height)*10)}.ag-set-filter-filter{margin-left:var(--ag-widget-container-horizontal-padding);margin-right:var(--ag-widget-container-horizontal-padding);margin-top:var(--ag-widget-container-vertical-padding)}.ag-filter-to{margin-top:var(--ag-widget-vertical-spacing)}.ag-mini-filter{margin:var(--ag-widget-container-vertical-padding) var(--ag-widget-container-horizontal-padding)}:where(.ag-ltr) .ag-set-filter-add-group-indent{margin-left:calc(var(--ag-icon-size) + var(--ag-widget-container-horizontal-padding))}:where(.ag-rtl) .ag-set-filter-add-group-indent{margin-right:calc(var(--ag-icon-size) + var(--ag-widget-container-horizontal-padding))}:where(.ag-filter-menu) .ag-set-filter-list{min-width:200px}.ag-filter-virtual-list-item:focus-visible{box-shadow:inset var(--ag-focus-shadow)}.ag-filter-apply-panel{display:flex;justify-content:flex-end;overflow:hidden;padding:var(--ag-widget-vertical-spacing) var(--ag-widget-container-horizontal-padding) var(--ag-widget-container-vertical-padding)}.ag-filter-apply-panel-button{line-height:1.5}:where(.ag-ltr) .ag-filter-apply-panel-button{margin-left:calc(var(--ag-spacing)*2)}:where(.ag-rtl) .ag-filter-apply-panel-button{margin-right:calc(var(--ag-spacing)*2)}.ag-simple-filter-body-wrapper{display:flex;flex-direction:column;gap:var(--ag-widget-vertical-spacing);min-height:calc(var(--ag-list-item-height) + var(--ag-widget-container-vertical-padding) + var(--ag-widget-vertical-spacing));overflow-y:auto;padding:var(--ag-widget-container-vertical-padding) var(--ag-widget-container-horizontal-padding);padding-bottom:var(--ag-widget-container-vertical-padding);:where(.ag-resizer-wrapper){margin:0}}.ag-multi-filter-menu-item{margin:var(--ag-spacing) 0}.ag-multi-filter-group-title-bar{background-color:transparent;color:var(--ag-header-text-color);font-weight:500;padding:calc(var(--ag-spacing)*1.5) var(--ag-spacing)}.ag-group-filter-field-select-wrapper{display:flex;flex-direction:column;gap:var(--ag-widget-vertical-spacing);padding:var(--ag-widget-container-vertical-padding) var(--ag-widget-container-horizontal-padding)}"; function isColumnFilterPresent(beans) { const filterManager = beans.filterManager; return !!filterManager?.isColumnFilterPresent() || !!filterManager?.isAggregateFilterPresent(); } function getColumnFilterInstance(beans, key) { return beans.filterManager?.getColumnFilterInstance(key) ?? Promise.resolve(undefined); } function destroyFilter(beans, key) { const column = beans.colModel.getColDefCol(key); if (column) { return beans.colFilter?.destroyFilter(column, "api"); } } function setFilterModel(beans, model) { beans.frameworkOverrides.wrapIncoming(() => beans.filterManager?.setFilterModel(model)); } function getFilterModel(beans) { return beans.filterManager?.getFilterModel() ?? {}; } function getColumnFilterModel(beans, key, useUnapplied) { const { gos, colModel, colFilter } = beans; if (useUnapplied && !gos.get("enableFilterHandlers")) { _warn(288); useUnapplied = false; } const column = colModel.getColDefCol(key); return column ? colFilter?.getModelForColumn(column, useUnapplied) ?? null : null; } function setColumnFilterModel(beans, column, model) { return beans.filterManager?.setColumnFilterModel(column, model) ?? Promise.resolve(); } function showColumnFilter(beans, colKey) { const column = beans.colModel.getCol(colKey); if (!column) { _error(12, { colKey }); return; } beans.menuSvc?.showFilterMenu({ column, containerType: "columnFilter", positionBy: "auto" }); } function hideColumnFilter(beans) { beans.menuSvc?.hideFilterMenu(); } function getColumnFilterHandler(beans, colKey) { const column = beans.colModel.getCol(colKey); if (!column) { _error(12, { colKey }); return; } return beans.colFilter?.getHandler(column, true); } function doFilterAction(beans, params) { const { colModel, colFilter, gos } = beans; if (!gos.get("enableFilterHandlers")) { _warn(287); return; } const { colId, action } = params; if (colId) { const column = colModel.getColById(colId); if (column) { colFilter?.updateModel(column, action); } } else { colFilter?.updateAllModels(action); } } var MONTH_LOCALE_TEXT = { january: "January", february: "February", march: "March", april: "April", may: "May", june: "June", july: "July", august: "August", september: "September", october: "October", november: "November", december: "December" }; var MONTH_KEYS = [ "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" ]; function setFilterNumberComparator(a, b) { if (a == null) { return -1; } if (b == null) { return 1; } return Number.parseFloat(a) - Number.parseFloat(b); } function setFilterBigIntComparator(a, b) { if (a == null) { return -1; } if (b == null) { return 1; } const valueA = _parseBigIntOrNull(a); const valueB = _parseBigIntOrNull(b); if (valueA != null && valueB != null) { if (valueA === valueB) { return 0; } return valueA > valueB ? 1 : -1; } return String(a).localeCompare(String(b)); } function isValidDate(value) { return value instanceof Date && !isNaN(value.getTime()); } var filterParamsForEachDataType = { number: () => { return; }, bigint: () => { return; }, boolean: () => ({ maxNumConditions: 1, debounceMs: 0, filterOptions: [ "empty", { displayKey: "true", displayName: "True", predicate: (_filterValues, cellValue) => cellValue, numberOfInputs: 0 }, { displayKey: "false", displayName: "False", predicate: (_filterValues, cellValue) => cellValue === false, numberOfInputs: 0 } ] }), date: () => ({ isValidDate }), dateString: ({ dataTypeDefinition }) => ({ comparator: (filterDate, cellValue) => { const cellAsDate = dataTypeDefinition.dateParser(cellValue); if (cellValue == null || cellAsDate < filterDate) { return -1; } if (cellAsDate > filterDate) { return 1; } return 0; }, isValidDate: (value) => typeof value === "string" && isValidDate(dataTypeDefinition.dateParser(value)) }), dateTime: (args) => filterParamsForEachDataType.date(args), dateTimeString: (args) => filterParamsForEachDataType.dateString(args), object: () => { return; }, text: () => { return; } }; var setFilterParamsForEachDataType = { number: () => ({ comparator: setFilterNumberComparator }), bigint: () => ({ comparator: setFilterBigIntComparator }), boolean: ({ t }) => ({ valueFormatter: (params) => _exists(params.value) ? t(String(params.value), params.value ? "True" : "False") : t("blanks", "(Blanks)") }), date: ({ formatValue, t }) => ({ valueFormatter: (params) => { const valueFormatted = formatValue(params); return _exists(valueFormatted) ? valueFormatted : t("blanks", "(Blanks)"); }, treeList: true, treeListFormatter: (pathKey, level) => { if (pathKey === "NaN") { return t("invalidDate", "Invalid Date"); } if (level === 1 && pathKey != null) { const monthKey = MONTH_KEYS[Number(pathKey) - 1]; return t(monthKey, MONTH_LOCALE_TEXT[monthKey]); } return pathKey ?? t("blanks", "(Blanks)"); }, treeListPathGetter: (date) => _getDateParts(date, false) }), dateString: ({ formatValue, dataTypeDefinition, t }) => ({ valueFormatter: (params) => { const valueFormatted = formatValue(params); return _exists(valueFormatted) ? valueFormatted : t("blanks", "(Blanks)"); }, treeList: true, treeListPathGetter: (value) => _getDateParts(dataTypeDefinition.dateParser(value ?? undefined), false), treeListFormatter: (pathKey, level) => { if (level === 1 && pathKey != null) { const monthKey = MONTH_KEYS[Number(pathKey) - 1]; return t(monthKey, MONTH_LOCALE_TEXT[monthKey]); } return pathKey ?? t("blanks", "(Blanks)"); } }), dateTime: (args) => { const params = setFilterParamsForEachDataType.date(args); params.treeListPathGetter = _getDateParts; return params; }, dateTimeString(args) { const convertToDate = args.dataTypeDefinition.dateParser; const params = setFilterParamsForEachDataType.dateString(args); params.treeListPathGetter = (value) => _getDateParts(convertToDate(value ?? undefined)); return params; }, object: ({ formatValue, t }) => ({ valueFormatter: (params) => { const valueFormatted = formatValue(params); return _exists(valueFormatted) ? valueFormatted : t("blanks", "(Blanks)"); } }), text: () => { return; } }; function _getFilterParamsForDataType(filter, existingFilterParams, existingFilterValueGetter, dataTypeDefinition, formatValue, beans, translate) { let filterParams = existingFilterParams; let filterValueGetter = existingFilterValueGetter; const usingSetFilter = filter === "agSetColumnFilter"; if (!filterValueGetter && dataTypeDefinition.baseDataType === "object" && !usingSetFilter) { filterValueGetter = ({ column, node }) => formatValue({ column, node, value: beans.valueSvc.getValue(column, node, "data") }); } const filterParamsMap = usingSetFilter ? setFilterParamsForEachDataType : filterParamsForEachDataType; const filterParamsGetter = filterParamsMap[dataTypeDefinition.baseDataType]; const newFilterParams = filterParamsGetter({ dataTypeDefinition, formatValue, t: translate }); filterParams = typeof existingFilterParams === "object" ? { ...newFilterParams, ...existingFilterParams } : newFilterParams; return { filterParams, filterValueGetter }; } var defaultFilters = { boolean: "agTextColumnFilter", date: "agDateColumnFilter", dateString: "agDateColumnFilter", dateTime: "agDateColumnFilter", dateTimeString: "agDateColumnFilter", bigint: "agBigIntColumnFilter", number: "agNumberColumnFilter", object: "agTextColumnFilter", text: "agTextColumnFilter" }; var defaultFloatingFilters = { boolean: "agTextColumnFloatingFilter", date: "agDateColumnFloatingFilter", dateString: "agDateColumnFloatingFilter", dateTime: "agDateColumnFloatingFilter", dateTimeString: "agDateColumnFloatingFilter", bigint: "agBigIntColumnFloatingFilter", number: "agNumberColumnFloatingFilter", object: "agTextColumnFloatingFilter", text: "agTextColumnFloatingFilter" }; function _getDefaultSimpleFilter(cellDataType, isFloating = false) { const filterSet = isFloating ? defaultFloatingFilters : defaultFilters; return filterSet[cellDataType ?? "text"]; } function _getDefaultFloatingFilterType(frameworkOverrides, def, getFromDefault) { if (def == null) { return null; } let defaultFloatingFilterType = null; const { compName, jsComp, fwComp } = _getFilterCompKeys(frameworkOverrides, def); if (compName) { const floatingFilterTypeMap = { agSetColumnFilter: "agSetColumnFloatingFilter", agMultiColumnFilter: "agMultiColumnFloatingFilter", agGroupColumnFilter: "agGroupColumnFloatingFilter", agNumberColumnFilter: "agNumberColumnFloatingFilter", agBigIntColumnFilter: "agBigIntColumnFloatingFilter", agDateColumnFilter: "agDateColumnFloatingFilter", agTextColumnFilter: "agTextColumnFloatingFilter" }; defaultFloatingFilterType = floatingFilterTypeMap[compName]; } else { const usingDefaultFilter = jsComp == null && fwComp == null && def.filter === true; if (usingDefaultFilter) { defaultFloatingFilterType = getFromDefault(); } } return defaultFloatingFilterType; } var DUMMY_HANDLER = { filterHandler: () => ({ doesFilterPass: () => true }) }; function isAggFilter(column, isPivotMode, isPivotActive, groupFilterEnabled) { const isSecondary = !column.isPrimary(); if (isSecondary) { return true; } const isShowingPrimaryColumns = !isPivotActive; const isValueActive = column.isValueActive(); if (!isValueActive || !isShowingPrimaryColumns) { return false; } if (isPivotMode) { return true; } return groupFilterEnabled; } var ColumnFilterService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colFilter"; this.allColumnFilters = /* @__PURE__ */ new Map; this.allColumnListeners = /* @__PURE__ */ new Map; this.activeAggregateFilters = []; this.activeColumnFilters = []; this.processingFilterChange = false; this.modelUpdates = []; this.columnModelUpdates = []; this.state = /* @__PURE__ */ new Map; this.handlerMap = { ...FILTER_HANDLER_MAP }; this.isGlobalButtons = false; this.activeFilterComps = /* @__PURE__ */ new Set; } postConstruct() { this.addManagedEventListeners({ gridColumnsChanged: this.onColumnsChanged.bind(this), dataTypesInferred: this.processFilterModelUpdateQueue.bind(this) }); this.addManagedPropertyListener("pivotMode", this.onPivotModeChanged.bind(this)); const gos = this.gos; const initialFilterModel = { ...gos.get("initialState")?.filter?.filterModel ?? {} }; this.initialModel = initialFilterModel; this.model = { ...initialFilterModel }; if (!gos.get("enableFilterHandlers")) { delete this.handlerMap["agMultiColumnFilter"]; } } refreshModel() { this.onNewRowsLoaded("rowDataUpdated"); } setModel(model, source = "api", forceUpdateActive) { const { colModel, dataTypeSvc, filterManager } = this.beans; if (dataTypeSvc?.isPendingInference) { this.modelUpdates.push({ model, source }); return; } const allPromises = []; const previousModel = this.getModel(true); if (model) { const modelKeys = new Set(Object.keys(model)); this.allColumnFilters.forEach((filterWrapper, colId) => { const newModel = model[colId]; allPromises.push(this.setModelOnFilterWrapper(filterWrapper, newModel)); modelKeys.delete(colId); }); modelKeys.forEach((colId) => { const column = colModel.getColDefCol(colId) || colModel.getCol(colId); if (!column) { _warn(62, { colId }); return; } if (!column.isFilterAllowed()) { _warn(63, { colId }); return; } const filterWrapper = this.getOrCreateFilterWrapper(column, true); if (!filterWrapper) { _warn(64, { colId }); return; } allPromises.push(this.setModelOnFilterWrapper(filterWrapper, model[colId], true)); }); } else { this.model = {}; this.allColumnFilters.forEach((filterWrapper) => { allPromises.push(this.setModelOnFilterWrapper(filterWrapper, null)); }); } AgPromise.all(allPromises).then(() => { const currentModel = this.getModel(true); const columns = []; this.allColumnFilters.forEach((filterWrapper, colId) => { const before = previousModel ? previousModel[colId] : null; const after = currentModel ? currentModel[colId] : null; if (!_jsonEquals(before, after)) { columns.push(filterWrapper.column); } }); if (columns.length > 0) { filterManager?.onFilterChanged({ columns, source }); } else if (forceUpdateActive) { this.updateActive("filterChanged"); } }); } getModel(excludeInitialState) { const result = {}; const { allColumnFilters, initialModel, beans: { colModel } } = this; allColumnFilters.forEach((filterWrapper, key) => { const model = this.getModelFromFilterWrapper(filterWrapper); if (_exists(model)) { result[key] = model; } }); if (!excludeInitialState) { for (const colId of Object.keys(initialModel)) { const model = initialModel[colId]; if (_exists(model) && !allColumnFilters.has(colId) && colModel.getCol(colId)?.isFilterAllowed()) { result[colId] = model; } } } return result; } setState(model, state, source = "api") { this.state.clear(); if (state) { for (const colId of Object.keys(state)) { const newState = state[colId]; this.state.set(colId, { model: _getFilterModel(this.model, colId), state: newState }); } } this.setModel(model, source, true); } getState() { const state = this.state; if (!state.size) { return; } const newState = {}; let hasNewState = false; state.forEach((colState, colId) => { const actualState = colState.state; if (actualState != null) { hasNewState = true; newState[colId] = actualState; } }); return hasNewState ? newState : undefined; } getModelFromFilterWrapper(filterWrapper) { const column = filterWrapper.column; const colId = column.getColId(); if (filterWrapper.isHandler) { return _getFilterModel(this.model, colId); } const filter = filterWrapper.filter; if (filter) { if (typeof filter.getModel !== "function") { _warn(66); return null; } return filter.getModel(); } return _getFilterModel(this.initialModel, colId); } isFilterPresent() { return this.activeColumnFilters.length > 0; } isAggFilterPresent() { return !!this.activeAggregateFilters.length; } disableFilters() { this.initialModel = {}; const { allColumnFilters } = this; if (allColumnFilters.size) { allColumnFilters.forEach((filterWrapper) => this.disposeFilterWrapper(filterWrapper, "advancedFilterEnabled")); return true; } return false; } updateActiveFilters() { const isFilterActive = (filter) => { if (!filter) { return false; } if (!filter.isFilterActive) { _warn(67); return false; } return filter.isFilterActive(); }; const { colModel, gos } = this.beans; const groupFilterEnabled = !!_getGroupAggFiltering(gos); const activeAggregateFilters = []; const activeColumnFilters = []; const addFilter = (column, filterActive, doesFilterPassWrapper) => { if (filterActive) { if (isAggFilter(column, colModel.isPivotMode(), colModel.isPivotActive(), groupFilterEnabled)) { activeAggregateFilters.push(doesFilterPassWrapper); } else { activeColumnFilters.push(doesFilterPassWrapper); } } }; const promises = []; this.allColumnFilters.forEach((filterWrapper) => { const column = filterWrapper.column; const colId = column.getColId(); if (filterWrapper.isHandler) { promises.push(AgPromise.resolve().then(() => { addFilter(column, this.isHandlerActive(column), { colId, isHandler: true, handler: filterWrapper.handler, handlerParams: filterWrapper.handlerParams }); })); } else { const promise = getFilterUiFromWrapper(filterWrapper); if (promise) { promises.push(promise.then((filter) => { addFilter(column, isFilterActive(filter), { colId, isHandler: false, comp: filter }); })); } } }); return AgPromise.all(promises).then(() => { this.activeAggregateFilters = activeAggregateFilters; this.activeColumnFilters = activeColumnFilters; }); } updateFilterFlagInColumns(source, additionalEventAttributes) { const promises = []; this.allColumnFilters.forEach((filterWrapper) => { const column = filterWrapper.column; if (filterWrapper.isHandler) { promises.push(AgPromise.resolve().then(() => { this.setColFilterActive(column, this.isHandlerActive(column), source, additionalEventAttributes); })); } else { const promise = getFilterUiFromWrapper(filterWrapper); if (promise) { promises.push(promise.then((filter) => { this.setColFilterActive(column, filter.isFilterActive(), source, additionalEventAttributes); })); } } }); this.beans.groupFilter?.updateFilterFlags(source, additionalEventAttributes); return AgPromise.all(promises); } doFiltersPass(node, colIdToSkip, targetAggregates) { const { data, aggData } = node; const targetedFilters = targetAggregates ? this.activeAggregateFilters : this.activeColumnFilters; const targetedData = targetAggregates ? aggData : data; const model = this.model; for (let i = 0;i < targetedFilters.length; i++) { const filter = targetedFilters[i]; const { colId, isHandler } = filter; if (colId === colIdToSkip) { continue; } if (isHandler) { const { handler, handlerParams } = filter; if (!handler.doesFilterPass({ node, data: targetedData, model: _getFilterModel(model, colId), handlerParams })) { return false; } } else { const comp = filter.comp; if (typeof comp.doesFilterPass !== "function") { _error(91); continue; } if (!comp.doesFilterPass({ node, data: targetedData })) { return false; } } } return true; } getHandlerParams(column) { const wrapper = this.allColumnFilters.get(column.getColId()); return wrapper?.isHandler ? wrapper.handlerParams : undefined; } callOnFilterChangedOutsideRenderCycle(params) { const { rowRenderer, filterManager } = this.beans; const action = () => { if (this.isAlive()) { filterManager?.onFilterChanged(params); } }; if (rowRenderer.isRefreshInProgress()) { setTimeout(action, 0); } else { action(); } } updateBeforeFilterChanged(params = {}) { const { column, additionalEventAttributes } = params; const colId = column?.getColId(); return this.updateActiveFilters().then(() => this.updateFilterFlagInColumns("filterChanged", additionalEventAttributes).then(() => { this.allColumnFilters.forEach((filterWrapper) => { const { column: filterColumn, isHandler } = filterWrapper; if (colId === filterColumn.getColId()) { return; } if (isHandler) { filterWrapper.handler.onAnyFilterChanged?.(); } getFilterUiFromWrapper(filterWrapper, isHandler)?.then((filter) => { if (typeof filter?.onAnyFilterChanged === "function") { filter.onAnyFilterChanged(); } }); }); this.processingFilterChange = true; })); } updateAfterFilterChanged() { this.processingFilterChange = false; } isSuppressFlashingCellsBecauseFiltering() { const allowShowChangeAfterFilter = this.gos.get("allowShowChangeAfterFilter") ?? false; return !allowShowChangeAfterFilter && this.processingFilterChange; } onNewRowsLoaded(source) { const promises = []; this.allColumnFilters.forEach((filterWrapper) => { const isHandler = filterWrapper.isHandler; if (isHandler) { filterWrapper.handler.onNewRowsLoaded?.(); } const promise = getFilterUiFromWrapper(filterWrapper, isHandler); if (promise) { promises.push(promise.then((filter) => { filter.onNewRowsLoaded?.(); })); } }); AgPromise.all(promises).then(() => this.updateActive(source, { afterDataChange: true })); } updateActive(source, additionalEventAttributes) { this.updateFilterFlagInColumns(source, additionalEventAttributes).then(() => this.updateActiveFilters()); } createGetValue(filterColumn, filterValueGetterOverride) { const { filterValueSvc, colModel } = this.beans; return (rowNode, column) => { const columnToUse = column ? colModel.getCol(column) : filterColumn; return columnToUse ? filterValueSvc.getValue(columnToUse, rowNode, filterValueGetterOverride) : undefined; }; } isFilterActive(column) { const filterWrapper = this.cachedFilter(column); if (filterWrapper?.isHandler) { return this.isHandlerActive(column); } const filter = filterWrapper?.filter; if (filter) { return filter.isFilterActive(); } return _getFilterModel(this.initialModel, column.getColId()) != null; } isHandlerActive(column) { const active = _exists(_getFilterModel(this.model, column.getColId())); if (active) { return active; } const groupFilter = this.beans.groupFilter; return groupFilter?.isGroupFilter(column) ? groupFilter.isFilterActive(column) : false; } getOrCreateFilterUi(column) { const filterWrapper = this.getOrCreateFilterWrapper(column, true); return filterWrapper ? getFilterUiFromWrapper(filterWrapper) : null; } getFilterUiForDisplay(column) { const filterWrapper = this.getOrCreateFilterWrapper(column, true); if (!filterWrapper) { return null; } const compPromise = getFilterUiFromWrapper(filterWrapper); if (!compPromise) { return null; } return compPromise.then((comp) => ({ comp, params: filterWrapper.filterUi.filterParams, isHandler: filterWrapper.isHandler })); } getHandler(column, createIfMissing) { const filterWrapper = this.getOrCreateFilterWrapper(column, createIfMissing); return filterWrapper?.isHandler ? filterWrapper.handler : undefined; } getOrCreateFilterWrapper(column, createIfMissing) { if (!column.isFilterAllowed()) { return; } let filterWrapper = this.cachedFilter(column); if (!filterWrapper && createIfMissing) { filterWrapper = this.createFilterWrapper(column); this.setColumnFilterWrapper(column, filterWrapper); } return filterWrapper; } cachedFilter(column) { return this.allColumnFilters.get(column.getColId()); } getDefaultFilter(column, isFloating = false) { return this.getDefaultFilterFromDataType(() => this.beans.dataTypeSvc?.getBaseDataType(column), isFloating); } getDefaultFilterFromDataType(getCellDataType, isFloating = false) { if (_isSetFilterByDefault(this.gos)) { return isFloating ? "agSetColumnFloatingFilter" : "agSetColumnFilter"; } return _getDefaultSimpleFilter(getCellDataType(), isFloating); } getDefaultFloatingFilter(column) { return this.getDefaultFilter(column, true); } createFilterComp(column, filterDef, defaultFilter, getFilterParams, isHandler, source) { const createFilterCompDetails = () => { const params = this.createFilterCompParams(column, isHandler, source); const updatedParams = getFilterParams(params, isHandler); return _getFilterDetails(this.beans.userCompFactory, filterDef, updatedParams, defaultFilter); }; const compDetails = createFilterCompDetails(); if (!compDetails) { return null; } const createFilterUi = (update) => { return (update ? createFilterCompDetails() : compDetails).newAgStackInstance(); }; return { compDetails, createFilterUi }; } createFilterInstance(column, filterDef, defaultFilter, getFilterParams) { const selectableFilter = this.beans.selectableFilter; if (selectableFilter?.isSelectable(filterDef)) { filterDef = selectableFilter.getFilterDef(column, filterDef); } const { handler, handlerParams, handlerGenerator } = this.createHandler(column, filterDef, defaultFilter) ?? {}; const filterCompDetails = this.createFilterComp(column, filterDef, defaultFilter, getFilterParams, !!handler, "init"); if (!filterCompDetails) { return { compDetails: null, createFilterUi: null, handler, handlerGenerator, handlerParams }; } const { compDetails, createFilterUi } = filterCompDetails; if (this.isGlobalButtons) { const hasLocalButtons = !!compDetails.params?.buttons?.length; if (!hasLocalButtons) { _warn(281, { colId: column.getColId() }); } } return { compDetails, handler, handlerGenerator, handlerParams, createFilterUi }; } createBaseFilterParams(column, forFloatingFilter) { const { filterManager, rowModel } = this.beans; return _addGridCommonParams(this.gos, { column, colDef: column.getColDef(), getValue: this.createGetValue(column), doesRowPassOtherFilter: forFloatingFilter ? () => true : (node) => filterManager?.doesRowPassOtherFilters(column.getColId(), node) ?? true, rowModel }); } createFilterCompParams(column, useHandler, source, forFloatingFilter) { const filterChangedCallback = this.filterChangedCallbackFactory(column); const params = this.createBaseFilterParams(column, forFloatingFilter); params.filterChangedCallback = filterChangedCallback; params.filterModifiedCallback = forFloatingFilter ? () => {} : (additionalEventAttributes) => this.filterModified(column, additionalEventAttributes); if (useHandler) { const displayParams = params; const colId = column.getColId(); const model = _getFilterModel(this.model, colId); displayParams.model = model; displayParams.state = this.state.get(colId) ?? { model }; displayParams.onModelChange = (model2, additionalEventAttributes) => { this.updateStoredModel(colId, model2); this.refreshHandlerAndUi(column, model2, "ui", false, additionalEventAttributes).then(() => { filterChangedCallback({ ...additionalEventAttributes, source: "columnFilter" }); }); }; displayParams.onStateChange = (state) => { this.updateState(column, state); this.updateOrRefreshFilterUi(column); }; displayParams.onAction = (action, additionalEventAttributes, event) => { this.updateModel(column, action, additionalEventAttributes); this.dispatchLocalEvent({ type: "filterAction", column, action, event }); }; displayParams.getHandler = () => this.getHandler(column, true); displayParams.onUiChange = (additionalEventAttributes) => this.filterUiChanged(column, additionalEventAttributes); displayParams.source = source; } return params; } createFilterUiForHandler(compDetails, createFilterUi) { return createFilterUi ? { created: false, create: createFilterUi, filterParams: compDetails.params, compDetails } : null; } createFilterUiLegacy(compDetails, createFilterUi, updateInstanceCallback) { const promise = createFilterUi(); const filterUi = { created: true, create: createFilterUi, filterParams: compDetails.params, compDetails, promise }; promise.then(updateInstanceCallback); return filterUi; } createFilterWrapper(column) { const { compDetails, handler, handlerGenerator, handlerParams, createFilterUi } = this.createFilterInstance(column, column.getColDef(), this.getDefaultFilter(column), (params) => params); const colId = column.getColId(); if (handler) { delete this.initialModel[colId]; handler.init?.({ ...handlerParams, source: "init", model: _getFilterModel(this.model, colId) }); return { column, isHandler: true, handler, handlerGenerator, handlerParams, filterUi: this.createFilterUiForHandler(compDetails, createFilterUi) }; } if (createFilterUi) { const filterWrapper = { column, filterUi: null, isHandler: false }; filterWrapper.filterUi = this.createFilterUiLegacy(compDetails, createFilterUi, (filterComp) => { filterWrapper.filter = filterComp ?? undefined; }); return filterWrapper; } return { column, filterUi: null, isHandler: false }; } createHandlerFunc(column, filterDef, defaultFilter) { const { gos, frameworkOverrides, registry } = this.beans; let doesFilterPass; const getFilterHandlerFromDef = (filterDef2) => { const filter = filterDef2.filter; if (isColumnFilterComp(filter)) { const handler = filter.handler; if (handler) { return handler; } doesFilterPass = filter.doesFilterPass; if (doesFilterPass) { return () => ({ doesFilterPass }); } return; } return typeof filter === "string" ? filter : undefined; }; const enableFilterHandlers = gos.get("enableFilterHandlers"); const providedFilterHandler = enableFilterHandlers ? getFilterHandlerFromDef(filterDef) : undefined; const resolveProvidedFilterHandler = (handlerName2) => () => this.createBean(registry.createDynamicBean(handlerName2, true)); let filterHandler; let handlerName; if (typeof providedFilterHandler === "string") { const userFilterHandler = gos.get("filterHandlers")?.[providedFilterHandler]; if (userFilterHandler != null) { filterHandler = userFilterHandler; } else if (FILTER_HANDLERS.has(providedFilterHandler)) { filterHandler = resolveProvidedFilterHandler(providedFilterHandler); handlerName = providedFilterHandler; } } else { filterHandler = providedFilterHandler; } if (!filterHandler) { let filterName; const { compName, jsComp, fwComp } = _getFilterCompKeys(frameworkOverrides, filterDef); if (compName) { filterName = compName; } else { const usingDefaultFilter = jsComp == null && fwComp == null && filterDef.filter === true; if (usingDefaultFilter) { filterName = defaultFilter; } } handlerName = this.handlerMap[filterName]; if (handlerName) { filterHandler = resolveProvidedFilterHandler(handlerName); } } if (!filterHandler) { if (!enableFilterHandlers) { return; } if (_isClientSideRowModel(gos)) { _warn(277, { colId: column.getColId() }); } return DUMMY_HANDLER; } return { filterHandler, handlerNameOrCallback: doesFilterPass ?? handlerName }; } createHandler(column, filterDef, defaultFilter) { const handlerFunc = this.createHandlerFunc(column, filterDef, defaultFilter); if (!handlerFunc) { return; } const filterParams = _mergeFilterParamsWithApplicationProvidedParams(this.beans.userCompFactory, filterDef, this.createFilterCompParams(column, true, "init")); const { handlerNameOrCallback, filterHandler } = handlerFunc; const { handler, handlerParams } = this.createHandlerFromFunc(column, filterHandler, filterParams); return { handler, handlerParams, handlerGenerator: handlerNameOrCallback ?? filterHandler }; } createHandlerFromFunc(column, filterHandler, filterParams) { const colDef = column.getColDef(); const handler = filterHandler(_addGridCommonParams(this.gos, { column, colDef })); const handlerParams = this.createHandlerParams(column, filterParams); return { handler, handlerParams }; } createHandlerParams(column, filterParams) { const colDef = column.getColDef(); const colId = column.getColId(); const filterChangedCallback = this.filterChangedCallbackFactory(column); return _addGridCommonParams(this.gos, { colDef, column, getValue: this.createGetValue(column), doesRowPassOtherFilter: (node) => this.beans.filterManager?.doesRowPassOtherFilters(colId, node) ?? true, onModelChange: (newModel, additionalEventAttributes) => { this.updateStoredModel(colId, newModel); this.refreshHandlerAndUi(column, newModel, "handler", false, additionalEventAttributes).then(() => { filterChangedCallback({ ...additionalEventAttributes, source: "columnFilter" }); }); }, onModelAsStringChange: () => { column.dispatchColEvent("filterChanged", "filterChanged"); this.dispatchLocalEvent({ type: "filterModelAsStringChanged", column }); }, filterParams }); } onColumnsChanged() { const columns = []; const { colModel, filterManager, groupFilter } = this.beans; this.allColumnFilters.forEach((wrapper, colId) => { let currentColumn; if (wrapper.column.isPrimary()) { currentColumn = colModel.getColDefCol(colId); } else { currentColumn = colModel.getCol(colId); } if (currentColumn && currentColumn === wrapper.column) { return; } columns.push(wrapper.column); this.disposeFilterWrapper(wrapper, "columnChanged"); this.disposeColumnListener(colId); }); const allFiltersAreGroupFilters = groupFilter && columns.every((col) => groupFilter.isGroupFilter(col)); if (columns.length > 0 && !allFiltersAreGroupFilters) { filterManager?.onFilterChanged({ columns, source: "api" }); } } isFilterAllowed(column) { const isFilterAllowed = column.isFilterAllowed(); if (!isFilterAllowed) { return false; } const groupFilter = this.beans.groupFilter; if (groupFilter?.isGroupFilter(column)) { return groupFilter.isFilterAllowed(column); } return true; } getFloatingFilterCompDetails(column, showParentFilter) { const { userCompFactory, frameworkOverrides, selectableFilter, gos } = this.beans; const parentFilterInstance = (callback) => { const filterComponent = this.getOrCreateFilterUi(column); filterComponent?.then((instance) => { callback(_unwrapUserComp(instance)); }); }; const colDef = column.getColDef(); const filterDef = selectableFilter?.isSelectable(colDef) ? selectableFilter.getFilterDef(column, colDef) : colDef; const defaultFloatingFilterType = _getDefaultFloatingFilterType(frameworkOverrides, filterDef, () => this.getDefaultFloatingFilter(column)) ?? "agReadOnlyFloatingFilter"; const isReactive = gos.get("enableFilterHandlers"); const filterParams = _mergeFilterParamsWithApplicationProvidedParams(userCompFactory, filterDef, this.createFilterCompParams(column, isReactive, "init", true)); const params = _addGridCommonParams(gos, { column, filterParams, currentParentModel: () => this.getCurrentFloatingFilterParentModel(column), parentFilterInstance, showParentFilter }); if (isReactive) { const displayParams = params; const colId = column.getColId(); const filterChangedCallback = this.filterChangedCallbackFactory(column); displayParams.onUiChange = (additionalEventAttributes) => this.floatingFilterUiChanged(column, additionalEventAttributes); displayParams.model = _getFilterModel(this.model, colId); displayParams.onModelChange = (model, additionalEventAttributes) => { this.updateStoredModel(colId, model); this.refreshHandlerAndUi(column, model, "floating", true, additionalEventAttributes).then(() => { filterChangedCallback({ ...additionalEventAttributes, source: "columnFilter" }); }); }; displayParams.getHandler = () => this.getHandler(column, true); displayParams.source = "init"; } return _getFloatingFilterCompDetails(userCompFactory, colDef, params, defaultFloatingFilterType); } getCurrentFloatingFilterParentModel(column) { return this.getModelFromFilterWrapper(this.cachedFilter(column) ?? { column }); } destroyFilterUi(filterWrapper, column, compDetails, createFilterUi) { const source = "paramsUpdated"; if (filterWrapper.isHandler) { const colId = column.getColId(); delete this.initialModel[colId]; this.state.delete(colId); const filterUi = filterWrapper.filterUi; const newFilterUi = this.createFilterUiForHandler(compDetails, createFilterUi); filterWrapper.filterUi = newFilterUi; const eventSvc = this.eventSvc; if (filterUi?.created) { filterUi.promise.then((filter) => { this.destroyBean(filter); eventSvc.dispatchEvent({ type: "filterDestroyed", source, column }); }); } else { eventSvc.dispatchEvent({ type: "filterHandlerDestroyed", source, column }); } } else { this.destroyFilter(column, source); } } destroyFilter(column, source = "api") { const colId = column.getColId(); const filterWrapper = this.allColumnFilters.get(colId); this.disposeColumnListener(colId); delete this.initialModel[colId]; if (filterWrapper) { this.disposeFilterWrapper(filterWrapper, source).then((wasActive) => { if (wasActive && this.isAlive()) { this.beans.filterManager?.onFilterChanged({ columns: [column], source: "api" }); } }); } } disposeColumnListener(colId) { const columnListener = this.allColumnListeners.get(colId); if (columnListener) { this.allColumnListeners.delete(colId); columnListener(); } } disposeFilterWrapper(filterWrapper, source) { let isActive = false; const { column, isHandler, filterUi } = filterWrapper; const colId = column.getColId(); if (isHandler) { isActive = this.isHandlerActive(column); this.destroyBean(filterWrapper.handler); delete this.model[colId]; this.state.delete(colId); } const removeFilter = () => { this.setColFilterActive(column, false, "filterDestroyed"); this.allColumnFilters.delete(colId); this.eventSvc.dispatchEvent({ type: "filterDestroyed", source, column }); }; if (filterUi) { if (filterUi.created) { return filterUi.promise.then((filter) => { isActive = isHandler ? isActive : !!filter?.isFilterActive(); this.destroyBean(filter); removeFilter(); return isActive; }); } else { removeFilter(); } } return AgPromise.resolve(isActive); } filterChangedCallbackFactory(column) { return (additionalEventAttributes) => { this.callOnFilterChangedOutsideRenderCycle({ additionalEventAttributes, columns: [column], column, source: additionalEventAttributes?.source ?? "columnFilter" }); }; } filterParamsChanged(colId, source = "api") { const filterWrapper = this.allColumnFilters.get(colId); if (!filterWrapper) { return; } const beans = this.beans; const column = filterWrapper.column; const colDef = column.getColDef(); const isFilterAllowed = column.isFilterAllowed(); const defaultFilter = this.getDefaultFilter(column); const selectableFilter = beans.selectableFilter; const filterDef = selectableFilter?.isSelectable(colDef) ? selectableFilter.getFilterDef(column, colDef) : colDef; const handlerFunc = isFilterAllowed ? this.createHandlerFunc(column, filterDef, this.getDefaultFilter(column)) : undefined; const isHandler = !!handlerFunc; const wasHandler = filterWrapper.isHandler; if (wasHandler != isHandler) { this.destroyFilter(column, "paramsUpdated"); return; } const { compDetails, createFilterUi } = (isFilterAllowed ? this.createFilterComp(column, filterDef, defaultFilter, (params) => params, isHandler, "colDef") : null) ?? { compDetails: null, createFilterUi: null }; const newFilterParams = compDetails?.params ?? _mergeFilterParamsWithApplicationProvidedParams(beans.userCompFactory, filterDef, this.createFilterCompParams(column, isHandler, "colDef")); if (wasHandler) { const handlerGenerator = handlerFunc?.handlerNameOrCallback ?? handlerFunc?.filterHandler; const existingModel = _getFilterModel(this.model, colId); if (filterWrapper.handlerGenerator != handlerGenerator) { const oldHandler = filterWrapper.handler; const { handler, handlerParams } = this.createHandlerFromFunc(column, handlerFunc.filterHandler, newFilterParams); filterWrapper.handler = handler; filterWrapper.handlerParams = handlerParams; filterWrapper.handlerGenerator = handlerGenerator; delete this.model[colId]; handler.init?.({ ...handlerParams, source: "init", model: null }); this.destroyBean(oldHandler); if (existingModel != null) { this.beans.filterManager?.onFilterChanged({ columns: [column], source }); } } else { const handlerParams = this.createHandlerParams(column, compDetails?.params); filterWrapper.handlerParams = handlerParams; filterWrapper.handler.refresh?.({ ...handlerParams, source: "colDef", model: existingModel }); } } if (this.areFilterCompsDifferent(filterWrapper.filterUi?.compDetails ?? null, compDetails) || !filterWrapper.filterUi || !compDetails) { this.destroyFilterUi(filterWrapper, column, compDetails, createFilterUi); return; } filterWrapper.filterUi.filterParams = newFilterParams; getFilterUiFromWrapper(filterWrapper, wasHandler)?.then((filter) => { const shouldRefreshFilter = filter?.refresh ? filter.refresh(newFilterParams) : true; if (shouldRefreshFilter === false) { this.destroyFilterUi(filterWrapper, column, compDetails, createFilterUi); } else { this.dispatchLocalEvent({ type: "filterParamsChanged", column, params: newFilterParams }); } }); } refreshHandlerAndUi(column, model, source, createIfMissing, additionalEventAttributes) { const filterWrapper = this.cachedFilter(column); if (!filterWrapper) { if (createIfMissing) { this.getOrCreateFilterWrapper(column, true); } return AgPromise.resolve(); } if (!filterWrapper.isHandler) { return AgPromise.resolve(); } const { filterUi, handler, handlerParams } = filterWrapper; return _refreshHandlerAndUi(() => { if (filterUi) { const { created, filterParams } = filterUi; if (created) { return filterUi.promise.then((filter) => { return filter ? { filter, filterParams } : undefined; }); } else { filterUi.refreshed = true; } } return AgPromise.resolve(undefined); }, handler, handlerParams, model, this.state.get(column.getColId()) ?? { model }, source, additionalEventAttributes); } setColumnFilterWrapper(column, filterWrapper) { const colId = column.getColId(); this.allColumnFilters.set(colId, filterWrapper); this.allColumnListeners.set(colId, this.addManagedListeners(column, { colDefChanged: () => this.filterParamsChanged(colId) })[0]); } areFilterCompsDifferent(oldCompDetails, newCompDetails) { if (!newCompDetails || !oldCompDetails) { return true; } const { componentClass: oldComponentClass } = oldCompDetails; const { componentClass: newComponentClass } = newCompDetails; const isSameComponentClass = oldComponentClass === newComponentClass || oldComponentClass?.render && newComponentClass?.render && oldComponentClass.render === newComponentClass.render; return !isSameComponentClass; } hasFloatingFilters() { const gridColumns = this.beans.colModel.getCols(); return gridColumns.some((col) => col.getColDef().floatingFilter); } getFilterInstance(key) { const column = this.beans.colModel.getColDefCol(key); if (!column) { return Promise.resolve(undefined); } const filterPromise = this.getOrCreateFilterUi(column); if (!filterPromise) { return Promise.resolve(null); } return new Promise((resolve) => { filterPromise.then((filter) => { resolve(_unwrapUserComp(filter)); }); }); } processFilterModelUpdateQueue() { this.modelUpdates.forEach(({ model, source }) => this.setModel(model, source)); this.modelUpdates = []; this.columnModelUpdates.forEach(({ key, model, resolve }) => { this.setModelForColumn(key, model).then(() => resolve()); }); this.columnModelUpdates = []; } getModelForColumn(column, useUnapplied) { if (useUnapplied) { const { state, model } = this; const colId = column.getColId(); const colState = state.get(colId); if (colState) { return colState.model ?? null; } return _getFilterModel(model, colId); } const filterWrapper = this.cachedFilter(column); return filterWrapper ? this.getModelFromFilterWrapper(filterWrapper) : null; } setModelForColumn(key, model) { if (this.beans.dataTypeSvc?.isPendingInference) { let resolve = () => {}; const promise = new Promise((res) => { resolve = res; }); this.columnModelUpdates.push({ key, model, resolve }); return promise; } return new Promise((resolve) => { this.setModelForColumnLegacy(key, model).then((result) => resolve(result)); }); } getStateForColumn(colId) { return this.state.get(colId) ?? { model: _getFilterModel(this.model, colId) }; } setModelForColumnLegacy(key, model) { const column = this.beans.colModel.getColDefCol(key); const filterWrapper = column ? this.getOrCreateFilterWrapper(column, true) : null; return filterWrapper ? this.setModelOnFilterWrapper(filterWrapper, model) : AgPromise.resolve(); } setColDefPropsForDataType(colDef, dataTypeDefinition, formatValue) { const providedFilter = colDef.filter; const filter = providedFilter === true ? this.getDefaultFilterFromDataType(() => dataTypeDefinition.baseDataType) : providedFilter; if (typeof filter !== "string") { return; } let filterParams; let filterValueGetter; const beans = this.beans; const { filterParams: colDefFilterParams, filterValueGetter: colDefFilterValueGetter } = colDef; if (filter === "agMultiColumnFilter") { ({ filterParams, filterValueGetter } = beans.multiFilter?.getParamsForDataType(colDefFilterParams, colDefFilterValueGetter, dataTypeDefinition, formatValue) ?? {}); } else { ({ filterParams, filterValueGetter } = _getFilterParamsForDataType(filter, colDefFilterParams, colDefFilterValueGetter, dataTypeDefinition, formatValue, beans, this.getLocaleTextFunc())); } colDef.filterParams = filterParams; if (filterValueGetter) { colDef.filterValueGetter = filterValueGetter; } } setColFilterActive(column, active, source, additionalEventAttributes) { if (column.filterActive !== active) { column.filterActive = active; column.dispatchColEvent("filterActiveChanged", source); } column.dispatchColEvent("filterChanged", source, additionalEventAttributes); } setModelOnFilterWrapper(filterWrapper, newModel, justCreated) { return new AgPromise((resolve) => { if (filterWrapper.isHandler) { const column = filterWrapper.column; const colId = column.getColId(); const existingModel = this.model[colId]; this.updateStoredModel(colId, newModel); if (justCreated && newModel === existingModel) { resolve(); return; } this.refreshHandlerAndUi(column, newModel, "api").then(() => resolve()); return; } const uiPromise = getFilterUiFromWrapper(filterWrapper); if (uiPromise) { uiPromise.then((filter) => { if (typeof filter?.setModel !== "function") { _warn(65); resolve(); return; } (filter.setModel(newModel) || AgPromise.resolve()).then(() => resolve()); }); return; } resolve(); }); } updateStoredModel(colId, model) { if (_exists(model)) { this.model[colId] = model; } else { delete this.model[colId]; } const oldState = this.state.get(colId); const newState = { model, state: oldState?.state }; this.state.set(colId, newState); } filterModified(column, additionalEventAttributes) { this.getOrCreateFilterUi(column)?.then((filterInstance) => { this.eventSvc.dispatchEvent({ type: "filterModified", column, filterInstance, ...additionalEventAttributes }); }); } filterUiChanged(column, additionalEventAttributes) { if (this.gos.get("enableFilterHandlers")) { this.eventSvc.dispatchEvent({ type: "filterUiChanged", column, ...additionalEventAttributes }); } } floatingFilterUiChanged(column, additionalEventAttributes) { if (this.gos.get("enableFilterHandlers")) { this.eventSvc.dispatchEvent({ type: "floatingFilterUiChanged", column, ...additionalEventAttributes }); } } updateModel(column, action, additionalEventAttributes) { const colId = column.getColId(); const filterWrapper = this.cachedFilter(column); const getFilterUi = () => filterWrapper?.filterUi; _updateFilterModel({ action, filterParams: filterWrapper?.filterUi?.filterParams, getFilterUi, getModel: () => _getFilterModel(this.model, colId), getState: () => this.state.get(colId), updateState: (state) => this.updateState(column, state), updateModel: (model) => getFilterUi()?.filterParams?.onModelChange(model, { ...additionalEventAttributes, fromAction: action }), processModelToApply: filterWrapper?.isHandler ? filterWrapper.handler.processModelToApply?.bind(filterWrapper.handler) : undefined }); } updateAllModels(action, additionalEventAttributes) { const promises = []; this.allColumnFilters.forEach((filter, colId) => { const column = this.beans.colModel.getColDefCol(colId); if (column) { _updateFilterModel({ action, filterParams: filter.filterUi?.filterParams, getFilterUi: () => filter.filterUi, getModel: () => _getFilterModel(this.model, colId), getState: () => this.state.get(colId), updateState: (state) => this.updateState(column, state), updateModel: (model) => { this.updateStoredModel(colId, model); this.dispatchLocalEvent({ type: "filterAction", column, action }); promises.push(this.refreshHandlerAndUi(column, model, "ui")); }, processModelToApply: filter?.isHandler ? filter.handler.processModelToApply?.bind(filter.handler) : undefined }); } }); if (promises.length) { AgPromise.all(promises).then(() => { this.callOnFilterChangedOutsideRenderCycle({ source: "columnFilter", additionalEventAttributes, columns: [] }); }); } } updateOrRefreshFilterUi(column) { const colId = column.getColId(); getAndRefreshFilterUi(() => this.cachedFilter(column)?.filterUi, () => _getFilterModel(this.model, colId), () => this.state.get(colId)); } updateState(column, state) { this.state.set(column.getColId(), state); this.dispatchLocalEvent({ type: "filterStateChanged", column, state }); } canApplyAll() { const { state, model, activeFilterComps } = this; for (const comp of activeFilterComps) { if (comp.source === "COLUMN_MENU") { return false; } } let hasChanges = false; for (const colId of state.keys()) { const colState = state.get(colId); if (colState.valid === false) { return false; } if ((colState.model ?? null) !== _getFilterModel(model, colId)) { hasChanges = true; } } return hasChanges; } hasUnappliedModel(colId) { const { model, state } = this; return (state.get(colId)?.model ?? null) !== _getFilterModel(model, colId); } setGlobalButtons(isGlobal) { this.isGlobalButtons = isGlobal; this.dispatchLocalEvent({ type: "filterGlobalButtons", isGlobal }); } shouldKeepStateOnDetach(column, lastContainerType) { if (lastContainerType === "newFiltersToolPanel") { return true; } const filterPanelSvc = this.beans.filterPanelSvc; if (filterPanelSvc?.isActive) { return !!filterPanelSvc.getState(column.getColId()); } return false; } onPivotModeChanged(event) { const { colModel, pivotColsSvc } = this.beans; const groupFilterEnabled = !!_getGroupAggFiltering(this.gos); const isPivotMode = event.currentValue; const from = isPivotMode ? this.activeColumnFilters : this.activeAggregateFilters; const to = isPivotMode ? this.activeAggregateFilters : this.activeColumnFilters; const moved = []; for (const filter of from) { const column = colModel.getColById(filter.colId); const isPivotActive = isPivotMode && !!pivotColsSvc?.columns.length; if (column && isPivotMode === isAggFilter(column, isPivotMode, isPivotActive, groupFilterEnabled)) { to.push(filter); moved.push(filter); } } _removeAllFromArray(from, moved); } destroy() { super.destroy(); this.allColumnFilters.forEach((filterWrapper) => this.disposeFilterWrapper(filterWrapper, "gridDestroyed")); this.allColumnListeners.clear(); this.state.clear(); this.activeFilterComps.clear(); } }; function isAnyFilterPresent(beans) { return !!beans.filterManager?.isAnyFilterPresent(); } function onFilterChanged(beans, source = "api") { beans.filterManager?.onFilterChanged({ source }); } var FilterManager = class extends BeanStub { constructor() { super(...arguments); this.beanName = "filterManager"; this.advFilterModelUpdateQueue = []; } wireBeans(beans) { this.quickFilter = beans.quickFilter; this.advancedFilter = beans.advancedFilter; this.colFilter = beans.colFilter; } postConstruct() { const refreshFiltersForAggregations = this.refreshFiltersForAggregations.bind(this); const updateAdvFilterColumns = this.updateAdvFilterColumns.bind(this); this.addManagedEventListeners({ columnValueChanged: refreshFiltersForAggregations, columnPivotChanged: refreshFiltersForAggregations, columnPivotModeChanged: refreshFiltersForAggregations, newColumnsLoaded: updateAdvFilterColumns, columnVisible: updateAdvFilterColumns, advancedFilterEnabledChanged: ({ enabled }) => this.onAdvFilterEnabledChanged(enabled), dataTypesInferred: this.processFilterModelUpdateQueue.bind(this) }); this.externalFilterPresent = this.isExternalFilterPresentCallback(); this.addManagedPropertyListeners(["isExternalFilterPresent", "doesExternalFilterPass"], () => { this.onFilterChanged({ source: "api" }); }); this.updateAggFiltering(); this.addManagedPropertyListener("groupAggFiltering", () => { this.updateAggFiltering(); this.onFilterChanged(); }); if (this.quickFilter) { this.addManagedListeners(this.quickFilter, { quickFilterChanged: () => this.onFilterChanged({ source: "quickFilter" }) }); } const { gos } = this; this.alwaysPassFilter = gos.get("alwaysPassFilter"); this.addManagedPropertyListener("alwaysPassFilter", () => { this.alwaysPassFilter = gos.get("alwaysPassFilter"); this.onFilterChanged({ source: "api" }); }); } isExternalFilterPresentCallback() { const isFilterPresent = this.gos.getCallback("isExternalFilterPresent"); return typeof isFilterPresent === "function" && isFilterPresent({}); } doesExternalFilterPass(node) { const doesFilterPass = this.gos.get("doesExternalFilterPass"); return typeof doesFilterPass === "function" && doesFilterPass(node); } setFilterState(model, state, source = "api") { if (this.isAdvFilterEnabled()) { return; } this.colFilter?.setState(model, state, source); } setFilterModel(model, source = "api", skipWarning) { if (this.isAdvFilterEnabled()) { if (!skipWarning) { this.warnAdvFilters(); } return; } this.colFilter?.setModel(model, source); } getFilterModel() { return this.colFilter?.getModel() ?? {}; } getFilterState() { return this.colFilter?.getState(); } isColumnFilterPresent() { return !!this.colFilter?.isFilterPresent(); } isAggregateFilterPresent() { return !!this.colFilter?.isAggFilterPresent(); } isChildFilterPresent() { return this.isColumnFilterPresent() || this.isQuickFilterPresent() || this.externalFilterPresent || this.isAdvFilterPresent(); } isAnyFilterPresent() { return this.isChildFilterPresent() || this.isAggregateFilterPresent(); } isAdvFilterPresent() { return this.isAdvFilterEnabled() && this.advancedFilter.isFilterPresent(); } onAdvFilterEnabledChanged(enabled) { if (enabled) { if (this.colFilter?.disableFilters()) { this.onFilterChanged({ source: "advancedFilter" }); } } else if (this.advancedFilter?.isFilterPresent()) { this.advancedFilter.setModel(null); this.onFilterChanged({ source: "advancedFilter" }); } } isAdvFilterEnabled() { return !!this.advancedFilter?.isEnabled(); } isAdvFilterHeaderActive() { return this.isAdvFilterEnabled() && this.advancedFilter.isHeaderActive(); } refreshFiltersForAggregations() { if (_getGroupAggFiltering(this.gos) && this.isAnyFilterPresent()) { this.onFilterChanged(); } } onFilterChanged(params = {}) { const { source, additionalEventAttributes, columns = [] } = params; this.externalFilterPresent = this.isExternalFilterPresentCallback(); (this.colFilter ? this.colFilter.updateBeforeFilterChanged(params) : AgPromise.resolve()).then(() => { const filterChangedEvent = { source, type: "filterChanged", columns }; if (additionalEventAttributes) { _mergeDeep(filterChangedEvent, additionalEventAttributes); } this.eventSvc.dispatchEvent(filterChangedEvent); this.colFilter?.updateAfterFilterChanged(); }); } isSuppressFlashingCellsBecauseFiltering() { return !!this.colFilter?.isSuppressFlashingCellsBecauseFiltering(); } isQuickFilterPresent() { return !!this.quickFilter?.isFilterPresent(); } updateAggFiltering() { this.aggFiltering = !!_getGroupAggFiltering(this.gos); } isAggregateQuickFilterPresent() { return this.isQuickFilterPresent() && this.shouldApplyQuickFilterAfterAgg(); } isNonAggregateQuickFilterPresent() { return this.isQuickFilterPresent() && !this.shouldApplyQuickFilterAfterAgg(); } shouldApplyQuickFilterAfterAgg() { return (this.aggFiltering || this.beans.colModel.isPivotMode()) && !this.gos.get("applyQuickFilterBeforePivotOrAgg"); } doesRowPassOtherFilters(colIdToSkip, rowNode) { return this.doesRowPassFilter({ rowNode, colIdToSkip }); } doesRowPassAggregateFilters(params) { const { rowNode } = params; if (this.alwaysPassFilter?.(rowNode)) { return true; } if (this.isAggregateQuickFilterPresent() && !this.quickFilter.doesRowPass(rowNode)) { return false; } if (this.isAggregateFilterPresent() && !this.colFilter.doFiltersPass(rowNode, params.colIdToSkip, true)) { return false; } return true; } doesRowPassFilter(params) { const { rowNode } = params; if (this.alwaysPassFilter?.(rowNode)) { return true; } if (this.isNonAggregateQuickFilterPresent() && !this.quickFilter.doesRowPass(rowNode)) { return false; } if (this.externalFilterPresent && !this.doesExternalFilterPass(rowNode)) { return false; } if (this.isColumnFilterPresent() && !this.colFilter.doFiltersPass(rowNode, params.colIdToSkip)) { return false; } if (this.isAdvFilterPresent() && !this.advancedFilter.doesFilterPass(rowNode)) { return false; } return true; } isFilterAllowed(column) { if (this.isAdvFilterEnabled()) { return false; } return !!this.colFilter?.isFilterAllowed(column); } getAdvFilterModel() { return this.isAdvFilterEnabled() ? this.advancedFilter.getModel() : null; } setAdvFilterModel(expression, source = "api") { if (!this.isAdvFilterEnabled()) { return; } if (this.beans.dataTypeSvc?.isPendingInference) { this.advFilterModelUpdateQueue.push(expression); return; } this.advancedFilter.setModel(expression ?? null); this.onFilterChanged({ source }); } toggleAdvFilterBuilder(show, source) { if (!this.isAdvFilterEnabled()) { return; } this.advancedFilter.getCtrl().toggleFilterBuilder({ source, force: show }); } updateAdvFilterColumns() { if (!this.isAdvFilterEnabled()) { return; } if (this.advancedFilter.updateValidity()) { this.onFilterChanged({ source: "advancedFilter" }); } } hasFloatingFilters() { if (this.isAdvFilterEnabled()) { return false; } return !!this.colFilter?.hasFloatingFilters(); } getColumnFilterInstance(key) { if (this.isAdvFilterEnabled()) { this.warnAdvFilters(); return Promise.resolve(undefined); } return this.colFilter?.getFilterInstance(key) ?? Promise.resolve(undefined); } warnAdvFilters() { _warn(68); } setupAdvFilterHeaderComp(eCompToInsertBefore) { this.advancedFilter?.getCtrl().setupHeaderComp(eCompToInsertBefore); } getHeaderRowCount() { return this.isAdvFilterHeaderActive() ? 1 : 0; } getHeaderHeight() { return this.isAdvFilterHeaderActive() ? this.advancedFilter.getCtrl().getHeaderHeight() : 0; } processFilterModelUpdateQueue() { for (const model of this.advFilterModelUpdateQueue) { this.setAdvFilterModel(model); } this.advFilterModelUpdateQueue = []; } setColumnFilterModel(key, model) { if (this.isAdvFilterEnabled()) { this.warnAdvFilters(); return Promise.resolve(); } return this.colFilter?.setModelForColumn(key, model) ?? Promise.resolve(); } }; function getElement(className) { return { tag: "div", cls: className }; } var FilterButtonComp = class extends Component { constructor(config) { const { className = "ag-filter-apply-panel" } = config ?? {}; super(getElement(className)); this.listeners = []; this.validationMessage = null; this.className = className; } updateButtons(buttons, useForm) { const oldButtons = this.buttons; this.buttons = buttons; if (oldButtons === buttons) { return; } const eGui = this.getGui(); _clearElement(eGui); let eApplyButton; this.destroyListeners(); const fragment = document.createDocumentFragment(); const className = this.className; const addButton = ({ type, label }) => { const clickListener = (event) => { this.dispatchLocalEvent({ type, event }); }; if (!["apply", "clear", "reset", "cancel"].includes(type)) { _warn(75); } const isApply = type === "apply"; const buttonType = isApply && useForm ? "submit" : "button"; const button = _createElement({ tag: "button", attrs: { type: buttonType }, ref: `${type}FilterButton`, cls: `ag-button ag-standard-button ${className}-button${isApply ? " " + className + "-apply-button" : ""}`, children: label }); this.activateTabIndex([button]); if (isApply) { eApplyButton = button; } const keydownListener = (event) => { if (event.key === KeyCode.ENTER) { event.preventDefault(); clickListener(event); } }; const listeners = this.listeners; button.addEventListener("click", clickListener); listeners.push(() => button.removeEventListener("click", clickListener)); button.addEventListener("keydown", keydownListener); listeners.push(() => button.removeEventListener("keydown", keydownListener)); fragment.append(button); }; for (const button of buttons) { addButton(button); } this.eApply = eApplyButton; const tooltip = this.validationTooltipFeature; if (eApplyButton && !tooltip) { this.validationTooltipFeature = this.createOptionalManagedBean(this.beans.registry.createDynamicBean("tooltipFeature", false, { getGui: () => this.eApply, getLocation: () => "advancedFilter", getTooltipShowDelayOverride: () => 1000 })); } else if (!eApplyButton && tooltip) { this.validationTooltipFeature = this.destroyBean(tooltip); } eGui.append(fragment); } getApplyButton() { return this.eApply; } updateValidity(valid, message = null) { const eApplyButton = this.eApply; if (!eApplyButton) { return; } _setDisabled(eApplyButton, !valid); this.validationMessage = message; this.validationTooltipFeature?.setTooltipAndRefresh(this.validationMessage); } destroyListeners() { for (const destroyFunc of this.listeners) { destroyFunc(); } this.listeners = []; } destroy() { this.destroyListeners(); super.destroy(); } }; var FilterWrapperComp = class extends Component { constructor(column, wrapper, eventParent, updateModel, isGlobalButtons, enableGlobalButtonCheck) { super(); this.column = column; this.wrapper = wrapper; this.eventParent = eventParent; this.updateModel = updateModel; this.isGlobalButtons = isGlobalButtons; this.enableGlobalButtonCheck = enableGlobalButtonCheck; this.hidePopup = null; this.applyActive = false; } postConstruct() { const { comp, params: originalParams } = this.wrapper; const params = originalParams; const useForm = params.useForm; const tag = useForm ? "form" : "div"; this.setTemplate({ tag, cls: "ag-filter-wrapper" }); if (useForm) { this.addManagedElementListeners(this.getGui(), { submit: (e) => { e?.preventDefault(); }, keydown: this.handleKeyDown.bind(this) }); } this.appendChild(comp.getGui()); this.params = params; this.resetButtonsPanel(params); this.addManagedListeners(this.eventParent, { filterParamsChanged: ({ column, params: eventParams }) => { if (column === this.column) { this.resetButtonsPanel(eventParams, this.params); } }, filterStateChanged: ({ column, state }) => { if (column === this.column) { this.eButtons?.updateValidity(state.valid !== false); } }, filterAction: ({ column, action, event: keyboardEvent }) => { if (column === this.column) { this.afterAction(action, keyboardEvent); } }, ...this.enableGlobalButtonCheck ? { filterGlobalButtons: ({ isGlobal }) => { if (isGlobal !== this.isGlobalButtons) { this.isGlobalButtons = isGlobal; const currentParams = this.params; this.resetButtonsPanel(currentParams, currentParams, true); } } } : undefined }); } afterGuiAttached(params) { if (params) { this.hidePopup = params.hidePopup; } } resetButtonsPanel(newParams, oldParams, forceUpdate) { const { buttons: oldButtons, readOnly: oldReadOnly } = oldParams ?? {}; const { buttons: newButtons, readOnly, useForm } = newParams; if (!forceUpdate && oldReadOnly === readOnly && _jsonEquals(oldButtons, newButtons)) { return; } const hasButtons = newButtons && newButtons.length > 0 && !newParams.readOnly && !this.isGlobalButtons; let eButtonsPanel = this.eButtons; if (hasButtons) { const buttons = newButtons.map((type) => { const localeKey = `${type}Filter`; return { type, label: translateForFilter(this, localeKey) }; }); this.applyActive = _isUseApplyButton(this.params); if (!eButtonsPanel) { eButtonsPanel = this.createBean(new FilterButtonComp); this.appendChild(eButtonsPanel.getGui()); const column = this.column; const getListener = (action) => ({ event }) => { this.updateModel(column, action, { fromButtons: true }); this.afterAction(action, event); }; eButtonsPanel?.addManagedListeners(eButtonsPanel, { apply: getListener("apply"), clear: getListener("clear"), reset: getListener("reset"), cancel: getListener("cancel") }); this.eButtons = eButtonsPanel; } eButtonsPanel.updateButtons(buttons, useForm); } else { this.applyActive = false; if (eButtonsPanel) { _removeFromParent(eButtonsPanel.getGui()); this.eButtons = this.destroyBean(eButtonsPanel); } } } close(e) { const hidePopup = this.hidePopup; if (!hidePopup) { return; } const keyboardEvent = e; const key = keyboardEvent?.key; let params; if (key === KeyCode.ENTER || key === KeyCode.SPACE) { params = { keyboardEvent }; } hidePopup(params); this.hidePopup = null; } afterAction(action, event) { const { params, applyActive } = this; const closeOnApply = params?.closeOnApply; switch (action) { case "apply": { event?.preventDefault(); if (closeOnApply && applyActive) { this.close(event); } break; } case "reset": { if (closeOnApply && applyActive) { this.close(); } break; } case "cancel": { if (closeOnApply) { this.close(event); } break; } } } handleKeyDown(event) { if (!event.defaultPrevented && event.key === KeyCode.ENTER && this.applyActive) { this.updateModel(this.column, "apply", { fromButtons: true }); this.afterAction("apply", event); } } destroy() { this.hidePopup = null; this.eButtons = this.destroyBean(this.eButtons); } }; var legacyFilter_default = ":where(.ag-menu:not(.ag-tabs) .ag-filter)>:not(.ag-filter-wrapper){min-width:180px}"; var FilterElement = { tag: "div", cls: "ag-filter" }; var FilterComp = class extends Component { constructor(column, source, enableGlobalButtonCheck) { super(FilterElement); this.column = column; this.source = source; this.enableGlobalButtonCheck = enableGlobalButtonCheck; this.wrapper = null; } postConstruct() { this.beans.colFilter?.activeFilterComps.add(this); this.createFilter(true); this.addManagedEventListeners({ filterDestroyed: this.onFilterDestroyed.bind(this) }); } hasFilter() { return this.wrapper != null; } getFilter() { return this.wrapper?.then((wrapper) => wrapper.comp) ?? null; } afterInit() { return this.wrapper?.then(() => {}) ?? AgPromise.resolve(); } afterGuiAttached(params) { this.afterGuiAttachedParams = params; this.wrapper?.then((wrapper) => { this.comp?.afterGuiAttached(params); wrapper?.comp?.afterGuiAttached?.(params); }); } afterGuiDetached() { this.wrapper?.then((wrapper) => { wrapper?.comp?.afterGuiDetached?.(); }); } createFilter(init) { const { column, source, beans: { colFilter } } = this; const filterPromise = colFilter.getFilterUiForDisplay(column) ?? null; this.wrapper = filterPromise; filterPromise?.then((wrapper) => { if (!wrapper) { return; } const { isHandler, comp } = wrapper; let filterGui; if (isHandler) { const enableGlobalButtonCheck = !!this.enableGlobalButtonCheck; const displayComp = this.createBean(new FilterWrapperComp(column, wrapper, colFilter, colFilter.updateModel.bind(colFilter), enableGlobalButtonCheck && colFilter.isGlobalButtons, enableGlobalButtonCheck)); this.comp = displayComp; filterGui = displayComp.getGui(); } else { this.registerCSS(legacyFilter_default); filterGui = comp.getGui(); if (!_exists(filterGui)) { _warn(69, { guiFromFilter: filterGui }); } } this.appendChild(filterGui); if (init) { this.eventSvc.dispatchEvent({ type: "filterOpened", column, source, eGui: this.getGui() }); } else { comp.afterGuiAttached?.(this.afterGuiAttachedParams); } }); } onFilterDestroyed(event) { const { source, column } = event; if ((source === "api" || source === "paramsUpdated") && column.getId() === this.column.getId() && this.beans.colModel.getColDefCol(this.column)) { _clearElement(this.getGui()); this.comp = this.destroyBean(this.comp); this.createFilter(); } } destroy() { this.beans.colFilter?.activeFilterComps.delete(this); this.eventSvc.dispatchEvent({ type: "filterClosed", column: this.column }); this.wrapper = null; this.comp = this.destroyBean(this.comp); this.afterGuiAttachedParams = undefined; super.destroy(); } }; var FilterMenuFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "filterMenuFactory"; } wireBeans(beans) { this.popupSvc = beans.popupSvc; } hideActiveMenu() { this.hidePopup?.(); } showMenuAfterMouseEvent(column, mouseEvent, containerType, onClosedCallback) { if (column && !column.isColumn) { return; } this.showPopup(column, (eMenu) => { this.popupSvc?.positionPopupUnderMouseEvent({ additionalParams: { column }, type: containerType, mouseEvent, ePopup: eMenu }); }, containerType, mouseEvent.target, _isLegacyMenuEnabled(this.gos), onClosedCallback); } showMenuAfterButtonClick(column, eventSource, containerType, onClosedCallback) { if (column && !column.isColumn) { return; } let multiplier = -1; let alignSide = "left"; const isLegacyMenuEnabled = _isLegacyMenuEnabled(this.gos); if (!isLegacyMenuEnabled && this.gos.get("enableRtl")) { multiplier = 1; alignSide = "right"; } const nudgeX = isLegacyMenuEnabled ? undefined : 4 * multiplier; const nudgeY = isLegacyMenuEnabled ? undefined : 4; this.showPopup(column, (eMenu) => { this.popupSvc?.positionPopupByComponent({ type: containerType, eventSource, ePopup: eMenu, nudgeX, nudgeY, alignSide, keepWithinBounds: true, position: "under", additionalParams: { column } }); }, containerType, eventSource, isLegacyMenuEnabled, onClosedCallback); } showPopup(column, positionCallback, containerType, eventSource, isLegacyMenuEnabled, onClosedCallback) { const comp = column ? this.createBean(new FilterComp(column, "COLUMN_MENU")) : undefined; this.activeMenu = comp; if (!comp?.hasFilter() || !column) { _error(57); return; } const eMenu = _createElement({ tag: "div", cls: `ag-menu${!isLegacyMenuEnabled ? " ag-filter-menu" : ""}`, role: "presentation" }); [this.tabListener] = this.addManagedElementListeners(eMenu, { keydown: (e) => this.trapFocusWithin(e, eMenu) }); eMenu.appendChild(comp?.getGui()); let hidePopup; const afterGuiDetached = () => comp?.afterGuiDetached(); const anchorToElement = _isColumnMenuAnchoringEnabled(this.gos) ? eventSource ?? this.beans.ctrlsSvc.getGridBodyCtrl().eGridBody : undefined; const closedCallback = (e) => { _setColMenuVisible(column, false, "contextMenu"); const isKeyboardEvent = e instanceof KeyboardEvent; if (this.tabListener) { this.tabListener = this.tabListener(); } if (isKeyboardEvent && eventSource && _isVisible(eventSource)) { const focusableEl = _findTabbableParent(eventSource); focusableEl?.focus({ preventScroll: true }); } afterGuiDetached(); this.destroyBean(this.activeMenu); this.dispatchVisibleChangedEvent(false, containerType, column); onClosedCallback?.(); }; const translate = this.getLocaleTextFunc(); const ariaLabel = isLegacyMenuEnabled && containerType !== "columnFilter" ? translate("ariaLabelColumnMenu", "Column Menu") : translate("ariaLabelColumnFilter", "Column Filter"); const addPopupRes = this.popupSvc?.addPopup({ modal: true, eChild: eMenu, closeOnEsc: true, closedCallback, positionCallback: () => positionCallback(eMenu), anchorToElement, ariaLabel }); if (addPopupRes) { this.hidePopup = hidePopup = addPopupRes.hideFunc; } comp.afterInit().then(() => { positionCallback(eMenu); comp.afterGuiAttached({ container: containerType, hidePopup }); }); _setColMenuVisible(column, true, "contextMenu"); this.dispatchVisibleChangedEvent(true, containerType, column); } trapFocusWithin(e, menu) { if (e.key !== KeyCode.TAB || e.defaultPrevented || _findNextFocusableElement(this.beans, menu, false, e.shiftKey)) { return; } e.preventDefault(); _focusInto(menu, e.shiftKey); } dispatchVisibleChangedEvent(visible, containerType, column) { this.eventSvc.dispatchEvent({ type: "columnMenuVisibleChanged", visible, switchingTab: false, key: containerType, column: column ?? null, columnGroup: null }); } isMenuEnabled(column) { return column.isFilterAllowed() && (column.getColDef().menuTabs ?? ["filterMenuTab"]).includes("filterMenuTab"); } showMenuAfterContextMenuEvent() {} destroy() { this.destroyBean(this.activeMenu); super.destroy(); } }; var FilterValueService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "filterValueSvc"; } getValue(column, rowNode, filterValueGetterOverride) { if (!rowNode) { return; } const colDef = column.getColDef(); const { selectableFilter, valueSvc, formula } = this.beans; const filterValueGetter = filterValueGetterOverride ?? selectableFilter?.getFilterValueGetter(column.getColId()) ?? colDef.filterValueGetter; if (filterValueGetter) { return this.executeFilterValueGetter(filterValueGetter, rowNode.data, column, rowNode, colDef); } const value = valueSvc.getValue(column, rowNode, "data"); if (column.isAllowFormula() && formula?.isFormula(value)) { return formula.resolveValue(column, rowNode); } return value; } executeFilterValueGetter(valueGetter, data, column, node, colDef) { const { expressionSvc, valueSvc } = this.beans; const params = _addGridCommonParams(this.gos, { data, node, column, colDef, getValue: valueSvc.getValueCallback.bind(valueSvc, node) }); if (typeof valueGetter === "function") { return valueGetter(params); } return expressionSvc?.evaluate(valueGetter, params); } }; var AgRadioButton = class extends AgCheckbox { constructor(config) { super(config, "ag-radio-button", "radio"); } isSelected() { return this.eInput.checked; } toggle() { if (this.eInput.disabled) { return; } if (!this.isSelected()) { this.setValue(true); } } addInputListeners() { super.addInputListeners(); this.addManagedEventListeners({ checkboxChanged: this.onChange.bind(this) }); } onChange(event) { const eInput = this.eInput; if (event.selected && event.name && eInput.name && eInput.name === event.name && event.id && eInput.id !== event.id) { this.setValue(false, true); } } }; var OptionsFactory = class { constructor() { this.customFilterOptions = {}; } init(params, defaultOptions) { this.filterOptions = params.filterOptions ?? defaultOptions; this.mapCustomOptions(); this.defaultOption = this.getDefaultItem(params.defaultOption); } refresh(params, defaultOptions) { const filterOptions = params.filterOptions ?? defaultOptions; if (this.filterOptions !== filterOptions) { this.filterOptions = filterOptions; this.customFilterOptions = {}; this.mapCustomOptions(); } this.defaultOption = this.getDefaultItem(params.defaultOption); } mapCustomOptions() { const { filterOptions } = this; if (!filterOptions) { return; } for (const filterOption of filterOptions) { if (typeof filterOption === "string") { continue; } const requiredProperties = [["displayKey"], ["displayName"], ["predicate", "test"]]; const propertyCheck = (keys) => { if (!keys.some((key) => filterOption[key] != null)) { _warn(72, { keys }); return false; } return true; }; if (!requiredProperties.every(propertyCheck)) { this.filterOptions = filterOptions.filter((v) => v === filterOption) || []; continue; } this.customFilterOptions[filterOption.displayKey] = filterOption; } } getDefaultItem(defaultOption) { const { filterOptions } = this; if (defaultOption) { return defaultOption; } else if (filterOptions.length >= 1) { const firstFilterOption = filterOptions[0]; if (typeof firstFilterOption === "string") { return firstFilterOption; } else if (firstFilterOption.displayKey) { return firstFilterOption.displayKey; } else { _warn(73); } } else { _warn(74); } return; } getCustomOption(name) { return this.customFilterOptions[name]; } }; function removeItems(items, startPosition, deleteCount) { return deleteCount == null ? items.splice(startPosition) : items.splice(startPosition, deleteCount); } function isBlank(cellValue) { return cellValue == null || typeof cellValue === "string" && cellValue.trim().length === 0; } function getDefaultJoinOperator(defaultJoinOperator) { return defaultJoinOperator === "AND" || defaultJoinOperator === "OR" ? defaultJoinOperator : "AND"; } function evaluateCustomFilter(customFilterOption, values, cellValue) { if (customFilterOption == null) { return; } const { predicate } = customFilterOption; if (predicate != null && !values.some((v) => v == null)) { return predicate(values, cellValue); } } function validateAndUpdateConditions(conditions, maxNumConditions) { let numConditions = conditions.length; if (numConditions > maxNumConditions) { conditions.splice(maxNumConditions); _warn(78); numConditions = maxNumConditions; } return numConditions; } var zeroInputTypes = /* @__PURE__ */ new Set([ "empty", "notBlank", "blank", "today", "yesterday", "tomorrow", "thisWeek", "lastWeek", "nextWeek", "thisMonth", "lastMonth", "nextMonth", "thisQuarter", "lastQuarter", "nextQuarter", "thisYear", "lastYear", "nextYear", "yearToDate", "last7Days", "last30Days", "last90Days", "last6Months", "last12Months", "last24Months" ]); function getNumberOfInputs(type, optionsFactory) { const customOpts = optionsFactory.getCustomOption(type); if (customOpts) { const { numberOfInputs } = customOpts; return numberOfInputs != null ? numberOfInputs : 1; } if (type && zeroInputTypes.has(type)) { return 0; } else if (type === "inRange") { return 2; } return 1; } var SimpleFilter = class extends ProvidedFilter { constructor(filterNameKey, mapValuesFromModel, defaultOptions) { super(filterNameKey, "simple-filter"); this.mapValuesFromModel = mapValuesFromModel; this.defaultOptions = defaultOptions; this.eTypes = []; this.eJoinPanels = []; this.eJoinAnds = []; this.eJoinOrs = []; this.eConditionBodies = []; this.listener = () => this.onUiChanged(); this.lastUiCompletePosition = null; this.joinOperatorId = 0; } setParams(params) { super.setParams(params); const optionsFactory = new OptionsFactory; this.optionsFactory = optionsFactory; optionsFactory.init(params, this.defaultOptions); this.commonUpdateSimpleParams(params); this.createOption(); this.createMissingConditionsAndOperators(); } updateParams(newParams, oldParams) { this.optionsFactory.refresh(newParams, this.defaultOptions); super.updateParams(newParams, oldParams); this.commonUpdateSimpleParams(newParams); } commonUpdateSimpleParams(params) { this.setNumConditions(params); this.defaultJoinOperator = getDefaultJoinOperator(params.defaultJoinOperator); this.filterPlaceholder = params.filterPlaceholder; this.createFilterListOptions(); _addOrRemoveAttribute(this.getGui(), "tabindex", this.isReadOnly() ? "-1" : null); } onFloatingFilterChanged(type, value) { this.setTypeFromFloatingFilter(type); this.setValueFromFloatingFilter(value); this.onUiChanged("immediately", true); } setTypeFromFloatingFilter(type) { this.eTypes.forEach((eType, position) => { const value = position === 0 ? type : this.optionsFactory.defaultOption; eType.setValue(value, true); }); } getModelFromUi() { const conditions = this.getUiCompleteConditions(); if (conditions.length === 0) { return null; } if (this.maxNumConditions > 1 && conditions.length > 1) { return { filterType: this.filterType, operator: this.getJoinOperator(), conditions }; } return conditions[0]; } getConditionTypes() { return this.eTypes.map((eType) => eType.getValue()); } getConditionType(position) { return this.eTypes[position].getValue(); } getJoinOperator() { const { eJoinOrs: eJoinOperatorsOr, defaultJoinOperator } = this; return eJoinOperatorsOr.length === 0 ? defaultJoinOperator : eJoinOperatorsOr[0].getValue() === true ? "OR" : "AND"; } areNonNullModelsEqual(a, b) { const aIsSimple = !a.operator; const bIsSimple = !b.operator; const oneSimpleOneCombined = !aIsSimple && bIsSimple || aIsSimple && !bIsSimple; if (oneSimpleOneCombined) { return false; } let res; if (aIsSimple) { const aSimple = a; const bSimple = b; res = this.areSimpleModelsEqual(aSimple, bSimple); } else { const aCombined = a; const bCombined = b; res = aCombined.operator === bCombined.operator && _areEqual(aCombined.conditions, bCombined.conditions, (aModel, bModel) => this.areSimpleModelsEqual(aModel, bModel)); } return res; } setModelIntoUi(model, isInitialLoad) { if (model == null) { this.resetUiToDefaults(isInitialLoad); return AgPromise.resolve(); } const isCombined = model.operator; if (isCombined) { const combinedModel = model; let conditions = combinedModel.conditions; if (conditions == null) { conditions = []; _warn(77); } const numConditions = validateAndUpdateConditions(conditions, this.maxNumConditions); const numPrevConditions = this.getNumConditions(); if (numConditions < numPrevConditions) { this.removeConditionsAndOperators(numConditions); } else if (numConditions > numPrevConditions) { for (let i = numPrevConditions;i < numConditions; i++) { this.createJoinOperatorPanel(); this.createOption(); } } const orChecked = combinedModel.operator === "OR"; this.eJoinAnds.forEach((eJoinOperatorAnd) => eJoinOperatorAnd.setValue(!orChecked, true)); this.eJoinOrs.forEach((eJoinOperatorOr) => eJoinOperatorOr.setValue(orChecked, true)); conditions.forEach((condition, position) => { this.eTypes[position].setValue(condition.type, true); this.setConditionIntoUi(condition, position); }); } else { const simpleModel = model; if (this.getNumConditions() > 1) { this.removeConditionsAndOperators(1); } this.eTypes[0].setValue(simpleModel.type, true); this.setConditionIntoUi(simpleModel, 0); } this.lastUiCompletePosition = this.getNumConditions() - 1; this.createMissingConditionsAndOperators(); this.updateUiVisibility(); if (!isInitialLoad) { this.params.onUiChange(this.getUiChangeEventParams()); } return AgPromise.resolve(); } setNumConditions(params) { let maxNumConditions = params.maxNumConditions ?? 2; if (maxNumConditions < 1) { _warn(79); maxNumConditions = 1; } this.maxNumConditions = maxNumConditions; let numAlwaysVisibleConditions = params.numAlwaysVisibleConditions ?? 1; if (numAlwaysVisibleConditions < 1) { _warn(80); numAlwaysVisibleConditions = 1; } if (numAlwaysVisibleConditions > maxNumConditions) { _warn(81); numAlwaysVisibleConditions = maxNumConditions; } this.numAlwaysVisibleConditions = numAlwaysVisibleConditions; } createOption() { const eGui = this.getGui(); const eType = this.createManagedBean(new AgSelect); this.eTypes.push(eType); eType.addCss("ag-filter-select"); eGui.appendChild(eType.getGui()); const eConditionBody = this.createEValue(); this.eConditionBodies.push(eConditionBody); eGui.appendChild(eConditionBody); this.putOptionsIntoDropdown(eType); this.resetType(eType); const position = this.getNumConditions() - 1; this.forEachPositionInput(position, (element) => this.resetInput(element)); this.addChangedListeners(eType, position); } createJoinOperatorPanel() { const eJoinOperatorPanel = _createElement({ tag: "div", cls: "ag-filter-condition" }); this.eJoinPanels.push(eJoinOperatorPanel); const eJoinOperatorAnd = this.createJoinOperator(this.eJoinAnds, eJoinOperatorPanel, "and"); const eJoinOperatorOr = this.createJoinOperator(this.eJoinOrs, eJoinOperatorPanel, "or"); this.getGui().appendChild(eJoinOperatorPanel); const index = this.eJoinPanels.length - 1; const uniqueGroupId = this.joinOperatorId++; this.resetJoinOperatorAnd(eJoinOperatorAnd, index, uniqueGroupId); this.resetJoinOperatorOr(eJoinOperatorOr, index, uniqueGroupId); if (!this.isReadOnly()) { eJoinOperatorAnd.onValueChange(this.listener); eJoinOperatorOr.onValueChange(this.listener); } } createJoinOperator(eJoinOperators, eJoinOperatorPanel, andOr) { const eJoinOperator = this.createManagedBean(new AgRadioButton); eJoinOperators.push(eJoinOperator); const baseClass = "ag-filter-condition-operator"; eJoinOperator.addCss(baseClass); eJoinOperator.addCss(`${baseClass}-${andOr}`); eJoinOperatorPanel.appendChild(eJoinOperator.getGui()); return eJoinOperator; } createFilterListOptions() { this.filterListOptions = this.optionsFactory.filterOptions.map((option) => typeof option === "string" ? this.createBoilerplateListOption(option) : this.createCustomListOption(option)); } putOptionsIntoDropdown(eType) { const { filterListOptions } = this; for (const listOption of filterListOptions) { eType.addOption(listOption); } eType.setDisabled(filterListOptions.length <= 1); } createBoilerplateListOption(option) { return { value: option, text: this.translate(option) }; } createCustomListOption(option) { const { displayKey } = option; const customOption = this.optionsFactory.getCustomOption(option.displayKey); return { value: displayKey, text: customOption ? this.getLocaleTextFunc()(customOption.displayKey, customOption.displayName) : this.translate(displayKey) }; } createBodyTemplate() { return null; } getAgComponents() { return []; } updateUiVisibility() { const joinOperator = this.getJoinOperator(); this.updateNumConditions(); this.updateConditionStatusesAndValues(this.lastUiCompletePosition, joinOperator); } updateNumConditions() { let lastUiCompletePosition = -1; let areAllConditionsUiComplete = true; for (let position = 0;position < this.getNumConditions(); position++) { if (this.isConditionUiComplete(position)) { lastUiCompletePosition = position; } else { areAllConditionsUiComplete = false; } } if (this.shouldAddNewConditionAtEnd(areAllConditionsUiComplete)) { this.createJoinOperatorPanel(); this.createOption(); } else { const activePosition = this.lastUiCompletePosition ?? this.getNumConditions() - 2; if (lastUiCompletePosition < activePosition) { this.removeConditionsAndOperators(activePosition + 1); const removeStartPosition = lastUiCompletePosition + 1; const numConditionsToRemove = activePosition - removeStartPosition; if (numConditionsToRemove > 0) { this.removeConditionsAndOperators(removeStartPosition, numConditionsToRemove); } this.createMissingConditionsAndOperators(); } } this.lastUiCompletePosition = lastUiCompletePosition; } updateConditionStatusesAndValues(lastUiCompletePosition, joinOperator) { this.eTypes.forEach((eType, position) => { const disabled = this.isConditionDisabled(position, lastUiCompletePosition); eType.setDisabled(disabled || this.filterListOptions.length <= 1); if (position === 1) { _setDisabled(this.eJoinPanels[0], disabled); this.eJoinAnds[0].setDisabled(disabled); this.eJoinOrs[0].setDisabled(disabled); } }); this.eConditionBodies.forEach((element, index) => { _setDisplayed(element, this.isConditionBodyVisible(index)); }); const orChecked = (joinOperator ?? this.getJoinOperator()) === "OR"; for (const eJoinOperatorAnd of this.eJoinAnds) { eJoinOperatorAnd.setValue(!orChecked, true); } for (const eJoinOperatorOr of this.eJoinOrs) { eJoinOperatorOr.setValue(orChecked, true); } this.forEachInput((element, index, position, numberOfInputs) => { this.setElementDisplayed(element, index < numberOfInputs); this.setElementDisabled(element, this.isConditionDisabled(position, lastUiCompletePosition)); }); this.resetPlaceholder(); } shouldAddNewConditionAtEnd(areAllConditionsUiComplete) { return areAllConditionsUiComplete && this.getNumConditions() < this.maxNumConditions && !this.isReadOnly(); } removeConditionsAndOperators(startPosition, deleteCount) { if (startPosition >= this.getNumConditions()) { return; } const { eTypes, eConditionBodies, eJoinPanels: eJoinOperatorPanels, eJoinAnds: eJoinOperatorsAnd, eJoinOrs: eJoinOperatorsOr } = this; this.removeComponents(eTypes, startPosition, deleteCount); this.removeElements(eConditionBodies, startPosition, deleteCount); this.removeEValues(startPosition, deleteCount); const joinOperatorIndex = Math.max(startPosition - 1, 0); this.removeElements(eJoinOperatorPanels, joinOperatorIndex, deleteCount); this.removeComponents(eJoinOperatorsAnd, joinOperatorIndex, deleteCount); this.removeComponents(eJoinOperatorsOr, joinOperatorIndex, deleteCount); } removeElements(elements, startPosition, deleteCount) { const removedElements = removeItems(elements, startPosition, deleteCount); for (const element of removedElements) { _removeFromParent(element); } } removeComponents(components, startPosition, deleteCount) { const removedComponents = removeItems(components, startPosition, deleteCount); for (const comp of removedComponents) { _removeFromParent(comp.getGui()); this.destroyBean(comp); } } afterGuiAttached(params) { super.afterGuiAttached(params); this.resetPlaceholder(); if (!params?.suppressFocus) { let elementToFocus; if (!this.isReadOnly()) { const firstInput = this.getInputs(0)[0]; if (firstInput instanceof AgAbstractInputField && this.isConditionBodyVisible(0)) { elementToFocus = firstInput.getInputElement(); } else { elementToFocus = this.eTypes[0]?.getFocusableElement(); } } (elementToFocus ?? this.getGui()).focus({ preventScroll: true }); } } shouldKeepInvalidInputState() { return false; } afterGuiDetached() { super.afterGuiDetached(); const params = this.params; if (this.beans.colFilter?.shouldKeepStateOnDetach(params.column) || this.shouldKeepInvalidInputState()) { return; } params.onStateChange({ model: params.model }); let lastUiCompletePosition = -1; let updatedLastUiCompletePosition = -1; let conditionsRemoved = false; const joinOperator = this.getJoinOperator(); for (let position = this.getNumConditions() - 1;position >= 0; position--) { if (this.isConditionUiComplete(position)) { if (lastUiCompletePosition === -1) { lastUiCompletePosition = position; updatedLastUiCompletePosition = position; } } else { const shouldRemovePositionAtEnd = position >= this.numAlwaysVisibleConditions && !this.isConditionUiComplete(position - 1); const positionBeforeLastUiCompletePosition = position < lastUiCompletePosition; if (shouldRemovePositionAtEnd || positionBeforeLastUiCompletePosition) { this.removeConditionsAndOperators(position, 1); conditionsRemoved = true; if (positionBeforeLastUiCompletePosition) { updatedLastUiCompletePosition--; } } } } let shouldUpdateConditionStatusesAndValues = false; if (this.getNumConditions() < this.numAlwaysVisibleConditions) { this.createMissingConditionsAndOperators(); shouldUpdateConditionStatusesAndValues = true; } if (this.shouldAddNewConditionAtEnd(updatedLastUiCompletePosition === this.getNumConditions() - 1)) { this.createJoinOperatorPanel(); this.createOption(); shouldUpdateConditionStatusesAndValues = true; } if (shouldUpdateConditionStatusesAndValues) { this.updateConditionStatusesAndValues(updatedLastUiCompletePosition, joinOperator); } if (conditionsRemoved) { this.updateJoinOperatorsDisabled(); } this.lastUiCompletePosition = updatedLastUiCompletePosition; } getModelAsString(model) { return this.params.getHandler()?.getModelAsString?.(model) ?? ""; } resetPlaceholder() { const globalTranslate = this.getLocaleTextFunc(); const { filterPlaceholder, eTypes } = this; this.forEachInput((element, index, position, numberOfInputs) => { if (!(element instanceof AgAbstractInputField)) { return; } const placeholderKey = index === 0 && numberOfInputs > 1 ? "inRangeStart" : index === 0 ? "filterOoo" : "inRangeEnd"; const ariaLabel = index === 0 && numberOfInputs > 1 ? globalTranslate("ariaFilterFromValue", "Filter from value") : index === 0 ? globalTranslate("ariaFilterValue", "Filter Value") : globalTranslate("ariaFilterToValue", "Filter to Value"); const filterOptionKey = eTypes[position].getValue(); const placeholderText = getPlaceholderText(this, filterPlaceholder, placeholderKey, filterOptionKey); element.setInputPlaceholder(placeholderText); element.setInputAriaLabel(ariaLabel); }); } setElementValue(element, value, fromFloatingFilter) { if (element instanceof AgAbstractInputField) { element.setValue(value != null ? String(value) : null, true); } } setElementDisplayed(element, displayed) { if (_isComponent(element)) { _setDisplayed(element.getGui(), displayed); } } setElementDisabled(element, disabled) { if (_isComponent(element)) { _setDisabled(element.getGui(), disabled); } } attachElementOnChange(element, listener) { if (element instanceof AgAbstractInputField) { element.onValueChange(listener); } } forEachInput(cb) { this.getConditionTypes().forEach((type, position) => { this.forEachPositionTypeInput(position, type, cb); }); } forEachPositionInput(position, cb) { const type = this.getConditionType(position); this.forEachPositionTypeInput(position, type, cb); } forEachPositionTypeInput(position, type, cb) { const numberOfInputs = getNumberOfInputs(type, this.optionsFactory); const inputs = this.getInputs(position); for (let index = 0;index < inputs.length; index++) { const input = inputs[index]; if (input != null) { cb(input, index, position, numberOfInputs); } } } isConditionDisabled(position, lastUiCompletePosition) { if (this.isReadOnly()) { return true; } if (position === 0) { return false; } return position > lastUiCompletePosition + 1; } isConditionBodyVisible(position) { const type = this.getConditionType(position); const numberOfInputs = getNumberOfInputs(type, this.optionsFactory); return numberOfInputs > 0; } isConditionUiComplete(position) { if (position >= this.getNumConditions()) { return false; } const type = this.getConditionType(position); if (type === "empty") { return false; } if (this.getValues(position).some((v) => v == null)) { return false; } if (this.positionHasInvalidInputs(position)) { return false; } return true; } getNumConditions() { return this.eTypes.length; } getUiCompleteConditions() { const conditions = []; for (let position = 0;position < this.getNumConditions(); position++) { if (this.isConditionUiComplete(position)) { conditions.push(this.createCondition(position)); } } return conditions; } createMissingConditionsAndOperators() { if (this.isReadOnly()) { return; } for (let i = this.getNumConditions();i < this.numAlwaysVisibleConditions; i++) { this.createJoinOperatorPanel(); this.createOption(); } } resetUiToDefaults(silent) { this.removeConditionsAndOperators(this.isReadOnly() ? 1 : this.numAlwaysVisibleConditions); this.eTypes.forEach((eType) => this.resetType(eType)); this.eJoinAnds.forEach((eJoinOperatorAnd, index) => this.resetJoinOperatorAnd(eJoinOperatorAnd, index, this.joinOperatorId + index)); this.eJoinOrs.forEach((eJoinOperatorOr, index) => this.resetJoinOperatorOr(eJoinOperatorOr, index, this.joinOperatorId + index)); this.joinOperatorId++; this.forEachInput((element) => this.resetInput(element)); this.resetPlaceholder(); this.createMissingConditionsAndOperators(); this.lastUiCompletePosition = null; this.updateUiVisibility(); if (!silent) { this.params.onUiChange(this.getUiChangeEventParams()); } } resetType(eType) { const translate = this.getLocaleTextFunc(); const filteringLabel = translate("ariaFilteringOperator", "Filtering operator"); eType.setValue(this.optionsFactory.defaultOption, true).setAriaLabel(filteringLabel).setDisabled(this.isReadOnly() || this.filterListOptions.length <= 1); } resetJoinOperatorAnd(eJoinOperatorAnd, index, uniqueGroupId) { this.resetJoinOperator(eJoinOperatorAnd, index, this.defaultJoinOperator === "AND", this.translate("andCondition"), uniqueGroupId); } resetJoinOperatorOr(eJoinOperatorOr, index, uniqueGroupId) { this.resetJoinOperator(eJoinOperatorOr, index, this.defaultJoinOperator === "OR", this.translate("orCondition"), uniqueGroupId); } resetJoinOperator(eJoinOperator, index, value, label, uniqueGroupId) { this.updateJoinOperatorDisabled(eJoinOperator.setValue(value, true).setName(`ag-simple-filter-and-or-${this.getCompId()}-${uniqueGroupId}`).setLabel(label), index); } updateJoinOperatorsDisabled() { const updater = (eJoinOperator, index) => this.updateJoinOperatorDisabled(eJoinOperator, index); this.eJoinAnds.forEach(updater); this.eJoinOrs.forEach(updater); } updateJoinOperatorDisabled(eJoinOperator, index) { eJoinOperator.setDisabled(this.isReadOnly() || index > 0); } resetInput(element) { this.setElementValue(element, null); this.setElementDisabled(element, this.isReadOnly()); } setConditionIntoUi(model, position) { const values = this.mapValuesFromModel(model, this.optionsFactory); this.forEachInput((element, index, elPosition) => { if (elPosition !== position) { return; } this.setElementValue(element, values[index] != null ? values[index] : null); }); } setValueFromFloatingFilter(value) { this.forEachInput((element, index, position) => { this.setElementValue(element, index === 0 && position === 0 ? value : null, true); }); } addChangedListeners(eType, position) { if (this.isReadOnly()) { return; } eType.onValueChange(this.listener); this.forEachPositionInput(position, (element) => { this.attachElementOnChange(element, this.listener); }); } hasInvalidInputs() { return false; } positionHasInvalidInputs(_position) { return false; } isReadOnly() { return !!this.params.readOnly; } }; var SimpleFilterHandler = class extends BeanStub { constructor(mapValuesFromModel, defaultOptions) { super(); this.mapValuesFromModel = mapValuesFromModel; this.defaultOptions = defaultOptions; } init(params) { const filterParams = params.filterParams; const optionsFactory = new OptionsFactory; this.optionsFactory = optionsFactory; optionsFactory.init(filterParams, this.defaultOptions); this.filterModelFormatter = this.createManagedBean(new this.FilterModelFormatterClass(optionsFactory, filterParams)); this.updateParams(params); this.validateModel(params); } refresh(params) { if (params.source === "colDef") { const filterParams = params.filterParams; const optionsFactory = this.optionsFactory; optionsFactory.refresh(filterParams, this.defaultOptions); this.filterModelFormatter.updateParams({ optionsFactory, filterParams }); this.updateParams(params); } this.validateModel(params); } updateParams(params) { this.params = params; } doesFilterPass(params) { const model = params.model; if (model == null) { return true; } const { operator } = model; const models = []; if (operator) { const combinedModel = model; models.push(...combinedModel.conditions ?? []); } else { models.push(model); } const combineFunction = operator && operator === "OR" ? "some" : "every"; const cellValue = this.params.getValue(params.node); return models[combineFunction]((m) => this.individualConditionPasses(params, m, cellValue)); } getModelAsString(model, source) { return this.filterModelFormatter.getModelAsString(model, source) ?? ""; } validateModel(params) { const { model, filterParams: { filterOptions, maxNumConditions } } = params; if (model == null) { return; } const isCombined = isCombinedFilterModel(model); let conditions = isCombined ? model.conditions : [model]; const newOptionsList = filterOptions?.map((option) => typeof option === "string" ? option : option.displayKey) ?? this.defaultOptions; const allConditionsExistInNewOptionsList = !conditions || conditions.every((condition) => newOptionsList.find((option) => option === condition.type) !== undefined); if (!allConditionsExistInNewOptionsList) { this.params = { ...params, model: null }; params.onModelChange(null); return; } let needsUpdate = false; const filterType = this.filterType; if (conditions && !conditions.every((condition) => condition.filterType === filterType) || model.filterType !== filterType) { conditions = conditions.map((condition) => ({ ...condition, filterType })); needsUpdate = true; } if (typeof maxNumConditions === "number" && conditions && conditions.length > maxNumConditions) { conditions = conditions.slice(0, maxNumConditions); needsUpdate = true; } if (needsUpdate) { const updatedModel = conditions.length > 1 ? { ...model, filterType, conditions } : { ...conditions[0], filterType }; this.params = { ...params, model: updatedModel }; params.onModelChange(updatedModel); } } individualConditionPasses(params, filterModel, cellValue) { const optionsFactory = this.optionsFactory; const values = this.mapValuesFromModel(filterModel, optionsFactory); const customFilterOption = optionsFactory.getCustomOption(filterModel.type); const customFilterResult = evaluateCustomFilter(customFilterOption, values, cellValue); if (customFilterResult != null) { return customFilterResult; } if (cellValue == null) { return this.evaluateNullValue(filterModel.type); } return this.evaluateNonNullValue(values, cellValue, filterModel, params); } }; var ScalarFilterHandler = class extends SimpleFilterHandler { evaluateNullValue(filterType) { const { includeBlanksInEquals, includeBlanksInNotEqual, includeBlanksInGreaterThan, includeBlanksInLessThan, includeBlanksInRange } = this.params.filterParams; switch (filterType) { case "equals": if (includeBlanksInEquals) { return true; } break; case "notEqual": if (includeBlanksInNotEqual) { return true; } break; case "greaterThan": case "greaterThanOrEqual": if (includeBlanksInGreaterThan) { return true; } break; case "lessThan": case "lessThanOrEqual": if (includeBlanksInLessThan) { return true; } break; case "inRange": if (includeBlanksInRange) { return true; } break; case "blank": return true; case "notBlank": return false; } return false; } evaluateNonNullValue(values, cellValue, filterModel) { const type = filterModel.type; if (!this.isValid(cellValue)) { return type === "notEqual" || type === "notBlank"; } const comparator = this.comparator(); const compareResult = values[0] != null ? comparator(values[0], cellValue) : 0; switch (type) { case "equals": return compareResult === 0; case "notEqual": return compareResult !== 0; case "greaterThan": return compareResult > 0; case "greaterThanOrEqual": return compareResult >= 0; case "lessThan": return compareResult < 0; case "lessThanOrEqual": return compareResult <= 0; case "inRange": { const compareToResult = comparator(values[1], cellValue); return this.params.filterParams.inRangeInclusive ? compareResult >= 0 && compareToResult <= 0 : compareResult > 0 && compareToResult < 0; } case "blank": return isBlank(cellValue); case "notBlank": return !isBlank(cellValue); default: _warn(76, { filterModelType: type }); return true; } } }; var SCALAR_FILTER_TYPE_KEYS = { equals: "Equals", notEqual: "NotEqual", greaterThan: "GreaterThan", greaterThanOrEqual: "GreaterThanOrEqual", lessThan: "LessThan", lessThanOrEqual: "LessThanOrEqual", inRange: "InRange" }; var TEXT_FILTER_TYPE_KEYS = { contains: "Contains", notContains: "NotContains", equals: "TextEquals", notEqual: "TextNotEqual", startsWith: "StartsWith", endsWith: "EndsWith", inRange: "InRange" }; var SimpleFilterModelFormatter = class extends BeanStub { constructor(optionsFactory, filterParams, valueFormatter) { super(); this.optionsFactory = optionsFactory; this.filterParams = filterParams; this.valueFormatter = valueFormatter; } getModelAsString(model, source) { const translate = this.getLocaleTextFunc(); const forToolPanel = source === "filterToolPanel"; if (!model) { return forToolPanel ? translateForFilter(this, "filterSummaryInactive") : null; } const isCombined = model.operator != null; if (isCombined) { const combinedModel = model; const conditions = combinedModel.conditions ?? []; const customOptions = conditions.map((condition) => this.getModelAsString(condition, source)); const joinOperatorTranslateKey = combinedModel.operator === "AND" ? "andCondition" : "orCondition"; return customOptions.join(` ${translateForFilter(this, joinOperatorTranslateKey)} `); } else if (model.type === "blank" || model.type === "notBlank") { return forToolPanel ? translateForFilter(this, model.type === "blank" ? "filterSummaryBlank" : "filterSummaryNotBlank") : translate(model.type, model.type); } else { const condition = model; const customOption = this.optionsFactory.getCustomOption(condition.type); const { displayKey, displayName, numberOfInputs } = customOption || {}; if (displayKey && displayName && numberOfInputs === 0) { return translate(displayKey, displayName); } return this.conditionToString(condition, forToolPanel, condition.type === "inRange" || numberOfInputs === 2, displayKey, displayName); } } updateParams(params) { const { optionsFactory, filterParams } = params; this.optionsFactory = optionsFactory; this.filterParams = filterParams; } conditionForToolPanel(type, isRange, getFilter, getFilterTo, customDisplayKey, customDisplayName) { let typeValue; const typeKey = this.getTypeKey(type); if (typeKey) { typeValue = translateForFilter(this, typeKey); } if (customDisplayKey && customDisplayName) { typeValue = this.getLocaleTextFunc()(customDisplayKey, customDisplayName); } if (typeValue != null) { if (isRange) { return `${typeValue} ${translateForFilter(this, "filterSummaryInRangeValues", [getFilter(), getFilterTo()])}`; } else { return `${typeValue} ${getFilter()}`; } } return null; } getTypeKey(type) { const suffix = this.filterTypeKeys[type]; return suffix ? `filterSummary${suffix}` : null; } formatValue(value) { const valueFormatter = this.valueFormatter; return valueFormatter ? valueFormatter(value ?? null) ?? "" : String(value); } }; var FloatingFilterTextInputService = class extends BeanStub { constructor(params) { super(); this.params = params; this.eInput = RefPlaceholder; this.onValueChanged = () => {}; } setupGui(parentElement) { this.eInput = this.createManagedBean(new AgInputTextField(this.params?.config)); const eInput = this.eInput.getGui(); parentElement.appendChild(eInput); const listener = (e) => this.onValueChanged(e); this.addManagedListeners(eInput, { input: listener, keydown: listener }); } setEditable(editable) { this.eInput.setDisabled(!editable); } getValue() { return this.eInput.getValue(); } setValue(value, silent) { this.eInput.setValue(value, silent); } setValueChangedListener(listener) { this.onValueChanged = listener; } setParams({ ariaLabel, autoComplete, placeholder }) { const { eInput } = this; eInput.setInputAriaLabel(ariaLabel); if (autoComplete !== undefined) { eInput.setAutoComplete(autoComplete); } eInput.toggleCss("ag-floating-filter-search-icon", !!placeholder); eInput.setInputPlaceholder(placeholder); } }; function trimInputForFilter(value) { const trimmedInput = value?.trim(); return trimmedInput === "" ? value : trimmedInput; } function mapValuesFromTextFilterModel(filterModel, optionsFactory) { const { filter, filterTo, type } = filterModel || {}; return [filter || null, filterTo || null].slice(0, getNumberOfInputs(type, optionsFactory)); } var SimpleFloatingFilter = class extends Component { constructor() { super(...arguments); this.defaultDebounceMs = 0; } setLastTypeFromModel(model) { if (!model) { this.lastType = this.optionsFactory.defaultOption; return; } const isCombined = model.operator; let condition; if (isCombined) { const combinedModel = model; condition = combinedModel.conditions[0]; } else { condition = model; } this.lastType = condition.type; } canWeEditAfterModelFromParentFilter(model) { if (!model) { return this.isTypeEditable(this.lastType); } const isCombined = model.operator; if (isCombined) { return false; } const simpleModel = model; return this.isTypeEditable(simpleModel.type); } init(params) { this.params = params; const reactive = this.gos.get("enableFilterHandlers"); this.reactive = reactive; this.setParams(params); if (reactive) { const reactiveParams = params; this.onModelUpdated(reactiveParams.model); } } setParams(params) { const optionsFactory = new OptionsFactory; this.optionsFactory = optionsFactory; optionsFactory.init(params.filterParams, this.defaultOptions); this.filterModelFormatter = this.createManagedBean(new this.FilterModelFormatterClass(optionsFactory, params.filterParams)); this.setSimpleParams(params, false); } setSimpleParams(params, update = true) { const defaultOption = this.optionsFactory.defaultOption; if (!update) { this.lastType = defaultOption; } this.readOnly = !!params.filterParams.readOnly; const editable = this.isTypeEditable(defaultOption); this.setEditable(editable); } refresh(params) { this.params = params; const reactiveParams = params; const reactive = this.reactive; if (!reactive || reactiveParams.source === "colDef") { this.updateParams(params); } if (reactive) { const { source, model } = reactiveParams; if (source === "dataChanged" || source === "ui") { return; } this.onModelUpdated(model); } } updateParams(params) { const optionsFactory = this.optionsFactory; optionsFactory.refresh(params.filterParams, this.defaultOptions); this.setSimpleParams(params); this.filterModelFormatter.updateParams({ optionsFactory, filterParams: params.filterParams }); } onParentModelChanged(model, event) { if (event?.afterFloatingFilter || event?.afterDataChange) { return; } this.onModelUpdated(model); } isTypeEditable(type) { return !!type && !this.readOnly && getNumberOfInputs(type, this.optionsFactory) === 1; } getAriaLabel(column) { const displayName = this.beans.colNames.getDisplayNameForColumn(column, "header", true); return `${displayName} ${this.getLocaleTextFunc()("ariaFilterInput", "Filter Input")}`; } }; var TextInputFloatingFilterElement = { tag: "div", ref: "eFloatingFilterInputContainer", cls: "ag-floating-filter-input", role: "presentation" }; var TextInputFloatingFilter = class extends SimpleFloatingFilter { constructor() { super(...arguments); this.eFloatingFilterInputContainer = RefPlaceholder; this.defaultDebounceMs = 500; } postConstruct() { this.setTemplate(TextInputFloatingFilterElement); } onModelUpdated(model) { this.setLastTypeFromModel(model); this.setEditable(this.canWeEditAfterModelFromParentFilter(model)); this.inputSvc.setValue(this.filterModelFormatter.getModelAsString(model)); } setParams(params) { this.setupFloatingFilterInputService(params); super.setParams(params); this.setTextInputParams(params); } setupFloatingFilterInputService(params) { this.inputSvc = this.createFloatingFilterInputService(params); this.inputSvc.setupGui(this.eFloatingFilterInputContainer); } setTextInputParams(params) { const { inputSvc, defaultDebounceMs, readOnly } = this; const { filterPlaceholder, column, browserAutoComplete, filterParams } = params; const filterOptionKey = this.lastType ?? this.optionsFactory.defaultOption; const parentFilterPlaceholder = params.filterParams.filterPlaceholder; const placeholder = filterPlaceholder === true ? getPlaceholderText(this, parentFilterPlaceholder, "filterOoo", filterOptionKey) : filterPlaceholder || undefined; inputSvc.setParams({ ariaLabel: this.getAriaLabel(column), autoComplete: browserAutoComplete ?? false, placeholder }); this.applyActive = _isUseApplyButton(filterParams); if (!readOnly) { const debounceMs = getDebounceMs(filterParams, defaultDebounceMs); inputSvc.setValueChangedListener(_debounce(this, this.syncUpWithParentFilter.bind(this), debounceMs)); } } updateParams(params) { super.updateParams(params); this.setTextInputParams(params); } recreateFloatingFilterInputService(params) { const { inputSvc } = this; const value = inputSvc.getValue(); _clearElement(this.eFloatingFilterInputContainer); this.destroyBean(inputSvc); this.setupFloatingFilterInputService(params); inputSvc.setValue(value, true); } syncUpWithParentFilter(e) { const isEnterKey = e.key === KeyCode.ENTER; const reactive = this.reactive; if (reactive) { const reactiveParams = this.params; reactiveParams.onUiChange(); } if (this.applyActive && !isEnterKey) { return; } const { inputSvc, params, lastType } = this; let value = inputSvc.getValue(); if (params.filterParams.trimInput) { value = trimInputForFilter(value); inputSvc.setValue(value, true); } if (reactive) { const reactiveParams = params; const model = reactiveParams.model; const parsedValue = this.convertValue(value); const newModel = parsedValue == null ? null : { ...model ?? { filterType: this.filterType, type: lastType ?? this.optionsFactory.defaultOption }, filter: parsedValue }; reactiveParams.onModelChange(newModel, { afterFloatingFilter: true }); } else { params.parentFilterInstance((filterInstance) => { filterInstance?.onFloatingFilterChanged(lastType || null, value || null); }); } } convertValue(value) { return value || null; } setEditable(editable) { this.inputSvc.setEditable(editable); } }; var CLASS_INPUT_FIELD = ".ag-input-field-input"; var DateCompWrapper = class { constructor(context, userCompFactory, colDef, dateComponentParams, eParent, onReady) { this.context = context; this.eParent = eParent; this.alive = true; this.debouncedReport = _debounce({ isAlive: () => this.alive }, reportValidity, 500); this.timeoutHandle = null; const compDetails = _getDateCompDetails(userCompFactory, colDef, dateComponentParams); compDetails?.newAgStackInstance().then((dateComp) => { if (!this.alive) { context.destroyBean(dateComp); return; } this.dateComp = dateComp; if (!dateComp) { return; } eParent.appendChild(dateComp.getGui()); dateComp?.afterGuiAttached?.(); const { tempValue, disabled } = this; if (tempValue) { dateComp.setDate(tempValue); } if (disabled != null) { dateComp.setDisabled?.(disabled); } onReady?.(this); }); } destroy() { this.alive = false; this.dateComp = this.context.destroyBean(this.dateComp); } getDate() { return this.dateComp ? this.dateComp.getDate() : this.tempValue; } setDate(value) { const dateComp = this.dateComp; if (dateComp) { dateComp.setDate(value); } else { this.tempValue = value; } } setDisabled(disabled) { const dateComp = this.dateComp; if (dateComp) { dateComp.setDisabled?.(disabled); } else { this.disabled = disabled; } } setDisplayed(displayed) { _setDisplayed(this.eParent, displayed); } setInputPlaceholder(placeholder) { this.dateComp?.setInputPlaceholder?.(placeholder); } setInputAriaLabel(label) { this.dateComp?.setInputAriaLabel?.(label); } afterGuiAttached(params) { this.dateComp?.afterGuiAttached?.(params); } updateParams(params) { this.dateComp?.refresh?.(params); } setCustomValidity(message, defer = false) { const eInput = this.dateComp?.getGui().querySelector(CLASS_INPUT_FIELD); if (eInput && "setCustomValidity" in eInput) { const isInvalid = message.length > 0; eInput.setCustomValidity(message); if (isInvalid) { if (defer) { this.timeoutHandle = this.debouncedReport(eInput); } else { reportValidity(eInput); } } else if (this.timeoutHandle) { window.clearTimeout(this.timeoutHandle); } _setAriaInvalid(eInput, isInvalid); } } getValidity() { return this.dateComp?.getGui().querySelector(CLASS_INPUT_FIELD)?.validity; } }; function reportValidity(eInput) { eInput.reportValidity(); } var DEFAULT_DATE_FILTER_OPTIONS = [ "equals", "notEqual", "lessThan", "greaterThan", "inRange", "blank", "notBlank" ]; function mapValuesFromDateFilterModel(filterModel, optionsFactory) { const { dateFrom, dateTo, type } = filterModel || {}; return [ dateFrom && _parseDateTimeFromString(dateFrom, undefined, true) || null, dateTo && _parseDateTimeFromString(dateTo, undefined, true) || null ].slice(0, getNumberOfInputs(type, optionsFactory)); } var DEFAULT_MIN_YEAR = 1000; var DEFAULT_MAX_YEAR = Infinity; var DateFilter = class extends SimpleFilter { constructor() { super("dateFilter", mapValuesFromDateFilterModel, DEFAULT_DATE_FILTER_OPTIONS); this.eConditionPanelsFrom = []; this.eConditionPanelsTo = []; this.dateConditionFromComps = []; this.dateConditionToComps = []; this.minValidYear = DEFAULT_MIN_YEAR; this.maxValidYear = DEFAULT_MAX_YEAR; this.minValidDate = null; this.maxValidDate = null; this.filterType = "date"; } afterGuiAttached(params) { super.afterGuiAttached(params); this.dateConditionFromComps[0].afterGuiAttached(params); this.refreshInputValidation(); } shouldKeepInvalidInputState() { return !_isBrowserFirefox() && this.hasInvalidInputs() && this.getConditionTypes().includes("inRange"); } commonUpdateSimpleParams(params) { super.commonUpdateSimpleParams(params); const yearParser = (param, fallback) => { const value = params[param]; if (value != null) { if (!isNaN(value)) { return value == null ? fallback : Number(value); } else { _warn(82, { param }); } } return fallback; }; const minValidYear = yearParser("minValidYear", DEFAULT_MIN_YEAR); const maxValidYear = yearParser("maxValidYear", DEFAULT_MAX_YEAR); this.minValidYear = minValidYear; this.maxValidYear = maxValidYear; if (minValidYear > maxValidYear) { _warn(83); } const { minValidDate, maxValidDate } = params; const parsedMinValidDate = minValidDate instanceof Date ? minValidDate : _parseDateTimeFromString(minValidDate); this.minValidDate = parsedMinValidDate; const parsedMaxValidDate = maxValidDate instanceof Date ? maxValidDate : _parseDateTimeFromString(maxValidDate); this.maxValidDate = parsedMaxValidDate; if (parsedMinValidDate && parsedMaxValidDate && parsedMinValidDate > parsedMaxValidDate) { _warn(84); } } refreshInputValidation() { for (let i = 0;i < this.dateConditionFromComps.length; i++) { this.refreshInputPairValidation(i, false, true); } } refreshInputPairValidation(position, isFrom = false, forceImmediate = false) { const { dateConditionFromComps, dateConditionToComps, beans } = this; const from = dateConditionFromComps[position]; const to = dateConditionToComps[position]; const numberOfInputs = getNumberOfInputs(this.getConditionType(position), this.optionsFactory); const fromDate = from.getDate(); const toDate = to.getDate(); const localeKey = numberOfInputs >= 2 ? getRangeValidityMessageKey(fromDate, toDate, isFrom) : null; const message = localeKey ? this.translate(localeKey, [String(isFrom ? toDate : fromDate)]) : ""; const shouldDebounceReport = !_isBrowserFirefox() && !forceImmediate; (isFrom ? from : to).setCustomValidity(message, shouldDebounceReport); (isFrom ? to : from).setCustomValidity("", shouldDebounceReport); if (message.length > 0) { beans.ariaAnnounce.announceValue(message, "dateFilter"); } } createDateCompWrapper(element, position, fromTo) { const { beans: { userCompFactory, context, gos }, params } = this; const isFrom = fromTo === "from"; const dateCompWrapper = new DateCompWrapper(context, userCompFactory, params.colDef, _addGridCommonParams(gos, { onDateChanged: () => { this.refreshInputPairValidation(position, isFrom); this.onUiChanged(); }, onFocusIn: () => this.refreshInputPairValidation(position, isFrom), filterParams: params, location: "filter" }), element); this.addDestroyFunc(() => dateCompWrapper.destroy()); return dateCompWrapper; } getState() { return { isInvalid: this.hasInvalidInputs() }; } areStatesEqual(stateA, stateB) { return (stateA?.isInvalid ?? false) === (stateB?.isInvalid ?? false); } setElementValue(element, value) { element.setDate(value); if (!value) { element.setCustomValidity(""); } } setElementDisplayed(element, displayed) { element.setDisplayed(displayed); } setElementDisabled(element, disabled) { element.setDisabled(disabled); } createEValue() { const eCondition = _createElement({ tag: "div", cls: "ag-filter-body" }); this.createFromToElement(eCondition, this.eConditionPanelsFrom, this.dateConditionFromComps, "from"); this.createFromToElement(eCondition, this.eConditionPanelsTo, this.dateConditionToComps, "to"); return eCondition; } createFromToElement(eCondition, eConditionPanels, dateConditionComps, fromTo) { const eConditionPanel = _createElement({ tag: "div", cls: `ag-filter-${fromTo} ag-filter-date-${fromTo}` }); eConditionPanels.push(eConditionPanel); eCondition.appendChild(eConditionPanel); dateConditionComps.push(this.createDateCompWrapper(eConditionPanel, eConditionPanels.length - 1, fromTo)); } removeEValues(startPosition, deleteCount) { this.removeDateComps(this.dateConditionFromComps, startPosition, deleteCount); this.removeDateComps(this.dateConditionToComps, startPosition, deleteCount); removeItems(this.eConditionPanelsFrom, startPosition, deleteCount); removeItems(this.eConditionPanelsTo, startPosition, deleteCount); } removeDateComps(components, startPosition, deleteCount) { const removedComponents = removeItems(components, startPosition, deleteCount); for (const comp of removedComponents) { comp.destroy(); } } isValidDateValue(value) { if (value === null) { return false; } const { minValidDate, maxValidDate, minValidYear, maxValidYear } = this; if (minValidDate) { if (value < minValidDate) { return false; } } else if (value.getUTCFullYear() < minValidYear) { return false; } if (maxValidDate) { if (value > maxValidDate) { return false; } } else if (value.getUTCFullYear() > maxValidYear) { return false; } return true; } hasInvalidInputs() { let invalidInputs = false; this.forEachInput((element) => invalidInputs || (invalidInputs = element.getDate() != null && !(element.getValidity()?.valid ?? true))); return invalidInputs; } positionHasInvalidInputs(position) { let invalidInputs = false; this.forEachPositionInput(position, (element) => invalidInputs || (invalidInputs = !(element.getValidity()?.valid ?? true))); return invalidInputs; } canApply(_model) { return !this.hasInvalidInputs(); } isConditionUiComplete(position) { if (!super.isConditionUiComplete(position)) { return false; } let valid = true; this.forEachPositionInput(position, (element, index, _pos, numberOfInputs) => { if (!valid || index >= numberOfInputs) { return; } valid && (valid = this.isValidDateValue(element.getDate())); }); return valid; } areSimpleModelsEqual(aSimple, bSimple) { return aSimple.dateFrom === bSimple.dateFrom && aSimple.dateTo === bSimple.dateTo && aSimple.type === bSimple.type; } createCondition(position) { const type = this.getConditionType(position); const model = {}; const { params, filterType } = this; const values = this.getValues(position); const separator = params.useIsoSeparator ? "T" : " "; if (values.length > 0) { model.dateFrom = _serialiseDate(values[0], true, separator); } if (values.length > 1) { model.dateTo = _serialiseDate(values[1], true, separator); } return { dateFrom: null, dateTo: null, filterType, type, ...model }; } removeConditionsAndOperators(startPosition, deleteCount) { if (this.hasInvalidInputs()) { return; } return super.removeConditionsAndOperators(startPosition, deleteCount); } resetPlaceholder() { const globalTranslate = this.getLocaleTextFunc(); const placeholder = this.translate("dateFormatOoo"); const ariaLabel = globalTranslate("ariaFilterValue", "Filter Value"); this.forEachInput((element) => { element.setInputPlaceholder(placeholder); element.setInputAriaLabel(ariaLabel); }); } getInputs(position) { const { dateConditionFromComps, dateConditionToComps } = this; if (position >= dateConditionFromComps.length) { return [null, null]; } return [dateConditionFromComps[position], dateConditionToComps[position]]; } getValues(position) { const result = []; this.forEachPositionInput(position, (element, index, _elPosition, numberOfInputs) => { if (index < numberOfInputs) { result.push(element.getDate()); } }); return result; } translate(key, variableValues) { let normalisedKey = key; if (key === "lessThan") { normalisedKey = "before"; } else if (key === "greaterThan") { normalisedKey = "after"; } return super.translate(normalisedKey, variableValues); } }; function getRangeValidityMessageKey(fromDate, toDate, isFrom) { const isInvalid = fromDate != null && toDate != null && fromDate >= toDate; if (!isInvalid) { return null; } return `${isFrom ? "max" : "min"}DateValidation`; } var DateFilterModelFormatter = class extends SimpleFilterModelFormatter { constructor(optionsFactory, filterParams) { super(optionsFactory, filterParams, (value) => { const { dataTypeSvc, valueSvc } = this.beans; const column = filterParams.column; const dateFormatFn = dataTypeSvc?.getDateFormatterFunction(column); const valueToFormat = dateFormatFn ? dateFormatFn(value ?? undefined) : value; return valueSvc.formatValue(column, null, valueToFormat); }); this.filterTypeKeys = SCALAR_FILTER_TYPE_KEYS; } conditionToString(condition, forToolPanel, isRange, customDisplayKey, customDisplayName) { const { type } = condition; const dateFrom = _parseDateTimeFromString(condition.dateFrom); const dateTo = _parseDateTimeFromString(condition.dateTo); const format = this.filterParams.inRangeFloatingFilterDateFormat; const formatDate = forToolPanel ? this.formatValue.bind(this) : (value) => _dateToFormattedString(value, format); const formattedFrom = () => dateFrom !== null ? formatDate(dateFrom) : "null"; const formattedTo = () => dateTo !== null ? formatDate(dateTo) : "null"; if (dateFrom == null && dateTo == null) { return translateForFilter(this, type); } if (forToolPanel) { const valueForToolPanel = this.conditionForToolPanel(type, isRange, formattedFrom, formattedTo, customDisplayKey, customDisplayName); if (valueForToolPanel != null) { return valueForToolPanel; } } if (isRange) { return `${formattedFrom()}-${formattedTo()}`; } if (dateFrom != null) { return formatDate(dateFrom); } return `${type}`; } }; function defaultDateComparator(filterDate, cellValue) { const cellAsDate = cellValue; if (cellAsDate < filterDate) { return -1; } if (cellAsDate > filterDate) { return 1; } return 0; } var DateFilterHandler = class extends ScalarFilterHandler { constructor() { super(mapValuesFromDateFilterModel, DEFAULT_DATE_FILTER_OPTIONS); this.filterType = "date"; this.FilterModelFormatterClass = DateFilterModelFormatter; this.filterTypeToRangeCache = /* @__PURE__ */ new Map; } getOrRefreshRangeCacheItem(key, rangeFn) { const { filterTypeToRangeCache } = this; const now = Date.now(); let cache = filterTypeToRangeCache.get(key); if (cache && cache.expires < now) { cache = undefined; } if (!cache) { const [from, to] = rangeFn(new Date(now), new Date(now)); cache = { from, to, expires: setStartOfNextDay(new Date(now)).getTime() - now }; filterTypeToRangeCache.set(key, cache); } return cache; } comparator() { return this.params.filterParams.comparator ?? defaultDateComparator; } isValid(value) { const isValidDate2 = this.params.filterParams.isValidDate; return !isValidDate2 || isValidDate2(value); } evaluateNonNullValue(values, cellValue, filterModel) { const type = filterModel.type; const comparator = this.comparator(); if (!this.isValid(cellValue)) { return type === "notEqual" || type === "notBlank"; } const maybeTypeAsPreset = type; const presetDateRangeFn = presetDateFilterTypeRelativeFromToMap[maybeTypeAsPreset]; if (presetDateRangeFn) { const { from, to } = this.getOrRefreshRangeCacheItem(maybeTypeAsPreset, presetDateRangeFn); return comparator(from, cellValue) >= 0 && comparator(to, cellValue) < 0; } return super.evaluateNonNullValue(values, cellValue, filterModel); } }; var DEFAULT_FIRST_DAY_OF_WEEK = 1; var cachedFirstDayOfWeek = null; var getFirstDayOfWeek = () => { if (cachedFirstDayOfWeek != null) { return cachedFirstDayOfWeek; } let firstDay; const locale = typeof navigator === "undefined" ? undefined : navigator.languages?.[0] ?? navigator.language; if (locale && typeof Intl !== "undefined" && typeof Intl.Locale === "function") { try { const weekInfo = new Intl.Locale(locale).getWeekInfo?.(); firstDay = weekInfo?.firstDay; } catch { firstDay = undefined; } } cachedFirstDayOfWeek = firstDay == null ? DEFAULT_FIRST_DAY_OF_WEEK : firstDay % 7; return cachedFirstDayOfWeek; }; var setStartOfDay = (date) => { date.setHours(0, 0, 0, 0); return date; }; var setStartOfWeek = (date) => { const day = date.getDay(); const weekStart = getFirstDayOfWeek(); const diff = (day - weekStart + 7) % 7; date.setDate(date.getDate() - diff); return setStartOfDay(date); }; var setPreviousNDay = (date, n = 1) => { date.setDate(date.getDate() - n); return date; }; var setStartOfNextDay = (date) => { date.setDate(date.getDate() + 1); return setStartOfDay(date); }; var setStartOfNextWeek = (date) => { setStartOfWeek(date); date.setDate(date.getDate() + 6); return setStartOfNextDay(date); }; var setStartOfMonth = (date) => { date.setDate(1); return setStartOfDay(date); }; var setStartOfNextMonth = (date) => { date.setDate(1); date.setMonth(date.getMonth() + 1); return setStartOfDay(date); }; var setStartOfQuarter = (date) => { const quarter = Math.floor(date.getMonth() / 3); date.setMonth(quarter * 3); return setStartOfMonth(date); }; var setStartOfNextQuarter = (date) => { const quarter = Math.floor(date.getMonth() / 3); date.setMonth(quarter * 3 + 2); return setStartOfNextMonth(date); }; var setStartOfYear = (date) => { date.setMonth(0, 1); return setStartOfDay(date); }; var setStartOfNextYear = (date) => { date.setMonth(12, 0); return setStartOfNextDay(date); }; var setPreviousDay = (date) => setPreviousNDay(date); var setPreviousWeek = (date) => setPreviousDay(setStartOfWeek(date)); var setPreviousMonth = (date) => setPreviousDay(setStartOfMonth(date)); var setPreviousQuarter = (date) => setPreviousDay(setStartOfQuarter(date)); var today = (from, to) => [setStartOfDay(from), setStartOfNextDay(to)]; var yesterday = (from, to) => today(setPreviousDay(from), setPreviousDay(to)); var thisWeek = (from, to) => [setStartOfWeek(from), setStartOfNextWeek(to)]; var lastWeek = (from, to) => thisWeek(setPreviousWeek(from), setPreviousWeek(to)); var thisMonth = (from, to) => [setStartOfMonth(from), setStartOfNextMonth(to)]; var lastMonth = (from, to) => thisMonth(setPreviousMonth(from), setPreviousMonth(to)); var thisQuarter = (from, to) => [setStartOfQuarter(from), setStartOfNextQuarter(to)]; var lastQuarter = (from, to) => thisQuarter(setPreviousQuarter(from), setPreviousQuarter(to)); var thisYear = (from, to) => [setStartOfYear(from), setStartOfNextYear(to)]; var yearToDate = (from, to) => [setStartOfYear(from), setStartOfNextDay(to)]; var last7Days = (from, to) => [ setStartOfDay(setPreviousNDay(from, 7)), setStartOfNextDay(to) ]; var last30Days = (from, to) => [ setStartOfDay(setPreviousNDay(from, 30)), setStartOfNextDay(to) ]; var last90Days = (from, to) => [ setStartOfDay(setPreviousNDay(from, 90)), setStartOfNextDay(to) ]; var last6Months = (from, to) => { from.setFullYear(from.getFullYear() - 1); from.setMonth(from.getMonth() + 6); return [setStartOfDay(from), setStartOfNextDay(to)]; }; var last12Months = (from, to) => { from.setFullYear(from.getFullYear() - 1); return [setStartOfDay(from), setStartOfNextDay(to)]; }; var last24Months = (from, to) => { from.setFullYear(from.getFullYear() - 2); return [setStartOfDay(from), setStartOfNextDay(to)]; }; var lastYear = (from, to) => { from.setFullYear(from.getFullYear() - 1); to.setFullYear(to.getFullYear() - 1); return thisYear(from, to); }; var nextYear = (from, to) => { from.setFullYear(from.getFullYear() + 1); to.setFullYear(to.getFullYear() + 1); return thisYear(from, to); }; var nextQuarter = (from, to) => { from.setMonth(from.getMonth() + 3); to.setMonth(to.getMonth() + 3); return thisQuarter(from, to); }; var nextMonth = (from, to) => { from.setMonth(from.getMonth() + 1); to.setMonth(to.getMonth() + 1); return thisMonth(from, to); }; var nextWeek = (from, to) => { from.setDate(from.getDate() + 7); to.setDate(to.getDate() + 7); return thisWeek(from, to); }; var tomorrow = (from, to) => { from.setDate(from.getDate() + 1); to.setDate(to.getDate() + 1); return today(from, to); }; var presetDateFilterTypeRelativeFromToMap = { today, yesterday, tomorrow, thisWeek, lastWeek, nextWeek, thisMonth, lastMonth, nextMonth, thisQuarter, lastQuarter, nextQuarter, thisYear, lastYear, nextYear, yearToDate, last7Days, last30Days, last90Days, last6Months, last12Months, last24Months, setStartOfDay, setStartOfWeek, setStartOfNextDay, setStartOfNextWeek, setStartOfMonth, setStartOfNextMonth, setStartOfQuarter, setStartOfNextQuarter, setStartOfYear, setStartOfNextYear, setPreviousDay, setPreviousWeek, setPreviousMonth, setPreviousQuarter }; var DateFloatingFilterElement = { tag: "div", cls: "ag-floating-filter-input", role: "presentation", children: [ { tag: "ag-input-text-field", ref: "eReadOnlyText" }, { tag: "div", ref: "eDateWrapper", cls: "ag-date-floating-filter-wrapper" } ] }; var DateFloatingFilter = class extends SimpleFloatingFilter { constructor() { super(DateFloatingFilterElement, [AgInputTextFieldSelector]); this.eReadOnlyText = RefPlaceholder; this.eDateWrapper = RefPlaceholder; this.FilterModelFormatterClass = DateFilterModelFormatter; this.filterType = "date"; this.defaultOptions = DEFAULT_DATE_FILTER_OPTIONS; } setParams(params) { super.setParams(params); this.createDateComponent(); const translate = this.getLocaleTextFunc(); this.eReadOnlyText.setDisabled(true).setInputAriaLabel(translate("ariaDateFilterInput", "Date Filter Input")); } updateParams(params) { super.updateParams(params); this.dateComp.updateParams(this.getDateComponentParams()); this.updateCompOnModelChange(params.currentParentModel()); } updateCompOnModelChange(model) { const allowEditing = !this.readOnly && this.canWeEditAfterModelFromParentFilter(model); this.setEditable(allowEditing); if (allowEditing) { const dateModel = model ? _parseDateTimeFromString(model.dateFrom) : null; this.dateComp.setDate(dateModel); this.eReadOnlyText.setValue(""); } else { this.eReadOnlyText.setValue(this.filterModelFormatter.getModelAsString(model)); this.dateComp.setDate(null); } } setEditable(editable) { _setDisplayed(this.eDateWrapper, editable); _setDisplayed(this.eReadOnlyText.getGui(), !editable); } onModelUpdated(model) { super.setLastTypeFromModel(model); this.updateCompOnModelChange(model); } onDateChanged() { const filterValueDate = this.dateComp.getDate(); if (this.reactive) { const reactiveParams = this.params; reactiveParams.onUiChange(); const model = reactiveParams.model; const filterValueText = _serialiseDate(filterValueDate); const newModel = filterValueText == null ? null : { ...model ?? { filterType: this.filterType, type: this.lastType ?? this.optionsFactory.defaultOption }, dateFrom: filterValueText }; reactiveParams.onModelChange(newModel, { afterFloatingFilter: true }); } else { this.params.parentFilterInstance((filterInstance) => { filterInstance?.onFloatingFilterChanged(this.lastType || null, filterValueDate); }); } } getDateComponentParams() { const { filterParams } = this.params; const debounceMs = getDebounceMs(filterParams, this.defaultDebounceMs); return _addGridCommonParams(this.gos, { onDateChanged: _debounce(this, this.onDateChanged.bind(this), debounceMs), filterParams, location: "floatingFilter" }); } createDateComponent() { const { beans: { context, userCompFactory }, eDateWrapper, params: { column } } = this; this.dateComp = new DateCompWrapper(context, userCompFactory, column.getColDef(), this.getDateComponentParams(), eDateWrapper, (dateComp) => { dateComp.setInputAriaLabel(this.getAriaLabel(column)); }); this.addDestroyFunc(() => this.dateComp.destroy()); } }; var DefaultDateElement = { tag: "div", cls: "ag-filter-filter", children: [ { tag: "ag-input-text-field", ref: "eDateInput", cls: "ag-date-filter" } ] }; var DefaultDateComponent = class extends Component { constructor() { super(DefaultDateElement, [AgInputTextFieldSelector]); this.eDateInput = RefPlaceholder; this.isApply = false; this.applyOnFocusOut = false; } init(params) { this.params = params; this.setParams(params); const inputElement = this.eDateInput.getInputElement(); this.addManagedListeners(inputElement, { mouseDown: () => { if (this.eDateInput.isDisabled() || this.usingSafariDatePicker) { return; } inputElement.focus({ preventScroll: true }); }, input: this.handleInput.bind(this, false), change: this.handleInput.bind(this, true), focusout: this.handleFocusOut.bind(this), focusin: this.handleFocusIn.bind(this) }); } handleInput(isChange) { if (this.eDateInput.isDisabled()) { return; } if (this.isApply) { this.applyOnFocusOut = !isChange; if (isChange) { this.params.onDateChanged(); } return; } if (!isChange) { this.params.onDateChanged(); } } handleFocusOut() { if (this.applyOnFocusOut) { this.applyOnFocusOut = false; this.params.onDateChanged(); } } handleFocusIn() { this.params.onFocusIn?.(); } setParams(params) { const inputElement = this.eDateInput.getInputElement(); const shouldUseBrowserDatePicker = this.shouldUseBrowserDatePicker(params); this.usingSafariDatePicker = shouldUseBrowserDatePicker && _isBrowserSafari(); const { minValidYear, maxValidYear, minValidDate, maxValidDate, buttons, includeTime, colDef } = params.filterParams || {}; const dataTypeSvc = this.beans.dataTypeSvc; const shouldUseDateTimeLocal = includeTime ?? dataTypeSvc?.getDateIncludesTimeFlag?.(colDef.cellDataType) ?? false; if (shouldUseBrowserDatePicker) { if (shouldUseDateTimeLocal) { inputElement.type = "datetime-local"; inputElement.step = "1"; } else { inputElement.type = "date"; } } else { inputElement.type = "text"; } const parsedMinValidDate = parseOrConstructDate(minValidDate, minValidYear, true); const parsedMaxValidDate = parseOrConstructDate(maxValidDate, maxValidYear, false); if (parsedMinValidDate && parsedMaxValidDate && parsedMinValidDate.getTime() > parsedMaxValidDate.getTime()) { _warn(87); } if (parsedMinValidDate) { inputElement.min = _serialiseDate(parsedMinValidDate, shouldUseDateTimeLocal); } if (parsedMaxValidDate) { inputElement.max = _serialiseDate(parsedMaxValidDate, shouldUseDateTimeLocal); } this.isApply = params.location === "floatingFilter" && !!buttons?.includes("apply"); } refresh(params) { this.params = params; this.setParams(params); } getDate() { return _parseDateTimeFromString(this.eDateInput.getValue()); } setDate(date) { const colType = this.params.filterParams.colDef.cellDataType; const includeTime = this.beans.dataTypeSvc?.getDateIncludesTimeFlag(colType) ?? false; this.eDateInput.setValue(_serialiseDate(date, includeTime)); } setInputPlaceholder(placeholder) { this.eDateInput.setInputPlaceholder(placeholder); } setInputAriaLabel(ariaLabel) { this.eDateInput.setAriaLabel(ariaLabel); } setDisabled(disabled) { this.eDateInput.setDisabled(disabled); } afterGuiAttached(params) { if (!params?.suppressFocus) { this.eDateInput.getInputElement().focus({ preventScroll: true }); } } shouldUseBrowserDatePicker(params) { return params?.filterParams?.browserDatePicker ?? true; } }; function parseOrConstructDate(date, year, isMin) { if (date && year) { _warn(isMin ? 85 : 86); } if (date instanceof Date) { return date; } if (date) { return _parseDateTimeFromString(date); } else if (year) { return _parseDateTimeFromString(`${year}-${isMin ? "01-01" : "12-31"}`); } return null; } var DEFAULT_NUMBER_FILTER_OPTIONS = [ "equals", "notEqual", "greaterThan", "greaterThanOrEqual", "lessThan", "lessThanOrEqual", "inRange", "blank", "notBlank" ]; function getAllowedCharPattern2(filterParams) { return filterParams?.allowedCharPattern ?? null; } function processNumberFilterValue(value) { if (value == null) { return null; } return isNaN(value) ? null : value; } function mapValuesFromNumberFilterModel(filterModel, optionsFactory) { const { filter, filterTo, type } = filterModel || {}; return [processNumberFilterValue(filter), processNumberFilterValue(filterTo)].slice(0, getNumberOfInputs(type, optionsFactory)); } var NumberFilter = class extends SimpleFilter { constructor() { super("numberFilter", mapValuesFromNumberFilterModel, DEFAULT_NUMBER_FILTER_OPTIONS); this.eValuesFrom = []; this.eValuesTo = []; this.filterType = "number"; this.defaultDebounceMs = 500; } afterGuiAttached(params) { super.afterGuiAttached(params); this.refreshInputValidation(); } shouldKeepInvalidInputState() { return !_isBrowserFirefox() && this.hasInvalidInputs() && this.getConditionTypes().includes("inRange"); } refreshInputValidation() { for (let i = 0;i < this.eValuesFrom.length; i++) { const from = this.eValuesFrom[i]; const to = this.eValuesTo[i]; this.refreshInputPairValidation(from, to); } } refreshInputPairValidation(from, to, isFrom = false) { const parser = this.params.numberParser; const fromValue = getNormalisedValue(parser, from); const toValue = getNormalisedValue(parser, to); const localeKey = getValidityMessageKey2(fromValue, toValue, isFrom); const validityMessage = localeKey ? this.translate(localeKey, [String(isFrom ? toValue : fromValue)]) : ""; (isFrom ? from : to).setCustomValidity(validityMessage); (isFrom ? to : from).setCustomValidity(""); if (validityMessage.length > 0) { this.beans.ariaAnnounce.announceValue(validityMessage, "dateFilter"); } } getState() { return { isInvalid: this.hasInvalidInputs() }; } areStatesEqual(stateA, stateB) { return (stateA?.isInvalid ?? false) === (stateB?.isInvalid ?? false); } refresh(legacyNewParams) { const result = super.refresh(legacyNewParams); const { state: newState, additionalEventAttributes } = legacyNewParams; const oldState = this.state; const fromAction = additionalEventAttributes?.fromAction; const forceRefreshValidation = fromAction && fromAction != "apply"; if (forceRefreshValidation || newState.model !== oldState.model || !this.areStatesEqual(newState.state, oldState.state)) { this.refreshInputValidation(); } return result; } setElementValue(element, value, fromFloatingFilter) { const { numberFormatter } = this.params; const valueToSet = !fromFloatingFilter && numberFormatter ? numberFormatter(value ?? null) : value; super.setElementValue(element, valueToSet); if (valueToSet === null) { element.setCustomValidity(""); } } createEValue() { const { params, eValuesFrom, eValuesTo } = this; const allowedCharPattern = getAllowedCharPattern2(params); const eCondition = _createElement({ tag: "div", cls: "ag-filter-body", role: "presentation" }); const from = this.createFromToElement(eCondition, eValuesFrom, "from", allowedCharPattern); const to = this.createFromToElement(eCondition, eValuesTo, "to", allowedCharPattern); const getFieldChangedListener = (from2, to2, isFrom) => () => this.refreshInputPairValidation(from2, to2, isFrom); const fromListener = getFieldChangedListener(from, to, true); from.onValueChange(fromListener); from.addGuiEventListener("focusin", fromListener); const toListener = getFieldChangedListener(from, to, false); to.onValueChange(toListener); to.addGuiEventListener("focusin", toListener); return eCondition; } createFromToElement(eCondition, eValues, fromTo, allowedCharPattern) { const eValue = this.createManagedBean(allowedCharPattern ? new AgInputTextField({ allowedCharPattern }) : new AgInputNumberField); eValue.addCss(`ag-filter-${fromTo}`); eValue.addCss("ag-filter-filter"); eValues.push(eValue); eCondition.appendChild(eValue.getGui()); return eValue; } removeEValues(startPosition, deleteCount) { const removeComps = (eGui) => this.removeComponents(eGui, startPosition, deleteCount); removeComps(this.eValuesFrom); removeComps(this.eValuesTo); } getValues(position) { const result = []; this.forEachPositionInput(position, (element, index, _elPosition, numberOfInputs) => { if (index < numberOfInputs) { result.push(processNumberFilterValue(stringToFloat(this.params.numberParser, element.getValue()))); } }); return result; } areSimpleModelsEqual(aSimple, bSimple) { return aSimple.filter === bSimple.filter && aSimple.filterTo === bSimple.filterTo && aSimple.type === bSimple.type; } createCondition(position) { const type = this.getConditionType(position); const model = { filterType: this.filterType, type }; const values = this.getValues(position); if (values.length > 0) { model.filter = values[0]; } if (values.length > 1) { model.filterTo = values[1]; } return model; } removeConditionsAndOperators(startPosition, deleteCount) { if (this.hasInvalidInputs()) { return; } return super.removeConditionsAndOperators(startPosition, deleteCount); } getInputs(position) { const { eValuesFrom, eValuesTo } = this; if (position >= eValuesFrom.length) { return [null, null]; } return [eValuesFrom[position], eValuesTo[position]]; } hasInvalidInputs() { let invalidInputs = false; this.forEachInput((element) => invalidInputs || (invalidInputs = !element.getInputElement().validity.valid)); return invalidInputs; } positionHasInvalidInputs(position) { let invalidInputs = false; this.forEachPositionInput(position, (element) => invalidInputs || (invalidInputs = !element.getInputElement().validity.valid)); return invalidInputs; } canApply(_model) { return !this.hasInvalidInputs(); } }; function stringToFloat(numberParser, value) { if (typeof value === "number") { return value; } let filterText = _makeNull(value); if (filterText != null && filterText.trim() === "") { filterText = null; } if (numberParser) { return numberParser(filterText); } return filterText == null || filterText.trim() === "-" ? null : Number.parseFloat(filterText); } function getNormalisedValue(numberParser, input) { return processNumberFilterValue(stringToFloat(numberParser, input.getValue(true))); } function getValidityMessageKey2(fromValue, toValue, isFrom) { const isInvalid = fromValue != null && toValue != null && fromValue >= toValue; if (!isInvalid) { return null; } return `strict${isFrom ? "Max" : "Min"}ValueValidation`; } var NumberFilterModelFormatter = class extends SimpleFilterModelFormatter { constructor(optionsFactory, filterParams) { super(optionsFactory, filterParams, filterParams.numberFormatter); this.filterTypeKeys = SCALAR_FILTER_TYPE_KEYS; } conditionToString(condition, forToolPanel, isRange, customDisplayKey, customDisplayName) { const { filter, filterTo, type } = condition; const formatValue = this.formatValue.bind(this); if (forToolPanel) { const valueForToolPanel = this.conditionForToolPanel(type, isRange, () => formatValue(filter), () => formatValue(filterTo), customDisplayKey, customDisplayName); if (valueForToolPanel != null) { return valueForToolPanel; } } if (isRange) { return `${formatValue(filter)}-${formatValue(filterTo)}`; } if (filter != null) { return formatValue(filter); } return `${type}`; } }; var NumberFilterHandler = class extends ScalarFilterHandler { constructor() { super(mapValuesFromNumberFilterModel, DEFAULT_NUMBER_FILTER_OPTIONS); this.filterType = "number"; this.FilterModelFormatterClass = NumberFilterModelFormatter; } comparator() { return (left, right) => { if (left === right) { return 0; } return left < right ? 1 : -1; }; } isValid(value) { return !isNaN(value); } }; var FloatingFilterNumberInputService = class extends BeanStub { constructor() { super(...arguments); this.onValueChanged = () => {}; this.numberInputActive = true; } setupGui(parentElement) { this.eNumberInput = this.createManagedBean(new AgInputNumberField); this.eTextInput = this.createManagedBean(new AgInputTextField); this.eTextInput.setDisabled(true); const eNumberInput = this.eNumberInput.getGui(); const eTextInput = this.eTextInput.getGui(); parentElement.appendChild(eNumberInput); parentElement.appendChild(eTextInput); this.setupListeners(eNumberInput, (e) => this.onValueChanged(e)); this.setupListeners(eTextInput, (e) => this.onValueChanged(e)); } setEditable(editable) { this.numberInputActive = editable; this.eNumberInput.setDisplayed(this.numberInputActive); this.eTextInput.setDisplayed(!this.numberInputActive); } setAutoComplete(autoComplete) { this.eNumberInput.setAutoComplete(autoComplete); this.eTextInput.setAutoComplete(autoComplete); } getValue() { return this.getActiveInputElement().getValue(); } setValue(value, silent) { this.getActiveInputElement().setValue(value, silent); } getActiveInputElement() { return this.numberInputActive ? this.eNumberInput : this.eTextInput; } setValueChangedListener(listener) { this.onValueChanged = listener; } setupListeners(element, listener) { this.addManagedListeners(element, { input: listener, keydown: listener }); } setParams({ ariaLabel, autoComplete, placeholder }) { this.setAriaLabel(ariaLabel); if (autoComplete !== undefined) { this.setAutoComplete(autoComplete); } this.setPlaceholder(this.eNumberInput, placeholder); this.setPlaceholder(this.eTextInput, placeholder); } setPlaceholder(input, placeholder) { input.toggleCss("ag-floating-filter-search-icon", !!placeholder); input.setInputPlaceholder(placeholder); } setAriaLabel(ariaLabel) { this.eNumberInput.setInputAriaLabel(ariaLabel); this.eTextInput.setInputAriaLabel(ariaLabel); } }; var NumberFloatingFilter = class extends TextInputFloatingFilter { constructor() { super(...arguments); this.FilterModelFormatterClass = NumberFilterModelFormatter; this.filterType = "number"; this.defaultOptions = DEFAULT_NUMBER_FILTER_OPTIONS; } updateParams(params) { const allowedCharPattern = getAllowedCharPattern2(params.filterParams); if (allowedCharPattern !== this.allowedCharPattern) { this.recreateFloatingFilterInputService(params); } super.updateParams(params); } createFloatingFilterInputService(params) { this.allowedCharPattern = getAllowedCharPattern2(params.filterParams); if (this.allowedCharPattern) { return this.createManagedBean(new FloatingFilterTextInputService({ config: { allowedCharPattern: this.allowedCharPattern } })); } return this.createManagedBean(new FloatingFilterNumberInputService); } convertValue(value) { return value ? Number(value) : null; } }; var DEFAULT_TEXT_FILTER_OPTIONS = [ "contains", "notContains", "equals", "notEqual", "startsWith", "endsWith", "blank", "notBlank" ]; var TextFilter = class extends SimpleFilter { constructor() { super("textFilter", mapValuesFromTextFilterModel, DEFAULT_TEXT_FILTER_OPTIONS); this.filterType = "text"; this.eValuesFrom = []; this.eValuesTo = []; this.defaultDebounceMs = 500; } createCondition(position) { const type = this.getConditionType(position); const model = { filterType: this.filterType, type }; const values = this.getValues(position); if (values.length > 0) { model.filter = values[0]; } if (values.length > 1) { model.filterTo = values[1]; } return model; } areSimpleModelsEqual(aSimple, bSimple) { return aSimple.filter === bSimple.filter && aSimple.filterTo === bSimple.filterTo && aSimple.type === bSimple.type; } getInputs(position) { const { eValuesFrom, eValuesTo } = this; if (position >= eValuesFrom.length) { return [null, null]; } return [eValuesFrom[position], eValuesTo[position]]; } getValues(position) { const result = []; this.forEachPositionInput(position, (element, index, _elPosition, numberOfInputs) => { if (index < numberOfInputs) { result.push(_makeNull(element.getValue())); } }); return result; } createEValue() { const eCondition = _createElement({ tag: "div", cls: "ag-filter-body", role: "presentation" }); const { eValuesFrom, eValuesTo } = this; this.createFromToElement(eCondition, eValuesFrom, "from"); this.createFromToElement(eCondition, eValuesTo, "to"); return eCondition; } createFromToElement(eCondition, eValues, fromTo) { const eValue = this.createManagedBean(new AgInputTextField); eValue.addCss(`ag-filter-${fromTo}`); eValue.addCss("ag-filter-filter"); eValues.push(eValue); eCondition.appendChild(eValue.getGui()); } removeEValues(startPosition, deleteCount) { const removeComps = (eGui) => this.removeComponents(eGui, startPosition, deleteCount); const { eValuesFrom, eValuesTo } = this; removeComps(eValuesFrom); removeComps(eValuesTo); } }; var TextFilterModelFormatter = class extends SimpleFilterModelFormatter { constructor() { super(...arguments); this.filterTypeKeys = TEXT_FILTER_TYPE_KEYS; } conditionToString(condition, forToolPanel, isRange, customDisplayKey, customDisplayName) { const { filter, filterTo, type } = condition; if (forToolPanel) { const getValueFunc = (value) => () => translateForFilter(this, "filterSummaryTextQuote", [value]); const valueForToolPanel = this.conditionForToolPanel(type, isRange, getValueFunc(filter), getValueFunc(filterTo), customDisplayKey, customDisplayName); if (valueForToolPanel != null) { return valueForToolPanel; } } if (isRange) { return `${filter}-${filterTo}`; } if (filter != null) { return `${filter}`; } return `${type}`; } }; var defaultMatcher = ({ filterOption, value, filterText }) => { if (filterText == null) { return false; } switch (filterOption) { case "contains": return value.includes(filterText); case "notContains": return !value.includes(filterText); case "equals": return value === filterText; case "notEqual": return value != filterText; case "startsWith": return value.indexOf(filterText) === 0; case "endsWith": { const index = value.lastIndexOf(filterText); return index >= 0 && index === value.length - filterText.length; } default: return false; } }; var defaultFormatter = (from) => from; var defaultLowercaseFormatter = (from) => from == null ? null : from.toString().toLowerCase(); var TextFilterHandler = class extends SimpleFilterHandler { constructor() { super(mapValuesFromTextFilterModel, DEFAULT_TEXT_FILTER_OPTIONS); this.filterType = "text"; this.FilterModelFormatterClass = TextFilterModelFormatter; } updateParams(params) { super.updateParams(params); const filterParams = params.filterParams; this.matcher = filterParams.textMatcher ?? defaultMatcher; this.formatter = filterParams.textFormatter ?? (filterParams.caseSensitive ? defaultFormatter : defaultLowercaseFormatter); } evaluateNullValue(filterType) { const filterTypesAllowNulls = ["notEqual", "notContains", "blank"]; return filterType ? filterTypesAllowNulls.indexOf(filterType) >= 0 : false; } evaluateNonNullValue(values, cellValue, filterModel, params) { const formattedValues = values.map((v) => this.formatter(v)) || []; const cellValueFormatted = this.formatter(cellValue); const { api, colDef, column, context, filterParams: { textFormatter } } = this.params; if (filterModel.type === "blank") { return isBlank(cellValue); } else if (filterModel.type === "notBlank") { return !isBlank(cellValue); } const matcherParams = { api, colDef, column, context, node: params.node, data: params.data, filterOption: filterModel.type, value: cellValueFormatted, textFormatter }; return formattedValues.some((v) => this.matcher({ ...matcherParams, filterText: v })); } processModelToApply(model) { if (model && this.params.filterParams.trimInput) { const processCondition = (condition) => { const newCondition = { ...condition }; const { filter, filterTo } = condition; if (filter) { newCondition.filter = trimInputForFilter(filter) ?? null; } if (filterTo) { newCondition.filterTo = trimInputForFilter(filterTo) ?? null; } return newCondition; }; if (isCombinedFilterModel(model)) { return { ...model, conditions: model.conditions.map(processCondition) }; } return processCondition(model); } return model; } }; var TextFloatingFilter = class extends TextInputFloatingFilter { constructor() { super(...arguments); this.FilterModelFormatterClass = TextFilterModelFormatter; this.filterType = "text"; this.defaultOptions = DEFAULT_TEXT_FILTER_OPTIONS; } createFloatingFilterInputService() { return this.createManagedBean(new FloatingFilterTextInputService); } }; function isQuickFilterPresent(beans) { return !!beans.quickFilter?.isFilterPresent(); } function getQuickFilter(beans) { return beans.quickFilter?.getText(); } function resetQuickFilter(beans) { beans.quickFilter?.resetCache(); } var QuickFilterService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "quickFilter"; this.quickFilter = null; this.quickFilterParts = null; } postConstruct() { const resetListener = this.resetCache.bind(this); const gos = this.gos; this.addManagedEventListeners({ columnPivotModeChanged: resetListener, newColumnsLoaded: resetListener, columnRowGroupChanged: resetListener, columnVisible: () => { if (!gos.get("includeHiddenColumnsInQuickFilter")) { this.resetCache(); } } }); this.addManagedPropertyListener("quickFilterText", (e) => this.setFilter(e.currentValue)); this.addManagedPropertyListeners(["includeHiddenColumnsInQuickFilter", "applyQuickFilterBeforePivotOrAgg"], () => this.onColumnConfigChanged()); this.quickFilter = this.parseFilter(gos.get("quickFilterText")); this.parser = gos.get("quickFilterParser"); this.matcher = gos.get("quickFilterMatcher"); this.setFilterParts(); this.addManagedPropertyListeners(["quickFilterMatcher", "quickFilterParser"], () => this.setParserAndMatcher()); } refreshCols() { const { autoColSvc, colModel, gos, pivotResultCols } = this.beans; const pivotMode = colModel.isPivotMode(); const groupAutoCols = autoColSvc?.getColumns(); const providedCols = colModel.getColDefCols(); let columnsForQuickFilter = (pivotMode && !gos.get("applyQuickFilterBeforePivotOrAgg") ? pivotResultCols?.getPivotResultCols()?.list : providedCols) ?? []; if (groupAutoCols) { columnsForQuickFilter = columnsForQuickFilter.concat(groupAutoCols); } this.colsToUse = gos.get("includeHiddenColumnsInQuickFilter") ? columnsForQuickFilter : columnsForQuickFilter.filter((col) => col.isVisible() || col.isRowGroupActive()); } isFilterPresent() { return this.quickFilter !== null; } doesRowPass(node) { const usingCache = this.gos.get("cacheQuickFilter"); if (this.matcher) { return this.doesRowPassMatcher(usingCache, node); } return this.quickFilterParts.every((part) => usingCache ? this.doesRowPassCache(node, part) : this.doesRowPassNoCache(node, part)); } resetCache() { this.beans.rowModel.forEachNode((node) => node.quickFilterAggregateText = null); } getText() { return this.gos.get("quickFilterText"); } setFilterParts() { const { quickFilter, parser } = this; if (quickFilter) { this.quickFilterParts = parser ? parser(quickFilter) : quickFilter.split(" "); } else { this.quickFilterParts = null; } } parseFilter(newFilter) { if (!_exists(newFilter)) { return null; } return newFilter.toUpperCase(); } setFilter(newFilter) { if (newFilter != null && typeof newFilter !== "string") { _warn(70, { newFilter }); return; } const parsedFilter = this.parseFilter(newFilter); if (this.quickFilter !== parsedFilter) { this.quickFilter = parsedFilter; this.setFilterParts(); this.dispatchLocalEvent({ type: "quickFilterChanged" }); } } setParserAndMatcher() { const parser = this.gos.get("quickFilterParser"); const matcher = this.gos.get("quickFilterMatcher"); const hasChanged = parser !== this.parser || matcher !== this.matcher; this.parser = parser; this.matcher = matcher; if (hasChanged) { this.setFilterParts(); this.dispatchLocalEvent({ type: "quickFilterChanged" }); } } onColumnConfigChanged() { this.refreshCols(); this.resetCache(); if (this.isFilterPresent()) { this.dispatchLocalEvent({ type: "quickFilterChanged" }); } } doesRowPassNoCache(node, filterPart) { return this.colsToUse.some((column) => { const part = this.getTextForColumn(column, node); return _exists(part) && part.includes(filterPart); }); } doesRowPassCache(node, filterPart) { this.checkGenerateAggText(node); return node.quickFilterAggregateText.includes(filterPart); } doesRowPassMatcher(usingCache, node) { let quickFilterAggregateText; if (usingCache) { this.checkGenerateAggText(node); quickFilterAggregateText = node.quickFilterAggregateText; } else { quickFilterAggregateText = this.getAggText(node); } const { quickFilterParts, matcher } = this; return matcher(quickFilterParts, quickFilterAggregateText); } checkGenerateAggText(node) { if (!node.quickFilterAggregateText) { node.quickFilterAggregateText = this.getAggText(node); } } getTextForColumn(column, node) { let value = this.beans.filterValueSvc.getValue(column, node); const colDef = column.getColDef(); if (colDef.getQuickFilterText) { const params = _addGridCommonParams(this.gos, { value, node, data: node.data, column, colDef }); value = colDef.getQuickFilterText(params); } return _exists(value) ? value.toString().toUpperCase() : null; } getAggText(node) { const stringParts = []; for (const column of this.colsToUse) { const part = this.getTextForColumn(column, node); if (_exists(part)) { stringParts.push(part); } } return stringParts.join(` `); } }; var ClientSideRowModelFilterModule = { moduleName: "ClientSideRowModelFilter", version: VERSION, rowModels: ["clientSide"], beans: [FilterStage] }; var FilterCoreModule = { moduleName: "FilterCore", version: VERSION, beans: [FilterManager], apiFunctions: { isAnyFilterPresent, onFilterChanged }, css: [column_filters_default], dependsOn: [ClientSideRowModelFilterModule] }; var FilterValueModule = { moduleName: "FilterValue", version: VERSION, beans: [FilterValueService] }; var ColumnFilterModule = { moduleName: "ColumnFilter", version: VERSION, beans: [ColumnFilterService, FilterMenuFactory], dynamicBeans: { headerFilterCellCtrl: HeaderFilterCellCtrl }, icons: { filter: "filter", filterActive: "filter" }, apiFunctions: { isColumnFilterPresent, getColumnFilterInstance, destroyFilter, setFilterModel, getFilterModel, getColumnFilterModel, setColumnFilterModel, showColumnFilter, hideColumnFilter, getColumnFilterHandler, doFilterAction }, dependsOn: [FilterCoreModule, PopupModule, FilterValueModule, SharedMenuModule] }; var TextFilterModule = { moduleName: "TextFilter", version: VERSION, dependsOn: [ColumnFilterModule], userComponents: { agTextColumnFilter: { classImp: TextFilter, params: { useForm: true } }, agTextColumnFloatingFilter: TextFloatingFilter }, dynamicBeans: { agTextColumnFilterHandler: TextFilterHandler } }; var NumberFilterModule = { moduleName: "NumberFilter", version: VERSION, dependsOn: [ColumnFilterModule], userComponents: { agNumberColumnFilter: { classImp: NumberFilter, params: { useForm: true } }, agNumberColumnFloatingFilter: NumberFloatingFilter }, dynamicBeans: { agNumberColumnFilterHandler: NumberFilterHandler } }; var DateFilterModule = { moduleName: "DateFilter", version: VERSION, dependsOn: [ColumnFilterModule], userComponents: { agDateColumnFilter: { classImp: DateFilter, params: { useForm: true } }, agDateInput: DefaultDateComponent, agDateColumnFloatingFilter: DateFloatingFilter }, dynamicBeans: { agDateColumnFilterHandler: DateFilterHandler } }; var QuickFilterCoreModule = { moduleName: "QuickFilterCore", version: VERSION, rowModels: ["clientSide"], beans: [QuickFilterService], dependsOn: [FilterCoreModule, FilterValueModule] }; var QuickFilterModule = { moduleName: "QuickFilter", version: VERSION, apiFunctions: { isQuickFilterPresent, getQuickFilter, resetQuickFilter }, dependsOn: [QuickFilterCoreModule] }; var ApiEventService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "apiEventSvc"; this.syncListeners = /* @__PURE__ */ new Map; this.asyncListeners = /* @__PURE__ */ new Map; this.syncGlobalListeners = /* @__PURE__ */ new Set; this.globalListenerPairs = /* @__PURE__ */ new Map; } postConstruct() { this.wrapSvc = this.beans.frameworkOverrides.createGlobalEventListenerWrapper?.(); } addListener(eventType, userListener) { const listener = this.wrapSvc?.wrap(eventType, userListener) ?? userListener; const async = !ALWAYS_SYNC_GLOBAL_EVENTS.has(eventType); const listeners = async ? this.asyncListeners : this.syncListeners; if (!listeners.has(eventType)) { listeners.set(eventType, /* @__PURE__ */ new Set); } listeners.get(eventType).add(listener); this.eventSvc.addListener(eventType, listener, async); } removeListener(eventType, userListener) { const listener = this.wrapSvc?.unwrap(eventType, userListener) ?? userListener; const asyncListeners = this.asyncListeners.get(eventType); const hasAsync = !!asyncListeners?.delete(listener); if (!hasAsync) { this.syncListeners.get(eventType)?.delete(listener); } this.eventSvc.removeListener(eventType, listener, hasAsync); } addGlobalListener(userListener) { const listener = this.wrapSvc?.wrapGlobal(userListener) ?? userListener; const syncListener = (eventType, event) => { if (ALWAYS_SYNC_GLOBAL_EVENTS.has(eventType)) { listener(eventType, event); } }; const asyncListener = (eventType, event) => { if (!ALWAYS_SYNC_GLOBAL_EVENTS.has(eventType)) { listener(eventType, event); } }; this.globalListenerPairs.set(userListener, { syncListener, asyncListener }); const eventSvc = this.eventSvc; eventSvc.addGlobalListener(syncListener, false); eventSvc.addGlobalListener(asyncListener, true); } removeGlobalListener(userListener) { const { eventSvc, wrapSvc, globalListenerPairs } = this; const listener = wrapSvc?.unwrapGlobal(userListener) ?? userListener; const hasAsync = globalListenerPairs.has(listener); if (hasAsync) { const { syncListener, asyncListener } = globalListenerPairs.get(listener); eventSvc.removeGlobalListener(syncListener, false); eventSvc.removeGlobalListener(asyncListener, true); globalListenerPairs.delete(userListener); } else { this.syncGlobalListeners.delete(listener); eventSvc.removeGlobalListener(listener, false); } } destroyEventListeners(map, async) { map.forEach((listeners, eventType) => { listeners.forEach((listener) => this.eventSvc.removeListener(eventType, listener, async)); listeners.clear(); }); map.clear(); } destroyGlobalListeners(set, async) { for (const listener of set) { this.eventSvc.removeGlobalListener(listener, async); } set.clear(); } destroy() { super.destroy(); this.destroyEventListeners(this.syncListeners, false); this.destroyEventListeners(this.asyncListeners, true); this.destroyGlobalListeners(this.syncGlobalListeners, false); const { globalListenerPairs, eventSvc } = this; globalListenerPairs.forEach(({ syncListener, asyncListener }) => { eventSvc.removeGlobalListener(syncListener, false); eventSvc.removeGlobalListener(asyncListener, true); }); globalListenerPairs.clear(); } }; function addEventListener(beans, eventType, listener) { beans.apiEventSvc?.addListener(eventType, listener); } function removeEventListener(beans, eventType, listener) { beans.apiEventSvc?.removeListener(eventType, listener); } function addGlobalListener(beans, listener) { beans.apiEventSvc?.addGlobalListener(listener); } function removeGlobalListener(beans, listener) { beans.apiEventSvc?.removeGlobalListener(listener); } var EventApiModule = { moduleName: "EventApi", version: VERSION, apiFunctions: { addEventListener, addGlobalListener, removeEventListener, removeGlobalListener }, beans: [ApiEventService] }; function _formatNumberCommas(value, getLocaleTextFunc) { if (typeof value !== "number") { return ""; } const localeTextFunc = getLocaleTextFunc(); const thousandSeparator = localeTextFunc("thousandSeparator", ","); const decimalSeparator = localeTextFunc("decimalSeparator", "."); return value.toString().replace(".", decimalSeparator).replace(/(\d)(?=(\d{3})+(?!\d))/g, `$1${thousandSeparator}`); } var ARROW_UP = "↑"; var ARROW_DOWN = "↓"; var AnimateShowChangeCellRendererElement = { tag: "span", children: [ { tag: "span", ref: "eDelta", cls: "ag-value-change-delta" }, { tag: "span", ref: "eValue", cls: "ag-value-change-value" } ] }; var AnimateShowChangeCellRenderer = class extends Component { constructor() { super(AnimateShowChangeCellRendererElement); this.eValue = RefPlaceholder; this.eDelta = RefPlaceholder; this.refreshCount = 0; } init(params) { this.refresh(params, true); } showDelta(params, delta) { const absDelta = Math.abs(delta); const valueFormatted = params.formatValue(absDelta); const valueToUse = _exists(valueFormatted) ? valueFormatted : absDelta; const deltaUp = delta >= 0; const eDelta = this.eDelta; if (deltaUp) { eDelta.textContent = ARROW_UP + valueToUse; } else { eDelta.textContent = ARROW_DOWN + valueToUse; } eDelta.classList.toggle("ag-value-change-delta-up", deltaUp); eDelta.classList.toggle("ag-value-change-delta-down", !deltaUp); } setTimerToRemoveDelta() { this.refreshCount++; const refreshCountCopy = this.refreshCount; this.beans.frameworkOverrides.wrapIncoming(() => { window.setTimeout(() => { if (refreshCountCopy === this.refreshCount) { this.hideDeltaValue(); } }, 2000); }); } hideDeltaValue() { this.eValue.classList.remove("ag-value-change-value-highlight"); _clearElement(this.eDelta); } refresh(params, isInitialRender = false) { const { value, valueFormatted } = params; const { eValue, lastValue, beans } = this; if (value === lastValue) { return false; } if (_exists(valueFormatted)) { eValue.textContent = valueFormatted; } else if (_exists(value)) { eValue.textContent = value; } else { _clearElement(eValue); } if (beans.filterManager?.isSuppressFlashingCellsBecauseFiltering()) { return false; } const numericValue = value && typeof value === "object" && "toNumber" in value ? value.toNumber() : value; const numericLastValue = lastValue && typeof lastValue === "object" && "toNumber" in lastValue ? lastValue.toNumber() : lastValue; if (numericValue === numericLastValue) { return false; } if (typeof numericValue === "number" && typeof numericLastValue === "number") { const delta = numericValue - numericLastValue; this.showDelta(params, delta); } if (lastValue) { eValue.classList.add("ag-value-change-value-highlight"); } if (!isInitialRender) { this.setTimerToRemoveDelta(); } this.lastValue = value; return true; } }; var animateSlideCellRenderer_default = ".ag-value-slide-out{opacity:1}:where(.ag-ltr) .ag-value-slide-out{margin-right:5px;transition:opacity 3s,margin-right 3s}:where(.ag-rtl) .ag-value-slide-out{margin-left:5px;transition:opacity 3s,margin-left 3s}:where(.ag-ltr,.ag-rtl) .ag-value-slide-out{transition-timing-function:linear}.ag-value-slide-out-end{opacity:0}:where(.ag-ltr) .ag-value-slide-out-end{margin-right:10px}:where(.ag-rtl) .ag-value-slide-out-end{margin-left:10px}"; var AnimateSlideCellRendererElement = { tag: "span", children: [{ tag: "span", ref: "eCurrent", cls: "ag-value-slide-current" }] }; var AnimateSlideCellRenderer = class extends Component { constructor() { super(AnimateSlideCellRendererElement); this.eCurrent = RefPlaceholder; this.refreshCount = 0; this.registerCSS(animateSlideCellRenderer_default); } init(params) { this.refresh(params, true); } addSlideAnimation() { this.refreshCount++; const refreshCountCopy = this.refreshCount; this.ePrevious?.remove(); const { beans, eCurrent } = this; const prevElement = _createElement({ tag: "span", cls: "ag-value-slide-previous ag-value-slide-out" }); this.ePrevious = prevElement; prevElement.textContent = eCurrent.textContent; this.getGui().insertBefore(prevElement, eCurrent); beans.frameworkOverrides.wrapIncoming(() => { window.setTimeout(() => { if (refreshCountCopy !== this.refreshCount) { return; } this.ePrevious.classList.add("ag-value-slide-out-end"); }, 50); window.setTimeout(() => { if (refreshCountCopy !== this.refreshCount) { return; } this.ePrevious?.remove(); this.ePrevious = null; }, 3000); }); } refresh(params, isInitialRender = false) { let value = params.value; if (_missing(value)) { value = ""; } if (value === this.lastValue) { return false; } if (this.beans.filterManager?.isSuppressFlashingCellsBecauseFiltering()) { return false; } if (!isInitialRender) { this.addSlideAnimation(); } this.lastValue = value; const eCurrent = this.eCurrent; if (_exists(params.valueFormatted)) { eCurrent.textContent = params.valueFormatted; } else if (_exists(params.value)) { eCurrent.textContent = value; } else { _clearElement(eCurrent); } return true; } }; var CellFlashService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "cellFlashSvc"; this.nextAnimationTime = null; this.nextAnimationCycle = null; this.animations = { highlight: /* @__PURE__ */ new Map, "data-changed": /* @__PURE__ */ new Map }; } animateCell(cellCtrl, cssName, flashDuration = this.beans.gos.get("cellFlashDuration"), fadeDuration = this.beans.gos.get("cellFadeDuration")) { const animations = this.animations[cssName]; animations.delete(cellCtrl); const time = Date.now(); const flashEndTime = time + flashDuration; const fadeEndTime = time + flashDuration + fadeDuration; const animState = { phase: "flash", flashEndTime, fadeEndTime }; animations.set(cellCtrl, animState); const cssBase = `ag-cell-${cssName}`; const cssAnimation = `${cssBase}-animation`; const { comp, eGui: { style } } = cellCtrl; comp.toggleCss(cssBase, true); comp.toggleCss(cssAnimation, false); style.removeProperty("transition"); style.removeProperty("transition-delay"); if (this.nextAnimationTime && flashEndTime + 15 < this.nextAnimationTime) { clearTimeout(this.nextAnimationCycle); this.nextAnimationCycle = null; this.nextAnimationTime = null; } if (!this.nextAnimationCycle) { this.beans.frameworkOverrides.wrapIncoming(() => { this.nextAnimationCycle = setTimeout(this.advanceAnimations.bind(this), flashDuration); }); this.nextAnimationTime = flashEndTime; } } advanceAnimations() { const time = Date.now(); let nextAnimationTime = null; for (const cssName of Object.keys(this.animations)) { const animations = this.animations[cssName]; const cssBase = `ag-cell-${cssName}`; const cssAnimation = `${cssBase}-animation`; for (const [cell, animState] of animations) { if (!cell.isAlive() || !cell.comp) { animations.delete(cell); continue; } const { phase, flashEndTime, fadeEndTime } = animState; const nextActionableTime = phase === "flash" ? flashEndTime : fadeEndTime; const requiresAction = time + 15 >= nextActionableTime; if (!requiresAction) { nextAnimationTime = Math.min(nextActionableTime, nextAnimationTime ?? Infinity); continue; } const { comp, eGui: { style } } = cell; switch (phase) { case "flash": comp.toggleCss(cssBase, false); comp.toggleCss(cssAnimation, true); style.transition = `background-color ${fadeEndTime - flashEndTime}ms`; style.transitionDelay = `${flashEndTime - time}ms`; nextAnimationTime = Math.min(fadeEndTime, nextAnimationTime ?? Infinity); animState.phase = "fade"; break; case "fade": comp.toggleCss(cssBase, false); comp.toggleCss(cssAnimation, false); style.removeProperty("transition"); style.removeProperty("transition-delay"); animations.delete(cell); break; } } } if (nextAnimationTime == null) { this.nextAnimationTime = null; this.nextAnimationCycle = null; } else if (nextAnimationTime) { this.nextAnimationCycle = setTimeout(this.advanceAnimations.bind(this), nextAnimationTime - time); this.nextAnimationTime = nextAnimationTime; } } onFlashCells(cellCtrl, event) { if (!cellCtrl.comp) { return; } const cellId = _createCellId(cellCtrl.cellPosition); const shouldFlash = event.cells[cellId]; if (shouldFlash) { this.animateCell(cellCtrl, "highlight"); } } flashCell(cellCtrl, delays) { this.animateCell(cellCtrl, "data-changed", delays?.flashDuration, delays?.fadeDuration); } destroy() { for (const cssName of Object.keys(this.animations)) { const animations = this.animations[cssName]; animations.clear(); } } }; function flashCells(beans, params = {}) { const { cellFlashSvc } = beans; if (!cellFlashSvc) { return; } beans.frameworkOverrides.wrapIncoming(() => { for (const cellCtrl of beans.rowRenderer.getCellCtrls(params.rowNodes, params.columns)) { cellFlashSvc.flashCell(cellCtrl, params); } }); } var HighlightChangesModule = { moduleName: "HighlightChanges", version: VERSION, beans: [CellFlashService], userComponents: { agAnimateShowChangeCellRenderer: AnimateShowChangeCellRenderer, agAnimateSlideCellRenderer: AnimateSlideCellRenderer }, apiFunctions: { flashCells } }; var SelectionColService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "selectionColSvc"; } postConstruct() { this.addManagedPropertyListener("rowSelection", (event) => { this.onSelectionOptionsChanged(event.currentValue, event.previousValue, _convertColumnEventSourceType(event.source)); }); this.addManagedPropertyListener("selectionColumnDef", this.updateColumns.bind(this)); } addColumns(cols) { const selectionCols = this.columns; if (selectionCols == null) { return; } cols.list = selectionCols.list.concat(cols.list); cols.tree = selectionCols.tree.concat(cols.tree); _updateColsMap(cols); } createColumns(cols, updateOrders) { const destroyCollection = () => { _destroyColumnTree(this.beans, this.columns?.tree); this.columns = null; }; const newTreeDepth = cols.treeDepth; const oldTreeDepth = this.columns?.treeDepth ?? -1; const treeDepthSame = oldTreeDepth == newTreeDepth; const list = this.generateSelectionCols(); const areSame = _areColIdsEqual(list, this.columns?.list ?? []); if (areSame && treeDepthSame) { return; } destroyCollection(); const { colGroupSvc } = this.beans; const treeDepth = colGroupSvc?.findDepth(cols.tree) ?? 0; const tree = colGroupSvc?.balanceTreeForAutoCols(list, treeDepth) ?? []; this.columns = { list, tree, treeDepth, map: {} }; const putSelectionColsFirstInList = (cols2) => { if (!cols2) { return null; } const colsFiltered = cols2.filter((col) => !isColumnSelectionCol(col)); return [...list, ...colsFiltered]; }; updateOrders(putSelectionColsFirstInList); } updateColumns(event) { const source = _convertColumnEventSourceType(event.source); const { beans } = this; for (const col of this.columns?.list ?? []) { const colDef = this.createSelectionColDef(event.currentValue); col.setColDef(colDef, null, source); _applyColumnState(beans, { state: [_getColumnStateFromColDef(colDef, col.colId)] }, source); } } getColumn(key) { return this.columns?.list.find((col) => _columnsMatch(col, key)) ?? null; } getColumns() { return this.columns?.list ?? null; } isSelectionColumnEnabled() { const { gos, beans } = this; const rowSelection = gos.get("rowSelection"); if (typeof rowSelection !== "object" || !_isRowSelection(gos)) { return false; } const hasAutoCols = (beans.autoColSvc?.getColumns()?.length ?? 0) > 0; if (rowSelection.checkboxLocation === "autoGroupColumn" && hasAutoCols) { return false; } const checkboxes = !!_getCheckboxes(rowSelection); const headerCheckbox = _getHeaderCheckbox(rowSelection); return checkboxes || headerCheckbox; } createSelectionColDef(def) { const { gos } = this; const selectionColumnDef = def ?? gos.get("selectionColumnDef"); const enableRTL = gos.get("enableRtl"); const { rowSpan: _, spanRows: __, ...filteredSelColDef } = selectionColumnDef ?? {}; return { width: 50, resizable: false, suppressHeaderMenuButton: true, sortable: false, suppressMovable: true, lockPosition: enableRTL ? "right" : "left", comparator(valueA, valueB, nodeA, nodeB) { const aSelected = nodeA.isSelected(); const bSelected = nodeB.isSelected(); return aSelected === bSelected ? 0 : aSelected ? 1 : -1; }, editable: false, suppressFillHandle: true, suppressAutoSize: true, pinned: null, ...filteredSelColDef, colId: SELECTION_COLUMN_ID, chartDataType: "excluded" }; } generateSelectionCols() { if (!this.isSelectionColumnEnabled()) { return []; } const colDef = this.createSelectionColDef(); const colId = colDef.colId; this.gos.validateColDef(colDef, colId, true); const col = new AgColumn(colDef, null, colId, false); this.createBean(col); return [col]; } onSelectionOptionsChanged(current, prev, source) { const prevCheckbox = prev && typeof prev !== "string" ? _getCheckboxes(prev) : undefined; const currCheckbox = current && typeof current !== "string" ? _getCheckboxes(current) : undefined; const checkboxHasChanged = prevCheckbox !== currCheckbox; const prevHeaderCheckbox = prev && typeof prev !== "string" ? _getHeaderCheckbox(prev) : undefined; const currHeaderCheckbox = current && typeof current !== "string" ? _getHeaderCheckbox(current) : undefined; const headerCheckboxHasChanged = prevHeaderCheckbox !== currHeaderCheckbox; const currLocation = _getCheckboxLocation(current); const prevLocation = _getCheckboxLocation(prev); const locationChanged = currLocation !== prevLocation; if (checkboxHasChanged || headerCheckboxHasChanged || locationChanged) { this.beans.colModel.refreshAll(source); } } destroy() { _destroyColumnTree(this.beans, this.columns?.tree); super.destroy(); } refreshVisibility(leftCols, centerCols, rightCols) { if (!this.columns?.list.length) { return; } const numVisibleCols = leftCols.length + centerCols.length + rightCols.length; if (numVisibleCols === 0) { return; } const column = this.columns.list[0]; if (!column.isVisible()) { return; } const hideSelectionCol = () => { let cols; switch (column.pinned) { case "left": case true: cols = leftCols; break; case "right": cols = rightCols; break; default: cols = centerCols; } if (cols) { _removeFromArray(cols, column); } }; const rowNumbersCol = this.beans.rowNumbersSvc?.getColumn(ROW_NUMBERS_COLUMN_ID); const expectedNumCols = rowNumbersCol ? 2 : 1; if (expectedNumCols === numVisibleCols) { hideSelectionCol(); } } }; var rowSelection_default = ':where(.ag-selection-checkbox) .ag-checkbox-input-wrapper:before{content:"";cursor:pointer;inset:-8px;position:absolute}'; function setNodesSelected(beans, params) { const allNodesValid = params.nodes.every((node) => { if (node.rowPinned && !_isManualPinnedRow(node)) { _warn(59); return false; } if (node.id === undefined) { _warn(60); return false; } return true; }); if (!allNodesValid) { return; } const { nodes, source, newValue } = params; beans.selectionSvc?.setNodesSelected({ nodes, source: source ?? "api", newValue }); } function selectAll(beans, selectAll2, source = "apiSelectAll") { beans.selectionSvc?.selectAllRowNodes({ source, selectAll: selectAll2 }); } function deselectAll(beans, selectAll2, source = "apiSelectAll") { beans.selectionSvc?.deselectAllRowNodes({ source, selectAll: selectAll2 }); } function selectAllFiltered(beans, source = "apiSelectAllFiltered") { beans.selectionSvc?.selectAllRowNodes({ source, selectAll: "filtered" }); } function deselectAllFiltered(beans, source = "apiSelectAllFiltered") { beans.selectionSvc?.deselectAllRowNodes({ source, selectAll: "filtered" }); } function selectAllOnCurrentPage(beans, source = "apiSelectAllCurrentPage") { beans.selectionSvc?.selectAllRowNodes({ source, selectAll: "currentPage" }); } function deselectAllOnCurrentPage(beans, source = "apiSelectAllCurrentPage") { beans.selectionSvc?.deselectAllRowNodes({ source, selectAll: "currentPage" }); } function getSelectedNodes(beans) { return beans.selectionSvc?.getSelectedNodes() ?? []; } function getSelectedRows(beans) { return beans.selectionSvc?.getSelectedRows() ?? []; } var CheckboxSelectionComponentElement = { tag: "div", cls: "ag-selection-checkbox", role: "presentation", children: [ { tag: "ag-checkbox", ref: "eCheckbox", role: "presentation" } ] }; var CheckboxSelectionComponent = class extends Component { constructor() { super(CheckboxSelectionComponentElement, [AgCheckboxSelector]); this.eCheckbox = RefPlaceholder; } postConstruct() { this.eCheckbox.setPassive(true); } onDataChanged() { this.onSelectionChanged(); } onSelectableChanged() { this.showOrHideSelect(); } onSelectionChanged() { const translate = this.getLocaleTextFunc(); const { rowNode, eCheckbox } = this; const state = rowNode.isSelected(); const stateName = _getAriaCheckboxStateName(translate, state); const [ariaKey, ariaLabel] = rowNode.selectable ? ["ariaRowToggleSelection", "Press Space to toggle row selection"] : ["ariaRowSelectionDisabled", "Row Selection is disabled for this row"]; const translatedLabel = translate(ariaKey, ariaLabel); eCheckbox.setValue(state, true); eCheckbox.setInputAriaLabel(`${translatedLabel} (${stateName})`); } init(params) { this.rowNode = params.rowNode; this.column = params.column; this.overrides = params.overrides; this.onSelectionChanged(); this.addManagedListeners(this.eCheckbox.getWrapperElement(), { dblclick: _stopPropagationForAgGrid, click: (event) => { _stopPropagationForAgGrid(event); if (this.eCheckbox.isDisabled()) { return; } this.beans.selectionSvc?.handleSelectionEvent(event, this.rowNode, "checkboxSelected"); } }); this.addManagedListeners(this.rowNode, { rowSelected: this.onSelectionChanged.bind(this), dataChanged: this.onDataChanged.bind(this), selectableChanged: this.onSelectableChanged.bind(this) }); this.addManagedPropertyListener("rowSelection", ({ currentValue, previousValue }) => { const curr = typeof currentValue === "object" ? _getHideDisabledCheckboxes(currentValue) : undefined; const prev = typeof previousValue === "object" ? _getHideDisabledCheckboxes(previousValue) : undefined; if (curr !== prev) { this.onSelectableChanged(); } }); const isRowSelectableFunc = _getIsRowSelectable(this.gos); const checkboxVisibleIsDynamic = isRowSelectableFunc || typeof this.getIsVisible() === "function"; if (checkboxVisibleIsDynamic) { const showOrHideSelectListener = this.showOrHideSelect.bind(this); this.addManagedEventListeners({ displayedColumnsChanged: showOrHideSelectListener }); this.addManagedListeners(this.rowNode, { dataChanged: showOrHideSelectListener, cellChanged: showOrHideSelectListener }); this.showOrHideSelect(); } this.eCheckbox.getInputElement().setAttribute("tabindex", "-1"); } showOrHideSelect() { const { column, rowNode, overrides, gos } = this; const selectable = rowNode.selectable; const isVisible = this.getIsVisible(); let checkboxes = undefined; if (typeof isVisible === "function") { const extraParams = overrides?.callbackParams; if (!column) { checkboxes = isVisible({ ...extraParams, node: rowNode, data: rowNode.data }); } else { const params = column.createColumnFunctionCallbackParams(rowNode); checkboxes = isVisible({ ...extraParams, ...params }); } } else { checkboxes = isVisible ?? false; } const disabled = selectable && !checkboxes || !selectable && checkboxes; const visible = selectable || checkboxes; const so = gos.get("rowSelection"); const showDisabledCheckboxes = so && typeof so !== "string" ? !_getHideDisabledCheckboxes(so) : !!column?.getColDef().showDisabledCheckboxes; this.setVisible(visible && (disabled ? showDisabledCheckboxes : true)); this.setDisplayed(visible && (disabled ? showDisabledCheckboxes : true)); if (visible) { this.eCheckbox.setDisabled(disabled); } if (overrides?.removeHidden) { this.setDisplayed(visible); } } getIsVisible() { const overrides = this.overrides; if (overrides) { return overrides.isVisible; } const so = this.gos.get("rowSelection"); if (so && typeof so !== "string") { return _getCheckboxes(so); } return this.column?.getColDef()?.checkboxSelection; } }; var RowRangeSelectionContext = class { constructor(rowModel, pinnedRowModel) { this.rowModel = rowModel; this.pinnedRowModel = pinnedRowModel; this.selectAll = false; this.rootId = null; this.endId = null; this.cachedRange = []; } reset() { this.rootId = null; this.endId = null; this.cachedRange.length = 0; } setRoot(node) { this.rootId = node.id; this.endId = null; this.cachedRange.length = 0; } setEndRange(end) { this.endId = end.id; this.cachedRange.length = 0; } getRange() { if (this.cachedRange.length === 0) { const root = this.getRoot(); const end = this.getEnd(); if (root == null || end == null) { return this.cachedRange; } this.cachedRange = this.getNodesInRange(root, end) ?? []; } return this.cachedRange; } isInRange(node) { if (this.rootId === null) { return false; } return this.getRange().some((nodeInRange) => nodeInRange.id === node.id); } getRoot(fallback) { if (this.rootId) { return this.getRowNode(this.rootId); } if (fallback) { this.setRoot(fallback); return fallback; } } getEnd() { if (this.endId) { return this.getRowNode(this.endId); } } getRowNode(id) { let node; const { rowModel, pinnedRowModel } = this; node ?? (node = rowModel.getRowNode(id)); if (pinnedRowModel?.isManual()) { node ?? (node = pinnedRowModel.getPinnedRowById(id, "top")); node ?? (node = pinnedRowModel.getPinnedRowById(id, "bottom")); } return node; } truncate(node) { const range = this.getRange(); if (range.length === 0) { return { keep: [], discard: [] }; } const discardAfter = range[0].id === this.rootId; const idx = range.findIndex((rowNode) => rowNode.id === node.id); if (idx > -1) { const above = range.slice(0, idx); const below = range.slice(idx + 1); this.setEndRange(node); return discardAfter ? { keep: above, discard: below } : { keep: below, discard: above }; } else { return { keep: range, discard: [] }; } } extend(node, groupSelectsChildren = false) { const root = this.getRoot(); if (root == null) { const keep = this.getRange().slice(); if (groupSelectsChildren) { node.depthFirstSearch((node2) => !node2.group && keep.push(node2)); } keep.push(node); this.setRoot(node); return { keep, discard: [] }; } const newRange = this.getNodesInRange(root, node); if (!newRange) { this.setRoot(node); return { keep: [node], discard: [] }; } if (newRange.find((newRangeNode) => newRangeNode.id === this.endId)) { this.setEndRange(node); return { keep: this.getRange(), discard: [] }; } else { const discard = this.getRange().slice(); this.setEndRange(node); return { keep: this.getRange(), discard }; } } getNodesInRange(start, end) { const { pinnedRowModel, rowModel } = this; if (!pinnedRowModel?.isManual()) { return rowModel.getNodesInRangeForSelection(start, end); } if (start.rowPinned === "top" && !end.rowPinned) { const pinnedRange = _getNodesInRangeForSelection(pinnedRowModel, "top", start, undefined); return pinnedRange.concat(rowModel.getNodesInRangeForSelection(rowModel.getRow(0), end) ?? []); } if (start.rowPinned === "bottom" && !end.rowPinned) { const pinnedRange = _getNodesInRangeForSelection(pinnedRowModel, "bottom", undefined, start); const count = rowModel.getRowCount(); const lastMain = rowModel.getRow(count - 1); return (rowModel.getNodesInRangeForSelection(end, lastMain) ?? []).concat(pinnedRange); } if (!start.rowPinned && !end.rowPinned) { return rowModel.getNodesInRangeForSelection(start, end); } if (start.rowPinned === "top" && end.rowPinned === "top") { return _getNodesInRangeForSelection(pinnedRowModel, "top", start, end); } if (start.rowPinned === "bottom" && end.rowPinned === "top") { const top = _getNodesInRangeForSelection(pinnedRowModel, "top", end, undefined); const bottom = _getNodesInRangeForSelection(pinnedRowModel, "bottom", undefined, start); const first = rowModel.getRow(0); const last = rowModel.getRow(rowModel.getRowCount() - 1); return top.concat(rowModel.getNodesInRangeForSelection(first, last) ?? []).concat(bottom); } if (!start.rowPinned && end.rowPinned === "top") { const pinned = _getNodesInRangeForSelection(pinnedRowModel, "top", end, undefined); return pinned.concat(rowModel.getNodesInRangeForSelection(rowModel.getRow(0), start) ?? []); } if (start.rowPinned === "top" && end.rowPinned === "bottom") { const top = _getNodesInRangeForSelection(pinnedRowModel, "top", start, undefined); const bottom = _getNodesInRangeForSelection(pinnedRowModel, "bottom", undefined, end); const first = rowModel.getRow(0); const last = rowModel.getRow(rowModel.getRowCount() - 1); return top.concat(rowModel.getNodesInRangeForSelection(first, last) ?? []).concat(bottom); } if (start.rowPinned === "bottom" && end.rowPinned === "bottom") { return _getNodesInRangeForSelection(pinnedRowModel, "bottom", start, end); } if (!start.rowPinned && end.rowPinned === "bottom") { const pinned = _getNodesInRangeForSelection(pinnedRowModel, "bottom", undefined, end); const last = rowModel.getRow(rowModel.getRowCount()); return (rowModel.getNodesInRangeForSelection(start, last) ?? []).concat(pinned); } return null; } }; var SelectAllFeature = class extends BeanStub { constructor(column) { super(); this.column = column; this.cbSelectAllVisible = false; this.processingEventFromCheckbox = false; } onSpaceKeyDown(e) { const checkbox = this.cbSelectAll; if (checkbox.isDisplayed() && !checkbox.getGui().contains(_getActiveDomElement(this.beans))) { e.preventDefault(); checkbox.setValue(!checkbox.getValue()); } } getCheckboxGui() { return this.cbSelectAll.getGui(); } setComp(ctrl) { this.headerCellCtrl = ctrl; const cbSelectAll = this.createManagedBean(new AgCheckbox); this.cbSelectAll = cbSelectAll; cbSelectAll.addCss("ag-header-select-all"); _setAriaRole(cbSelectAll.getGui(), "presentation"); this.showOrHideSelectAll(); const updateStateOfCheckbox = this.updateStateOfCheckbox.bind(this); this.addManagedEventListeners({ newColumnsLoaded: () => this.showOrHideSelectAll(), displayedColumnsChanged: this.onDisplayedColumnsChanged.bind(this), selectionChanged: updateStateOfCheckbox, paginationChanged: updateStateOfCheckbox, modelUpdated: updateStateOfCheckbox }); this.addManagedPropertyListener("rowSelection", ({ currentValue, previousValue }) => { const getSelectAll = (rowSelection) => typeof rowSelection === "string" || !rowSelection || rowSelection.mode === "singleRow" ? undefined : rowSelection.selectAll; if (getSelectAll(currentValue) !== getSelectAll(previousValue)) { this.showOrHideSelectAll(); } this.updateStateOfCheckbox(); }); this.addManagedListeners(cbSelectAll, { fieldValueChanged: this.onCbSelectAll.bind(this) }); cbSelectAll.getInputElement().setAttribute("tabindex", "-1"); this.refreshSelectAllLabel(); } onDisplayedColumnsChanged(e) { if (!this.isAlive()) { return; } this.showOrHideSelectAll(e.source === "uiColumnMoved"); } showOrHideSelectAll(fromColumnMoved = false) { const cbSelectAllVisible = this.isCheckboxSelection(); this.cbSelectAllVisible = cbSelectAllVisible; this.cbSelectAll.setDisplayed(cbSelectAllVisible); if (cbSelectAllVisible) { this.checkRightRowModelType("selectAllCheckbox"); this.checkSelectionType("selectAllCheckbox"); this.updateStateOfCheckbox(); } this.refreshSelectAllLabel(fromColumnMoved); } updateStateOfCheckbox() { if (!this.cbSelectAllVisible || this.processingEventFromCheckbox) { return; } this.processingEventFromCheckbox = true; const selectAllMode = this.getSelectAllMode(); const selectionSvc = this.beans.selectionSvc; const cbSelectAll = this.cbSelectAll; const allSelected = selectionSvc.getSelectAllState(selectAllMode); cbSelectAll.setValue(allSelected); const hasNodesToSelect = selectionSvc.hasNodesToSelect(selectAllMode); cbSelectAll.setDisabled(!hasNodesToSelect); this.refreshSelectAllLabel(); this.processingEventFromCheckbox = false; } refreshSelectAllLabel(fromColumnMoved = false) { const translate = this.getLocaleTextFunc(); const { headerCellCtrl, cbSelectAll, cbSelectAllVisible } = this; const checked = cbSelectAll.getValue(); const ariaStatus = _getAriaCheckboxStateName(translate, checked); const ariaLabel = translate("ariaRowSelectAll", "Press Space to toggle all rows selection"); headerCellCtrl.setAriaDescriptionProperty("selectAll", cbSelectAllVisible ? `${ariaLabel} (${ariaStatus})` : null); cbSelectAll.setInputAriaLabel(translate("ariaHeaderSelection", "Column with Header Selection")); if (!fromColumnMoved) { headerCellCtrl.announceAriaDescription(); } } checkSelectionType(feature) { const isMultiSelect = _isMultiRowSelection(this.gos); if (!isMultiSelect) { _warn(128, { feature }); return false; } return true; } checkRightRowModelType(feature) { const { gos, rowModel } = this.beans; const rowModelMatches = _isClientSideRowModel(gos) || _isServerSideRowModel(gos); if (!rowModelMatches) { _warn(129, { feature, rowModel: rowModel.getType() }); return false; } return true; } onCbSelectAll() { if (this.processingEventFromCheckbox) { return; } if (!this.cbSelectAllVisible) { return; } const value = this.cbSelectAll.getValue(); const selectAll2 = this.getSelectAllMode(); let source = "uiSelectAll"; if (selectAll2 === "currentPage") { source = "uiSelectAllCurrentPage"; } else if (selectAll2 === "filtered") { source = "uiSelectAllFiltered"; } const params = { source, selectAll: selectAll2 }; const selectionSvc = this.beans.selectionSvc; if (value) { selectionSvc.selectAllRowNodes(params); } else { selectionSvc.deselectAllRowNodes(params); } } isCheckboxSelection() { const { column, gos, beans } = this; const rowSelection = gos.get("rowSelection"); const newHeaderCheckbox = typeof rowSelection === "object"; const featureName = newHeaderCheckbox ? "headerCheckbox" : "headerCheckboxSelection"; return isCheckboxSelection(beans, column) && this.checkRightRowModelType(featureName) && this.checkSelectionType(featureName); } getSelectAllMode() { const selectAll2 = _getSelectAll(this.gos, false); if (selectAll2) { return selectAll2; } const { headerCheckboxSelectionCurrentPageOnly, headerCheckboxSelectionFilteredOnly } = this.column.getColDef(); if (headerCheckboxSelectionCurrentPageOnly) { return "currentPage"; } if (headerCheckboxSelectionFilteredOnly) { return "filtered"; } return "all"; } destroy() { super.destroy(); this.cbSelectAll = undefined; this.headerCellCtrl = undefined; } }; function isCheckboxSelection({ gos, selectionColSvc }, column) { const rowSelection = gos.get("rowSelection"); const colDef = column.getColDef(); const { headerCheckboxSelection } = colDef; let result = false; const newHeaderCheckbox = typeof rowSelection === "object"; if (newHeaderCheckbox) { const isSelectionCol = isColumnSelectionCol(column); const isAutoCol = isColumnGroupAutoCol(column); const location = _getCheckboxLocation(rowSelection); if (location === "autoGroupColumn" && isAutoCol || isSelectionCol && selectionColSvc?.isSelectionColumnEnabled()) { result = _getHeaderCheckbox(rowSelection); } } else if (typeof headerCheckboxSelection === "function") { result = headerCheckboxSelection(_addGridCommonParams(gos, { column, colDef })); } else { result = !!headerCheckboxSelection; } return result; } var BaseSelectionService = class extends BeanStub { postConstruct() { const { gos, beans } = this; this.selectionCtx = new RowRangeSelectionContext(beans.rowModel, beans.pinnedRowModel); this.addManagedPropertyListeners(["isRowSelectable", "rowSelection"], () => { const callback = _getIsRowSelectable(gos); if (callback !== this.isRowSelectable) { this.isRowSelectable = callback; this.updateSelectable(); } }); this.isRowSelectable = _getIsRowSelectable(gos); this.addManagedEventListeners({ cellValueChanged: (e) => this.updateRowSelectable(e.node), rowNodeDataChanged: (e) => this.updateRowSelectable(e.node) }); } destroy() { super.destroy(); this.selectionCtx.reset(); } createCheckboxSelectionComponent() { return new CheckboxSelectionComponent; } createSelectAllFeature(column) { if (isCheckboxSelection(this.beans, column)) { return new SelectAllFeature(column); } } isMultiSelect() { return _isMultiRowSelection(this.gos); } onRowCtrlSelected(rowCtrl, hasFocusFunc, gui) { const selected = !!rowCtrl.rowNode.isSelected(); rowCtrl.forEachGui(gui, (gui2) => { gui2.rowComp.toggleCss("ag-row-selected", selected); const element = gui2.element; _setAriaSelected(element, selected); const hasFocus = element.contains(_getActiveDomElement(this.beans)); if (hasFocus) { hasFocusFunc(gui2); } }); } announceAriaRowSelection(rowNode) { if (this.isRowSelectionBlocked(rowNode)) { return; } const selected = rowNode.isSelected(); const isEditing2 = this.beans.editSvc?.isEditing({ rowNode }); if (!rowNode.selectable || isEditing2) { return; } const translate = this.getLocaleTextFunc(); const label = translate(selected ? "ariaRowDeselect" : "ariaRowSelect", `Press SPACE to ${selected ? "deselect" : "select"} this row`); this.beans.ariaAnnounce?.announceValue(label, "rowSelection"); } isRowSelectionBlocked(rowNode) { return !rowNode.selectable || rowNode.rowPinned && !_isManualPinnedRow(rowNode) || !_isRowSelection(this.gos); } updateRowSelectable(rowNode, suppressSelectionUpdate) { const selectable = rowNode.rowPinned && rowNode.pinnedSibling ? rowNode.pinnedSibling.selectable : this.isRowSelectable?.(rowNode) ?? true; this.setRowSelectable(rowNode, selectable, suppressSelectionUpdate); return selectable; } setRowSelectable(rowNode, newVal, suppressSelectionUpdate) { if (rowNode.selectable !== newVal) { rowNode.selectable = newVal; rowNode.dispatchRowEvent("selectableChanged"); if (suppressSelectionUpdate) { return; } const isGroupSelectsChildren = _getGroupSelectsDescendants(this.gos); if (isGroupSelectsChildren) { const selected = this.calculateSelectedFromChildren(rowNode); this.setNodesSelected({ nodes: [rowNode], newValue: selected ?? false, source: "selectableChanged" }); return; } if (rowNode.isSelected() && !rowNode.selectable) { this.setNodesSelected({ nodes: [rowNode], newValue: false, source: "selectableChanged" }); } } } calculateSelectedFromChildren(rowNode) { let atLeastOneSelected = false; let atLeastOneDeSelected = false; if (!rowNode.childrenAfterGroup?.length) { return rowNode.selectable ? rowNode.__selected : null; } for (let i = 0;i < rowNode.childrenAfterGroup.length; i++) { const child = rowNode.childrenAfterGroup[i]; let childState = child.isSelected(); if (!child.selectable) { const selectable = this.calculateSelectedFromChildren(child); if (selectable === null) { continue; } childState = selectable; } switch (childState) { case true: atLeastOneSelected = true; break; case false: atLeastOneDeSelected = true; break; default: return; } } if (atLeastOneSelected && atLeastOneDeSelected) { return; } if (atLeastOneSelected) { return true; } if (atLeastOneDeSelected) { return false; } if (!rowNode.selectable) { return null; } return rowNode.__selected; } selectRowNode(rowNode, newValue, e, source = "api") { if (newValue && rowNode.destroyed) { return false; } const selectionNotAllowed = !rowNode.selectable && newValue; const selectionNotChanged = rowNode.__selected === newValue; if (selectionNotAllowed || selectionNotChanged) { return false; } rowNode.__selected = newValue; rowNode.dispatchRowEvent("rowSelected"); const sibling = rowNode.sibling; if (sibling && sibling.footer && sibling.__localEventService) { sibling.dispatchRowEvent("rowSelected"); } const pinnedSibling = rowNode.pinnedSibling; if (pinnedSibling?.rowPinned && pinnedSibling.__localEventService) { pinnedSibling.dispatchRowEvent("rowSelected"); } this.eventSvc.dispatchEvent({ ..._createGlobalRowEvent(rowNode, this.gos, "rowSelected"), event: e || null, source }); return true; } isCellCheckboxSelection(column, rowNode) { const so = this.gos.get("rowSelection"); if (so && typeof so !== "string") { const checkbox = isColumnSelectionCol(column) && _getCheckboxes(so); return column.isColumnFunc(rowNode, checkbox); } else { return column.isColumnFunc(rowNode, column.colDef.checkboxSelection); } } inferNodeSelections(node, shiftKey, metaKey, source) { const { gos, selectionCtx } = this; const currentSelection = node.isSelected(); const groupSelectsDescendants = _getGroupSelectsDescendants(gos); const enableClickSelection = _getEnableSelection(gos); const enableDeselection = _getEnableDeselection(gos); const isMultiSelect = this.isMultiSelect(); const isRowClicked = source === "rowClicked"; if (isRowClicked && !(enableClickSelection || enableDeselection)) { return null; } if (shiftKey && metaKey && isMultiSelect) { const root = selectionCtx.getRoot(); if (!root) { return null; } else if (!root.isSelected()) { const partition = selectionCtx.extend(node, groupSelectsDescendants); return { select: [], deselect: partition.keep, reset: false }; } else { const partition = selectionCtx.isInRange(node) ? selectionCtx.truncate(node) : selectionCtx.extend(node, groupSelectsDescendants); return { deselect: partition.discard, select: partition.keep, reset: false }; } } else if (shiftKey && isMultiSelect) { const fallback = selectionCtx.selectAll ? this.beans.rowModel.getRow(0) : undefined; const root = selectionCtx.getRoot(fallback); const partition = selectionCtx.isInRange(node) ? selectionCtx.truncate(node) : selectionCtx.extend(node, groupSelectsDescendants); return { select: partition.keep, deselect: partition.discard, reset: selectionCtx.selectAll || !!(root && !root.isSelected()) }; } else if (metaKey) { if (isRowClicked) { const newValue = !currentSelection; const selectingWhenDisabled = newValue && !enableClickSelection; const deselectingWhenDisabled = !newValue && !enableDeselection; if (selectingWhenDisabled || deselectingWhenDisabled) { return null; } selectionCtx.setRoot(node); return { node, newValue, clearSelection: false }; } selectionCtx.setRoot(node); return { node, newValue: !currentSelection, clearSelection: !isMultiSelect }; } else { selectionCtx.setRoot(node); const enableSelectionWithoutKeys = _getEnableSelectionWithoutKeys(gos); const groupSelectsFiltered = _getGroupSelection(gos) === "filteredDescendants"; const shouldClear = isRowClicked && (!enableSelectionWithoutKeys || !enableClickSelection); if (groupSelectsFiltered && currentSelection === undefined && _isClientSideRowModel(gos)) { return { node, newValue: false, checkFilteredNodes: true, clearSelection: !isMultiSelect || shouldClear }; } if (isRowClicked) { const newValue = currentSelection ? !enableSelectionWithoutKeys : enableClickSelection; const selectingWhenDisabled = newValue && !enableClickSelection; const deselectingWhenDisabled = !newValue && !enableDeselection; const wouldStateBeUnchanged = newValue === currentSelection && !shouldClear; if (wouldStateBeUnchanged || selectingWhenDisabled || deselectingWhenDisabled) { return null; } return { node, newValue, clearSelection: !isMultiSelect || shouldClear, keepDescendants: node.group && groupSelectsDescendants }; } return { node, newValue: !currentSelection, clearSelection: !isMultiSelect || shouldClear }; } } }; var SelectionService = class extends BaseSelectionService { constructor() { super(...arguments); this.beanName = "selectionSvc"; this.selectedNodes = /* @__PURE__ */ new Map; this.detailSelection = /* @__PURE__ */ new Map; this.masterSelectsDetail = false; } postConstruct() { super.postConstruct(); const { gos } = this; this.mode = _getRowSelectionMode(gos); this.groupSelectsDescendants = _getGroupSelectsDescendants(gos); this.groupSelectsFiltered = _getGroupSelection(gos) === "filteredDescendants"; this.masterSelectsDetail = _getMasterSelects(gos) === "detail"; this.addManagedPropertyListeners(["groupSelectsChildren", "groupSelectsFiltered", "rowSelection"], () => { const groupSelectsDescendants = _getGroupSelectsDescendants(gos); const selectionMode = _getRowSelectionMode(gos); const groupSelectsFiltered = _getGroupSelection(gos) === "filteredDescendants"; this.masterSelectsDetail = _getMasterSelects(gos) === "detail"; if (groupSelectsDescendants !== this.groupSelectsDescendants || groupSelectsFiltered !== this.groupSelectsFiltered || selectionMode !== this.mode) { this.deselectAllRowNodes({ source: "api" }); this.groupSelectsDescendants = groupSelectsDescendants; this.groupSelectsFiltered = groupSelectsFiltered; this.mode = selectionMode; } }); this.addManagedEventListeners({ rowSelected: this.onRowSelected.bind(this) }); } destroy() { super.destroy(); this.resetNodes(); } handleSelectionEvent(event, rowNode, source) { if (this.isRowSelectionBlocked(rowNode)) { return 0; } const selection = this.inferNodeSelections(rowNode, event.shiftKey, event.metaKey || event.ctrlKey, source); if (selection == null) { return 0; } this.selectionCtx.selectAll = false; if ("select" in selection) { if (selection.reset) { this.resetNodes(); } else { this.selectRange(selection.deselect, false, source); } return this.selectRange(selection.select, true, source); } else { const newValue = selection.checkFilteredNodes ? recursiveCanNodesBeSelected(selection.node) : selection.newValue; return this.setNodesSelected({ nodes: [selection.node], newValue, clearSelection: selection.clearSelection, keepDescendants: selection.keepDescendants, event, source }); } } setNodesSelected({ newValue, clearSelection, suppressFinishActions, nodes, event, source, keepDescendants = false }) { if (nodes.length === 0) { return 0; } const { gos } = this; if (!_isRowSelection(gos) && newValue) { _warn(132); return 0; } if (nodes.length > 1 && !this.isMultiSelect()) { _warn(130); return 0; } let updatedCount = 0; for (let i = 0;i < nodes.length; i++) { const rowNode = nodes[i]; const node = rowNode.primaryRow; if (node.rowPinned && !_isManualPinnedRow(node)) { _warn(59); continue; } if (node.id === undefined) { _warn(60); continue; } if (newValue && rowNode.destroyed) { continue; } const skipThisNode = this.groupSelectsFiltered && node.group && !gos.get("treeData"); if (!skipThisNode) { const thisNodeWasSelected = this.selectRowNode(node, newValue, event, source); if (thisNodeWasSelected) { this.detailSelection.delete(node.id); updatedCount++; } } if (this.groupSelectsDescendants && node.childrenAfterGroup?.length) { updatedCount += this.selectChildren(node, newValue, source); } } if (!suppressFinishActions) { if (nodes.length === 1 && source === "api") { this.selectionCtx.setRoot(nodes[0].primaryRow); } const clearOtherNodes = newValue && (clearSelection || !this.isMultiSelect()); if (clearOtherNodes) { updatedCount += this.clearOtherNodes(nodes[0].primaryRow, keepDescendants, source); } if (updatedCount > 0) { this.updateGroupsFromChildrenSelections(source); this.dispatchSelectionChanged(source); } } return updatedCount; } selectRange(nodesToSelect, value, source) { let updatedCount = 0; nodesToSelect.forEach((node) => { const rowNode = node.primaryRow; if (rowNode.group && this.groupSelectsDescendants) { return; } const nodeWasSelected = this.selectRowNode(rowNode, value, undefined, source); if (nodeWasSelected) { updatedCount++; } }); if (updatedCount > 0) { this.updateGroupsFromChildrenSelections(source); this.dispatchSelectionChanged(source); } return updatedCount; } selectChildren(node, newValue, source) { const children = this.groupSelectsFiltered ? node.childrenAfterAggFilter : node.childrenAfterGroup; if (!children) { return 0; } return this.setNodesSelected({ newValue, clearSelection: false, suppressFinishActions: true, source, nodes: children }); } getSelectedNodes() { return Array.from(this.selectedNodes.values()); } getSelectedRows() { const selectedRows = []; this.selectedNodes.forEach((rowNode) => rowNode.data && selectedRows.push(rowNode.data)); return selectedRows; } getSelectionCount() { return this.selectedNodes.size; } filterFromSelection(predicate) { const newSelectedNodes = /* @__PURE__ */ new Map; this.selectedNodes.forEach((rowNode, key) => { if (predicate(rowNode)) { newSelectedNodes.set(key, rowNode); } }); this.selectedNodes = newSelectedNodes; } updateGroupsFromChildrenSelections(source, changedPath) { if (!this.groupSelectsDescendants) { return false; } const { gos, rowModel } = this.beans; if (!_isClientSideRowModel(gos, rowModel)) { return false; } const rootNode = rowModel.rootNode; if (!rootNode) { return false; } let selectionChanged = false; const nodeCallback = (rowNode) => { if (rowNode !== rootNode) { const selected = this.calculateSelectedFromChildren(rowNode); selectionChanged = this.selectRowNode(rowNode, selected === null ? false : selected, undefined, source) || selectionChanged; } }; _forEachChangedGroupDepthFirst(rootNode, this.beans.rowModel.hierarchical, changedPath, nodeCallback); return selectionChanged; } clearOtherNodes(rowNodeToKeepSelected, keepDescendants, source) { const groupsToRefresh = /* @__PURE__ */ new Map; let updatedCount = 0; this.selectedNodes.forEach((otherRowNode) => { const isNodeToKeep = otherRowNode.id == rowNodeToKeepSelected.id; const shouldClearDescendant = keepDescendants ? !isDescendantOf(rowNodeToKeepSelected, otherRowNode) : true; if (shouldClearDescendant && !isNodeToKeep) { const rowNode = this.selectedNodes.get(otherRowNode.id); updatedCount += this.setNodesSelected({ nodes: [rowNode], newValue: false, clearSelection: false, suppressFinishActions: true, source }); if (this.groupSelectsDescendants && otherRowNode.parent) { groupsToRefresh.set(otherRowNode.parent.id, otherRowNode.parent); } } }); groupsToRefresh.forEach((group) => { const selected = this.calculateSelectedFromChildren(group); this.selectRowNode(group, selected === null ? false : selected, undefined, source); }); return updatedCount; } onRowSelected(event) { const rowNode = event.node; if (this.groupSelectsDescendants && rowNode.group) { return; } if (rowNode.isSelected()) { this.selectedNodes.set(rowNode.id, rowNode); } else { this.selectedNodes.delete(rowNode.id); } } syncInRowNode(rowNode, oldNode) { this.syncInOldRowNode(rowNode, oldNode); this.syncInNewRowNode(rowNode); } createDaemonNode(rowNode) { if (!rowNode.id) { return; } const oldNode = new RowNode(this.beans); oldNode.id = rowNode.id; oldNode.data = rowNode.data; oldNode.__selected = rowNode.__selected; oldNode.level = rowNode.level; return oldNode; } syncInOldRowNode(rowNode, oldNode) { if (oldNode && rowNode.id !== oldNode.id) { const oldNodeSelected = this.selectedNodes.get(oldNode.id) == rowNode; if (oldNodeSelected) { this.selectedNodes.set(oldNode.id, oldNode); } } } syncInNewRowNode(rowNode) { if (this.selectedNodes.has(rowNode.id)) { rowNode.__selected = true; this.selectedNodes.set(rowNode.id, rowNode); } else { rowNode.__selected = false; } } reset(source) { const selectionCount = this.getSelectionCount(); this.resetNodes(); if (selectionCount) { this.dispatchSelectionChanged(source); } } resetNodes() { this.selectedNodes.forEach((node) => { this.selectRowNode(node, false); }); this.selectedNodes.clear(); } getBestCostNodeSelection() { const { gos, rowModel } = this.beans; if (!_isClientSideRowModel(gos, rowModel)) { return; } const topLevelNodes = rowModel.getTopLevelNodes(); if (topLevelNodes === null) { return; } const result = []; function traverse(nodes) { for (let i = 0, l = nodes.length;i < l; i++) { const node = nodes[i]; if (node.isSelected()) { result.push(node); } else if (node.group && node.childrenAfterGroup) { traverse(node.childrenAfterGroup); } } } traverse(topLevelNodes); return result; } isEmpty() { return this.getSelectionCount() === 0; } deselectAllRowNodes({ source, selectAll: selectAll2 }) { const rowModelClientSide = _isClientSideRowModel(this.gos); let updatedNodes = false; const callback = (rowNode) => { const updated = this.selectRowNode(rowNode.primaryRow, false, undefined, source); updatedNodes || (updatedNodes = updated); }; if (selectAll2 === "currentPage" || selectAll2 === "filtered") { if (!rowModelClientSide) { _error(102); return; } this.getNodesToSelect(selectAll2).forEach(callback); } else { this.selectedNodes.forEach(callback); this.reset(source); } this.selectionCtx.selectAll = false; if (rowModelClientSide && this.groupSelectsDescendants) { const updated = this.updateGroupsFromChildrenSelections(source); updatedNodes || (updatedNodes = updated); } if (updatedNodes) { this.dispatchSelectionChanged(source); } } getSelectedCounts(selectAll2) { let selectedCount = 0; let notSelectedCount = 0; this.getNodesToSelect(selectAll2).forEach((node) => { if (this.groupSelectsDescendants && node.group) { return; } if (node.isSelected()) { selectedCount++; } else if (node.selectable) { notSelectedCount++; } }); return { selectedCount, notSelectedCount }; } getSelectAllState(selectAll2) { const { selectedCount, notSelectedCount } = this.getSelectedCounts(selectAll2); return _calculateSelectAllState(selectedCount, notSelectedCount) ?? null; } hasNodesToSelect(selectAll2) { return this.getNodesToSelect(selectAll2).filter((node) => node.selectable).length > 0; } getNodesToSelect(selectAll2) { if (!this.canSelectAll()) { return []; } const nodes = []; const addToResult = (node) => nodes.push(node); if (selectAll2 === "currentPage") { this.forEachNodeOnPage((node) => { if (!node.group) { addToResult(node); return; } if (!node.footer && !node.expanded) { const recursivelyAddChildren = (child) => { addToResult(child); const children = child.childrenAfterFilter; if (children) { for (let i = 0, len = children.length;i < len; ++i) { recursivelyAddChildren(children[i]); } } }; recursivelyAddChildren(node); return; } if (!this.groupSelectsDescendants) { addToResult(node); } }); return nodes; } const clientSideRowModel = this.beans.rowModel; if (selectAll2 === "filtered") { clientSideRowModel.forEachNodeAfterFilter(addToResult); return nodes; } clientSideRowModel.forEachNode(addToResult); return nodes; } forEachNodeOnPage(callback) { const { pageBounds, rowModel } = this.beans; const firstRow = pageBounds.getFirstRow(); const lastRow = pageBounds.getLastRow(); for (let i = firstRow;i <= lastRow; i++) { const node = rowModel.getRow(i); if (node) { callback(node); } } } selectAllRowNodes(params) { const { gos, selectionCtx } = this; if (!_isRowSelection(gos)) { _warn(132); return; } if (_isUsingNewRowSelectionAPI(gos) && !_isMultiRowSelection(gos)) { _warn(130); return; } if (!this.canSelectAll()) { return; } const { source, selectAll: selectAll2 } = params; let updatedNodes = false; this.getNodesToSelect(selectAll2).forEach((rowNode) => { const updated = this.selectRowNode(rowNode.primaryRow, true, undefined, source); updatedNodes || (updatedNodes = updated); }); selectionCtx.selectAll = true; if (_isClientSideRowModel(gos) && this.groupSelectsDescendants) { const updated = this.updateGroupsFromChildrenSelections(source); updatedNodes || (updatedNodes = updated); } if (updatedNodes) { this.dispatchSelectionChanged(source); } } getSelectionState() { return this.isEmpty() ? null : Array.from(this.selectedNodes.keys()); } setSelectionState(state, source, clearSelection) { if (!state) { state = []; } if (!Array.isArray(state)) { _error(103); return; } const rowIds = new Set(state); const nodes = []; this.beans.rowModel.forEachNode((node) => { if (rowIds.has(node.id)) { nodes.push(node); } }); if (clearSelection) { this.resetNodes(); } this.setNodesSelected({ newValue: true, nodes, source }); } canSelectAll() { return _isClientSideRowModel(this.beans.gos); } updateSelectable(changedPath) { const { gos, rowModel } = this.beans; if (!_isRowSelection(gos)) { return; } const source = "selectableChanged"; const isCSRMGroupSelectsDescendants = _isClientSideRowModel(gos) && this.groupSelectsDescendants; const nodesToDeselect = []; if (isCSRMGroupSelectsDescendants) { const rootNode = rowModel.rootNode; if (rootNode) { _forEachChangedGroupDepthFirst(rootNode, rowModel.hierarchical, changedPath, (node) => { let childSelectable = false; for (const child of node.childrenAfterGroup) { childSelectable || (childSelectable = child.selectable); if (!child.group && !this.updateRowSelectable(child, true) && child.isSelected()) { nodesToDeselect.push(child); } } this.setRowSelectable(node, childSelectable, true); }); } } else { rowModel.forEachNode((node) => { if (!this.updateRowSelectable(node, true) && node.isSelected()) { nodesToDeselect.push(node); } }); } if (nodesToDeselect.length) { this.setNodesSelected({ nodes: nodesToDeselect, newValue: false, source }); } if (!changedPath && isCSRMGroupSelectsDescendants) { this.updateGroupsFromChildrenSelections?.(source); } } updateSelectableAfterGrouping(changedPath) { this.updateSelectable(changedPath); if (this.groupSelectsDescendants) { const selectionChanged = this.updateGroupsFromChildrenSelections?.("rowGroupChanged", changedPath); if (selectionChanged) { this.dispatchSelectionChanged("rowGroupChanged"); } } } refreshMasterNodeState(node, e) { if (!this.masterSelectsDetail) { return; } const detailApi = node.detailNode?.detailGridInfo?.api; if (!detailApi) { return; } const isSelectAll = _isAllSelected(detailApi); const current = node.isSelected(); if (current !== isSelectAll) { const selectionChanged = this.selectRowNode(node, isSelectAll, e, "masterDetail"); if (selectionChanged) { this.dispatchSelectionChanged("masterDetail"); } } if (!isSelectAll) { this.detailSelection.set(node.id, new Set(detailApi.getSelectedNodes().map((n) => n.id))); } } setDetailSelectionState(masterNode, detailGridOptions, detailApi) { if (!this.masterSelectsDetail) { return; } if (!_isMultiRowSelection(detailGridOptions)) { _warn(269); return; } switch (masterNode.isSelected()) { case true: { detailApi.selectAll(); break; } case false: { detailApi.deselectAll(); break; } case undefined: { const selectedIds = this.detailSelection.get(masterNode.id); if (selectedIds) { const nodes = []; for (const id of selectedIds) { const n = detailApi.getRowNode(id); if (n) { nodes.push(n); } } detailApi.setNodesSelected({ nodes, newValue: true, source: "masterDetail" }); } break; } default: break; } } dispatchSelectionChanged(source) { this.eventSvc.dispatchEvent({ type: "selectionChanged", source, selectedNodes: this.getSelectedNodes(), serverSideState: null }); } }; function _isAllSelected(api) { let selectedCount = 0; let notSelectedCount = 0; api.forEachNode((node) => { if (node.isSelected()) { selectedCount++; } else if (node.selectable) { notSelectedCount++; } }); return _calculateSelectAllState(selectedCount, notSelectedCount); } function _calculateSelectAllState(selected, notSelected) { if (selected === 0 && notSelected === 0) { return false; } if (selected > 0 && notSelected > 0) { return; } return selected > 0; } function isDescendantOf(root, child) { let parent = child.parent; while (parent) { if (parent === root) { return true; } parent = parent.parent; } return false; } function recursiveCanNodesBeSelected(root) { const rootCanBeSelected = root.isSelected() === false; const childrenCanBeSelected = root.childrenAfterFilter?.some(recursiveCanNodesBeSelected) ?? false; return rootCanBeSelected || childrenCanBeSelected; } var SharedRowSelectionModule = { moduleName: "SharedRowSelection", version: VERSION, beans: [SelectionColService], css: [rowSelection_default], apiFunctions: { setNodesSelected, selectAll, deselectAll, selectAllFiltered, deselectAllFiltered, selectAllOnCurrentPage, deselectAllOnCurrentPage, getSelectedNodes, getSelectedRows } }; var RowSelectionModule = { moduleName: "RowSelection", version: VERSION, rowModels: ["clientSide", "infinite", "viewport"], beans: [SelectionService], dependsOn: [SharedRowSelectionModule] }; var CellCustomStyleFeature = class extends BeanStub { constructor(cellCtrl, beans) { super(); this.cellCtrl = cellCtrl; this.staticClasses = []; this.beans = beans; this.column = cellCtrl.column; } setComp(comp) { this.cellComp = comp; this.applyUserStyles(); this.applyCellClassRules(); this.applyClassesFromColDef(); } applyCellClassRules() { const { column, cellComp } = this; const colDef = column.colDef; const cellClassRules = colDef.cellClassRules; const cellClassParams = this.getCellClassParams(column, colDef); processClassRules(this.beans.expressionSvc, cellClassRules === this.cellClassRules ? undefined : this.cellClassRules, cellClassRules, cellClassParams, (className) => cellComp.toggleCss(className, true), (className) => cellComp.toggleCss(className, false)); this.cellClassRules = cellClassRules; } applyUserStyles() { const column = this.column; const colDef = column.colDef; const cellStyle = colDef.cellStyle; if (!cellStyle) { return; } let styles; if (typeof cellStyle === "function") { const cellStyleParams = this.getCellClassParams(column, colDef); styles = cellStyle(cellStyleParams); } else { styles = cellStyle; } if (styles) { this.cellComp.setUserStyles(styles); } } applyClassesFromColDef() { const { column, cellComp } = this; const colDef = column.colDef; const cellClassParams = this.getCellClassParams(column, colDef); for (const className of this.staticClasses) { cellComp.toggleCss(className, false); } const newStaticClasses = this.beans.cellStyles.getStaticCellClasses(colDef, cellClassParams); this.staticClasses = newStaticClasses; for (const className of newStaticClasses) { cellComp.toggleCss(className, true); } } getCellClassParams(column, colDef) { const { value, rowNode } = this.cellCtrl; return _addGridCommonParams(this.beans.gos, { value, data: rowNode.data, node: rowNode, colDef, column, rowIndex: rowNode.rowIndex }); } }; var CellStyleService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "cellStyles"; } processAllCellClasses(colDef, params, onApplicableClass, onNotApplicableClass) { processClassRules(this.beans.expressionSvc, undefined, colDef.cellClassRules, params, onApplicableClass, onNotApplicableClass); this.processStaticCellClasses(colDef, params, onApplicableClass); } getStaticCellClasses(colDef, params) { const { cellClass } = colDef; if (!cellClass) { return []; } let classOrClasses; if (typeof cellClass === "function") { const cellClassFunc = cellClass; classOrClasses = cellClassFunc(params); } else { classOrClasses = cellClass; } if (typeof classOrClasses === "string") { classOrClasses = [classOrClasses]; } return classOrClasses || []; } createCellCustomStyleFeature(ctrl) { return new CellCustomStyleFeature(ctrl, this.beans); } processStaticCellClasses(colDef, params, onApplicableClass) { const classOrClasses = this.getStaticCellClasses(colDef, params); classOrClasses.forEach((cssClassItem) => { onApplicableClass(cssClassItem); }); } }; var CellStyleModule = { moduleName: "CellStyle", version: VERSION, beans: [CellStyleService] }; var INITIAL_GRID_OPTION_KEYS = { enableBrowserTooltips: true, tooltipTrigger: true, tooltipMouseTrack: true, tooltipShowMode: true, tooltipInteraction: true, defaultColGroupDef: true, suppressAutoSize: true, skipHeaderOnAutoSize: true, autoSizeStrategy: true, components: true, stopEditingWhenCellsLoseFocus: true, undoRedoCellEditing: true, undoRedoCellEditingLimit: true, excelStyles: true, cacheQuickFilter: true, customChartThemes: true, chartThemeOverrides: true, chartToolPanelsDef: true, loadingCellRendererSelector: true, localeText: true, keepDetailRows: true, keepDetailRowsCount: true, detailRowHeight: true, detailRowAutoHeight: true, tabIndex: true, valueCache: true, valueCacheNeverExpires: true, enableCellExpressions: true, suppressTouch: true, suppressBrowserResizeObserver: true, suppressPropertyNamesCheck: true, debug: true, dragAndDropImageComponent: true, overlayComponent: true, suppressOverlays: true, loadingOverlayComponent: true, suppressLoadingOverlay: true, noRowsOverlayComponent: true, paginationPageSizeSelector: true, paginateChildRows: true, pivotPanelShow: true, pivotSuppressAutoColumn: true, suppressExpandablePivotGroups: true, aggFuncs: true, allowShowChangeAfterFilter: true, ensureDomOrder: true, enableRtl: true, suppressColumnVirtualisation: true, suppressMaxRenderedRowRestriction: true, suppressRowVirtualisation: true, rowDragText: true, groupLockGroupColumns: true, suppressGroupRowsSticky: true, rowModelType: true, cacheOverflowSize: true, infiniteInitialRowCount: true, serverSideInitialRowCount: true, maxBlocksInCache: true, maxConcurrentDatasourceRequests: true, blockLoadDebounceMillis: true, serverSideOnlyRefreshFilteredGroups: true, serverSidePivotResultFieldSeparator: true, viewportRowModelPageSize: true, viewportRowModelBufferSize: true, debounceVerticalScrollbar: true, suppressAnimationFrame: true, suppressPreventDefaultOnMouseWheel: true, scrollbarWidth: true, icons: true, suppressRowTransform: true, gridId: true, enableGroupEdit: true, initialState: true, processUnpinnedColumns: true, createChartContainer: true, getLocaleText: true, getRowId: true, reactiveCustomComponents: true, renderingMode: true, columnMenu: true, suppressSetFilterByDefault: true, getDataPath: true, enableCellSpan: true, enableFilterHandlers: true, filterHandlers: true }; var clientSide = "clientSide"; var serverSide = "serverSide"; var infinite = "infinite"; var functionRowModels = { onGroupExpandedOrCollapsed: [clientSide], refreshClientSideRowModel: [clientSide], isRowDataEmpty: [clientSide], forEachLeafNode: [clientSide], forEachNodeAfterFilter: [clientSide], forEachNodeAfterFilterAndSort: [clientSide], resetRowHeights: [clientSide, serverSide], applyTransaction: [clientSide], applyTransactionAsync: [clientSide], flushAsyncTransactions: [clientSide], getBestCostNodeSelection: [clientSide], getServerSideSelectionState: [serverSide], setServerSideSelectionState: [serverSide], applyServerSideTransaction: [serverSide], applyServerSideTransactionAsync: [serverSide], applyServerSideRowData: [serverSide], retryServerSideLoads: [serverSide], flushServerSideAsyncTransactions: [serverSide], refreshServerSide: [serverSide], getServerSideGroupLevelState: [serverSide], refreshInfiniteCache: [infinite], purgeInfiniteCache: [infinite], getInfiniteRowCount: [infinite], isLastRowIndexKnown: [infinite, serverSide], expandAll: [clientSide, serverSide], collapseAll: [clientSide, serverSide], onRowHeightChanged: [clientSide, serverSide], setRowCount: [infinite, serverSide], getCacheBlockState: [infinite, serverSide] }; var deprecatedFunctions = { showLoadingOverlay: { version: "v32", message: '`showLoadingOverlay` is deprecated. Use the grid option "loading"=true instead or setGridOption("loading", true).' }, clearRangeSelection: { version: "v32.2", message: "Use `clearCellSelection` instead." }, getInfiniteRowCount: { version: "v32.2", old: "getInfiniteRowCount()", new: "getDisplayedRowCount()" }, selectAllFiltered: { version: "v33", old: "selectAllFiltered()", new: 'selectAll("filtered")' }, deselectAllFiltered: { version: "v33", old: "deselectAllFiltered()", new: 'deselectAll("filtered")' }, selectAllOnCurrentPage: { version: "v33", old: "selectAllOnCurrentPage()", new: 'selectAll("currentPage")' }, deselectAllOnCurrentPage: { version: "v33", old: "deselectAllOnCurrentPage()", new: 'deselectAll("currentPage")' } }; function validateApiFunction(functionName, apiFunction, beans) { const deprecation = deprecatedFunctions[functionName]; if (deprecation) { const { version, new: replacement, old, message } = deprecation; const apiMethod = old ?? functionName; return (...args) => { const replacementMessage = replacement ? `Please use ${replacement} instead. ` : ""; _warnOnce(`Since ${version} api.${apiMethod} is deprecated. ${replacementMessage}${message ?? ""}`); return apiFunction.apply(apiFunction, args); }; } const rowModels = functionRowModels[functionName]; if (rowModels) { return (...args) => { const rowModel = beans.rowModel.getType(); if (!rowModels.includes(rowModel)) { _errorOnce(`api.${functionName} can only be called when gridOptions.rowModelType is ${rowModels.join(" or ")}`); return; } return apiFunction.apply(apiFunction, args); }; } return apiFunction; } var DYNAMIC_BEAN_MODULES = { detailCellRendererCtrl: "SharedMasterDetail", dndSourceComp: "DragAndDrop", fillHandle: "CellSelection", groupCellRendererCtrl: "GroupCellRenderer", headerFilterCellCtrl: "ColumnFilter", headerGroupCellCtrl: "ColumnGroup", rangeHandle: "CellSelection", tooltipFeature: "Tooltip", highlightTooltipFeature: "Tooltip", tooltipStateManager: "Tooltip", groupStrategy: "RowGrouping", treeGroupStrategy: "TreeData", rowNumberRowResizer: "RowNumbers", singleCell: "EditCore", fullRow: "EditCore", agSetColumnFilterHandler: "SetFilter", agMultiColumnFilterHandler: "MultiFilter", agGroupColumnFilterHandler: "GroupFilter", agNumberColumnFilterHandler: "NumberFilter", agBigIntColumnFilterHandler: "BigIntFilter", agDateColumnFilterHandler: "DateFilter", agTextColumnFilterHandler: "TextFilter" }; var ICON_VALUES = { expanded: 1, contracted: 1, "tree-closed": 1, "tree-open": 1, "tree-indeterminate": 1, pin: 1, "eye-slash": 1, arrows: 1, left: 1, right: 1, group: 1, aggregation: 1, pivot: 1, "not-allowed": 1, chart: 1, cross: 1, cancel: 1, tick: 1, first: 1, previous: 1, next: 1, last: 1, linked: 1, unlinked: 1, "color-picker": 1, loading: 1, menu: 1, "menu-alt": 1, filter: 1, "filter-add": 1, columns: 1, maximize: 1, minimize: 1, copy: 1, cut: 1, paste: 1, grip: 1, save: 1, csv: 1, excel: 1, "small-down": 1, "small-left": 1, "small-right": 1, "small-up": 1, asc: 1, desc: 1, aasc: 1, adesc: 1, none: 1, up: 1, down: 1, plus: 1, minus: 1, settings: 1, "checkbox-checked": 1, "checkbox-indeterminate": 1, "checkbox-unchecked": 1, "radio-button-on": 1, "radio-button-off": 1, eye: 1, "column-arrow": 1, "un-pin": 1, "pinned-top": 1, "pinned-bottom": 1, "chevron-up": 1, "chevron-down": 1, "chevron-left": 1, "chevron-right": 1, edit: 1 }; var ICON_MODULES = { chart: "MenuCore", cancel: "EnterpriseCore", first: "Pagination", previous: "Pagination", next: "Pagination", last: "Pagination", linked: "IntegratedCharts", loadingMenuItems: "MenuCore", unlinked: "IntegratedCharts", menu: "ColumnHeaderComp", legacyMenu: "ColumnMenu", filter: "ColumnFilter", filterActive: "ColumnFilter", filterAdd: "NewFiltersToolPanel", filterCardCollapse: "NewFiltersToolPanel", filterCardExpand: "NewFiltersToolPanel", filterCardEditing: "NewFiltersToolPanel", filterTab: "ColumnMenu", filtersToolPanel: "FiltersToolPanel", columns: ["MenuCore"], columnsToolPanel: ["ColumnsToolPanel"], maximize: "EnterpriseCore", minimize: "EnterpriseCore", save: "MenuCore", columnGroupOpened: "ColumnGroupHeaderComp", columnGroupClosed: "ColumnGroupHeaderComp", accordionOpen: "EnterpriseCore", accordionClosed: "EnterpriseCore", accordionIndeterminate: "EnterpriseCore", columnSelectClosed: ["ColumnsToolPanel", "ColumnMenu"], columnSelectOpen: ["ColumnsToolPanel", "ColumnMenu"], columnSelectIndeterminate: ["ColumnsToolPanel", "ColumnMenu"], columnMovePin: "SharedDragAndDrop", columnMoveHide: "SharedDragAndDrop", columnMoveMove: "SharedDragAndDrop", columnMoveLeft: "SharedDragAndDrop", columnMoveRight: "SharedDragAndDrop", columnMoveGroup: "SharedDragAndDrop", columnMoveValue: "SharedDragAndDrop", columnMovePivot: "SharedDragAndDrop", dropNotAllowed: "SharedDragAndDrop", ensureColumnVisible: ["ColumnsToolPanel", "ColumnMenu"], groupContracted: "GroupCellRenderer", groupExpanded: "GroupCellRenderer", setFilterGroupClosed: "SetFilter", setFilterGroupOpen: "SetFilter", setFilterGroupIndeterminate: "SetFilter", setFilterLoading: "SetFilter", close: "EnterpriseCore", check: "MenuItem", colorPicker: "CommunityCore", groupLoading: "LoadingCellRenderer", overlayLoading: "Overlay", overlayExporting: "Overlay", menuAlt: "ColumnHeaderComp", menuPin: "MenuCore", menuValue: "MenuCore", menuAddRowGroup: ["MenuCore", "ColumnsToolPanel"], menuRemoveRowGroup: ["MenuCore", "ColumnsToolPanel"], clipboardCopy: "MenuCore", clipboardCut: "MenuCore", clipboardPaste: "MenuCore", pivotPanel: ["ColumnsToolPanel", "RowGroupingPanel"], rowGroupPanel: ["ColumnsToolPanel", "RowGroupingPanel"], valuePanel: "ColumnsToolPanel", columnDrag: "EnterpriseCore", rowDrag: ["RowDrag", "DragAndDrop"], csvExport: "MenuCore", excelExport: "MenuCore", smallDown: "CommunityCore", selectOpen: "CommunityCore", richSelectOpen: "RichSelect", richSelectRemove: "RichSelect", richSelectLoading: "RichSelect", smallLeft: "CommunityCore", smallRight: "CommunityCore", subMenuOpen: "MenuItem", subMenuOpenRtl: "MenuItem", panelDelimiter: "RowGroupingPanel", panelDelimiterRtl: "RowGroupingPanel", smallUp: "CommunityCore", sortAscending: ["MenuCore", "Sort"], sortDescending: ["MenuCore", "Sort"], sortAbsoluteAscending: ["MenuCore", "Sort"], sortAbsoluteDescending: ["MenuCore", "Sort"], sortUnSort: ["MenuCore", "Sort"], advancedFilterBuilder: "AdvancedFilter", advancedFilterBuilderDrag: "AdvancedFilter", advancedFilterBuilderInvalid: "AdvancedFilter", advancedFilterBuilderMoveUp: "AdvancedFilter", advancedFilterBuilderMoveDown: "AdvancedFilter", advancedFilterBuilderAdd: "AdvancedFilter", advancedFilterBuilderRemove: "AdvancedFilter", advancedFilterBuilderSelectOpen: "AdvancedFilter", chartsMenu: "IntegratedCharts", chartsMenuEdit: "IntegratedCharts", chartsMenuAdvancedSettings: "IntegratedCharts", chartsMenuAdd: "IntegratedCharts", chartsColorPicker: "IntegratedCharts", chartsThemePrevious: "IntegratedCharts", chartsThemeNext: "IntegratedCharts", chartsDownload: "IntegratedCharts", checkboxChecked: "CommunityCore", checkboxIndeterminate: "CommunityCore", checkboxUnchecked: "CommunityCore", radioButtonOn: "CommunityCore", radioButtonOff: "CommunityCore", rowPin: "PinnedRow", rowUnpin: "PinnedRow", rowPinBottom: "PinnedRow", rowPinTop: "PinnedRow" }; var DEPRECATED_ICONS_V33 = /* @__PURE__ */ new Set([ "colorPicker", "smallUp", "checkboxChecked", "checkboxIndeterminate", "checkboxUnchecked", "radioButtonOn", "radioButtonOff", "smallDown", "smallLeft", "smallRight" ]); var ValidationService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "validation"; } wireBeans(beans) { this.gridOptions = beans.gridOptions; provideValidationServiceLogger(getError); } warnOnInitialPropertyUpdate(source, key) { if (source === "api" && INITIAL_GRID_OPTION_KEYS[key]) { _warn(22, { key }); } } processGridOptions(options) { this.processOptions(options, GRID_OPTIONS_VALIDATORS()); } validateApiFunction(functionName, apiFunction) { return validateApiFunction(functionName, apiFunction, this.beans); } missingUserComponent(propertyName, componentName, agGridDefaults, jsComps) { const moduleForComponent = USER_COMP_MODULES[componentName]; if (moduleForComponent) { this.gos.assertModuleRegistered(moduleForComponent, `AG Grid '${propertyName}' component: ${componentName}`); } else { _warn(101, { propertyName, componentName, agGridDefaults, jsComps }); } } missingDynamicBean(beanName) { const moduleName = DYNAMIC_BEAN_MODULES[beanName]; return moduleName ? _errMsg(200, { ...this.gos.getModuleErrorParams(), moduleName, reasonOrId: beanName }) : undefined; } checkRowEvents(eventType) { if (DEPRECATED_ROW_NODE_EVENTS.has(eventType)) { _warn(10, { eventType }); } } validateIcon(iconName) { if (DEPRECATED_ICONS_V33.has(iconName)) { _warn(43, { iconName }); } if (ICON_VALUES[iconName]) { return; } const moduleName = ICON_MODULES[iconName]; if (moduleName) { _error(200, { reasonOrId: `icon '${iconName}'`, moduleName, gridScoped: _areModulesGridScoped(), gridId: this.beans.context.getId(), rowModelType: this.gos.get("rowModelType"), additionalText: "Alternatively, use the CSS icon name directly." }); return; } _warn(134, { iconName }); } isProvidedUserComp(compName) { return !!USER_COMP_MODULES[compName]; } validateColDef(colDef) { this.processOptions(colDef, COL_DEF_VALIDATORS()); } processOptions(options, validator) { const { validations, deprecations, allProperties, propertyExceptions, objectName, docsUrl } = validator; if (allProperties && this.gridOptions.suppressPropertyNamesCheck !== true) { this.checkProperties(options, [...propertyExceptions ?? [], ...Object.keys(deprecations)], allProperties, objectName, docsUrl); } const warnings = /* @__PURE__ */ new Set; const optionKeys = Object.keys(options); optionKeys.forEach((key) => { const deprecation = deprecations[key]; if (deprecation) { const { message, version } = deprecation; warnings.add(`As of v${version}, ${String(key)} is deprecated. ${message ?? ""}`); } const value = options[key]; if (value == null || value === false) { return; } const rules = validations[key]; if (!rules) { return; } const { dependencies, validate, supportedRowModels, expectedType } = rules; if (expectedType) { const actualType = typeof value; if (actualType !== expectedType) { warnings.add(`${String(key)} should be of type '${expectedType}' but received '${actualType}' (${value}).`); return; } } if (supportedRowModels) { const rowModel = this.gridOptions.rowModelType ?? "clientSide"; if (!supportedRowModels.includes(rowModel)) { warnings.add(`${String(key)} is not supported with the '${rowModel}' row model. It is only valid with: ${supportedRowModels.join(", ")}.`); return; } } if (dependencies) { const warning = this.checkForRequiredDependencies(key, dependencies, options); if (warning) { warnings.add(warning); return; } } if (validate) { const warning = validate(options, this.gridOptions, this.beans); if (warning) { warnings.add(warning); return; } } }); if (warnings.size > 0) { for (const warning of warnings) { _warnOnce(warning); } } } checkForRequiredDependencies(key, validator, options) { const optionEntries = Object.entries(validator); const failedOptions = optionEntries.filter(([key2, value]) => { const gridOptionValue = options[key2]; return !value.required.includes(gridOptionValue); }); if (failedOptions.length === 0) { return null; } return failedOptions.map(([failedKey, possibleOptions]) => `'${String(key)}' requires '${failedKey}' to be one of [${possibleOptions.required.map((o) => { if (o === null) { return "null"; } else if (o === undefined) { return "undefined"; } return o; }).join(", ")}]. ${possibleOptions.reason ?? ""}`).join(` `); } checkProperties(object, exceptions, validProperties, containerName, docsUrl) { const VUE_FRAMEWORK_PROPS = ["__ob__", "__v_skip", "__metadata__"]; const invalidProperties = _fuzzyCheckStrings(Object.getOwnPropertyNames(object), [...VUE_FRAMEWORK_PROPS, ...exceptions, ...validProperties], validProperties); const invalidPropertiesKeys = Object.keys(invalidProperties); for (const key of invalidPropertiesKeys) { const value = invalidProperties[key]; let message = `invalid ${containerName} property '${key}' did you mean any of these: ${value.slice(0, 8).join(", ")}.`; if (validProperties.includes("context")) { message += ` If you are trying to annotate ${containerName} with application data, use the '${containerName}.context' property instead.`; } _warnOnce(message); } if (invalidPropertiesKeys.length > 0 && docsUrl) { const url = this.beans.frameworkOverrides.getDocLink(docsUrl); _warnOnce(`to see all the valid ${containerName} properties please check: ${url}`); } } }; function _fuzzyCheckStrings(inputValues, validValues, allSuggestions) { const fuzzyMatches = {}; const invalidInputs = inputValues.filter((inputValue) => !validValues.some((validValue) => validValue === inputValue)); if (invalidInputs.length > 0) { for (const invalidInput of invalidInputs) { fuzzyMatches[invalidInput] = _fuzzySuggestions({ inputValue: invalidInput, allSuggestions }).values; } } return fuzzyMatches; } var DEPRECATED_ROW_NODE_EVENTS = /* @__PURE__ */ new Set([ "firstChildChanged", "lastChildChanged", "childIndexChanged" ]); var ValidationModule = { moduleName: "Validation", version: VERSION, beans: [ValidationService] }; var BaseColsService = class extends BeanStub { constructor() { super(...arguments); this.dispatchColumnChangedEvent = dispatchColumnChangedEvent; this.columns = []; this.columnIndexMap = {}; this.updateIndexMap = () => { this.columnIndexMap = {}; this.columns.forEach((col, index) => this.columnIndexMap[col.getId()] = index); }; } wireBeans(beans) { this.colModel = beans.colModel; this.aggFuncSvc = beans.aggFuncSvc; this.visibleCols = beans.visibleCols; this.groupHierarchCols = beans.groupHierarchyColSvc; } sortColumns(compareFn) { const { groupHierarchCols } = this; this.columns.sort((a, b) => groupHierarchCols?.compareVirtualColumns(a, b) ?? compareFn(a, b)); this.updateIndexMap(); } setColumns(colKeys, source) { this.setColList(colKeys, this.columns, this.eventName, true, true, this.columnProcessors.set, source); } addColumns(colKeys, source) { this.updateColList(colKeys, this.columns, true, true, this.columnProcessors.add, this.eventName, source); } removeColumns(colKeys, source) { this.updateColList(colKeys, this.columns, false, true, this.columnProcessors.remove, this.eventName, source); } getColumnIndex(colId) { return this.columnIndexMap[colId]; } setColList(colKeys = [], masterList, eventName, detectOrderChange, autoGroupsNeedBuilding, columnCallback, source) { const gridColumns = this.colModel.getCols(); if (!gridColumns || gridColumns.length === 0) { return; } const changes = /* @__PURE__ */ new Map; masterList.forEach((col, idx) => changes.set(col, idx)); masterList.length = 0; for (const key of colKeys) { const column = this.colModel.getColDefCol(key); if (column) { masterList.push(column); } } masterList.forEach((col, idx) => { const oldIndex = changes.get(col); if (oldIndex === undefined) { changes.set(col, 0); return; } if (detectOrderChange && oldIndex !== idx) { return; } changes.delete(col); }); this.updateIndexMap(); const primaryCols = this.colModel.getColDefCols(); for (const column of primaryCols ?? []) { const added = masterList.indexOf(column) >= 0; columnCallback(column, added, source); } if (autoGroupsNeedBuilding) { this.colModel.refreshCols(false, source); } this.visibleCols.refresh(source); this.dispatchColumnChangedEvent(this.eventSvc, eventName, [...changes.keys()], source); } updateColList(keys = [], masterList, actionIsAdd, autoGroupsNeedBuilding, columnCallback, eventType, source) { if (!keys || keys.length === 0) { return; } let atLeastOne = false; const updatedCols = /* @__PURE__ */ new Set; for (const key of keys) { if (!key) { continue; } const columnToAdd = this.colModel.getColDefCol(key); if (!columnToAdd) { continue; } updatedCols.add(columnToAdd); if (actionIsAdd) { if (masterList.indexOf(columnToAdd) >= 0) { continue; } masterList.push(columnToAdd); } else { const currentIndex = masterList.indexOf(columnToAdd); if (currentIndex < 0) { continue; } for (let i = currentIndex + 1;i < masterList.length; i++) { updatedCols.add(masterList[i]); } _removeFromArray(masterList, columnToAdd); } columnCallback(columnToAdd, actionIsAdd, source); atLeastOne = true; } if (!atLeastOne) { return; } this.updateIndexMap(); if (autoGroupsNeedBuilding) { this.colModel.refreshCols(false, source); } this.visibleCols.refresh(source); const eventColumns = Array.from(updatedCols); this.eventSvc.dispatchEvent({ type: eventType, columns: eventColumns, column: eventColumns.length === 1 ? eventColumns[0] : null, source }); } extractCols(source, oldProvidedCols = []) { const previousCols = this.columns; const colsWithIndex = []; const colsWithValue = []; const { setFlagFunc, getIndexFunc, getInitialIndexFunc, getValueFunc, getInitialValueFunc } = this.columnExtractors; const primaryCols = this.colModel.getColDefCols(); for (const col of primaryCols ?? []) { const colIsNew = !oldProvidedCols.includes(col); const colDef = col.getColDef(); const value = getValueFunc(colDef); const initialValue = getInitialValueFunc(colDef); const index = getIndexFunc(colDef); const initialIndex = getInitialIndexFunc(colDef); let include; const valuePresent = value !== undefined; const indexPresent = index !== undefined; const initialValuePresent = initialValue !== undefined; const initialIndexPresent = initialIndex !== undefined; if (valuePresent) { include = value; } else if (indexPresent) { if (index === null) { include = false; } else { include = index >= 0; } } else if (colIsNew) { if (initialValuePresent) { include = initialValue; } else if (initialIndexPresent) { include = initialIndex != null && initialIndex >= 0; } else { include = false; } } else { include = previousCols.indexOf(col) >= 0; } if (include) { const useIndex = colIsNew ? index != null || initialIndex != null : index != null; if (useIndex) { colsWithIndex.push(col); } else { colsWithValue.push(col); } } } const getIndexForCol = (col) => { const colDef = col.getColDef(); return getIndexFunc(colDef) ?? getInitialIndexFunc(colDef); }; colsWithIndex.sort((colA, colB) => getIndexForCol(colA) - getIndexForCol(colB)); const res = []; const groupHierarchCols = this.groupHierarchCols; const addCol = (col) => { if (groupHierarchCols) { groupHierarchCols.expandColumnInto(res, col); } else { res.push(col); } }; colsWithIndex.forEach(addCol); for (const col of previousCols) { if (colsWithValue.indexOf(col) >= 0) { addCol(col); } } for (const col of colsWithValue) { if (res.indexOf(col) < 0) { addCol(col); } } for (const col of previousCols) { if (res.indexOf(col) < 0) { setFlagFunc(col, false, source); } } for (const col of res) { if (previousCols.indexOf(col) < 0) { setFlagFunc(col, true, source); } } this.columns = res; this.updateIndexMap(); return this.columns; } restoreColumnOrder(columnStateAccumulator, incomingColumnState) { const colList = this.columns; const primaryCols = this.colModel.getColDefCols(); if (!colList.length || !primaryCols) { return columnStateAccumulator; } const updatedColIdArray = Object.keys(incomingColumnState); const updatedColIds = new Set(updatedColIdArray); const newColIds = new Set(updatedColIdArray); const allColIds = new Set(colList.map((column) => { const colId = column.getColId(); newColIds.delete(colId); return colId; }).concat(updatedColIdArray)); const colIdsInOriginalOrder = []; const originalOrderMap = {}; let orderIndex = 0; for (let i = 0;i < primaryCols.length; i++) { const colId = primaryCols[i].getColId(); if (allColIds.has(colId)) { colIdsInOriginalOrder.push(colId); originalOrderMap[colId] = orderIndex++; } } let index = 1000; let hasAddedNewCols = false; let lastIndex = 0; const enableProp = this.columnOrdering.enableProp; const initialEnableProp = this.columnOrdering.initialEnableProp; const indexProp = this.columnOrdering.indexProp; const initialIndexProp = this.columnOrdering.initialIndexProp; const processPrecedingNewCols = (colId) => { const originalOrderIndex = originalOrderMap[colId]; for (let i = lastIndex;i < originalOrderIndex; i++) { const newColId = colIdsInOriginalOrder[i]; if (newColIds.has(newColId)) { incomingColumnState[newColId][indexProp] = index++; newColIds.delete(newColId); } } lastIndex = originalOrderIndex; }; for (const column of colList) { const colId = column.getColId(); if (updatedColIds.has(colId)) { processPrecedingNewCols(colId); incomingColumnState[colId][indexProp] = index++; } else { const colDef = column.getColDef(); const missingIndex = colDef[indexProp] === null || colDef[indexProp] === undefined && colDef[initialIndexProp] == null; if (missingIndex) { if (!hasAddedNewCols) { const propEnabled = colDef[enableProp] || colDef[enableProp] === undefined && colDef[initialEnableProp]; if (propEnabled) { processPrecedingNewCols(colId); } else { for (const newColId of newColIds) { incomingColumnState[newColId][indexProp] = index + originalOrderMap[newColId]; } index += colIdsInOriginalOrder.length; hasAddedNewCols = true; } } if (!columnStateAccumulator[colId]) { columnStateAccumulator[colId] = { colId }; } columnStateAccumulator[colId][indexProp] = index++; } } } return columnStateAccumulator; } }; var agToggleButton_default = '.ag-toggle-button{flex:none;min-width:unset;width:unset}.ag-toggle-button-input-wrapper{background-color:var(--ag-toggle-button-off-background-color);border-radius:calc(var(--ag-toggle-button-height)*.5);flex:none;height:var(--ag-toggle-button-height);max-width:var(--ag-toggle-button-width);min-width:var(--ag-toggle-button-width);position:relative;transition:background-color .1s;:where(.ag-toggle-button-input){-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;display:block;height:var(--ag-toggle-button-height);margin:0;max-width:var(--ag-toggle-button-width);min-width:var(--ag-toggle-button-width);opacity:0}&.ag-checked{background-color:var(--ag-toggle-button-on-background-color)}&.ag-disabled{opacity:.5}}.ag-toggle-button-input-wrapper:before{background-color:var(--ag-toggle-button-switch-background-color);border-radius:100%;content:"";display:block;height:calc(var(--ag-toggle-button-height) - var(--ag-toggle-button-switch-inset)*2);left:var(--ag-toggle-button-switch-inset);pointer-events:none;position:absolute;top:var(--ag-toggle-button-switch-inset);transition:left .1s;width:calc(var(--ag-toggle-button-height) - var(--ag-toggle-button-switch-inset)*2)}.ag-toggle-button-input-wrapper.ag-checked:before{left:calc(100% - var(--ag-toggle-button-height) + var(--ag-toggle-button-switch-inset))}.ag-toggle-button-input-wrapper:focus-within{box-shadow:var(--ag-focus-shadow)}'; var AgToggleButton = class extends AgCheckbox { constructor(config) { super(config, "ag-toggle-button"); this.registerCSS(agToggleButton_default); } setValue(value, silent) { super.setValue(value, silent); this.toggleCss("ag-selected", this.getValue()); return this; } }; var AgToggleButtonSelector = { selector: "AG-TOGGLE-BUTTON", component: AgToggleButton }; // ag-grid/dist/package/main.esm.mjs var MD5 = class { constructor() { this.ieCompatibility = false; } init() { this.ieCompatibility = this.md5("hello") != "5d41402abc4b2a76b9719d911017c592"; } md5cycle(x, k) { let a = x[0], b = x[1], c = x[2], d = x[3]; a = this.ff(a, b, c, d, k[0], 7, -680876936); d = this.ff(d, a, b, c, k[1], 12, -389564586); c = this.ff(c, d, a, b, k[2], 17, 606105819); b = this.ff(b, c, d, a, k[3], 22, -1044525330); a = this.ff(a, b, c, d, k[4], 7, -176418897); d = this.ff(d, a, b, c, k[5], 12, 1200080426); c = this.ff(c, d, a, b, k[6], 17, -1473231341); b = this.ff(b, c, d, a, k[7], 22, -45705983); a = this.ff(a, b, c, d, k[8], 7, 1770035416); d = this.ff(d, a, b, c, k[9], 12, -1958414417); c = this.ff(c, d, a, b, k[10], 17, -42063); b = this.ff(b, c, d, a, k[11], 22, -1990404162); a = this.ff(a, b, c, d, k[12], 7, 1804603682); d = this.ff(d, a, b, c, k[13], 12, -40341101); c = this.ff(c, d, a, b, k[14], 17, -1502002290); b = this.ff(b, c, d, a, k[15], 22, 1236535329); a = this.gg(a, b, c, d, k[1], 5, -165796510); d = this.gg(d, a, b, c, k[6], 9, -1069501632); c = this.gg(c, d, a, b, k[11], 14, 643717713); b = this.gg(b, c, d, a, k[0], 20, -373897302); a = this.gg(a, b, c, d, k[5], 5, -701558691); d = this.gg(d, a, b, c, k[10], 9, 38016083); c = this.gg(c, d, a, b, k[15], 14, -660478335); b = this.gg(b, c, d, a, k[4], 20, -405537848); a = this.gg(a, b, c, d, k[9], 5, 568446438); d = this.gg(d, a, b, c, k[14], 9, -1019803690); c = this.gg(c, d, a, b, k[3], 14, -187363961); b = this.gg(b, c, d, a, k[8], 20, 1163531501); a = this.gg(a, b, c, d, k[13], 5, -1444681467); d = this.gg(d, a, b, c, k[2], 9, -51403784); c = this.gg(c, d, a, b, k[7], 14, 1735328473); b = this.gg(b, c, d, a, k[12], 20, -1926607734); a = this.hh(a, b, c, d, k[5], 4, -378558); d = this.hh(d, a, b, c, k[8], 11, -2022574463); c = this.hh(c, d, a, b, k[11], 16, 1839030562); b = this.hh(b, c, d, a, k[14], 23, -35309556); a = this.hh(a, b, c, d, k[1], 4, -1530992060); d = this.hh(d, a, b, c, k[4], 11, 1272893353); c = this.hh(c, d, a, b, k[7], 16, -155497632); b = this.hh(b, c, d, a, k[10], 23, -1094730640); a = this.hh(a, b, c, d, k[13], 4, 681279174); d = this.hh(d, a, b, c, k[0], 11, -358537222); c = this.hh(c, d, a, b, k[3], 16, -722521979); b = this.hh(b, c, d, a, k[6], 23, 76029189); a = this.hh(a, b, c, d, k[9], 4, -640364487); d = this.hh(d, a, b, c, k[12], 11, -421815835); c = this.hh(c, d, a, b, k[15], 16, 530742520); b = this.hh(b, c, d, a, k[2], 23, -995338651); a = this.ii(a, b, c, d, k[0], 6, -198630844); d = this.ii(d, a, b, c, k[7], 10, 1126891415); c = this.ii(c, d, a, b, k[14], 15, -1416354905); b = this.ii(b, c, d, a, k[5], 21, -57434055); a = this.ii(a, b, c, d, k[12], 6, 1700485571); d = this.ii(d, a, b, c, k[3], 10, -1894986606); c = this.ii(c, d, a, b, k[10], 15, -1051523); b = this.ii(b, c, d, a, k[1], 21, -2054922799); a = this.ii(a, b, c, d, k[8], 6, 1873313359); d = this.ii(d, a, b, c, k[15], 10, -30611744); c = this.ii(c, d, a, b, k[6], 15, -1560198380); b = this.ii(b, c, d, a, k[13], 21, 1309151649); a = this.ii(a, b, c, d, k[4], 6, -145523070); d = this.ii(d, a, b, c, k[11], 10, -1120210379); c = this.ii(c, d, a, b, k[2], 15, 718787259); b = this.ii(b, c, d, a, k[9], 21, -343485551); x[0] = this.add32(a, x[0]); x[1] = this.add32(b, x[1]); x[2] = this.add32(c, x[2]); x[3] = this.add32(d, x[3]); } cmn(q, a, b, x, s2, t) { a = this.add32(this.add32(a, q), this.add32(x, t)); return this.add32(a << s2 | a >>> 32 - s2, b); } ff(a, b, c, d, x, s2, t) { return this.cmn(b & c | ~b & d, a, b, x, s2, t); } gg(a, b, c, d, x, s2, t) { return this.cmn(b & d | c & ~d, a, b, x, s2, t); } hh(a, b, c, d, x, s2, t) { return this.cmn(b ^ c ^ d, a, b, x, s2, t); } ii(a, b, c, d, x, s2, t) { return this.cmn(c ^ (b | ~d), a, b, x, s2, t); } md51(s2) { const n = s2.length; const state = [1732584193, -271733879, -1732584194, 271733878]; let i; for (i = 64;i <= s2.length; i += 64) { this.md5cycle(state, this.md5blk(s2.substring(i - 64, i))); } s2 = s2.substring(i - 64); const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; for (i = 0;i < s2.length; i++) { tail[i >> 2] |= s2.charCodeAt(i) << (i % 4 << 3); } tail[i >> 2] |= 128 << (i % 4 << 3); if (i > 55) { this.md5cycle(state, tail); for (i = 0;i < 16; i++) { tail[i] = 0; } } tail[14] = n * 8; this.md5cycle(state, tail); return state; } md5blk(s2) { const md5blks = []; for (let i = 0;i < 64; i += 4) { md5blks[i >> 2] = s2.charCodeAt(i) + (s2.charCodeAt(i + 1) << 8) + (s2.charCodeAt(i + 2) << 16) + (s2.charCodeAt(i + 3) << 24); } return md5blks; } rhex(n) { const hex_chr = "0123456789abcdef".split(""); let s2 = "", j = 0; for (;j < 4; j++) { s2 += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15]; } return s2; } hex(x) { for (let i = 0;i < x.length; i++) { x[i] = this.rhex(x[i]); } return x.join(""); } md5(s2) { return this.hex(this.md51(s2)); } add32(a, b) { return this.ieCompatibility ? this.add32Compat(a, b) : this.add32Std(a, b); } add32Std(a, b) { return a + b & 4294967295; } add32Compat(x, y) { const lsw = (x & 65535) + (y & 65535), msw = (x >> 16) + (y >> 16) + (lsw >> 16); return msw << 16 | lsw & 65535; } }; var LICENSE_TYPES = { "01": "GRID", "02": "CHARTS", "0102": "BOTH" }; var _LicenseManager = class _LicenseManager2 { constructor(document2) { this.watermarkMessage = undefined; this.totalMessageLength = 124; this.document = document2; this.md5 = new MD5; this.md5.init(); } validateLicense() { const licenseDetails = this.getLicenseDetails(_LicenseManager2.licenseKey); const currentLicenseName = `AG Grid ${licenseDetails.currentLicenseType === "BOTH" ? "and AG Charts " : ""}Enterprise`; const suppliedLicenseName = licenseDetails.suppliedLicenseType === undefined ? "" : `AG ${licenseDetails.suppliedLicenseType === "BOTH" ? "Grid and AG Charts" : licenseDetails.suppliedLicenseType === "GRID" ? "Grid" : "Charts"} Enterprise`; if (licenseDetails.missing) { if (!this.isWebsiteUrl() || this.isForceWatermark()) { this.outputMissingLicenseKey(currentLicenseName); } } else if (licenseDetails.expired) { const gridReleaseDate = _LicenseManager2.getGridReleaseDate(); const formattedReleaseDate = _LicenseManager2.formatDate(gridReleaseDate); this.outputExpiredKey(licenseDetails.expiry, formattedReleaseDate, currentLicenseName, suppliedLicenseName); } else if (!licenseDetails.valid) { this.outputInvalidLicenseKey(!!licenseDetails.incorrectLicenseType, currentLicenseName, suppliedLicenseName); } else if (licenseDetails.isTrial && licenseDetails.trialExpired) { this.outputExpiredTrialKey(licenseDetails.expiry, currentLicenseName, suppliedLicenseName); } } static extractExpiry(license) { const restrictionHashed = license.substring(license.lastIndexOf("_") + 1, license.length); return new Date(parseInt(_LicenseManager2.decode(restrictionHashed), 10)); } static extractLicenseComponents(licenseKey) { let cleanedLicenseKey = licenseKey.replace(/[\u200B-\u200D\uFEFF]/g, ""); cleanedLicenseKey = cleanedLicenseKey.replace(/\r?\n|\r/g, ""); if (licenseKey.length <= 32) { return { md5: null, license: licenseKey, version: null, isTrial: null }; } const hashStart = cleanedLicenseKey.length - 32; const md5 = cleanedLicenseKey.substring(hashStart); const license = cleanedLicenseKey.substring(0, hashStart); const [version, isTrial, type] = _LicenseManager2.extractBracketedInformation(cleanedLicenseKey); return { md5, license, version, isTrial, type }; } getLicenseDetails(licenseKey) { const currentLicenseType = _LicenseManager2.chartsLicenseManager ? "BOTH" : "GRID"; if (!licenseKey?.length) { return { licenseKey, valid: false, missing: true, currentLicenseType }; } const gridReleaseDate = _LicenseManager2.getGridReleaseDate(); const { md5, license, version, isTrial, type } = _LicenseManager2.extractLicenseComponents(licenseKey); let valid = md5 === this.md5.md5(license) && !licenseKey.includes("For_Trialing_ag-Grid_Only"); let trialExpired = undefined; let expired = undefined; let expiry = null; let incorrectLicenseType = false; let suppliedLicenseType = undefined; function handleTrial() { const now = /* @__PURE__ */ new Date; trialExpired = expiry < now; expired = undefined; } if (valid) { expiry = _LicenseManager2.extractExpiry(license); valid = !isNaN(expiry.getTime()); if (valid) { expired = gridReleaseDate > expiry; switch (version) { case "legacy": case "2": { if (isTrial) { handleTrial(); } break; } case "3": { if (!type?.length) { valid = false; } else { suppliedLicenseType = type; if (type !== LICENSE_TYPES["01"] && type !== LICENSE_TYPES["0102"] || currentLicenseType === "BOTH" && suppliedLicenseType !== "BOTH") { valid = false; incorrectLicenseType = true; } else if (isTrial) { handleTrial(); } } } } } } if (!valid) { return { licenseKey, valid, incorrectLicenseType, currentLicenseType, suppliedLicenseType }; } return { licenseKey, valid, expiry: _LicenseManager2.formatDate(expiry), expired, version, isTrial, trialExpired, incorrectLicenseType, currentLicenseType, suppliedLicenseType }; } isDisplayWatermark() { return this.isForceWatermark() || !this.isLocalhost() && !this.isWebsiteUrl() && !!this.watermarkMessage?.length; } getWatermarkMessage() { return this.watermarkMessage || ""; } getHostname() { const win = this.document.defaultView || window; const loc = win.location; const { hostname = "" } = loc; return hostname; } isForceWatermark() { const win = this.document.defaultView || window; const loc = win.location; const { pathname } = loc; return pathname ? pathname.includes("forceWatermark") : false; } isWebsiteUrl() { const hostname = this.getHostname(); return hostname.match(/^(?:[\w-]+\.)?(ag-grid|bryntum)\.com$/) !== null; } isLocalhost() { const hostname = this.getHostname(); return hostname.match(/^(?:127\.0\.0\.1|localhost)$/) !== null; } static formatDate(date) { const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; const day = date.getDate(); const monthIndex = date.getMonth(); const year = date.getFullYear(); return day + " " + monthNames[monthIndex] + " " + year; } static getGridReleaseDate() { return new Date(parseInt(_LicenseManager2.decode(_LicenseManager2.RELEASE_INFORMATION), 10)); } static decode(input) { const keystr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; let t = ""; let n, r, i; let s2, o, u, a; let f = 0; const e = input.replace(/[^A-Za-z0-9+/=]/g, ""); while (f < e.length) { s2 = keystr.indexOf(e.charAt(f++)); o = keystr.indexOf(e.charAt(f++)); u = keystr.indexOf(e.charAt(f++)); a = keystr.indexOf(e.charAt(f++)); n = s2 << 2 | o >> 4; r = (o & 15) << 4 | u >> 2; i = (u & 3) << 6 | a; t = t + String.fromCharCode(n); if (u != 64) { t = t + String.fromCharCode(r); } if (a != 64) { t = t + String.fromCharCode(i); } } t = _LicenseManager2.utf8_decode(t); return t; } static utf8_decode(input) { input = input.replace(/rn/g, "n"); let t = ""; for (let n = 0;n < input.length; n++) { const r = input.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r); } else if (r > 127 && r < 2048) { t += String.fromCharCode(r >> 6 | 192); t += String.fromCharCode(r & 63 | 128); } else { t += String.fromCharCode(r >> 12 | 224); t += String.fromCharCode(r >> 6 & 63 | 128); t += String.fromCharCode(r & 63 | 128); } } return t; } static setChartsLicenseManager(dependantLicenseManager) { this.chartsLicenseManager = dependantLicenseManager; this.chartsLicenseManager?.setLicenseKey(this.licenseKey, true); } static setLicenseKey(licenseKey) { if (_exists(this.licenseKey) && this.licenseKey !== licenseKey) { _logPreInitWarn(291, undefined, "AG Grid: License Key being set multiple times with different values. This can result in an incorrect license key being used."); } this.licenseKey = licenseKey; this.chartsLicenseManager?.setLicenseKey(licenseKey, true); } static extractBracketedInformation(licenseKey) { if (!licenseKey.includes("[")) { return ["legacy", false, undefined]; } const matches = licenseKey.match(/\[(.*?)\]/g).map((match) => match.replace("[", "").replace("]", "")); if (!matches || matches.length === 0) { return ["legacy", false, undefined]; } const isTrial = matches.filter((match) => match === "TRIAL").length === 1; const rawVersion = matches.filter((match) => match.indexOf("v") === 0)[0]; const version = rawVersion ? rawVersion.replace("v", "") : "legacy"; const type = LICENSE_TYPES[matches.filter((match) => LICENSE_TYPES[match])[0]]; return [version, isTrial, type]; } centerPadAndOutput(input) { const paddingRequired = this.totalMessageLength - input.length; } padAndOutput(input, padding = "*", terminateWithPadding = "") {} outputInvalidLicenseKey(incorrectLicenseType, currentLicenseName, suppliedLicenseName) {} outputExpiredTrialKey(formattedExpiryDate, currentLicenseName, suppliedLicenseName) {} outputMissingLicenseKey(currentLicenseName) {} outputExpiredKey(formattedExpiryDate, formattedReleaseDate, currentLicenseName, suppliedLicenseName) {} }; _LicenseManager.RELEASE_INFORMATION = "MTc3NDQyNTc0Nzc3NQ=="; var LicenseManager = _LicenseManager; var watermark_default = '.ag-watermark{bottom:20px;color:#9b9b9b;opacity:.7;position:absolute;transition:opacity 1s ease-out 3s}:where(.ag-ltr) .ag-watermark{right:25px}:where(.ag-rtl) .ag-watermark{left:25px}.ag-watermark:before{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDkiIGhlaWdodD0iMzYiIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyMDkgMzYiPjxwYXRoIGZpbGw9IiM5YjliOWIiIGQ9Ik0xOTIuOTkzIDIzLjY1OHYtNy45NDZoLTEzLjU0MWwtNy45NDcgNy45NDZ6TTIwOC4yNSAzLjk1aC0xNi45NzRsLTguMDEgNy45NDdoMjQuOTg0ek0xNjMuNjIyIDMxLjYwNWw0LjA2OS00LjA2OWgxMy43MzJ2Ny45NDdoLTE3LjgwMXoiLz48cGF0aCBmaWxsPSIjOWI5YjliIiBkPSJNMTY2LjYxIDE5Ljc4aDguNzczbDguMDEtNy45NDZIMTY2LjYxek0xNTcuMDExIDMxLjYwNWg2LjYxMWw3Ljg4My03Ljk0N2gtMTQuNDk0ek0xOTEuMjc2IDMuOTVsLTQuMDY4IDQuMDdIMTYxLjI3Vi4wNzJoMzAuMDA2ek0yMC44NCAzMC4yMDZIOC4zNzhsLTIuMTYyIDUuMzRILjc1TDEyLjI1NyA4LjU5Mmg0Ljc2OEwyOC41MyAzNS41NDZoLTUuNTN6bS0xLjcxNy00LjI2TDE0LjYwOSAxNC45NWwtNC41MTQgMTAuOTk4ek0xMDQuNDM3IDE4LjUwOWMxLjU4OS0yLjM1MiA1LjU5NC0yLjYwNyA3LjI0Ny0yLjYwN3Y0LjU3OGMtMi4wMzQgMC00LjA2OS4wNjMtNS4yNzcuOTUzLTEuMjA3Ljg5LTEuODQzIDIuMDk4LTEuODQzIDMuNTZ2MTAuNTUzaC00Ljk1OVYxNS45MDJoNC43Njh6TTExOS4zNzYgMTUuOTAyaC00Ljk1OHYxOS42NDRoNC45NTh6TTExOS4zNzYgNy4xM2gtNC45NTh2NS44NDhoNC45NTh6TTE0My45NzkgNy4xM3YyOC40MTZoLTQuNzY4bC0uMTI3LTIuOTg4YTguMyA4LjMgMCAwIDEtMi42NyAyLjQ4Yy0xLjA4MS41NzItMi40MTYuODktMy45NDIuODktMS4zMzUgMC0yLjYwNi0uMjU1LTMuNjg3LS43LTEuMTQ0LS41MDgtMi4xNjItMS4xNDQtMi45ODgtMi4wMzRhOS42IDkuNiAwIDAgMS0xLjk3MS0zLjE3OWMtLjUwOC0xLjIwNy0uNjk5LTIuNjA2LS42OTktNC4xMzJzLjI1NC0yLjkyNC42OTktNC4xOTZjLjUwOS0xLjI3MSAxLjE0NS0yLjM1MiAxLjk3MS0zLjI0MnMxLjg0NC0xLjU4OSAyLjk4OC0yLjA5OCAyLjM1Mi0uNzYzIDMuNjg3LS43NjNjMS41MjYgMCAyLjc5Ny4yNTUgMy44NzguODI3czEuOTcxIDEuMzM1IDIuNjcgMi40MTZWNy4xOTNoNC45NTl6bS0xMC40MjYgMjQuNTM4YzEuNjUzIDAgMi45MjQtLjU3MiAzLjk0MS0xLjY1M3MxLjUyNi0yLjU0MyAxLjUyNi00LjMyMy0uNTA5LTMuMTc4LTEuNTI2LTQuMzIyYy0xLjAxNy0xLjA4MS0yLjI4OC0xLjY1My0zLjk0MS0xLjY1My0xLjU5IDAtMi45MjUuNTcyLTMuODc4IDEuNjUzLTEuMDE3IDEuMDgtMS41MjYgMi41NDMtMS41MjYgNC4zMjIgMCAxLjc4LjUwOSAzLjE4IDEuNTI2IDQuMjYgMS4wMTcgMS4xNDQgMi4yODggMS43MTYgMy44NzggMS43MTZNNTcuMjAyIDIwLjM1M0g0NC45MzN2NC4yNTloNi45OTNjLS4xOSAyLjE2MS0xLjAxNyAzLjgxNC0yLjQxNiA1LjE1LTEuMzk4IDEuMjctMy4xNzggMS45MDYtNS40NjcgMS45MDYtMS4yNzEgMC0yLjQ4LS4yNTQtMy40OTYtLjY5OWE3IDcgMCAwIDEtMi43MzQtMS45N2MtLjc2My0uODI3LTEuMzM1LTEuODQ0LTEuNzgtMy4wNTJzLS42MzYtMi40OC0uNjM2LTMuOTQyLjE5LTIuNzMzLjYzNi0zLjk0MWMuMzgxLTEuMjA4IDEuMDE3LTIuMTYyIDEuNzgtMy4wNTIuNzYzLS44MjYgMS42NTMtMS40NjIgMi43MzMtMS45N2E5LjEgOS4xIDAgMCAxIDMuNTYtLjdxNC4wMDUgMCA2LjEwMyAxLjkwN2wzLjMwNi0zLjMwNWMtMi40OC0xLjkwNy01LjY1OC0yLjkyNS05LjQwOS0yLjkyNS0yLjA5NyAwLTQuMDA0LjMxOC01LjcyMSAxLjAxOC0xLjcxNi42OTktMy4xNzkgMS41ODktNC4zODYgMi43OTdBMTIuMSAxMi4xIDAgMCAwIDMxLjIgMTYuMjJjLS42MzUgMS43MTctLjk1MyAzLjYyNC0uOTUzIDUuNjU4cy4zMTggMy45NDIgMS4wMTcgNS42NThjLjcgMS43MTcgMS41OSAzLjE3OSAyLjc5NyA0LjM4N2ExMi4xIDEyLjEgMCAwIDAgNC4zODcgMi43OTdjMS43MTYuNyAzLjYyMyAxLjAxNyA1LjY1NyAxLjAxNyAyLjAzNSAwIDMuODc4LS4zMTggNS41MzEtMS4wMTcgMS42NTMtLjcgMy4wNTItMS41OSA0LjE5Ni0yLjc5N3ExLjcxNi0xLjgxMiAyLjY3LTQuMzg3Yy42MzYtMS43MTYuOTU0LTMuNjIzLjk1NC01LjY1OHYtLjgyNmMtLjE5MS0uMTI3LS4yNTUtLjQ0NS0uMjU1LS43TTk1Ljk4MiAyMC4zNTNoLTEyLjI3djQuMjU5aDYuOTkzYy0uMTkgMi4xNjEtMS4wMTcgMy44MTQtMi40MTYgNS4xNS0xLjM5OCAxLjI3LTMuMTc4IDEuOTA2LTUuNDY3IDEuOTA2LTEuMjcxIDAtMi40OC0uMjU0LTMuNDk2LS42OTlhNyA3IDAgMCAxLTIuNzM0LTEuOTdjLS43NjMtLjgyNy0xLjMzNS0xLjg0NC0xLjc4LTMuMDUycy0uNjM2LTIuNDgtLjYzNi0zLjk0Mi4xOS0yLjczMy42MzYtMy45NDFjLjM4MS0xLjIwOCAxLjAxNy0yLjE2MiAxLjc4LTMuMDUyLjc2My0uODI2IDEuNjUzLTEuNDYyIDIuNzM0LTEuOTdhOS4xIDkuMSAwIDAgMSAzLjU2LS43cTQuMDA1IDAgNi4xMDMgMS45MDdsMy4zMDUtMy4zMDVjLTIuNDc5LTEuOTA3LTUuNjU4LTIuOTI1LTkuNDA4LTIuOTI1LTIuMDk4IDAtNC4wMDUuMzE4LTUuNzIyIDEuMDE4LTEuNzE2LjY5OS0zLjE3OCAxLjU4OS00LjM4NiAyLjc5N2ExMi4xIDEyLjEgMCAwIDAtMi43OTcgNC4zODZjLS42MzYgMS43MTctLjk1NCAzLjYyNC0uOTU0IDUuNjU4cy4zMTggMy45NDIgMS4wMTcgNS42NThjLjcgMS43MTcgMS41OSAzLjE3OSAyLjc5NyA0LjM4N2ExMi4xIDEyLjEgMCAwIDAgNC4zODcgMi43OTdjMS43MTYuNyAzLjYyMyAxLjAxNyA1LjY1OCAxLjAxNyAyLjAzNCAwIDMuODc4LS4zMTggNS41My0xLjAxNyAxLjY1My0uNyAzLjA1Mi0xLjU5IDQuMTk2LTIuNzk3cTEuNzE4LTEuODEyIDIuNjctNC4zODdjLjYzNi0xLjcxNi45NTQtMy42MjMuOTU0LTUuNjU4di0uODI2Yy0uMTktLjEyNy0uMjU1LS40NDUtLjI1NS0uNyIvPjwvc3ZnPg==");background-repeat:no-repeat;background-size:170px 40px;content:"";display:block;height:40px;width:170px}.ag-watermark-text{font-family:Impact,sans-serif;font-size:19px;font-weight:700;opacity:.5}:where(.ag-ltr) .ag-watermark-text{padding-left:.7rem}:where(.ag-rtl) .ag-watermark-text{padding-right:.7rem}'; var WatermarkElement = { tag: "div", cls: "ag-watermark", children: [{ tag: "div", ref: "eLicenseTextRef", cls: "ag-watermark-text" }] }; var AgWatermark = class extends Component { constructor() { super(WatermarkElement); this.eLicenseTextRef = RefPlaceholder; this.registerCSS(watermark_default); } wireBeans(beans) { this.licenseManager = beans.licenseManager; } postConstruct() { const show = this.shouldDisplayWatermark(); this.setDisplayed(show); if (show) { this.eLicenseTextRef.textContent = this.licenseManager.getWatermarkMessage(); window.setTimeout(() => this.addCss("ag-opacity-zero"), 0); window.setTimeout(() => this.setDisplayed(false), 5000); } } shouldDisplayWatermark() { return this.licenseManager.isDisplayWatermark(); } }; var AgWatermarkSelector = { selector: "AG-WATERMARK", component: AgWatermark }; var GridLicenseManager = class extends BeanStub { constructor() { super(...arguments); this.beanName = "licenseManager"; } postConstruct() { this.validateLicense(); } validateLicense() { const beans = this.beans; if (beans.withinStudio) { this.licenseManager = { isDisplayWatermark: () => false, getWatermarkMessage: () => "" }; } else { const licenseManager = new LicenseManager(_getDocument(beans)); this.licenseManager = licenseManager; licenseManager.validateLicense(); } } static getLicenseDetails(licenseKey) { return new LicenseManager(null).getLicenseDetails(licenseKey); } getWatermarkSelector() { return AgWatermarkSelector; } isDisplayWatermark() { return this.licenseManager.isDisplayWatermark(); } getWatermarkMessage() { return this.licenseManager.getWatermarkMessage(); } static setLicenseKey(licenseKey) {} static setChartsLicenseManager(chartsLicenseManager) {} }; var INCH_TO_EMU = 9525; var numberFormatMap = { "0": 1, "0.00": 2, "#,##0": 3, "#,##0.00": 4, "0%": 9, "0.00%": 10, "0.00E+00": 11, "# ?/?": 12, "# ??/??": 13, "mm-dd-yy": 14, "d-mmm-yy": 15, "d-mmm": 16, "mmm-yy": 17, "h:mm AM/PM": 18, "h:mm:ss AM/PM": 19, "h:mm": 20, "h:mm:ss": 21, "m/d/yy h:mm": 22, "#,##0 ;(#,##0)": 37, "#,##0 ;[Red](#,##0)": 38, "#,##0.00;(#,##0.00)": 39, "#,##0.00;[Red](#,##0.00)": 40, "mm:ss": 45, "[h]:mm:ss": 46, "mmss.0": 47, "##0.0E+0": 48, "@": 49 }; var LINE_SEPARATOR2 = `\r `; function returnAttributeIfPopulated(key, value, booleanTransformer) { if (!value && value !== "" && value !== 0) { return ""; } let xmlValue = value; if (typeof value === "boolean") { if (booleanTransformer) { xmlValue = booleanTransformer(value); } } return ` ${key}="${xmlValue}"`; } function createXmlHeader(headerElement = {}) { const headerStart = ""; const keys = ["version"]; if (!headerElement.version) { headerElement.version = "1.0"; } if (headerElement.encoding) { keys.push("encoding"); } if (headerElement.standalone) { keys.push("standalone"); } const att = keys.map((key) => `${key}="${headerElement[key]}"`).join(" "); return `${headerStart}xml ${att} ${headerEnd}`; } function createXml(xmlElement, booleanTransformer) { let props = ""; if (xmlElement.properties) { if (xmlElement.properties.prefixedAttributes) { xmlElement.properties.prefixedAttributes.forEach((prefixedSet) => { for (const key of Object.keys(prefixedSet.map)) { props += returnAttributeIfPopulated(prefixedSet.prefix + key, prefixedSet.map[key], booleanTransformer); } }); } if (xmlElement.properties.rawMap) { for (const key of Object.keys(xmlElement.properties.rawMap)) { props += returnAttributeIfPopulated(key, xmlElement.properties.rawMap[key], booleanTransformer); } } } let result = "<" + xmlElement.name + props; if (!xmlElement.children && xmlElement.textNode == null) { return result + "/>" + LINE_SEPARATOR2; } if (xmlElement.textNode != null) { return result + ">" + xmlElement.textNode + "" + LINE_SEPARATOR2; } result += ">" + LINE_SEPARATOR2; if (xmlElement.children) { for (const it of xmlElement.children) { result += createXml(it, booleanTransformer); } } return result + "" + LINE_SEPARATOR2; } var pointsToPixel = (points) => { return Math.round(points * 96 / 72); }; var pixelsToEMU = (value) => { return Math.ceil(value * INCH_TO_EMU); }; var getFontFamilyId = (name) => { if (name === undefined) { return; } const families = ["Automatic", "Roman", "Swiss", "Modern", "Script", "Decorative"]; const pos = families.indexOf(name || "Automatic"); return Math.max(pos, 0); }; var getHeightFromProperty = (rowIndex, height) => { if (!height) { return; } let finalHeight; if (typeof height === "number") { finalHeight = height; } else { const heightFunc = height; finalHeight = heightFunc({ rowIndex }); } return finalHeight; }; var setExcelImageTotalWidth = (image, columnsToExport) => { const { colSpan, column } = image.position; if (!image.width) { return; } if (colSpan) { const columnsInSpan = columnsToExport.slice(column - 1, column + colSpan - 1); let totalWidth = 0; for (let i = 0;i < columnsInSpan.length; i++) { const colWidth = columnsInSpan[i].getActualWidth(); if (image.width < totalWidth + colWidth) { image.position.colSpan = i + 1; image.totalWidth = image.width; image.width = image.totalWidth - totalWidth; break; } totalWidth += colWidth; } } else { image.totalWidth = image.width; } }; var setExcelImageTotalHeight = (image, rowHeight) => { const { rowSpan, row } = image.position; if (!image.height) { return; } if (rowSpan) { let totalHeight = 0; let counter = 0; for (let i = row;i < row + rowSpan; i++) { const nextRowHeight = pointsToPixel(getHeightFromProperty(i, rowHeight) || 20); if (image.height < totalHeight + nextRowHeight) { image.position.rowSpan = counter + 1; image.totalHeight = image.height; image.height = image.totalHeight - totalHeight; break; } totalHeight += nextRowHeight; counter++; } } else { image.totalHeight = image.height; } }; var createXmlPart = (body, skipHeader) => { const header = createXmlHeader({ encoding: "UTF-8", standalone: "yes" }); const xmlBody = createXml(body); if (skipHeader) { return xmlBody; } return `${header}${xmlBody}`; }; var getExcelColumnName = (colIdx) => { const startCode = 65; const tableWidth = 26; const fromCharCode = String.fromCharCode; const pos = Math.floor(colIdx / tableWidth); const tableIdx = colIdx % tableWidth; if (!pos || colIdx === tableWidth) { return fromCharCode(startCode + colIdx - 1); } if (!tableIdx) { return getExcelColumnName(pos - 1) + "Z"; } if (pos < tableWidth) { return fromCharCode(startCode + pos - 1) + fromCharCode(startCode + tableIdx - 1); } return getExcelColumnName(pos) + fromCharCode(startCode + tableIdx - 1); }; var sanitizeTableName = (name) => { return name.replaceAll(` `, "_x000a_"); }; var replaceInvisibleCharacters = (str) => { if (str == null) { return null; } let newString = ""; for (let i = 0;i < str.length; i++) { const point = str.charCodeAt(i); if (point >= 0 && point <= 31 && point !== 10) { const convertedCode = point.toString(16).toUpperCase(); const paddedCode = convertedCode.padStart(4, "0"); const newValue = `_x${paddedCode}_`; newString += newValue; } else { newString += str[i]; } } return newString; }; var buildSharedString = (strMap) => { const ret = []; for (const key of strMap.keys()) { const textNode = key.toString(); const child = { name: "t", textNode: _escapeString(replaceInvisibleCharacters(textNode)) }; const preserveSpaces = textNode.trim().length !== textNode.length; if (preserveSpaces) { child.properties = { rawMap: { "xml:space": "preserve" } }; } ret.push({ name: "si", children: [child] }); } return ret; }; var ExcelSerializingSession = class extends BaseGridSerializingSession { constructor(config) { super(config); this.mixedStyles = {}; this.mixedStyleCounter = 0; this.rows = []; this.frozenRowCount = 0; this.skipFrozenRows = false; this.frozenColumnCount = 0; this.skipFrozenColumns = false; this.formulaSvc = config.formulaSvc; this.config = Object.assign({}, config); this.workbook = config.workbook; this.stylesByIds = {}; for (const style of this.config.baseExcelStyles) { this.stylesByIds[style.id] = style; } const quotePrefixStyle = { id: "_quotePrefix", quotePrefix: 1 }; this.stylesByIds[quotePrefixStyle.id] = quotePrefixStyle; this.excelStyles = [...this.config.baseExcelStyles, quotePrefixStyle]; } addCustomContent(customContent) { for (const row of customContent) { const rowLen = this.rows.length + 1; let outlineLevel; if (!this.config.suppressRowOutline && row.outlineLevel != null) { outlineLevel = row.outlineLevel; } const rowObj = { height: getHeightFromProperty(rowLen, row.height || this.config.rowHeight), cells: (row.cells || []).map((cell, idx) => { const image = this.addImage(rowLen, this.columnsToExport[idx], cell.data?.value); let excelStyles = null; if (cell.styleId) { excelStyles = typeof cell.styleId === "string" ? [cell.styleId] : cell.styleId; } const excelStyleId = this.getStyleId(excelStyles); if (image) { return this.createCell(excelStyleId, this.getDataTypeForValue(image.value), image.value == null ? "" : image.value); } const value = cell.data?.value ?? ""; const type = this.getDataTypeForValue(value); if (cell.mergeAcross) { return this.createMergedCell(excelStyleId, type, value, cell.mergeAcross); } return this.createCell(excelStyleId, type, value); }), outlineLevel }; if (row.collapsed != null) { rowObj.collapsed = row.collapsed; } if (row.hidden != null) { rowObj.hidden = row.hidden; } this.rows.push(rowObj); } } onNewHeaderGroupingRow() { const currentCells = []; const { freezeRows, headerRowHeight } = this.config; this.rows.push({ cells: currentCells, height: getHeightFromProperty(this.rows.length + 1, headerRowHeight) }); if (freezeRows) { this.frozenRowCount++; } return { onColumn: (columnGroup, header, index, span, collapsibleGroupRanges) => { const styleIds = this.config.styleLinker({ rowType: "HEADER_GROUPING", rowIndex: 1, value: `grouping-${header}`, columnGroup }); currentCells.push({ ...this.createMergedCell(this.getStyleId(styleIds), this.getDataTypeForValue("string"), header, span), collapsibleRanges: collapsibleGroupRanges }); } }; } onNewHeaderRow() { const { freezeRows, headerRowHeight } = this.config; if (freezeRows) { this.frozenRowCount++; } return this.onNewRow(this.onNewHeaderColumn, headerRowHeight); } onNewBodyRow(node) { const { freezeRows, rowHeight } = this.config; if (!this.skipFrozenRows) { if (freezeRows === "headersAndPinnedRows" && node?.rowPinned === "top") { this.frozenRowCount++; } else if (typeof freezeRows === "function") { if (freezeRows(_addGridCommonParams(this.gos, { node }))) { this.frozenRowCount++; } else { this.skipFrozenRows = true; } } else { this.skipFrozenRows = true; } } const rowAccumulator = this.onNewRow(this.onNewBodyColumn, rowHeight); if (node) { this.addRowOutlineIfNecessary(node); } return rowAccumulator; } prepare(columnsToExport) { super.prepare(columnsToExport); this.columnsToExport = [...columnsToExport]; this.cols = columnsToExport.map((col, i) => this.convertColumnToExcel(col, i)); } parse() { const longestRow = this.rows.reduce((a, b) => Math.max(a, b.cells.length), 0); while (this.cols.length < longestRow) { this.cols.push(this.convertColumnToExcel(null, this.cols.length + 1)); } const worksheet = this.createWorksheet(); return this.addWorksheetToWorkbook(worksheet); } createWorksheet() { const { sheetName } = this.config; let name; if (sheetName != null) { const sheetNameValue = typeof sheetName === "function" ? sheetName(_addGridCommonParams(this.gos, {})) : sheetName; name = String(sheetNameValue).substring(0, 31); } else { name = "ag-grid"; } return { name, table: { columns: this.cols, rows: this.rows } }; } addRowOutlineIfNecessary(node) { const { gos, suppressRowOutline, rowGroupExpandState = "expanded" } = this.config; const isGroupHideOpenParents = gos.get("groupHideOpenParents"); if (isGroupHideOpenParents || suppressRowOutline || node.level == null) { return; } const padding = node.footer ? 1 : 0; const currentRow = _last(this.rows); if (node.uiLevel == null || node.level === node.uiLevel) { const outlineLevel = Math.min(node.level + padding, 7); currentRow.outlineLevel = outlineLevel; } if (rowGroupExpandState === "expanded") { return; } const collapseAll = rowGroupExpandState === "collapsed"; if (node.isExpandable()) { const isExpanded = !collapseAll && node.expanded; currentRow.collapsed = !isExpanded; } currentRow.hidden = !!node.parent && node.parent.level !== -1 && (collapseAll || this.isAnyParentCollapsed(node.parent)); } isAnyParentCollapsed(node) { while (node && node.level !== -1) { if (!node.expanded) { return true; } node = node.parent; } return false; } convertColumnToExcel(column, index) { const columnWidth = this.config.columnWidth; const headerValue = column ? this.extractHeaderValue(column) : undefined; const displayName = headerValue ?? ""; const filterAllowed = column ? column.isFilterAllowed() : false; if (columnWidth) { if (typeof columnWidth === "number") { return { width: columnWidth, displayName, filterAllowed }; } return { width: columnWidth({ column, index }), displayName, filterAllowed }; } if (column) { const smallestUsefulWidth = 75; return { width: Math.max(column.getActualWidth(), smallestUsefulWidth), displayName, filterAllowed }; } return { displayName, filterAllowed }; } onNewHeaderColumn(rowIndex, currentCells) { return (column) => { const nameForCol = this.extractHeaderValue(column); const styleIds = this.config.styleLinker({ rowType: "HEADER", rowIndex, value: nameForCol, column }); currentCells.push(this.createCell(this.getStyleId(styleIds), this.getDataTypeForValue("string"), nameForCol)); }; } onNewBodyColumn(rowIndex, currentCells) { let skipCols = 0; const { freezeColumns, rightToLeft } = this.config; return (column, index, node) => { if (skipCols > 0) { skipCols -= 1; return; } if (!this.skipFrozenColumns) { const pinned = column.getPinned(); const isPinnedLeft = pinned === true || pinned === "left"; if (freezeColumns === "pinned" && pinned && isPinnedLeft !== rightToLeft) { this.frozenColumnCount++; } else if (typeof freezeColumns === "function" && freezeColumns(_addGridCommonParams(this.gos, { column }))) { this.frozenColumnCount++; } else { this.skipFrozenColumns = true; } } const { value: valueForCell, valueFormatted } = this.extractRowCellValue({ column, node, currentColumnIndex: index, accumulatedRowIndex: rowIndex, type: "excel", useRawFormula: true }); const rawValueForCell = valueForCell; const valueForCellString = typeof rawValueForCell === "bigint" ? rawValueForCell.toString() : rawValueForCell; const styleIds = this.config.styleLinker({ rowType: "BODY", rowIndex, value: rawValueForCell, column, node }); const excelStyleId = this.getStyleId(styleIds); const colSpan = column.getColSpan(node); const addedImage = this.addImage(rowIndex, column, valueForCellString); if (addedImage) { currentCells.push(this.createCell(excelStyleId, this.getDataTypeForValue(addedImage.value), addedImage.value == null ? "" : addedImage.value)); } else if (colSpan > 1) { skipCols = colSpan - 1; currentCells.push(this.createMergedCell(excelStyleId, this.getDataTypeForValue(rawValueForCell), valueForCellString, colSpan - 1)); } else { const isFormula = column.isAllowFormula() && this.formulaSvc?.isFormula(valueForCellString); const cell = this.createCell(excelStyleId, isFormula ? "f" : this.getDataTypeForValue(rawValueForCell), isFormula ? this.formulaSvc?.updateFormulaByOffset({ value: valueForCellString, rowDelta: rowIndex - (node.formulaRowIndex + 1), useRefFormat: false }) : valueForCellString, valueFormatted); currentCells.push(cell); } }; } onNewRow(onNewColumnAccumulator, height) { const currentCells = []; this.rows.push({ cells: currentCells, height: getHeightFromProperty(this.rows.length + 1, height) }); return { onColumn: onNewColumnAccumulator.bind(this, this.rows.length, currentCells)() }; } addWorksheetToWorkbook(worksheet) { const { excelStyles, config } = this; this.mapSharedStrings(worksheet); if (this.frozenColumnCount) { config.frozenColumnCount = this.frozenColumnCount; } if (this.frozenRowCount) { config.frozenRowCount = this.frozenRowCount; } return this.workbook.addWorksheet(excelStyles, worksheet, config); } mapSharedStrings(worksheet) { let emptyStringPosition; for (const row of worksheet.table.rows) { for (const cell of row.cells) { const data = cell.data; if (!data || data.type !== "s") { continue; } const value = data.value; if (value == null) { continue; } if (value === "") { emptyStringPosition ?? (emptyStringPosition = this.workbook.getStringPosition("").toString()); data.value = emptyStringPosition; continue; } data.value = this.workbook.getStringPosition(String(value)).toString(); } } } getDataTypeForValue(valueForCell) { if (valueForCell === undefined) { return "empty"; } let dataType = "s"; try { if (this.isNumerical(valueForCell)) { dataType = "n"; } } catch (e) {} return dataType; } getTypeFromStyle(style, value) { if (this.isFormula(value)) { return "f"; } if (style?.dataType) { switch (style.dataType.toLocaleLowerCase()) { case "formula": return "f"; case "string": return "s"; case "number": return "n"; case "datetime": return "d"; case "error": return "e"; case "boolean": return "b"; default: _warn(162, { id: style.id, dataType: style.dataType }); } } return null; } addImage(rowIndex, column, value) { if (!this.config.addImageToCell) { return; } const addedImage = this.config.addImageToCell(rowIndex, column, value); if (!addedImage) { return; } this.workbook.addBodyImageToMap(addedImage.image, rowIndex, column, this.columnsToExport, this.config.rowHeight); return addedImage; } createCell(styleId, type, value, valueFormatted) { const actualStyle = this.getStyleById(styleId); if (!actualStyle?.dataType && type === "s" && valueFormatted != null) { value = valueFormatted; } const processedType = this.getTypeFromStyle(actualStyle, value) || type; const { value: processedValue, escaped } = this.getCellValue(processedType, value); const styles = []; if (actualStyle) { styles.push(styleId); } if (escaped) { styles.push("_quotePrefix"); } styleId = this.getStyleId(styles) || undefined; return { styleId, data: { type: processedType, value: processedValue } }; } createMergedCell(styleId, type, value, numOfCells) { const valueToUse = value == null ? "" : value; return { styleId: this.getStyleById(styleId) ? styleId : undefined, data: { type, value: type === "s" ? String(valueToUse) : value }, mergeAcross: numOfCells }; } getCellValue(type, value) { let escaped = false; if (value == null || type === "s" && value === "") { return { value: "", escaped: false }; } if (type === "s") { value = String(value); if (value[0] === "'") { escaped = true; value = value.slice(1); } } else if (type === "f") { value = this.addXlfnPrefix(value).slice(1); } else if (type === "n") { const numberValue = Number(value); if (isNaN(numberValue)) { value = ""; } else if (value !== "") { value = numberValue.toString(); } } return { value, escaped }; } addXlfnPrefix(value) { if (!value) { return value; } const concatRegex = /(^|[^A-Z0-9._])(CONCAT)(\s*\()/gi; return value.replace(concatRegex, (_match, prefix, fn, openParen) => `${prefix}_xlfn.${fn}${openParen}`); } getStyleId(styleIds) { if (!styleIds?.length) { return null; } const filteredStyleIds = styleIds.filter((styleId) => this.stylesByIds[styleId] != null); if (!filteredStyleIds.length) { return null; } if (filteredStyleIds.length === 1) { return filteredStyleIds[0]; } const key = filteredStyleIds.join("-"); if (!this.mixedStyles[key]) { this.addNewMixedStyle(filteredStyleIds); } return this.mixedStyles[key].excelID; } addNewMixedStyle(styleIds) { this.mixedStyleCounter += 1; const excelId = `mixedStyle${this.mixedStyleCounter}`; const resultantStyle = {}; for (const styleId of styleIds) { const excelStyle = this.stylesByIds[styleId]; if (excelStyle) { _mergeDeep(resultantStyle, excelStyle, true, true); } } resultantStyle.id = excelId; const key = styleIds.join("-"); this.mixedStyles[key] = { excelID: excelId, key, result: resultantStyle }; this.excelStyles.push(resultantStyle); this.stylesByIds[excelId] = resultantStyle; } isFormula(value) { if (value == null) { return false; } const strValue = String(value); return this.config.autoConvertFormulas && _isExpressionString(strValue); } isNumerical(value) { if (typeof value === "bigint") { return false; } return isFinite(value) && value !== "" && !isNaN(parseFloat(value)); } getStyleById(styleId) { if (styleId == null) { return null; } return this.stylesByIds[styleId] || null; } }; var contentTypeFactory = { getTemplate(config) { const { name, ContentType, Extension, PartName } = config; return { name, properties: { rawMap: { Extension, PartName, ContentType } } }; } }; var contentType_default = contentTypeFactory; var _normaliseImageExtension = (ext) => ext === "jpg" ? "jpeg" : ext; var contentTypesFactory = { getTemplate({ sheetLen, hasCustomProperties }) { const worksheets = new Array(sheetLen).fill(undefined).map((v, i) => ({ name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", PartName: `/xl/worksheets/sheet${i + 1}.xml` })); const sheetsWithImages = XLSX_WORKSHEET_IMAGES.size; const headerFooterImages = XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.size; const imageTypesObject = {}; XLSX_WORKBOOK_IMAGE_IDS.forEach((v) => { imageTypesObject[_normaliseImageExtension(v.type)] = true; }); const imageDocs = new Array(sheetsWithImages).fill(undefined).map((v, i) => ({ name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.drawing+xml", PartName: `/xl/drawings/drawing${i + 1}.xml` })); const tableDocs = []; XLSX_WORKSHEET_DATA_TABLES.forEach(({ name }) => { tableDocs.push({ name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml", PartName: `/xl/tables/${name}.xml` }); }); const customPropertiesDocs = hasCustomProperties ? [ { name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.custom-properties+xml", PartName: "/docProps/custom.xml" } ] : []; const imageTypes = Object.keys(imageTypesObject).map((ext) => ({ name: "Default", ContentType: `image/${ext}`, Extension: ext })); if (headerFooterImages) { imageTypes.push({ name: "Default", Extension: "vml", ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing" }); } const children = [ ...imageTypes, { name: "Default", Extension: "rels", ContentType: "application/vnd.openxmlformats-package.relationships+xml" }, { name: "Default", ContentType: "application/xml", Extension: "xml" }, { name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", PartName: "/xl/workbook.xml" }, ...worksheets, { name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.theme+xml", PartName: "/xl/theme/theme1.xml" }, { name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml", PartName: "/xl/styles.xml" }, { name: "Override", ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", PartName: "/xl/sharedStrings.xml" }, ...imageDocs, ...tableDocs, { name: "Override", ContentType: "application/vnd.openxmlformats-package.core-properties+xml", PartName: "/docProps/core.xml" }, ...customPropertiesDocs ].map((contentType) => contentType_default.getTemplate(contentType)); return { name: "Types", properties: { rawMap: { xmlns: "http://schemas.openxmlformats.org/package/2006/content-types" } }, children }; } }; var contentTypes_default = contentTypesFactory; var coreFactory = { getTemplate(author) { const dt = /* @__PURE__ */ new Date; const jsonDate = dt.toJSON(); return { name: "cp:coreProperties", properties: { prefixedAttributes: [ { prefix: "xmlns:", map: { cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties", dc: "http://purl.org/dc/elements/1.1/", dcterms: "http://purl.org/dc/terms/", dcmitype: "http://purl.org/dc/dcmitype/", xsi: "http://www.w3.org/2001/XMLSchema-instance" } } ] }, children: [ { name: "dc:creator", textNode: author }, { name: "dc:title", textNode: "Workbook" }, { name: "dcterms:created", properties: { rawMap: { "xsi:type": "dcterms:W3CDTF" } }, textNode: jsonDate }, { name: "dcterms:modified", properties: { rawMap: { "xsi:type": "dcterms:W3CDTF" } }, textNode: jsonDate } ] }; } }; var core_default2 = coreFactory; var DEFAULT_FMTID = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"; var buildPropertyElements = (metadata) => { const keys = Object.keys(metadata).filter((name) => name && metadata[name] != null); return keys.map((name, index) => ({ name: "property", properties: { rawMap: { fmtid: DEFAULT_FMTID, pid: (index + 2).toString(), name: _escapeString(name) ?? "" } }, children: [ { name: "vt:lpwstr", textNode: _escapeString(replaceInvisibleCharacters(String(metadata[name]))) ?? "" } ] })); }; var customPropertiesFactory = { getTemplate(metadata) { return { name: "Properties", properties: { rawMap: { xmlns: "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties", "xmlns:vt": "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" } }, children: buildPropertyElements(metadata) }; } }; var customProperties_default = customPropertiesFactory; var getAnchor = (name, imageAnchor) => ({ name: `xdr:${name}`, children: [ { name: "xdr:col", textNode: imageAnchor.col.toString() }, { name: "xdr:colOff", textNode: imageAnchor.offsetX.toString() }, { name: "xdr:row", textNode: imageAnchor.row.toString() }, { name: "xdr:rowOff", textNode: imageAnchor.offsetY.toString() } ] }); var getExt = (image) => { const children = [ { name: "a:ext", properties: { rawMap: { uri: "{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}" } }, children: [ { name: "a16:creationId", properties: { rawMap: { id: "{822E6D20-D7BC-2841-A643-D49A6EF008A2}", "xmlns:a16": "http://schemas.microsoft.com/office/drawing/2014/main" } } } ] } ]; const recolor = image.recolor?.toLowerCase(); switch (recolor) { case "grayscale": case "sepia": case "washout": children.push({ name: "a:ext", properties: { rawMap: { uri: "{C183D7F6-B498-43B3-948B-1728B52AA6E4}" } }, children: [ { name: "adec:decorative", properties: { rawMap: { val: "0", "xmlns:adec": "http://schemas.microsoft.com/office/drawing/2017/decorative" } } } ] }); } return { name: "a:extLst", children }; }; var getNvPicPr = (image, index) => ({ name: "xdr:nvPicPr", children: [ { name: "xdr:cNvPr", properties: { rawMap: { id: index, name: image.id, descr: image.altText != null ? image.altText : undefined } }, children: [getExt(image)] }, { name: "xdr:cNvPicPr", properties: { rawMap: { preferRelativeResize: "0" } }, children: [ { name: "a:picLocks" } ] } ] }); var getColorDetails = (color) => { if (!color.saturation && !color.tint) { return; } const ret = []; if (color.saturation) { ret.push({ name: "a:satMod", properties: { rawMap: { val: color.saturation * 1000 } } }); } if (color.tint) { ret.push({ name: "a:tint", properties: { rawMap: { val: color.tint * 1000 } } }); } return ret; }; var getDuoTone = (primaryColor, secondaryColor) => { return { name: "a:duotone", children: [ { name: "a:prstClr", properties: { rawMap: { val: primaryColor.color } }, children: getColorDetails(primaryColor) }, { name: "a:srgbClr", properties: { rawMap: { val: secondaryColor.color } }, children: getColorDetails(secondaryColor) } ] }; }; var getBlipFill = (image, index) => { let blipChildren; if (image.transparency) { const transparency = Math.min(Math.max(image.transparency, 0), 100); blipChildren = [ { name: "a:alphaModFix", properties: { rawMap: { amt: 1e5 - Math.round(transparency * 1000) } } } ]; } if (image.recolor) { if (!blipChildren) { blipChildren = []; } switch (image.recolor.toLocaleLowerCase()) { case "grayscale": blipChildren.push({ name: "a:grayscl" }); break; case "sepia": blipChildren.push(getDuoTone({ color: "black" }, { color: "D9C3A5", tint: 50, saturation: 180 })); break; case "washout": blipChildren.push({ name: "a:lum", properties: { rawMap: { bright: "70000", contrast: "-70000" } } }); break; default: } } return { name: "xdr:blipFill", children: [ { name: "a:blip", properties: { rawMap: { cstate: "print", "r:embed": `rId${index}`, "xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships" } }, children: blipChildren }, { name: "a:stretch", children: [ { name: "a:fillRect" } ] } ] }; }; var getSpPr = (image, imageBoxSize) => { const xfrm = { name: "a:xfrm", children: [ { name: "a:off", properties: { rawMap: { x: 0, y: 0 } } }, { name: "a:ext", properties: { rawMap: { cx: imageBoxSize.width, cy: imageBoxSize.height } } } ] }; if (image.rotation) { const rotation = image.rotation; xfrm.properties = { rawMap: { rot: Math.min(Math.max(rotation, 0), 360) * 60000 } }; } const prstGeom = { name: "a:prstGeom", properties: { rawMap: { prst: "rect" } }, children: [{ name: "a:avLst" }] }; const ret = { name: "xdr:spPr", children: [xfrm, prstGeom] }; return ret; }; var getImageBoxSize = (image) => { image.fitCell = !!image.fitCell || !image.width || !image.height; const { position = {}, fitCell, width = 0, height = 0, totalHeight, totalWidth } = image; const { offsetX = 0, offsetY = 0, row = 1, rowSpan = 1, column = 1, colSpan = 1 } = position; return { from: { row: row - 1, col: column - 1, offsetX: pixelsToEMU(offsetX), offsetY: pixelsToEMU(offsetY) }, to: { row: row - 1 + (fitCell ? 1 : rowSpan - 1), col: column - 1 + (fitCell ? 1 : colSpan - 1), offsetX: pixelsToEMU(width + offsetX), offsetY: pixelsToEMU(height + offsetY) }, height: pixelsToEMU(totalHeight || height), width: pixelsToEMU(totalWidth || width) }; }; var getPicture = (image, currentIndex, worksheetImageIndex, imageBoxSize) => { return { name: "xdr:pic", children: [ getNvPicPr(image, currentIndex + 1), getBlipFill(image, worksheetImageIndex + 1), getSpPr(image, imageBoxSize) ] }; }; var drawingFactory = { getTemplate(config) { const { sheetIndex } = config; const sheetImages = XLSX_WORKSHEET_IMAGES.get(sheetIndex); const sheetImageIds = XLSX_WORKSHEET_IMAGE_IDS.get(sheetIndex); const children = sheetImages.map((image, idx) => { const boxSize = getImageBoxSize(image); return { name: "xdr:twoCellAnchor", properties: { rawMap: { editAs: "absolute" } }, children: [ getAnchor("from", boxSize.from), getAnchor("to", boxSize.to), getPicture(image, idx, sheetImageIds.get(image.id).index, boxSize), { name: "xdr:clientData" } ] }; }); return { name: "xdr:wsDr", properties: { rawMap: { "xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main", "xmlns:xdr": "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" } }, children }; } }; var drawing_default = drawingFactory; var relationshipFactory = { getTemplate(config) { const { Id, Type, Target } = config; return { name: "Relationship", properties: { rawMap: { Id, Type, Target } } }; } }; var relationship_default = relationshipFactory; var relationshipsFactory = { getTemplate(c) { const children = c.map((relationship) => relationship_default.getTemplate(relationship)); return { name: "Relationships", properties: { rawMap: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" } }, children }; } }; var relationships_default = relationshipsFactory; var sharedStrings = { getTemplate(strings) { return { name: "sst", properties: { rawMap: { xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main", count: strings.size, uniqueCount: strings.size } }, children: buildSharedString(strings) }; } }; var sharedStrings_default = sharedStrings; var getWeightName = (value) => { switch (value) { case 1: return "thin"; case 2: return "medium"; case 3: return "thick"; default: return "hair"; } }; var mappedBorderNames = { None: "None", Dot: "Dotted", Dash: "Dashed", Double: "Double", DashDot: "DashDot", DashDotDot: "DashDotDot", SlantDashDot: "SlantDashDot", Continuous: "Continuous" }; var mediumBorders = ["Dashed", "DashDot", "DashDotDot"]; var colorMap = { None: "none", Solid: "solid", Gray50: "mediumGray", Gray75: "darkGray", Gray25: "lightGray", HorzStripe: "darkHorizontal", VertStripe: "darkVertical", ReverseDiagStripe: "darkDown", DiagStripe: "darkUp", DiagCross: "darkGrid", ThickDiagCross: "darkTrellis", ThinHorzStripe: "lightHorizontal", ThinVertStripe: "lightVertical", ThinReverseDiagStripe: "lightDown", ThinDiagStripe: "lightUp", ThinHorzCross: "lightGrid", ThinDiagCross: "lightTrellis", Gray125: "gray125", Gray0625: "gray0625" }; var horizontalAlignmentMap = { Automatic: "general", Left: "left", Center: "center", Right: "right", Fill: "fill", Justify: "justify", CenterAcrossSelection: "centerContinuous", Distributed: "distributed", JustifyDistributed: "justify" }; var verticalAlignmentMap = { Automatic: undefined, Top: "top", Bottom: "bottom", Center: "center", Justify: "justify", Distributed: "distributed", JustifyDistributed: "justify" }; var convertLegacyPattern = (name) => { if (!name) { return "none"; } return colorMap[name] || name; }; var convertLegacyColor = (color) => { if (color == undefined) { return color; } if (color.charAt(0) === "#") { color = color.substring(1); } return color.length === 6 ? "FF" + color : color; }; var convertLegacyBorder = (type, weight) => { if (!type) { return "thin"; } const namedWeight = getWeightName(weight); if (type === "Continuous") { return namedWeight; } const mappedName = mappedBorderNames[type]; if (namedWeight === "medium" && mediumBorders.some((type2) => type2 === mappedName)) { return `medium${mappedName}`; } return `${mappedName.charAt(0).toLowerCase()}${mappedName.substring(1)}`; }; var convertLegacyHorizontalAlignment = (alignment) => { return horizontalAlignmentMap[alignment] || "general"; }; var convertLegacyVerticalAlignment = (alignment) => { return verticalAlignmentMap[alignment] || undefined; }; var getBorderColor = (color) => { return { name: "color", properties: { rawMap: { rgb: convertLegacyColor(color || "#000000") } } }; }; var borderFactory = { getTemplate(border) { const { left, right, top, bottom, diagonal } = border; const leftChildren = left ? [getBorderColor(left.color)] : undefined; const rightChildren = right ? [getBorderColor(right.color)] : undefined; const topChildren = top ? [getBorderColor(top.color)] : undefined; const bottomChildren = bottom ? [getBorderColor(bottom.color)] : undefined; const diagonalChildren = diagonal ? [getBorderColor(diagonal.color)] : undefined; return { name: "border", children: [ { name: "left", properties: { rawMap: { style: left?.style } }, children: leftChildren }, { name: "right", properties: { rawMap: { style: right?.style } }, children: rightChildren }, { name: "top", properties: { rawMap: { style: top?.style } }, children: topChildren }, { name: "bottom", properties: { rawMap: { style: bottom?.style } }, children: bottomChildren }, { name: "diagonal", properties: { rawMap: { style: diagonal?.style } }, children: diagonalChildren } ] }; } }; var border_default = borderFactory; var bordersFactory = { getTemplate(borders) { return { name: "borders", properties: { rawMap: { count: borders.length } }, children: borders.map((border) => border_default.getTemplate(border)) }; } }; var borders_default = bordersFactory; var getReadingOrderId = (readingOrder) => { const order = ["Context", "LeftToRight", "RightToLeft"]; const pos = order.indexOf(readingOrder); return Math.max(pos, 0); }; var alignmentFactory = { getTemplate(alignment) { const { horizontal, indent, readingOrder, rotate, shrinkToFit, vertical, wrapText } = alignment; return { name: "alignment", properties: { rawMap: { horizontal: horizontal && convertLegacyHorizontalAlignment(horizontal), indent, readingOrder: readingOrder && getReadingOrderId(readingOrder), textRotation: rotate, shrinkToFit, vertical: vertical && convertLegacyVerticalAlignment(vertical), wrapText } } }; } }; var alignment_default = alignmentFactory; var protectionFactory = { getTemplate(protection) { const locked = protection.protected === false ? 0 : 1; const hidden = protection.hideFormula === true ? 1 : 0; return { name: "protection", properties: { rawMap: { hidden, locked } } }; } }; var protection_default = protectionFactory; var xfFactory = { getTemplate(xf) { const { alignment, borderId, fillId, fontId, numFmtId, protection, quotePrefix, xfId } = xf; const children = []; if (alignment) { children.push(alignment_default.getTemplate(alignment)); } if (protection) { children.push(protection_default.getTemplate(protection)); } return { name: "xf", properties: { rawMap: { applyAlignment: alignment ? 1 : undefined, applyProtection: protection ? 1 : undefined, applyBorder: borderId ? 1 : undefined, applyFill: fillId ? 1 : undefined, borderId, fillId, applyFont: fontId ? 1 : undefined, fontId, applyNumberFormat: numFmtId ? 1 : undefined, numFmtId, quotePrefix: quotePrefix ? 1 : undefined, xfId } }, children: children.length ? children : undefined }; } }; var xf_default = xfFactory; var cellStylesXfsFactory = { getTemplate(xfs) { return { name: "cellStyleXfs", properties: { rawMap: { count: xfs.length } }, children: xfs.map((xf) => xf_default.getTemplate(xf)) }; } }; var cellStyleXfs_default = cellStylesXfsFactory; var borderFactory2 = { getTemplate(cellStyle) { const { builtinId, name, xfId } = cellStyle; return { name: "cellStyle", properties: { rawMap: { builtinId, name, xfId } } }; } }; var cellStyle_default = borderFactory2; var cellStylesFactory = { getTemplate(cellStyles) { return { name: "cellStyles", properties: { rawMap: { count: cellStyles.length } }, children: cellStyles.map((cellStyle) => cellStyle_default.getTemplate(cellStyle)) }; } }; var cellStyles_default = cellStylesFactory; var cellXfsFactory = { getTemplate(xfs) { return { name: "cellXfs", properties: { rawMap: { count: xfs.length } }, children: xfs.map((xf) => xf_default.getTemplate(xf)) }; } }; var cellXfs_default = cellXfsFactory; var fillFactory = { getTemplate(fill) { const { patternType, fgTheme, fgTint, fgRgb, bgRgb, bgIndexed } = fill; const pf = { name: "patternFill", properties: { rawMap: { patternType } } }; if (fgTheme || fgTint || fgRgb) { pf.children = [ { name: "fgColor", properties: { rawMap: { theme: fgTheme, tint: fgTint, rgb: fgRgb } } } ]; } if (bgIndexed || bgRgb) { if (!pf.children) { pf.children = []; } pf.children.push({ name: "bgColor", properties: { rawMap: { indexed: bgIndexed, rgb: bgRgb } } }); } return { name: "fill", children: [pf] }; } }; var fill_default = fillFactory; var fillsFactory = { getTemplate(fills) { return { name: "fills", properties: { rawMap: { count: fills.length } }, children: fills.map((fill) => fill_default.getTemplate(fill)) }; } }; var fills_default = fillsFactory; var fontFactory = { getTemplate(font) { const { size, colorTheme, color = "FF000000", fontName = "Calibri", family, scheme, italic, bold, strikeThrough, outline, shadow: shadow2, underline, verticalAlign } = font; const children = [ { name: "sz", properties: { rawMap: { val: size } } }, { name: "color", properties: { rawMap: { theme: colorTheme, rgb: color } } }, { name: "name", properties: { rawMap: { val: fontName } } } ]; if (family) { children.push({ name: "family", properties: { rawMap: { val: family } } }); } if (scheme) { children.push({ name: "scheme", properties: { rawMap: { val: scheme } } }); } if (italic) { children.push({ name: "i" }); } if (bold) { children.push({ name: "b" }); } if (strikeThrough) { children.push({ name: "strike" }); } if (outline) { children.push({ name: "outline" }); } if (shadow2) { children.push({ name: "shadow" }); } if (underline) { children.push({ name: "u", properties: { rawMap: { val: underline } } }); } if (verticalAlign) { children.push({ name: "vertAlign", properties: { rawMap: { val: verticalAlign } } }); } return { name: "font", children }; } }; var font_default = fontFactory; var fontsFactory = { getTemplate(fonts) { return { name: "fonts", properties: { rawMap: { count: fonts.length } }, children: fonts.map((font) => font_default.getTemplate(font)) }; } }; var fonts_default = fontsFactory; function prepareString(str) { const split = str.split(/(\[[^\]]*\])/); for (let i = 0;i < split.length; i++) { let currentString = split[i]; if (!currentString.length) { continue; } if (!currentString.startsWith("[")) { currentString = currentString.replace(/\$/g, '"$"'); } split[i] = _escapeString(currentString); } return split.join(""); } var numberFormatFactory = { getTemplate(numberFormat) { let { formatCode, numFmtId } = numberFormat; if (formatCode.length) { formatCode = prepareString(formatCode); } return { name: "numFmt", properties: { rawMap: { formatCode, numFmtId } } }; } }; var numberFormat_default = numberFormatFactory; var numberFormatsFactory = { getTemplate(numberFormats) { return { name: "numFmts", properties: { rawMap: { count: numberFormats.length } }, children: numberFormats.map((numberFormat) => numberFormat_default.getTemplate(numberFormat)) }; } }; var numberFormats_default = numberFormatsFactory; var stylesMap; var registeredNumberFmts; var registeredFonts; var registeredFills; var registeredBorders; var registeredCellStyleXfs; var registeredCellXfs; var registeredCellStyles; var currentSheet; var getStyleName = (name, currentSheet2) => { if (name.includes("mixedStyle") && currentSheet2 > 1) { name += `_${currentSheet2}`; } return name; }; var resetStylesheetValues = () => { stylesMap = { base: 0 }; registeredNumberFmts = []; registeredFonts = [{ fontName: "Calibri", colorTheme: "1", family: "2", scheme: "minor" }]; registeredFills = [{ patternType: "none" }, { patternType: "gray125" }]; registeredBorders = [{ left: undefined, right: undefined, top: undefined, bottom: undefined, diagonal: undefined }]; registeredCellStyleXfs = [{ borderId: 0, fillId: 0, fontId: 0, numFmtId: 0 }]; registeredCellXfs = [{ borderId: 0, fillId: 0, fontId: 0, numFmtId: 0, xfId: 0 }]; registeredCellStyles = [{ builtinId: 0, name: "Normal", xfId: 0 }]; }; var registerFill = (fill) => { const convertedPattern = convertLegacyPattern(fill.pattern); const convertedFillColor = convertLegacyColor(fill.color); const convertedPatternColor = convertLegacyColor(fill.patternColor); let pos = registeredFills.findIndex((currentFill) => { const { patternType, fgRgb, bgRgb } = currentFill; return !(patternType != convertedPattern || fgRgb != convertedFillColor || bgRgb != convertedPatternColor); }); if (pos === -1) { pos = registeredFills.length; registeredFills.push({ patternType: convertedPattern, fgRgb: convertedFillColor, bgRgb: convertedPatternColor }); } return pos; }; var registerNumberFmt = (format) => { if (numberFormatMap[format]) { return numberFormatMap[format]; } let pos = registeredNumberFmts.findIndex((currentFormat) => currentFormat.formatCode === format); if (pos === -1) { pos = registeredNumberFmts.length + 164; registeredNumberFmts.push({ formatCode: format, numFmtId: pos }); } else { pos = registeredNumberFmts[pos].numFmtId; } return pos; }; var registerBorders = (borders) => { const { borderBottom, borderTop, borderLeft, borderRight } = borders; let bottomStyle; let topStyle; let leftStyle; let rightStyle; let bottomColor; let topColor; let leftColor; let rightColor; if (borderLeft) { leftStyle = convertLegacyBorder(borderLeft.lineStyle, borderLeft.weight); leftColor = convertLegacyColor(borderLeft.color); } if (borderRight) { rightStyle = convertLegacyBorder(borderRight.lineStyle, borderRight.weight); rightColor = convertLegacyColor(borderRight.color); } if (borderBottom) { bottomStyle = convertLegacyBorder(borderBottom.lineStyle, borderBottom.weight); bottomColor = convertLegacyColor(borderBottom.color); } if (borderTop) { topStyle = convertLegacyBorder(borderTop.lineStyle, borderTop.weight); topColor = convertLegacyColor(borderTop.color); } let pos = registeredBorders.findIndex((currentBorder) => { const { left, right, top, bottom } = currentBorder; if (!left && (leftStyle || leftColor)) { return false; } if (!right && (rightStyle || rightColor)) { return false; } if (!top && (topStyle || topColor)) { return false; } if (!bottom && (bottomStyle || bottomColor)) { return false; } const { style: clS, color: clC } = left || {}; const { style: crS, color: crC } = right || {}; const { style: ctS, color: ctC } = top || {}; const { style: cbS, color: cbC } = bottom || {}; if (clS != leftStyle || clC != leftColor) { return false; } if (crS != rightStyle || crC != rightColor) { return false; } if (ctS != topStyle || ctC != topColor) { return false; } if (cbS != bottomStyle || cbC != bottomColor) { return false; } return true; }); if (pos === -1) { pos = registeredBorders.length; registeredBorders.push({ left: { style: leftStyle, color: leftColor }, right: { style: rightStyle, color: rightColor }, top: { style: topStyle, color: topColor }, bottom: { style: bottomStyle, color: bottomColor }, diagonal: { style: undefined, color: undefined } }); } return pos; }; var registerFont = (font) => { const { fontName: name = "Calibri", color, size, bold, italic, outline, shadow: shadow2, strikeThrough, underline, family, verticalAlign } = font; const convertedColor = convertLegacyColor(color); const familyId = getFontFamilyId(family); const convertedUnderline = underline ? underline.toLocaleLowerCase() : undefined; const convertedVerticalAlign = verticalAlign ? verticalAlign.toLocaleLowerCase() : undefined; let pos = registeredFonts.findIndex((currentFont) => { return !(currentFont.fontName != name || currentFont.color != convertedColor || currentFont.size != size || currentFont.bold != bold || currentFont.italic != italic || currentFont.outline != outline || currentFont.shadow != shadow2 || currentFont.strikeThrough != strikeThrough || currentFont.underline != convertedUnderline || currentFont.verticalAlign != convertedVerticalAlign || currentFont.family != familyId); }); if (pos === -1) { pos = registeredFonts.length; registeredFonts.push({ fontName: name, color: convertedColor, size, bold, italic, outline, shadow: shadow2, strikeThrough, underline: convertedUnderline, verticalAlign: convertedVerticalAlign, family: familyId != null ? familyId.toString() : undefined }); } return pos; }; var registerStyle = (config) => { const { alignment, borders, font, interior, numberFormat, protection, quotePrefix } = config; let { id } = config; let currentFill = 0; let currentBorder = 0; let currentFont = 0; let currentNumberFmt = 0; if (!id) { return; } id = getStyleName(id, currentSheet); if (stylesMap[id] != null) { return; } if (interior) { currentFill = registerFill(interior); } if (borders) { currentBorder = registerBorders(borders); } if (font) { currentFont = registerFont(font); } if (numberFormat) { currentNumberFmt = registerNumberFmt(numberFormat.format); } stylesMap[id] = registeredCellXfs.length; registeredCellXfs.push({ alignment, borderId: currentBorder || 0, fillId: currentFill || 0, fontId: currentFont || 0, numFmtId: currentNumberFmt || 0, protection, quotePrefix, xfId: 0 }); }; var stylesheetFactory = { getTemplate(defaultFontSize) { const numberFormats = numberFormats_default.getTemplate(registeredNumberFmts); const fonts = fonts_default.getTemplate(registeredFonts.map((font) => ({ ...font, size: font.size != null ? font.size : defaultFontSize }))); const fills = fills_default.getTemplate(registeredFills); const borders = borders_default.getTemplate(registeredBorders); const cellStylesXfs = cellStyleXfs_default.getTemplate(registeredCellStyleXfs); const cellXfs = cellXfs_default.getTemplate(registeredCellXfs); const cellStyles = cellStyles_default.getTemplate(registeredCellStyles); resetStylesheetValues(); return { name: "styleSheet", properties: { rawMap: { "mc:Ignorable": "x14ac x16r2 xr", xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main", "xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006", "xmlns:x14ac": "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac", "xmlns:x16r2": "http://schemas.microsoft.com/office/spreadsheetml/2015/02/main", "xmlns:xr": "http://schemas.microsoft.com/office/spreadsheetml/2014/revision" } }, children: [ numberFormats, fonts, fills, borders, cellStylesXfs, cellXfs, cellStyles, { name: "tableStyles", properties: { rawMap: { count: 0, defaultPivotStyle: "PivotStyleLight16", defaultTableStyle: "TableStyleMedium2" } } } ] }; } }; var getStyleId = (name, currentSheet2) => { return stylesMap[getStyleName(name, currentSheet2)] || 0; }; var registerStyles = (styles, _currentSheet) => { currentSheet = _currentSheet; if (currentSheet === 1) { resetStylesheetValues(); } styles.forEach(registerStyle); }; var stylesheet_default = stylesheetFactory; var tableFactory = { getTemplate(dataTable, idx) { const { name, columns, rowRange, displayName, showRowStripes, showColumnStripes, showFilterButtons, highlightFirstColumn, highlightLastColumn } = dataTable || {}; const noRows = !rowRange || rowRange[0] - rowRange[1] === 0; if (!dataTable || !name || !Array.isArray(columns) || !columns.length || noRows) { return { name: "table" }; } const filterColumns = columns.map((col, idx2) => ({ name: "filterColumn", properties: { rawMap: { colId: idx2.toString(), hiddenButton: showFilterButtons[idx2] ? 0 : 1 } } })); const firstCell = `A${rowRange[0]}`; const lastCell = `${getExcelColumnName(columns.length)}${rowRange[1]}`; const ref = `${firstCell}:${lastCell}`; const id = `${idx + 1}`; const displayNameToUse = idx ? `${displayName}_${id}` : displayName; return { name: "table", properties: { rawMap: { xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main", "xmlns:mc": "http://schemas.openxmlformats.org/markup-compatibility/2006", "mc:Ignorable": "xr xr3", "xmlns:xr": "http://schemas.microsoft.com/office/spreadsheetml/2014/revision", "xmlns:xr3": "http://schemas.microsoft.com/office/spreadsheetml/2016/revision3", name: displayNameToUse, displayName: displayNameToUse, ref, totalsRowShown: 0, id } }, children: [ { name: "autoFilter", properties: { rawMap: { ref } }, children: filterColumns }, { name: "tableColumns", properties: { rawMap: { count: columns.length } }, children: columns.map((col, idx2) => ({ name: "tableColumn", properties: { rawMap: { id: (idx2 + 1).toString(), name: _escapeString(sanitizeTableName(col)), dataCellStyle: "Normal" } } })) }, { name: "tableStyleInfo", properties: { rawMap: { name: "TableStyleLight1", showFirstColumn: highlightFirstColumn ? 1 : 0, showLastColumn: highlightLastColumn ? 1 : 0, showRowStripes: showRowStripes ? 1 : 0, showColumnStripes: showColumnStripes ? 1 : 0 } } } ] }; } }; var table_default = tableFactory; var getColorChildren = (props) => { const [type, innerType, val, lastClr] = props; return { name: `a:${type}`, children: [ { name: `a:${innerType}`, properties: { rawMap: { val, lastClr } } } ] }; }; var colorScheme = { getTemplate() { return { name: "a:clrScheme", properties: { rawMap: { name: "Office" } }, children: [ getColorChildren(["dk1", "sysClr", "windowText", "000000"]), getColorChildren(["lt1", "sysClr", "window", "FFFFFF"]), getColorChildren(["dk2", "srgbClr", "44546A"]), getColorChildren(["lt2", "srgbClr", "E7E6E6"]), getColorChildren(["accent1", "srgbClr", "4472C4"]), getColorChildren(["accent2", "srgbClr", "ED7D31"]), getColorChildren(["accent3", "srgbClr", "A5A5A5"]), getColorChildren(["accent4", "srgbClr", "FFC000"]), getColorChildren(["accent5", "srgbClr", "5B9BD5"]), getColorChildren(["accent6", "srgbClr", "70AD47"]), getColorChildren(["hlink", "srgbClr", "0563C1"]), getColorChildren(["folHlink", "srgbClr", "954F72"]) ] }; } }; var colorScheme_default = colorScheme; var getFont = (props) => { const [type, typeface, script, panose] = props; return { name: `a:${type}`, properties: { rawMap: { script, typeface, panose } } }; }; var fontScheme = { getTemplate() { return { name: "a:fontScheme", properties: { rawMap: { name: "Office" } }, children: [ { name: "a:majorFont", children: [ getFont(["latin", "Calibri Light", undefined, "020F0302020204030204"]), getFont(["ea", ""]), getFont(["cs", ""]), getFont(["font", "游ゴシック Light", "Jpan"]), getFont(["font", "맑은 고딕", "Hang"]), getFont(["font", "等线 Light", "Hans"]), getFont(["font", "新細明體", "Hant"]), getFont(["font", "Times New Roman", "Arab"]), getFont(["font", "Times New Roman", "Hebr"]), getFont(["font", "Tahoma", "Thai"]), getFont(["font", "Nyala", "Ethi"]), getFont(["font", "Vrinda", "Beng"]), getFont(["font", "Shruti", "Gujr"]), getFont(["font", "MoolBoran", "Khmr"]), getFont(["font", "Tunga", "Knda"]), getFont(["font", "Raavi", "Guru"]), getFont(["font", "Euphemia", "Cans"]), getFont(["font", "Plantagenet Cherokee", "Cher"]), getFont(["font", "Microsoft Yi Baiti", "Yiii"]), getFont(["font", "Microsoft Himalaya", "Tibt"]), getFont(["font", "MV Boli", "Thaa"]), getFont(["font", "Mangal", "Deva"]), getFont(["font", "Gautami", "Telu"]), getFont(["font", "Latha", "Taml"]), getFont(["font", "Estrangelo Edessa", "Syrc"]), getFont(["font", "Kalinga", "Orya"]), getFont(["font", "Kartika", "Mlym"]), getFont(["font", "DokChampa", "Laoo"]), getFont(["font", "Iskoola Pota", "Sinh"]), getFont(["font", "Mongolian Baiti", "Mong"]), getFont(["font", "Times New Roman", "Viet"]), getFont(["font", "Microsoft Uighur", "Uigh"]), getFont(["font", "Sylfaen", "Geor"]), getFont(["font", "Arial", "Armn"]), getFont(["font", "Leelawadee UI", "Bugi"]), getFont(["font", "Microsoft JhengHei", "Bopo"]), getFont(["font", "Javanese Text", "Java"]), getFont(["font", "Segoe UI", "Lisu"]), getFont(["font", "Myanmar Text", "Mymr"]), getFont(["font", "Ebrima", "Nkoo"]), getFont(["font", "Nirmala UI", "Olck"]), getFont(["font", "Ebrima", "Osma"]), getFont(["font", "Phagspa", "Phag"]), getFont(["font", "Estrangelo Edessa", "Syrn"]), getFont(["font", "Estrangelo Edessa", "Syrj"]), getFont(["font", "Estrangelo Edessa", "Syre"]), getFont(["font", "Nirmala UI", "Sora"]), getFont(["font", "Microsoft Tai Le", "Tale"]), getFont(["font", "Microsoft New Tai Lue", "Talu"]), getFont(["font", "Ebrima", "Tfng"]) ] }, { name: "a:minorFont", children: [ getFont(["latin", "Calibri", undefined, "020F0502020204030204"]), getFont(["ea", ""]), getFont(["cs", ""]), getFont(["font", "游ゴシック", "Jpan"]), getFont(["font", "맑은 고딕", "Hang"]), getFont(["font", "等线", "Hans"]), getFont(["font", "新細明體", "Hant"]), getFont(["font", "Arial", "Arab"]), getFont(["font", "Arial", "Hebr"]), getFont(["font", "Tahoma", "Thai"]), getFont(["font", "Nyala", "Ethi"]), getFont(["font", "Vrinda", "Beng"]), getFont(["font", "Shruti", "Gujr"]), getFont(["font", "DaunPenh", "Khmr"]), getFont(["font", "Tunga", "Knda"]), getFont(["font", "Raavi", "Guru"]), getFont(["font", "Euphemia", "Cans"]), getFont(["font", "Plantagenet Cherokee", "Cher"]), getFont(["font", "Microsoft Yi Baiti", "Yiii"]), getFont(["font", "Microsoft Himalaya", "Tibt"]), getFont(["font", "MV Boli", "Thaa"]), getFont(["font", "Mangal", "Deva"]), getFont(["font", "Gautami", "Telu"]), getFont(["font", "Latha", "Taml"]), getFont(["font", "Estrangelo Edessa", "Syrc"]), getFont(["font", "Kalinga", "Orya"]), getFont(["font", "Kartika", "Mlym"]), getFont(["font", "DokChampa", "Laoo"]), getFont(["font", "Iskoola Pota", "Sinh"]), getFont(["font", "Mongolian Baiti", "Mong"]), getFont(["font", "Arial", "Viet"]), getFont(["font", "Microsoft Uighur", "Uigh"]), getFont(["font", "Sylfaen", "Geor"]), getFont(["font", "Arial", "Armn"]), getFont(["font", "Leelawadee UI", "Bugi"]), getFont(["font", "Microsoft JhengHei", "Bopo"]), getFont(["font", "Javanese Text", "Java"]), getFont(["font", "Segoe UI", "Lisu"]), getFont(["font", "Myanmar Text", "Mymr"]), getFont(["font", "Ebrima", "Nkoo"]), getFont(["font", "Nirmala UI", "Olck"]), getFont(["font", "Ebrima", "Osma"]), getFont(["font", "Phagspa", "Phag"]), getFont(["font", "Estrangelo Edessa", "Syrn"]), getFont(["font", "Estrangelo Edessa", "Syrj"]), getFont(["font", "Estrangelo Edessa", "Syre"]), getFont(["font", "Nirmala UI", "Sora"]), getFont(["font", "Microsoft Tai Le", "Tale"]), getFont(["font", "Microsoft New Tai Lue", "Talu"]), getFont(["font", "Ebrima", "Tfng"]) ] } ] }; } }; var fontScheme_default = fontScheme; var getPropertyVal = (name, val, children) => ({ name: `a:${name}`, properties: { rawMap: { val } }, children }); var getGs = (props) => { const [pos, schemeColor, satMod, lumMod, tint, shade] = props; const children = []; children.push(getPropertyVal("satMod", satMod)); if (lumMod) { children.push(getPropertyVal("lumMod", lumMod)); } if (tint) { children.push(getPropertyVal("tint", tint)); } if (shade) { children.push(getPropertyVal("shade", shade)); } return { name: "a:gs", properties: { rawMap: { pos } }, children: [ { name: "a:schemeClr", properties: { rawMap: { val: schemeColor } }, children } ] }; }; var getSolidFill = (val, children) => ({ name: "a:solidFill", children: [getPropertyVal("schemeClr", val, children)] }); var getGradFill = (props) => { const [rotWithShape, gs1, gs2, gs3, lin] = props; const [ang, scaled] = lin; return { name: "a:gradFill", properties: { rawMap: { rotWithShape } }, children: [ { name: "a:gsLst", children: [getGs(gs1), getGs(gs2), getGs(gs3)] }, { name: "a:lin", properties: { rawMap: { ang, scaled } } } ] }; }; var getLine = (props) => { const [w, cap, cmpd, algn] = props; return { name: "a:ln", properties: { rawMap: { w, cap, cmpd, algn } }, children: [ getSolidFill("phClr"), getPropertyVal("prstDash", "solid"), { name: "a:miter", properties: { rawMap: { lim: "800000" } } } ] }; }; var getEffectStyle = (shadow2) => { const children = []; if (shadow2) { const [blurRad, dist, dir, algn, rotWithShape] = shadow2; children.push({ name: "a:outerShdw", properties: { rawMap: { blurRad, dist, dir, algn, rotWithShape } }, children: [getPropertyVal("srgbClr", "000000", [getPropertyVal("alpha", "63000")])] }); } return { name: "a:effectStyle", children: [ Object.assign({}, { name: "a:effectLst" }, children.length ? { children } : {}) ] }; }; var getFillStyleList = () => ({ name: "a:fillStyleLst", children: [ getSolidFill("phClr"), getGradFill([ "1", ["0", "phClr", "105000", "110000", "67000"], ["50000", "phClr", "103000", "105000", "73000"], ["100000", "phClr", "109000", "105000", "81000"], ["5400000", "0"] ]), getGradFill([ "1", ["0", "phClr", "103000", "102000", "94000"], ["50000", "phClr", "110000", "100000", undefined, "100000"], ["100000", "phClr", "120000", "99000", undefined, "78000"], ["5400000", "0"] ]) ] }); var getLineStyleList = () => ({ name: "a:lnStyleLst", children: [ getLine(["6350", "flat", "sng", "ctr"]), getLine(["12700", "flat", "sng", "ctr"]), getLine(["19050", "flat", "sng", "ctr"]) ] }); var getEffectStyleList = () => ({ name: "a:effectStyleLst", children: [getEffectStyle(), getEffectStyle(), getEffectStyle(["57150", "19050", "5400000", "ctr", "0"])] }); var getBgFillStyleList = () => ({ name: "a:bgFillStyleLst", children: [ getSolidFill("phClr"), getSolidFill("phClr", [getPropertyVal("tint", "95000"), getPropertyVal("satMod", "170000")]), getGradFill([ "1", ["0", "phClr", "150000", "102000", "93000", "98000"], ["50000", "phClr", "130000", "103000", "98000", "90000"], ["100000", "phClr", "120000", undefined, undefined, "63000"], ["5400000", "0"] ]) ] }); var formatScheme = { getTemplate() { return { name: "a:fmtScheme", properties: { rawMap: { name: "Office" } }, children: [getFillStyleList(), getLineStyleList(), getEffectStyleList(), getBgFillStyleList()] }; } }; var formatScheme_default = formatScheme; var themeElements = { getTemplate() { return { name: "a:themeElements", children: [colorScheme_default.getTemplate(), fontScheme_default.getTemplate(), formatScheme_default.getTemplate()] }; } }; var themeElements_default = themeElements; var officeTheme = { getTemplate() { return { name: "a:theme", properties: { prefixedAttributes: [ { prefix: "xmlns:", map: { a: "http://schemas.openxmlformats.org/drawingml/2006/main" } } ], rawMap: { name: "Office Theme" } }, children: [ themeElements_default.getTemplate(), { name: "a:objectDefaults" }, { name: "a:extraClrSchemeLst" } ] }; } }; var office_default = officeTheme; var getShapeLayout = () => ({ name: "o:shapelayout", properties: { prefixedAttributes: [ { prefix: "v:", map: { ext: "edit" } } ] }, children: [ { name: "o:idmap", properties: { prefixedAttributes: [ { prefix: "v:", map: { ext: "edit" } } ], rawMap: { data: "1" } } } ] }); var getStroke = () => ({ name: "v:stroke", properties: { rawMap: { joinstyle: "miter" } } }); var getFormulas = (formulas) => ({ name: "v:formulas", children: formulas.map((formula) => ({ name: "v:f", properties: { rawMap: { eqn: formula } } })) }); var getPath = () => ({ name: "v:path", properties: { prefixedAttributes: [ { prefix: "o:", map: { connecttype: "rect", extrusionok: "f" } } ], rawMap: { gradientshapeok: "t" } } }); var getLock = (params) => { const { aspectratio, rotation } = params || {}; const rawMap = {}; if (aspectratio) { rawMap.aspectratio = "t"; } if (rotation) { rawMap.rotation = "t"; } return { name: "o:lock", properties: { prefixedAttributes: [ { prefix: "v:", map: { ext: "edit" } } ], rawMap } }; }; function mapNumber(value, startSource, endSource, startTarget, endTarget) { return (value - startSource) / (endSource - startSource) * (endTarget - startTarget) + startTarget; } var getImageData = (image, idx) => { let rawMap; const { recolor, brightness, contrast, id } = image; if (recolor) { rawMap = {}; if (recolor === "Washout" || recolor === "Grayscale") { rawMap.gain = "19661f"; rawMap.blacklevel = "22938f"; } if (recolor === "Black & White" || recolor === "Grayscale") { rawMap.grayscale = "t"; if (recolor === "Black & White") { rawMap.bilevel = "t"; } } } if (!recolor || recolor === "Grayscale") { if (!rawMap) { rawMap = {}; } if (contrast != null && contrast !== 50) { let gain = "1"; if (contrast >= 0) { if (contrast < 50) { gain = String(contrast / 50); } else if (contrast < 100) { gain = String(50 / (100 - contrast)); } else if (contrast === 100) { gain = "2147483647f"; } } rawMap.gain = gain; } if (brightness != null && brightness !== 50) { rawMap.blacklevel = mapNumber(brightness, 0, 100, -0.5, 0.5).toString(); } } return { name: "v:imagedata", properties: { prefixedAttributes: [ { prefix: "o:", map: { relid: `rId${idx}`, title: id } } ], rawMap } }; }; var getShapeType = () => { const formulas = [ "if lineDrawn pixelLineWidth 0", "sum @0 1 0", "sum 0 0 @1", "prod @2 1 2", "prod @3 21600 pixelWidth", "prod @3 21600 pixelHeight", "sum @0 0 1", "prod @6 1 2", "prod @7 21600 pixelWidth", "sum @8 21600 0", "prod @7 21600 pixelHeight", "sum @10 21600 0" ]; return { name: "v:shapetype", properties: { prefixedAttributes: [ { prefix: "o:", map: { spt: "75", preferrelative: "t" } } ], rawMap: { coordsize: "21600,21600", filled: "f", id: "_x0000_t75", path: "m@4@5l@4@11@9@11@9@5xe", stroked: "f" } }, children: [getStroke(), getFormulas(formulas), getPath(), getLock({ aspectratio: true })] }; }; var pixelToPoint = (value) => Math.floor((value ?? 0) * 0.74999943307122); var getShape = (image, idx) => { const { width = 0, height = 0, altText } = image; const imageWidth = pixelToPoint(width); const imageHeight = pixelToPoint(height); return { name: "v:shape", properties: { rawMap: { id: image.headerFooterPosition, "o:spid": "_x0000_s1025", style: `position: absolute; margin-left: 0; margin-top: 10in; margin-bottom: 0; margin-right: 0; width: ${imageWidth}pt; height: ${imageHeight}pt; z-index: ${idx + 1}`, type: "#_x0000_t75", alt: altText } }, children: [getImageData(image, idx + 1), getLock({ rotation: true })] }; }; var vmlDrawingFactory = { getTemplate(params) { const headerFooterImages = XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.get(params.sheetIndex) || []; const children = [ getShapeLayout(), getShapeType(), ...headerFooterImages.map((img, idx) => getShape(img, idx)) ]; return { name: "xml", properties: { prefixedAttributes: [ { prefix: "xmlns:", map: { v: "urn:schemas-microsoft-com:vml", o: "urn:schemas-microsoft-com:office:office", x: "urn:schemas-microsoft-com:office:excel" } } ] }, children }; } }; var vmlDrawing_default = vmlDrawingFactory; var sheetFactory = { getTemplate(name, idx) { const sheetId = (idx + 1).toString(); return { name: "sheet", properties: { rawMap: { name, sheetId, "r:id": `rId${sheetId}` } } }; } }; var sheet_default = sheetFactory; var sheetsFactory = { getTemplate(names) { return { name: "sheets", children: names.map((sheet, idx) => sheet_default.getTemplate(sheet, idx)) }; } }; var sheets_default = sheetsFactory; var workbookFactory = { getTemplate(names, activeTab) { return { name: "workbook", properties: { prefixedAttributes: [ { prefix: "xmlns:", map: { r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships" } } ], rawMap: { xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main" } }, children: [ { name: "bookViews", children: [ { name: "workbookView", properties: { rawMap: { activeTab } } } ] }, sheets_default.getTemplate(names) ] }; } }; var workbook_default = workbookFactory; var getExcelCellWidth = (width) => Math.ceil((width - 12) / 7 + 1); var colFactory = { getTemplate(config) { const { min, max, outlineLevel, s: s2, width, hidden, bestFit } = config; let excelWidth = 1; let customWidth = "0"; if (width > 1) { excelWidth = getExcelCellWidth(width); customWidth = "1"; } return { name: "col", properties: { rawMap: { min, max, outlineLevel: outlineLevel != null ? outlineLevel : undefined, width: excelWidth, style: s2, hidden: hidden ? "1" : "0", bestFit: bestFit ? "1" : "0", customWidth } } }; } }; var column_default = colFactory; var mergeCellFactory = { getTemplate(ref) { return { name: "mergeCell", properties: { rawMap: { ref } } }; } }; var mergeCell_default = mergeCellFactory; var convertLegacyType = (type) => { const t = type.charAt(0).toLowerCase(); return t === "s" ? "inlineStr" : t; }; var cellFactory = { getTemplate(config, idx, currentSheet2) { const { ref, data, styleId } = config; const { type, value } = data || { type: "empty", value: null }; let convertedType = type; if (type === "f") { convertedType = "str"; } else if (type.charAt(0) === type.charAt(0).toUpperCase()) { convertedType = convertLegacyType(type); } const obj = { name: "c", properties: { rawMap: { r: ref, t: convertedType === "empty" ? undefined : convertedType, s: styleId ? getStyleId(styleId, currentSheet2) : undefined } } }; if (convertedType === "empty") { return obj; } let children; if (convertedType === "str" && type === "f") { children = [ { name: "f", textNode: _escapeString(replaceInvisibleCharacters(value)) } ]; } else if (convertedType === "inlineStr") { children = [ { name: "is", children: [ { name: "t", textNode: _escapeString(replaceInvisibleCharacters(value)) } ] } ]; } else { children = [ { name: "v", textNode: value } ]; } return Object.assign({}, obj, { children }); } }; var cell_default = cellFactory; var addEmptyCells = (cells, rowIdx) => { const mergeMap = []; let posCounter = 0; for (let i = 0;i < cells.length; i++) { const cell = cells[i]; if (cell.mergeAcross) { mergeMap.push({ pos: i, excelPos: posCounter }); posCounter += cell.mergeAcross; } posCounter++; } if (mergeMap.length) { for (let i = mergeMap.length - 1;i >= 0; i--) { const mergedCells = []; const cell = cells[mergeMap[i].pos]; for (let j = 1;j <= cell.mergeAcross; j++) { mergedCells.push({ ref: `${getExcelColumnName(mergeMap[i].excelPos + 1 + j)}${rowIdx + 1}`, styleId: cell.styleId, data: { type: "empty", value: null } }); } if (mergedCells.length) { cells.splice(mergeMap[i].pos + 1, 0, ...mergedCells); } } } }; var shouldDisplayCell = (cell) => cell.data?.value !== "" || cell.styleId !== undefined; var rowFactory = { getTemplate(config, idx, currentSheet2) { const { collapsed, hidden, height, outlineLevel, cells = [] } = config; addEmptyCells(cells, idx); const children = cells.filter(shouldDisplayCell).map((cell, idx2) => cell_default.getTemplate(cell, idx2, currentSheet2)); return { name: "row", properties: { rawMap: { r: idx + 1, collapsed: collapsed ? "1" : "0", hidden: hidden ? "1" : "0", ht: height, customHeight: height != null ? "1" : "0", spans: "1:1", outlineLevel: outlineLevel || undefined } }, children }; } }; var row_default = rowFactory; var getMergedCellsAndAddColumnGroups = (rows, cols, suppressColumnOutline) => { const mergedCells = []; const cellsWithCollapsibleGroups = []; rows.forEach((currentRow, rowIdx) => { const cells = currentRow.cells; let merges = 0; let lastCol; cells.forEach((currentCell, cellIdx) => { const min = cellIdx + merges + 1; const start = getExcelColumnName(min); const outputRow = rowIdx + 1; if (currentCell.mergeAcross) { merges += currentCell.mergeAcross; const end = getExcelColumnName(cellIdx + merges + 1); mergedCells.push(`${start}${outputRow}:${end}${outputRow}`); } if (!cols[min - 1]) { cols[min - 1] = {}; } const { collapsibleRanges } = currentCell; if (collapsibleRanges) { collapsibleRanges.forEach((range) => { cellsWithCollapsibleGroups.push([min + range[0], min + range[1]]); }); } lastCol = cols[min - 1]; lastCol.min = min; lastCol.max = min; currentCell.ref = `${start}${outputRow}`; }); }); cellsWithCollapsibleGroups.sort((a, b) => { if (a[0] !== b[0]) { return a[0] - b[0]; } return b[1] - a[1]; }); const rangeMap = /* @__PURE__ */ new Map; const outlineLevel = /* @__PURE__ */ new Map; cellsWithCollapsibleGroups.filter((currentRange) => { const rangeString = currentRange.toString(); const inMap = rangeMap.get(rangeString); if (inMap) { return false; } rangeMap.set(rangeString, true); return true; }).forEach((range) => { const refCol = cols.find((col) => col.min == range[0] && col.max == range[1]); const currentOutlineLevel = outlineLevel.get(range[0]); cols.push({ min: range[0], max: range[1], outlineLevel: suppressColumnOutline ? undefined : currentOutlineLevel || 1, width: (refCol || { width: 100 }).width }); outlineLevel.set(range[0], (currentOutlineLevel || 0) + 1); }); return mergedCells; }; var getPageOrientation = (orientation) => { if (!orientation || orientation !== "Portrait" && orientation !== "Landscape") { return "portrait"; } return orientation.toLocaleLowerCase(); }; var getPageSize = (pageSize) => { if (pageSize == null) { return 1; } const positions = [ "Letter", "Letter Small", "Tabloid", "Ledger", "Legal", "Statement", "Executive", "A3", "A4", "A4 Small", "A5", "A6", "B4", "B5", "Folio", "Envelope", "Envelope DL", "Envelope C5", "Envelope B5", "Envelope C3", "Envelope C4", "Envelope C6", "Envelope Monarch", "Japanese Postcard", "Japanese Double Postcard" ]; const pos = positions.indexOf(pageSize); return pos === -1 ? 1 : pos + 1; }; var replaceHeaderFooterTokens = (value) => { const map = { "&[Page]": "&P", "&[Pages]": "&N", "&[Date]": "&D", "&[Time]": "&T", "&[Tab]": "&A", "&[Path]": "&Z", "&[File]": "&F", "&[Picture]": "&G" }; for (const key of Object.keys(map)) { value = value.replace(key, map[key]); } return value; }; var getHeaderPosition = (position) => { if (position === "Center") { return "C"; } if (position === "Right") { return "R"; } return "L"; }; var applyHeaderFontStyle = (headerString, font) => { if (!font) { return headerString; } headerString += "&""; headerString += font.fontName || "Calibri"; if (font.bold !== font.italic) { headerString += font.bold ? ",Bold" : ",Italic"; } else if (font.bold) { headerString += ",Bold Italic"; } else { headerString += ",Regular"; } headerString += """; if (font.size) { headerString += `&${font.size}`; } if (font.strikeThrough) { headerString += "&S"; } if (font.underline) { headerString += `&${font.underline === "Double" ? "E" : "U"}`; } if (font.color) { headerString += `&K${font.color.replace("#", "").toUpperCase()}`; } return headerString; }; var processHeaderFooterContent = (content, location, rule) => content.reduce((prev, curr, idx) => { const pos = getHeaderPosition(curr.position); const output = applyHeaderFontStyle(`${prev}&${pos}`, curr.font); const PositionMap = ["Left", "Center", "Right"]; if (!curr.position) { curr.position = PositionMap[idx]; } const { image } = curr; if (curr.value === "&[Picture]" && image) { const imagePosition = `${pos}${location}${rule}`; addXlsxHeaderFooterImageToMap(image, imagePosition); } return `${output}${_escapeString(replaceHeaderFooterTokens(curr.value))}`; }, ""); var buildHeaderFooter = (headerFooterConfig) => { const rules = ["all", "first", "even"]; const headersAndFooters = []; rules.forEach((rule) => { const headerFooter = headerFooterConfig[rule]; const namePrefix = rule === "all" ? "odd" : rule; if (!headerFooter) { return; } for (const key of Object.keys(headerFooter)) { const value = headerFooter[key]; const nameSuffix = `${key.charAt(0).toUpperCase()}${key.slice(1)}`; const location = key[0].toUpperCase(); if (value) { const normalizedRule = rule === "all" ? "" : rule.toUpperCase(); headersAndFooters.push({ name: `${namePrefix}${nameSuffix}`, properties: { rawMap: { "xml:space": "preserve" } }, textNode: processHeaderFooterContent(value, location, normalizedRule) }); } } }); return headersAndFooters; }; var addColumns = (columns) => { return (params) => { if (columns.length) { params.children.push({ name: "cols", children: columns.map((column) => column_default.getTemplate(column)) }); } return params; }; }; var addSheetData = (rows, sheetNumber) => { return (params) => { if (rows.length) { params.children.push({ name: "sheetData", children: rows.map((row, idx) => row_default.getTemplate(row, idx, sheetNumber)) }); } return params; }; }; var getPasswordHash = (password) => { const passwordLength = password.length; if (!passwordLength) { return ""; } const passwordArray = new Array(passwordLength + 1); passwordArray[0] = passwordLength; for (let i = 1;i <= passwordLength; i++) { passwordArray[i] = password.charCodeAt(i - 1) & 255; } let verifier = 0; for (let i = passwordArray.length - 1;i >= 0; i--) { const passwordByte = passwordArray[i]; const intermediate1 = (verifier & 16384) === 0 ? 0 : 1; const intermediate2 = verifier << 1 & 32767; verifier = (intermediate1 | intermediate2) ^ passwordByte; } return (verifier ^ 52811).toString(16).toUpperCase().padStart(4, "0"); }; var addSheetProtection = (protectSheet) => { return (params) => { if (!protectSheet) { return params; } const sheetProtection = typeof protectSheet === "boolean" ? {} : protectSheet; const rawMap = { sheet: 1 }; const passwordHash = sheetProtection.password ? getPasswordHash(sheetProtection.password) : ""; if (passwordHash) { rawMap.password = passwordHash; } const defaults = { autoFilter: false, deleteColumns: false, deleteRows: false, formatCells: false, formatColumns: false, formatRows: false, insertColumns: false, insertHyperlinks: false, insertRows: false, pivotTables: false, selectLockedCells: true, selectUnlockedCells: true }; Object.keys(defaults).forEach((key) => { const allow = sheetProtection[key]; if (allow == null || allow === defaults[key]) { return; } rawMap[key] = allow ? 0 : 1; }); params.children.push({ name: "sheetProtection", properties: { rawMap } }); return params; }; }; var addMergeCells = (mergeCells) => { return (params) => { if (mergeCells.length) { params.children.push({ name: "mergeCells", properties: { rawMap: { count: mergeCells.length } }, children: mergeCells.map((mergedCell) => mergeCell_default.getTemplate(mergedCell)) }); } return params; }; }; var addPageMargins = (margins) => { return (params) => { const { top = 0.75, right = 0.7, bottom = 0.75, left = 0.7, header = 0.3, footer = 0.3 } = margins; params.children.push({ name: "pageMargins", properties: { rawMap: { bottom, footer, header, left, right, top } } }); return params; }; }; var addPageSetup = (pageSetup) => { return (params) => { if (pageSetup) { params.children.push({ name: "pageSetup", properties: { rawMap: { horizontalDpi: 0, verticalDpi: 0, orientation: getPageOrientation(pageSetup.orientation), paperSize: getPageSize(pageSetup.pageSize) } } }); } return params; }; }; var addHeaderFooter = (headerFooterConfig) => { return (params) => { if (!headerFooterConfig) { return params; } const differentFirst = headerFooterConfig.first != null ? 1 : 0; const differentOddEven = headerFooterConfig.even != null ? 1 : 0; params.children.push({ name: "headerFooter", properties: { rawMap: { differentFirst, differentOddEven } }, children: buildHeaderFooter(headerFooterConfig) }); return params; }; }; var addExcelTableRel = (excelTable) => { return (params) => { if (excelTable) { params.children.push({ name: "tableParts", properties: { rawMap: { count: "1" } }, children: [ { name: "tablePart", properties: { rawMap: { "r:id": `rId${++params.rIdCounter}` } } } ] }); } return params; }; }; var addDrawingRel = (currentSheet2) => { return (params) => { const worksheetImages = XLSX_WORKSHEET_IMAGES.get(currentSheet2); if (worksheetImages?.length) { params.children.push({ name: "drawing", properties: { rawMap: { "r:id": `rId${++params.rIdCounter}` } } }); } return params; }; }; var addVmlDrawingRel = (currentSheet2) => { return (params) => { if (XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.get(currentSheet2)) { params.children.push({ name: "legacyDrawingHF", properties: { rawMap: { "r:id": `rId${++params.rIdCounter}` } } }); } return params; }; }; var getPane = (xSplit = 0, ySplit = 0) => { const shouldSplit = xSplit > 0 || ySplit > 0; return shouldSplit ? [ { name: "pane", properties: { rawMap: { state: shouldSplit ? "frozen" : undefined, topLeftCell: shouldSplit ? `${getExcelColumnName(xSplit + 1)}${ySplit + 1}` : undefined, xSplit: xSplit === 0 ? undefined : xSplit, ySplit: ySplit === 0 ? undefined : ySplit } } } ] : undefined; }; var addSheetViews = (rtl = false, xSplit, ySplit) => { return (params) => { params.children.push({ name: "sheetViews", children: [ { name: "sheetView", properties: { rawMap: { rightToLeft: rtl === true ? "1" : "0", workbookViewId: "0" } }, children: getPane(xSplit, ySplit) } ] }); return params; }; }; var addSheetPr = () => { return (params) => { params.children.push({ name: "sheetPr", children: [ { name: "outlinePr", properties: { rawMap: { summaryBelow: 0 } } } ] }); return params; }; }; var addSheetFormatPr = (rows) => { return (params) => { const maxOutline = rows.reduce((prev, row) => { if (row.outlineLevel && row.outlineLevel > prev) { return row.outlineLevel; } return prev; }, 0); params.children.push({ name: "sheetFormatPr", properties: { rawMap: { baseColWidth: 10, defaultRowHeight: 16, outlineLevelRow: maxOutline ? maxOutline : undefined } } }); return params; }; }; var worksheetFactory = { getTemplate(params) { const { worksheet, currentSheet: currentSheet2, config } = params; const { margins = {}, pageSetup, headerFooterConfig, suppressColumnOutline, rightToLeft, frozenRowCount, frozenColumnCount, protectSheet } = config; const { table } = worksheet; const { rows, columns } = table; const mergedCells = columns?.length ? getMergedCellsAndAddColumnGroups(rows, columns, !!suppressColumnOutline) : []; const worksheetExcelTables = XLSX_WORKSHEET_DATA_TABLES.get(currentSheet2); const { children } = [ addSheetPr(), addSheetViews(rightToLeft, frozenColumnCount, frozenRowCount), addSheetFormatPr(rows), addColumns(columns), addSheetData(rows, currentSheet2 + 1), addSheetProtection(protectSheet), addMergeCells(mergedCells), addPageMargins(margins), addPageSetup(pageSetup), addHeaderFooter(headerFooterConfig), addDrawingRel(currentSheet2), addVmlDrawingRel(currentSheet2), addExcelTableRel(worksheetExcelTables) ].reduce((composed, f) => f(composed), { children: [], rIdCounter: 0 }); return { name: "worksheet", properties: { prefixedAttributes: [ { prefix: "xmlns:", map: { r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships" } } ], rawMap: { xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main" } }, children }; } }; var worksheet_default = worksheetFactory; var XLSX_SHARED_STRINGS = /* @__PURE__ */ new Map; var XLSX_SHEET_NAMES = []; var XLSX_SHEET_DATA = []; var XLSX_SHEET_CONTENT_INDICES = /* @__PURE__ */ new Map; var XLSX_IMAGES = /* @__PURE__ */ new Map; var XLSX_WORKSHEET_IMAGES = /* @__PURE__ */ new Map; var XLSX_WORKSHEET_HEADER_FOOTER_IMAGES = /* @__PURE__ */ new Map; var XLSX_WORKBOOK_IMAGE_IDS = /* @__PURE__ */ new Map; var XLSX_WORKSHEET_IMAGE_IDS = /* @__PURE__ */ new Map; var XLSX_WORKSHEET_DATA_TABLES = /* @__PURE__ */ new Map; var DEFAULT_TABLE_DISPLAY_NAME = "AG-GRID-TABLE"; var XLSX_FACTORY_MODE = "SINGLE_SHEET"; function getXlsxFactoryMode() { return XLSX_FACTORY_MODE; } function setXlsxFactoryMode(factoryMode) { XLSX_FACTORY_MODE = factoryMode; } function createXlsxExcel(styles, worksheet, config) { addSheetName(worksheet); registerStyles(styles, XLSX_SHEET_NAMES.length); const newConfig = Object.assign({}, config); if (config.exportAsExcelTable && config.pivotModeActive) { _warn(163, { featureName: "pivot mode" }); newConfig.exportAsExcelTable = false; } processTableConfig(worksheet, newConfig); const worksheetXml = createWorksheet(worksheet, newConfig); registerSheetXml(worksheetXml); return worksheetXml; } function getXlsxSanitizedTableName(name) { return name.replace(/^[^a-zA-Z_]+/, "_").replace(/\s/g, "_").replace(/[^a-zA-Z0-9_]/g, "_"); } function addXlsxTableToSheet(sheetIndex, table) { if (XLSX_WORKSHEET_DATA_TABLES.has(sheetIndex)) { _warn(164); return; } XLSX_WORKSHEET_DATA_TABLES.set(sheetIndex, table); } function processTableConfig(worksheet, config) { const { exportAsExcelTable, prependContent, appendContent, headerRowCount = 0 } = config; if (!exportAsExcelTable) { return; } const tableConfig = typeof exportAsExcelTable === "boolean" ? {} : exportAsExcelTable; const { name, showColumnStripes, showRowStripes, showFilterButton, highlightFirstColumn, highlightLastColumn } = tableConfig; const tableName = getXlsxSanitizedTableName(name || DEFAULT_TABLE_DISPLAY_NAME); const sheetIndex = XLSX_SHEET_NAMES.length - 1; const { table } = worksheet; const { rows, columns } = table; const skipTopRows = prependContent ? prependContent.length : 0; const removeFromBottom = appendContent ? appendContent.length : 0; const tableRowCount = rows.length; const tableColCount = columns.length; const tableColumns = []; const showFilterButtons = []; for (let i = 0;i < tableColCount; i++) { const col = columns[i]; tableColumns.push(col.displayName || ""); showFilterButtons.push(showFilterButton === "match" || showFilterButton === undefined ? col.filterAllowed ?? false : showFilterButton); } if (!tableColumns?.length || !tableRowCount || !tableName) { _warn(165); return; } addXlsxTableToSheet(sheetIndex, { name: `table${XLSX_WORKSHEET_DATA_TABLES.size + 1}`, displayName: tableName, columns: tableColumns, showFilterButtons, rowRange: [headerRowCount + skipTopRows, headerRowCount + (tableRowCount - headerRowCount) - removeFromBottom], showRowStripes: showRowStripes ?? true, showColumnStripes: showColumnStripes ?? false, highlightFirstColumn: highlightFirstColumn ?? false, highlightLastColumn: highlightLastColumn ?? false }); } function addXlsxHeaderFooterImageToMap(image, position) { const sheetIndex = XLSX_SHEET_NAMES.length - 1; const headerFooterImage = image; headerFooterImage.headerFooterPosition = position; buildImageMap({ imageToAdd: headerFooterImage, idx: sheetIndex }); let headerFooterImagesForSheet = XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.get(sheetIndex); if (!headerFooterImagesForSheet) { headerFooterImagesForSheet = []; XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.set(sheetIndex, headerFooterImagesForSheet); } if (!headerFooterImagesForSheet.find((img) => img.id === image.id)) { headerFooterImagesForSheet.push(image); } } function addXlsxBodyImageToMap(image, rowIndex, col, columnsToExport, rowHeight) { const sheetIndex = XLSX_SHEET_NAMES.length; const { row, column } = image.position || {}; const calculatedImage = image; if (columnsToExport) { if (rowIndex != null && col != null && (!row || !column)) { if (!image.position) { image.position = {}; } image.position = Object.assign({}, image.position, { row: rowIndex, column: columnsToExport.indexOf(col) + 1 }); } setExcelImageTotalWidth(calculatedImage, columnsToExport); setExcelImageTotalHeight(calculatedImage, rowHeight); } buildImageMap({ imageToAdd: calculatedImage, idx: sheetIndex }); let worksheetImageIdMap = XLSX_WORKSHEET_IMAGE_IDS.get(sheetIndex); if (!worksheetImageIdMap) { worksheetImageIdMap = /* @__PURE__ */ new Map; XLSX_WORKSHEET_IMAGE_IDS.set(sheetIndex, worksheetImageIdMap); } const sheetImages = XLSX_WORKSHEET_IMAGES.get(sheetIndex); if (!sheetImages) { XLSX_WORKSHEET_IMAGES.set(sheetIndex, [calculatedImage]); } else { sheetImages.push(calculatedImage); } if (!worksheetImageIdMap.get(image.id)) { worksheetImageIdMap.set(image.id, { index: worksheetImageIdMap.size, type: image.imageType }); } } function buildImageMap(params) { const { imageToAdd, idx } = params; const mappedImagesToSheet = XLSX_IMAGES.get(imageToAdd.id); if (mappedImagesToSheet) { const currentSheetImages = mappedImagesToSheet.find((currentImage) => currentImage.sheetId === idx); if (currentSheetImages) { currentSheetImages.image.push(imageToAdd); } else { mappedImagesToSheet.push({ sheetId: idx, image: [imageToAdd] }); } } else { XLSX_IMAGES.set(imageToAdd.id, [{ sheetId: idx, image: [imageToAdd] }]); XLSX_WORKBOOK_IMAGE_IDS.set(imageToAdd.id, { type: imageToAdd.imageType, index: XLSX_WORKBOOK_IMAGE_IDS.size }); } } function addSheetName(worksheet) { const name = _escapeString(worksheet.name) || ""; let append = ""; while (XLSX_SHEET_NAMES.indexOf(`${name}${append}`) !== -1) { if (append === "") { append = "_1"; } else { const curr = parseInt(append.slice(1), 10); append = `_${curr + 1}`; } } worksheet.name = `${name}${append}`; XLSX_SHEET_NAMES.push(worksheet.name); } function getXlsxStringPosition(str) { if (XLSX_SHARED_STRINGS.has(str)) { return XLSX_SHARED_STRINGS.get(str); } XLSX_SHARED_STRINGS.set(str, XLSX_SHARED_STRINGS.size); return XLSX_SHARED_STRINGS.size - 1; } function resetXlsxFactory() { XLSX_SHARED_STRINGS.clear(); XLSX_IMAGES.clear(); XLSX_WORKSHEET_IMAGES.clear(); XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.clear(); XLSX_WORKBOOK_IMAGE_IDS.clear(); XLSX_WORKSHEET_IMAGE_IDS.clear(); XLSX_WORKSHEET_DATA_TABLES.clear(); XLSX_SHEET_NAMES = []; XLSX_SHEET_DATA = []; XLSX_SHEET_CONTENT_INDICES = /* @__PURE__ */ new Map; XLSX_FACTORY_MODE = "SINGLE_SHEET"; } function createXlsxWorkbook(currentSheet2) { return createXmlPart(workbook_default.getTemplate(XLSX_SHEET_NAMES, currentSheet2)); } function createXlsxStylesheet(defaultFontSize) { return createXmlPart(stylesheet_default.getTemplate(defaultFontSize)); } function createXlsxSharedStrings() { return createXmlPart(sharedStrings_default.getTemplate(XLSX_SHARED_STRINGS)); } function createXlsxCore(author) { return createXmlPart(core_default2.getTemplate(author)); } function createXlsxCustomProperties(metadata) { return createXmlPart(customProperties_default.getTemplate(metadata)); } function createXlsxContentTypes(sheetLen, hasCustomProperties) { return createXmlPart(contentTypes_default.getTemplate({ sheetLen, hasCustomProperties })); } function createXlsxRels(hasCustomProperties) { const relationships = [ { Id: "rId1", Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", Target: "xl/workbook.xml" }, { Id: "rId2", Type: "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties", Target: "docProps/core.xml" } ]; if (hasCustomProperties) { relationships.push({ Id: "rId3", Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties", Target: "docProps/custom.xml" }); } const rs = relationships_default.getTemplate(relationships); return createXmlPart(rs); } function createXlsxTheme() { return createXmlPart(office_default.getTemplate()); } function createXlsxTable(dataTable, index) { return createXmlPart(table_default.getTemplate(dataTable, index)); } function createXlsxWorkbookRels(sheetLen) { const worksheets = new Array(sheetLen).fill(undefined).map((v, i) => ({ Id: `rId${i + 1}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", Target: `worksheets/sheet${i + 1}.xml` })); const rs = relationships_default.getTemplate([ ...worksheets, { Id: `rId${sheetLen + 1}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", Target: "theme/theme1.xml" }, { Id: `rId${sheetLen + 2}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", Target: "styles.xml" }, { Id: `rId${sheetLen + 3}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", Target: "sharedStrings.xml" } ]); return createXmlPart(rs); } function createXlsxDrawing(sheetIndex) { return createXmlPart(drawing_default.getTemplate({ sheetIndex })); } function createXlsxDrawingRel(sheetIndex) { const worksheetImageIds = XLSX_WORKSHEET_IMAGE_IDS.get(sheetIndex) || []; const XMLArr = []; for (const [key, value] of worksheetImageIds) { const { index, type } = value; XMLArr.push({ Id: `rId${index + 1}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", Target: `../media/image${XLSX_WORKBOOK_IMAGE_IDS.get(key).index + 1}.${_normaliseImageExtension(type)}` }); } return createXmlPart(relationships_default.getTemplate(XMLArr)); } function createXlsxVmlDrawing(sheetIndex) { return createXmlPart(vmlDrawing_default.getTemplate({ sheetIndex }), true); } function createXlsxVmlDrawingRel(sheetIndex) { const worksheetHeaderFooterImages = XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.get(sheetIndex) || []; const XMLArr = []; for (let i = 0;i < worksheetHeaderFooterImages.length; i++) { const headerFooterImage = worksheetHeaderFooterImages[i]; const workbookImage = XLSX_WORKBOOK_IMAGE_IDS.get(headerFooterImage.id); if (!workbookImage) { continue; } const { index, type } = workbookImage; XMLArr.push({ Id: `rId${i + 1}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", Target: `../media/image${index + 1}.${_normaliseImageExtension(type)}` }); } return createXmlPart(relationships_default.getTemplate(XMLArr)); } function createXlsxRelationships({ drawingIndex, vmlDrawingIndex, tableName } = {}) { if (drawingIndex === undefined && vmlDrawingIndex === undefined && tableName === undefined) { return ""; } const config = []; if (drawingIndex != null) { config.push({ Id: `rId${config.length + 1}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing", Target: `../drawings/drawing${drawingIndex + 1}.xml` }); } if (vmlDrawingIndex != null) { config.push({ Id: `rId${config.length + 1}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing", Target: `../drawings/vmlDrawing${vmlDrawingIndex + 1}.vml` }); } if (tableName != null) { config.push({ Id: `rId${config.length + 1}`, Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table", Target: `../tables/${tableName}.xml` }); } const rs = relationships_default.getTemplate(config); return createXmlPart(rs); } function createWorksheet(worksheet, config) { return createXmlPart(worksheet_default.getTemplate({ worksheet, currentSheet: XLSX_SHEET_NAMES.length - 1, config })); } var reorderSheetSpecificMap = (map, order) => { if (!map.size) { return; } const remapped = /* @__PURE__ */ new Map; order.forEach((originalIdx, newIdx) => { if (map.has(originalIdx)) { remapped.set(newIdx, map.get(originalIdx)); } }); map.clear(); remapped.forEach((value, key) => map.set(key, value)); }; var registerSheetXml = (worksheetXml) => { const indices = XLSX_SHEET_CONTENT_INDICES.get(worksheetXml) ?? []; indices.push(XLSX_SHEET_NAMES.length - 1); XLSX_SHEET_CONTENT_INDICES.set(worksheetXml, indices); XLSX_SHEET_DATA.push(worksheetXml); }; var getSheetOrderFromRefs = (data) => { const refMap = new Map(XLSX_SHEET_CONTENT_INDICES); const order = []; for (const sheetData of data) { const indices = refMap.get(sheetData); if (!indices?.length) { return null; } const idx = indices.shift(); order.push(idx); refMap.set(sheetData, indices); } return order; }; var getSheetOrderFromData = (data) => { if (!data.length || XLSX_SHEET_DATA.length === 0) { return null; } const consumed = /* @__PURE__ */ new Set; const order = []; for (const sheetData of data) { const matchIndex = XLSX_SHEET_DATA.findIndex((value, idx) => !consumed.has(idx) && value === sheetData); if (matchIndex === -1) { return null; } consumed.add(matchIndex); order.push(matchIndex); } return order; }; var reorderSheetState = (order) => { const indexRemap = /* @__PURE__ */ new Map; order.forEach((originalIdx, newIdx) => indexRemap.set(originalIdx, newIdx)); XLSX_SHEET_NAMES = order.map((idx) => XLSX_SHEET_NAMES[idx]); XLSX_SHEET_DATA = order.map((idx) => XLSX_SHEET_DATA[idx]); reorderSheetSpecificMap(XLSX_WORKSHEET_IMAGES, order); reorderSheetSpecificMap(XLSX_WORKSHEET_HEADER_FOOTER_IMAGES, order); reorderSheetSpecificMap(XLSX_WORKSHEET_DATA_TABLES, order); reorderSheetSpecificMap(XLSX_WORKSHEET_IMAGE_IDS, order); XLSX_IMAGES.forEach((sheetImages) => { sheetImages.forEach((entry) => { const remappedId = indexRemap.get(entry.sheetId); if (remappedId != null) { entry.sheetId = remappedId; } }); }); XLSX_SHEET_CONTENT_INDICES = /* @__PURE__ */ new Map; XLSX_SHEET_DATA.forEach((xml, idx) => { const indices = XLSX_SHEET_CONTENT_INDICES.get(xml) ?? []; indices.push(idx); XLSX_SHEET_CONTENT_INDICES.set(xml, indices); }); }; var syncXlsxOrderWithSheetData = (data) => { if (data.length <= 1) { return; } const order = getSheetOrderFromRefs(data) ?? getSheetOrderFromData(data); if (!order) { return; } reorderSheetState(order); }; var Workbook = class { getStringPosition(str) { return getXlsxStringPosition(str); } addBodyImageToMap(image, rowIndex, col, columnsToExport, rowHeight) { addXlsxBodyImageToMap(image, rowIndex, col, columnsToExport, rowHeight); } addHeaderFooterImageToMap(image, position) { addXlsxHeaderFooterImageToMap(image, position); } addWorksheet(styles, worksheet, config) { return createXlsxExcel(styles, worksheet, config); } syncOrderWithSheetData(data) { syncXlsxOrderWithSheetData(data); } reset() { resetXlsxFactory(); } setFactoryMode(factoryMode) { setXlsxFactoryMode(factoryMode); } getFactoryMode() { return getXlsxFactoryMode(); } getSheetNames() { return [...XLSX_SHEET_NAMES]; } }; var compressBlob = async (data) => { let chunksSize = 0; const chunks = []; const writeCompressedData = new WritableStream({ write: (chunk) => { chunks.push(chunk); chunksSize += chunk.length; } }); const readable = new ReadableStream({ start: (controller) => { const reader = new FileReader; reader.onload = (e) => { if (e.target?.result) { controller.enqueue(e.target.result); } controller.close(); }; reader.readAsArrayBuffer(data); } }); const compressStream = new window.CompressionStream("deflate-raw"); await readable.pipeThrough(compressStream).pipeTo(writeCompressedData); return { size: chunksSize, content: new Blob(chunks) }; }; var deflateLocalFile = async (rawContent) => { const contentAsBlob = new Blob([rawContent]); const { size: compressedSize, content: compressedContent } = await compressBlob(contentAsBlob); const compressedContentAsUint8Array = new Uint8Array(await compressedContent.arrayBuffer()); return { size: compressedSize, content: compressedContentAsUint8Array }; }; var convertTime = (date) => { let time = date.getHours(); time <<= 6; time = time | date.getMinutes(); time <<= 5; time = time | date.getSeconds() / 2; return time; }; var convertDate = (date) => { let dt = date.getFullYear() - 1980; dt <<= 4; dt = dt | date.getMonth() + 1; dt <<= 5; dt = dt | date.getDate(); return dt; }; function convertDecToHex(number, bytes) { let hex = ""; for (let i = 0;i < bytes; i++) { hex += String.fromCharCode(number & 255); number >>>= 8; } return hex; } var getCrcFromCrc32TableAndByteArray = (content) => { if (!content.length) { return 0; } let crc = 0 ^ -1; let j = 0; let k = 0; let l = 0; for (let i = 0;i < content.length; i++) { j = content[i]; k = (crc ^ j) & 255; l = crcTable[k]; crc = crc >>> 8 ^ l; } return crc ^ -1; }; var getCrcFromCrc32Table = (content) => { if (!content.length) { return 0; } if (typeof content === "string") { return getCrcFromCrc32TableAndByteArray(new TextEncoder().encode(content)); } return getCrcFromCrc32TableAndByteArray(content); }; var crcTable = /* @__PURE__ */ new Uint32Array([ 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117 ]); function _utf8_encode(s2) { const stringFromCharCode = String.fromCharCode; function ucs2decode(string) { const output = []; if (!string) { return []; } const len = string.length; let counter = 0; let value; let extra; while (counter < len) { value = string.charCodeAt(counter++); if (value >= 55296 && value <= 56319 && counter < len) { extra = string.charCodeAt(counter++); if ((extra & 64512) == 56320) { output.push(((value & 1023) << 10) + (extra & 1023) + 65536); } else { output.push(value); counter--; } } else { output.push(value); } } return output; } function checkScalarValue(point) { if (point >= 55296 && point <= 57343) { throw new Error(_errMsg(255, { point })); } } function createByte(point, shift) { return stringFromCharCode(point >> shift & 63 | 128); } function encodeCodePoint(point) { if ((point & 4294967168) == 0) { return stringFromCharCode(point); } let symbol = ""; if ((point & 4294965248) == 0) { symbol = stringFromCharCode(point >> 6 & 31 | 192); } else if ((point & 4294901760) == 0) { checkScalarValue(point); symbol = stringFromCharCode(point >> 12 & 15 | 224); symbol += createByte(point, 6); } else if ((point & 4292870144) == 0) { symbol = stringFromCharCode(point >> 18 & 7 | 240); symbol += createByte(point, 12); symbol += createByte(point, 6); } symbol += stringFromCharCode(point & 63 | 128); return symbol; } const codePoints = ucs2decode(s2); const length = codePoints.length; let index = -1; let codePoint; let byteString = ""; while (++index < length) { codePoint = codePoints[index]; byteString += encodeCodePoint(codePoint); } return byteString; } var getHeaders = (currentFile, isCompressed, offset, rawSize, rawContent, deflatedSize) => { const { content, path, created: creationDate } = currentFile; const time = convertTime(creationDate); const dt = convertDate(creationDate); const crcFlag = getCrcFromCrc32Table(rawContent); const zipSize = deflatedSize !== undefined ? deflatedSize : rawSize; const utfPath = _utf8_encode(path); const isUTF8 = utfPath !== path; let extraFields = ""; if (isUTF8) { const uExtraFieldPath = convertDecToHex(1, 1) + convertDecToHex(getCrcFromCrc32Table(utfPath), 4) + utfPath; extraFields = "up" + convertDecToHex(uExtraFieldPath.length, 2) + uExtraFieldPath; } const commonHeader = "\x14\x00" + (isUTF8 ? "\x00\b" : "\x00\x00") + convertDecToHex(isCompressed ? 8 : 0, 2) + convertDecToHex(time, 2) + convertDecToHex(dt, 2) + convertDecToHex(zipSize ? crcFlag : 0, 4) + convertDecToHex(deflatedSize ?? rawSize, 4) + convertDecToHex(rawSize, 4) + convertDecToHex(utfPath.length, 2) + convertDecToHex(extraFields.length, 2); const localFileHeader = "PK\x03\x04" + commonHeader + utfPath + extraFields; const centralDirectoryHeader = "PK\x01\x02\x14\x00" + commonHeader + "\x00\x00\x00\x00\x00\x00" + (content ? "\x00\x00\x00\x00" : "\x10\x00\x00\x00") + convertDecToHex(offset, 4) + utfPath + extraFields; return { localFileHeader: Uint8Array.from(localFileHeader, (c) => c.charCodeAt(0)), centralDirectoryHeader: Uint8Array.from(centralDirectoryHeader, (c) => c.charCodeAt(0)) }; }; var getDecodedContent = (content) => { let contentToUse; if (typeof content === "string") { const base64String = atob(content.split(";base64,")[1]); contentToUse = Uint8Array.from(base64String, (c) => c.charCodeAt(0)); } else { contentToUse = content; } return { size: contentToUse.length, content: contentToUse }; }; var preprocessFileForZip = async (currentFile) => { const { content } = currentFile; const { size: rawSize, content: rawContent } = !content ? { size: 0, content: Uint8Array.from([]) } : getDecodedContent(content); let deflatedContent; let deflatedSize; let deflationPerformed = false; const shouldDeflate = currentFile.type === "file" && rawContent && rawSize > 0; if (shouldDeflate) { const result = await deflateLocalFile(rawContent); deflatedContent = result.content; deflatedSize = result.size; deflationPerformed = true; } return { rawContent, rawSize, deflatedContent, deflatedSize, isCompressed: deflationPerformed }; }; var getHeaderAndContent = (currentFile, offset) => { const { content } = currentFile; const { content: rawContent } = !content ? { content: Uint8Array.from([]) } : getDecodedContent(content); const headers = getHeaders(currentFile, false, offset, rawContent.length, rawContent, undefined); return { ...headers, content: rawContent, isCompressed: false }; }; var buildCentralDirectoryEnd = (tLen, cLen, lLen) => { const str = "PK\x05\x06\x00\x00\x00\x00" + convertDecToHex(tLen, 2) + convertDecToHex(tLen, 2) + convertDecToHex(cLen, 4) + convertDecToHex(lLen, 4) + "\x00\x00"; return Uint8Array.from(str, (c) => c.charCodeAt(0)); }; var ZipContainer = class { constructor() { this.folders = []; this.files = []; } addFolders(paths) { paths.forEach(this.addFolder.bind(this)); } addFolder(path) { this.folders.push({ path, created: /* @__PURE__ */ new Date, isBase64: false, type: "folder" }); } addFile(path, content, isBase64 = false) { this.files.push({ path, created: /* @__PURE__ */ new Date, content: isBase64 ? content : new TextEncoder().encode(content), isBase64, type: "file" }); } async getZipFile(mimeType = "application/zip") { const textOutput = await this.buildCompressedFileStream(); this.clearStream(); return new Blob([textOutput], { type: mimeType }); } getUncompressedZipFile(mimeType = "application/zip") { const textOutput = this.buildFileStream(); this.clearStream(); return new Blob([textOutput], { type: mimeType }); } clearStream() { this.folders = []; this.files = []; } packageFiles(files) { let fileLen = 0; let folderLen = 0; for (const currentFile of files) { const { localFileHeader, centralDirectoryHeader, content } = currentFile; fileLen += localFileHeader.length + content.length; folderLen += centralDirectoryHeader.length; } const fileData = new Uint8Array(fileLen); const folderData = new Uint8Array(folderLen); let fileOffset = 0; let folderOffset = 0; for (const currentFile of files) { const { localFileHeader, centralDirectoryHeader, content } = currentFile; fileData.set(localFileHeader, fileOffset); fileOffset += localFileHeader.length; fileData.set(content, fileOffset); fileOffset += content.length; folderData.set(centralDirectoryHeader, folderOffset); folderOffset += centralDirectoryHeader.length; } const folderEnd = buildCentralDirectoryEnd(files.length, folderLen, fileLen); const result = new Uint8Array(fileData.length + folderData.length + folderEnd.length); result.set(fileData); result.set(folderData, fileData.length); result.set(folderEnd, fileData.length + folderData.length); return result; } async buildCompressedFileStream() { const totalFiles = [...this.folders, ...this.files]; const preprocessed = await Promise.all(totalFiles.map(preprocessFileForZip)); const processed = []; let offset = 0; for (let i = 0;i < totalFiles.length; i++) { const currentFile = totalFiles[i]; const { rawContent, rawSize, deflatedContent, deflatedSize, isCompressed } = preprocessed[i]; const headers = getHeaders(currentFile, isCompressed, offset, rawSize, rawContent, deflatedSize); const contentToUse = deflatedContent ?? rawContent; processed.push({ ...headers, content: contentToUse, isCompressed }); offset += headers.localFileHeader.length + contentToUse.length; } return this.packageFiles(processed); } buildFileStream() { const totalFiles = [...this.folders, ...this.files]; const readyFiles = []; let lL = 0; for (const currentFile of totalFiles) { const readyFile = getHeaderAndContent(currentFile, lL); const { localFileHeader, content } = readyFile; readyFiles.push(readyFile); lL += localFileHeader.length + content.length; } return this.packageFiles(readyFiles); } }; var createExcelXMLCoreFolderStructure = (zipContainer) => { zipContainer.addFolders(["_rels/", "docProps/", "xl/", "xl/theme/", "xl/_rels/", "xl/worksheets/"]); if (!XLSX_IMAGES.size) { return; } zipContainer.addFolders(["xl/worksheets/_rels", "xl/drawings/", "xl/drawings/_rels", "xl/media/"]); let imgCounter = 0; XLSX_IMAGES.forEach((value) => { const firstImage = value[0].image[0]; const { base64, imageType } = firstImage; zipContainer.addFile(`xl/media/image${++imgCounter}.${_normaliseImageExtension(imageType)}`, base64, true); }); }; var createExcelXmlWorksheets = (zipContainer, data) => { let imageRelationCounter = 0; let headerFooterImageCounter = 0; for (let i = 0;i < data.length; i++) { const value = data[i]; zipContainer.addFile(`xl/worksheets/sheet${i + 1}.xml`, value, false); const hasImages = XLSX_IMAGES.size > 0 && XLSX_WORKSHEET_IMAGES.has(i); const tableData = XLSX_WORKSHEET_DATA_TABLES.size > 0 && XLSX_WORKSHEET_DATA_TABLES.get(i); const hasHeaderFooterImages = XLSX_IMAGES.size && XLSX_WORKSHEET_HEADER_FOOTER_IMAGES.has(i); if (!hasImages && !tableData && !hasHeaderFooterImages) { continue; } let tableName; let drawingIndex; let vmlDrawingIndex; if (hasImages) { createExcelXmlDrawings(zipContainer, i, imageRelationCounter); drawingIndex = imageRelationCounter; imageRelationCounter++; } if (hasHeaderFooterImages) { createExcelVmlDrawings(zipContainer, i, headerFooterImageCounter); vmlDrawingIndex = headerFooterImageCounter; headerFooterImageCounter++; } if (tableData) { tableName = tableData.name; } const worksheetRelFile = `xl/worksheets/_rels/sheet${i + 1}.xml.rels`; zipContainer.addFile(worksheetRelFile, createXlsxRelationships({ tableName, drawingIndex, vmlDrawingIndex })); } }; var createExcelXmlDrawings = (zipContainer, sheetIndex, drawingIndex) => { const drawingFolder = "xl/drawings"; const drawingFileName = `${drawingFolder}/drawing${drawingIndex + 1}.xml`; const relFileName = `${drawingFolder}/_rels/drawing${drawingIndex + 1}.xml.rels`; zipContainer.addFile(relFileName, createXlsxDrawingRel(sheetIndex)); zipContainer.addFile(drawingFileName, createXlsxDrawing(sheetIndex)); }; var createExcelVmlDrawings = (zipContainer, sheetIndex, drawingIndex) => { const drawingFolder = "xl/drawings"; const drawingFileName = `${drawingFolder}/vmlDrawing${drawingIndex + 1}.vml`; const relFileName = `${drawingFolder}/_rels/vmlDrawing${drawingIndex + 1}.vml.rels`; zipContainer.addFile(drawingFileName, createXlsxVmlDrawing(sheetIndex)); zipContainer.addFile(relFileName, createXlsxVmlDrawingRel(sheetIndex)); }; var createExcelXmlTables = (zipContainer) => { const tablesDataByWorksheet = XLSX_WORKSHEET_DATA_TABLES; const worksheetKeys = Array.from(tablesDataByWorksheet.keys()); for (let i = 0;i < worksheetKeys.length; i++) { const sheetIndex = worksheetKeys[i]; const table = tablesDataByWorksheet.get(sheetIndex); if (!table) { continue; } zipContainer.addFile(`xl/tables/${table.name}.xml`, createXlsxTable(table, i)); } }; var createExcelXmlCoreSheets = (zipContainer, fontSize, author, sheetLen, activeTab, customMetadata) => { const hasCustomMetadata = !!customMetadata && Object.keys(customMetadata).some((key) => customMetadata[key] != null); zipContainer.addFile("xl/workbook.xml", createXlsxWorkbook(activeTab)); zipContainer.addFile("xl/styles.xml", createXlsxStylesheet(fontSize)); zipContainer.addFile("xl/sharedStrings.xml", createXlsxSharedStrings()); zipContainer.addFile("xl/theme/theme1.xml", createXlsxTheme()); zipContainer.addFile("xl/_rels/workbook.xml.rels", createXlsxWorkbookRels(sheetLen)); zipContainer.addFile("docProps/core.xml", createXlsxCore(author)); if (hasCustomMetadata) { zipContainer.addFile("docProps/custom.xml", createXlsxCustomProperties(customMetadata)); } zipContainer.addFile("[Content_Types].xml", createXlsxContentTypes(sheetLen, hasCustomMetadata)); zipContainer.addFile("_rels/.rels", createXlsxRels(hasCustomMetadata)); }; var createExcelFileForExcel = (zipContainer, data, options = {}, workbook) => { if (!data || data.length === 0) { _warn(159); workbook.reset(); return false; } workbook.syncOrderWithSheetData(data); const { fontSize = 11, author = "AG Grid", activeTab = 0, customMetadata } = options; const len = data.length; const activeTabWithinBounds = Math.max(Math.min(activeTab, len - 1), 0); createExcelXMLCoreFolderStructure(zipContainer); createExcelXmlTables(zipContainer); createExcelXmlWorksheets(zipContainer, data); createExcelXmlCoreSheets(zipContainer, fontSize, author, len, activeTabWithinBounds, customMetadata); workbook.reset(); return true; }; var getMultipleSheetsAsExcelCompressed = (params, workbook = new Workbook) => { const { data, fontSize, author, activeSheetIndex, customMetadata } = params; const mimeType = params.mimeType || "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; const zipContainer = new ZipContainer; if (!createExcelFileForExcel(zipContainer, data, { author, fontSize, activeTab: activeSheetIndex, customMetadata }, workbook)) { return Promise.resolve(undefined); } return zipContainer.getZipFile(mimeType); }; var getMultipleSheetsAsExcel = (params, workbook = new Workbook) => { const { data, fontSize, author, activeSheetIndex: activeTab, customMetadata } = params; const mimeType = params.mimeType || "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; const zipContainer = new ZipContainer; if (!createExcelFileForExcel(zipContainer, data, { author, fontSize, activeTab, customMetadata }, workbook)) { return; } return zipContainer.getUncompressedZipFile(mimeType); }; var ExcelCreator = class extends BaseCreator { constructor() { super(...arguments); this.beanName = "excelCreator"; this.workbook = new Workbook; } getMergedParams(params) { const baseParams6 = this.gos.get("defaultExcelExportParams"); return Object.assign({}, baseParams6, params); } export(userParams) { if (this.isExportSuppressed()) { _warn(160); return; } const exportFunc = () => { const mergedParams = this.getMergedParams(userParams); const data = this.getData(mergedParams); const { fontSize, author, mimeType, customMetadata } = mergedParams; const exportParams = { data: [data], fontSize, author, mimeType, customMetadata }; this.packageCompressedFile(exportParams).then((packageFile) => { if (packageFile) { const { fileName } = mergedParams; const providedFileName = typeof fileName === "function" ? fileName(_addGridCommonParams(this.gos, {})) : fileName; _downloadFile(this.getFileName(providedFileName), packageFile); } }); }; const { overlays } = this.beans; if (overlays) { overlays.showExportOverlay(exportFunc); } else { exportFunc(); } } exportDataAsExcel(params) { this.export(params); } getDataAsExcel(params) { const mergedParams = this.getMergedParams(params); const data = this.getData(mergedParams); const { fontSize, author, mimeType, customMetadata } = mergedParams; const exportParams = { data: [data], fontSize, author, mimeType, customMetadata }; return this.packageFile(exportParams); } setFactoryMode(factoryMode) { this.workbook.setFactoryMode(factoryMode); } getFactoryMode() { return this.workbook.getFactoryMode(); } getSheetDataForExcel(params) { const mergedParams = this.getMergedParams(params); return this.getData(mergedParams); } getMultipleSheetsAsExcel(params) { return getMultipleSheetsAsExcel(params, this.workbook); } exportMultipleSheetsAsExcel(params) { getMultipleSheetsAsExcelCompressed(params, this.workbook).then((contents) => { const { fileName = "export.xlsx" } = params; if (contents) { const downloadFileName = typeof fileName === "function" ? fileName() : fileName; _downloadFile(downloadFileName, contents); } }); } getDefaultFileExtension() { return "xlsx"; } createSerializingSession(params) { const { colModel, colNames, rowGroupColsSvc, valueSvc, formula, gos } = this.beans; const baseExcelStyles = gos.get("excelStyles") || []; const styleLinker = this.createStyleLinker(baseExcelStyles); const config = { ...params, colModel, colNames, rowGroupColsSvc, valueSvc, formulaSvc: formula, gos, suppressRowOutline: params.suppressRowOutline || params.skipRowGroups, headerRowHeight: params.headerRowHeight || params.rowHeight, baseExcelStyles, rightToLeft: params.rightToLeft ?? gos.get("enableRtl"), styleLinker, headerRowCount: getHeaderRowCount(colModel), pivotModeActive: colModel.isPivotActive(), workbook: this.workbook }; return new ExcelSerializingSession(config); } createStyleLinker(baseExcelStyles) { const styleIds = []; const styleIdsSet = /* @__PURE__ */ new Set; const styleIdOrder = /* @__PURE__ */ new Map; baseExcelStyles.forEach((it, idx) => { styleIds.push(it.id); styleIdsSet.add(it.id); styleIdOrder.set(it.id, idx); }); const { gos, cellStyles } = this.beans; return (params) => { const { rowType, rowIndex, value, column, columnGroup, node } = params; const isHeader = rowType === "HEADER"; const isGroupHeader = rowType === "HEADER_GROUPING"; const col = isHeader ? column : columnGroup; let headerClasses = []; if (isHeader || isGroupHeader) { headerClasses.push("header"); if (isGroupHeader) { headerClasses.push("headerGroup"); } if (col) { headerClasses = headerClasses.concat(_getHeaderClassesFromColDef(col.getDefinition(), gos, column || null, columnGroup || null)); } return headerClasses; } const applicableStyles = ["cell"]; if (!styleIds.length) { return applicableStyles; } const colDef = column.getDefinition(); cellStyles?.processAllCellClasses(colDef, _addGridCommonParams(gos, { value, data: node.data, node, colDef, column, rowIndex }), (className) => { if (styleIdsSet.has(className)) { applicableStyles.push(className); } }); return applicableStyles.sort((left, right) => { const leftIdx = styleIdOrder.get(left) ?? -1; const rightIdx = styleIdOrder.get(right) ?? -1; return leftIdx === rightIdx ? 0 : leftIdx < rightIdx ? -1 : 1; }); }; } isExportSuppressed() { return this.gos.get("suppressExcelExport"); } packageCompressedFile(params) { return getMultipleSheetsAsExcelCompressed(params, this.workbook); } packageFile(params) { return getMultipleSheetsAsExcel(params, this.workbook); } }; var agVirtualList_default = ":where(.ag-virtual-list-viewport) .ag-tab-guard{position:sticky}.ag-virtual-list-viewport{flex:1 1 auto;height:100%;min-width:0;overflow:auto;position:relative;width:100%}.ag-virtual-list-container{overflow:hidden;position:relative}.ag-virtual-list-item{height:var(--ag-list-item-height);position:absolute;width:100%}"; function getVirtualListTemplate(cssIdentifier) { return { tag: "div", cls: `ag-virtual-list-viewport ag-${cssIdentifier}-virtual-list-viewport`, role: "presentation", children: [ { tag: "div", ref: "eContainer", cls: `ag-virtual-list-container ag-${cssIdentifier}-virtual-list-container` } ] }; } var AgVirtualList = class extends AgTabGuardComp { constructor(stopPropagationCallbacks, params) { super(getVirtualListTemplate(params?.cssIdentifier || "default")); this.stopPropagationCallbacks = stopPropagationCallbacks; this.renderedRows = /* @__PURE__ */ new Map; this.rowHeight = 20; this.pageSize = -1; this.isScrolling = false; this.isHeightFromTheme = true; this.eContainer = RefPlaceholder; this.awaitStableCallbacks = []; this.registerCSS(agVirtualList_default); const { cssIdentifier = "default", ariaRole = "listbox", listName, moveItemCallback } = params || {}; this.cssIdentifier = cssIdentifier; this.ariaRole = ariaRole; this.listName = listName; this.moveItemCallback = moveItemCallback; } postConstruct() { this.addScrollListener(); this.rowHeight = this.getItemHeight(); this.addResizeObserver(); this.initialiseTabGuard({ onFocusIn: (e) => this.onFocusIn(e), onFocusOut: (e) => this.onFocusOut(e), focusInnerElement: (fromBottom) => this.focusInnerElement(fromBottom), onTabKeyDown: (e) => this.onTabKeyDown(e), handleKeyDown: (e) => this.handleKeyDown(e) }, this.stopPropagationCallbacks); this.refreshAriaProperties(); this.addManagedEventListeners({ stylesChanged: this.onStylesChanged.bind(this) }); } onStylesChanged(e) { if (e.listItemHeightChanged) { this.rowHeight = this.getItemHeight(); this.refresh(); } } refreshAriaProperties() { const translate = this.getLocaleTextFunc(); const listName = translate("ariaDefaultListName", this.listName || "List"); const ariaEl = this.eContainer; _setAriaRole(ariaEl, this.model?.getRowCount() > 0 ? this.ariaRole : "presentation"); _setAriaLabel(ariaEl, listName); } addResizeObserver() { const listener = () => _requestAnimationFrame(this.beans, () => this.drawVirtualRows()); const destroyObserver = _observeResize(this.beans, this.getGui(), listener); this.addDestroyFunc(destroyObserver); } focusInnerElement(fromBottom) { this.focusRow(fromBottom ? this.model.getRowCount() - 1 : 0); return true; } onFocusIn(e) { const target = e.target; if (target.classList.contains("ag-virtual-list-item")) { this.lastFocusedRowIndex = _getAriaPosInSet(target) - 1; } } onFocusOut(e) { if (!this.getFocusableElement().contains(e.relatedTarget)) { this.lastFocusedRowIndex = null; } } handleKeyDown(e) { const { key, shiftKey } = e; switch (key) { case KeyCode.UP: case KeyCode.DOWN: { const isUp = key === KeyCode.UP; e.preventDefault(); if (shiftKey) { this.moveItem(isUp); } else { this.navigate(isUp); } } break; case KeyCode.PAGE_HOME: case KeyCode.PAGE_END: case KeyCode.PAGE_UP: case KeyCode.PAGE_DOWN: if (this.navigateToPage(key) !== null) { e.preventDefault(); } break; } } onTabKeyDown(e) { this.stopPropagationCallbacks?.stopPropagation(e); this.forceFocusOutOfContainer(e.shiftKey); } getNextRow(up) { if (this.lastFocusedRowIndex == null) { return; } const nextRow = this.lastFocusedRowIndex + (up ? -1 : 1); if (nextRow < 0 || nextRow >= this.model.getRowCount()) { return; } return nextRow; } moveItem(up) { if (!this.moveItemCallback) { return; } const item = this.getComponentAt(this.lastFocusedRowIndex); if (!item) { return; } this.moveItemCallback(item, up); } navigate(up) { const nextRow = this.getNextRow(up); if (nextRow === undefined) { return; } this.focusRow(nextRow); } navigateToPage(key, fromItem = "focused") { let hasFocus = false; if (fromItem === "focused") { fromItem = this.getLastFocusedRow(); hasFocus = true; } const rowCount = this.model.getRowCount() - 1; let newIndex = -1; if (key === KeyCode.PAGE_HOME) { newIndex = 0; } else if (key === KeyCode.PAGE_END) { newIndex = rowCount; } else if (key === KeyCode.PAGE_DOWN) { newIndex = Math.min(fromItem + this.pageSize, rowCount); } else if (key === KeyCode.PAGE_UP) { newIndex = Math.max(fromItem - this.pageSize, 0); } if (newIndex === -1) { return null; } if (hasFocus) { this.focusRow(newIndex); } else { this.ensureIndexVisible(newIndex); } return newIndex; } getLastFocusedRow() { return this.lastFocusedRowIndex; } focusRow(rowNumber) { if (this.isScrolling) { return; } this.isScrolling = true; this.ensureIndexVisible(rowNumber); _requestAnimationFrame(this.beans, () => { this.isScrolling = false; if (!this.isAlive()) { return; } const renderedRow = this.renderedRows.get(rowNumber); if (renderedRow) { renderedRow.eDiv.focus(); } }); } getComponentAt(rowIndex) { const comp = this.renderedRows.get(rowIndex); return comp && comp.rowComponent; } forEachRenderedRow(func) { this.renderedRows.forEach((value, key) => func(value.rowComponent, key)); } getItemHeight() { if (!this.isHeightFromTheme) { return this.rowHeight; } return this.beans.environment.getDefaultListItemHeight(); } ensureIndexVisible(index, scrollPartialIntoView = true) { const lastRow = this.model.getRowCount(); if (typeof index !== "number" || index < 0 || index >= lastRow) { return false; } const rowTopPixel = index * this.rowHeight; const rowBottomPixel = rowTopPixel + this.rowHeight; const eGui = this.getGui(); const viewportTopPixel = eGui.scrollTop; const viewportHeight = eGui.offsetHeight; const viewportBottomPixel = viewportTopPixel + viewportHeight; const diff = scrollPartialIntoView ? 0 : this.rowHeight; const viewportScrolledPastRow = viewportTopPixel > rowTopPixel + diff; const viewportScrolledBeforeRow = viewportBottomPixel < rowBottomPixel - diff; if (viewportScrolledPastRow) { eGui.scrollTop = rowTopPixel; return true; } if (viewportScrolledBeforeRow) { const newScrollPosition = rowBottomPixel - viewportHeight; eGui.scrollTop = newScrollPosition; return true; } return false; } setComponentCreator(componentCreator) { this.componentCreator = componentCreator; } setComponentUpdater(componentUpdater) { this.componentUpdater = componentUpdater; } getRowHeight() { return this.rowHeight; } getScrollTop() { return this.getGui().scrollTop; } setRowHeight(rowHeight) { this.isHeightFromTheme = false; this.rowHeight = rowHeight; this.refresh(); } refresh(softRefresh) { if (this.model == null || !this.isAlive()) { return; } const rowCount = this.model.getRowCount(); this.eContainer.style.height = `${rowCount * this.rowHeight}px`; this.refreshAriaProperties(); this.awaitStable(() => { if (!this.isAlive()) { return; } if (this.canSoftRefresh(softRefresh)) { this.drawVirtualRows(true); } else { this.clearVirtualRows(); this.drawVirtualRows(); } }); } awaitStable(callback) { this.awaitStableCallbacks.push(callback); if (this.awaitStableCallbacks.length > 1) { return; } const rowCount = this.model.getRowCount(); _waitUntil(this, () => this.eContainer.clientHeight >= rowCount * this.rowHeight, () => { if (!this.isAlive()) { return; } const callbacks = this.awaitStableCallbacks; this.awaitStableCallbacks = []; for (const c of callbacks) { c(); } }); } canSoftRefresh(softRefresh) { return !!(softRefresh && this.renderedRows.size && typeof this.model.areRowsEqual === "function" && this.componentUpdater); } clearVirtualRows() { this.renderedRows.forEach((_, rowIndex) => this.removeRow(rowIndex)); } drawVirtualRows(softRefresh) { if (!this.isAlive() || !this.model) { return; } const gui = this.getGui(); const topPixel = gui.scrollTop; const bottomPixel = topPixel + gui.offsetHeight; if (topPixel === bottomPixel) { this.clearVirtualRows(); } else { const firstRow = Math.floor(topPixel / this.rowHeight); const lastRow = Math.floor(bottomPixel / this.rowHeight); this.pageSize = Math.floor((bottomPixel - topPixel) / this.rowHeight); this.ensureRowsRendered(firstRow, lastRow, softRefresh); } } ensureRowsRendered(start, finish, softRefresh) { this.renderedRows.forEach((_, rowIndex) => { if ((rowIndex < start || rowIndex > finish) && rowIndex !== this.lastFocusedRowIndex) { this.removeRow(rowIndex); } }); if (softRefresh) { this.refreshRows(); } for (let rowIndex = start;rowIndex <= finish; rowIndex++) { if (this.renderedRows.has(rowIndex)) { continue; } if (rowIndex < this.model.getRowCount()) { this.insertRow(rowIndex); } } } insertRow(rowIndex) { const { model } = this; if (rowIndex < 0 || rowIndex >= model.getRowCount()) { return; } const { cssIdentifier, ariaRole, renderedRows, eContainer } = this; const value = model.getRow(rowIndex); const role = ariaRole === "tree" ? "treeitem" : "option"; const eDiv = _createAgElement({ tag: "div", cls: `ag-virtual-list-item ag-${cssIdentifier}-virtual-list-item`, role, attrs: { tabindex: "-1" } }); _setAriaSetSize(eDiv, model.getRowCount()); _setAriaPosInSet(eDiv, rowIndex + 1); const rowHeight = this.rowHeight; eDiv.style.height = `${rowHeight}px`; eDiv.style.top = `${rowHeight * rowIndex}px`; const rowComponent = this.componentCreator(value, eDiv); rowComponent.addGuiEventListener("focusin", () => this.lastFocusedRowIndex = rowIndex); eDiv.appendChild(rowComponent.getGui()); if (renderedRows.has(rowIndex - 1)) { renderedRows.get(rowIndex - 1).eDiv.insertAdjacentElement("afterend", eDiv); } else if (renderedRows.has(rowIndex + 1)) { renderedRows.get(rowIndex + 1).eDiv.insertAdjacentElement("beforebegin", eDiv); } else { eContainer.appendChild(eDiv); } renderedRows.set(rowIndex, { rowComponent, eDiv, value }); } removeRow(rowIndex) { const component = this.renderedRows.get(rowIndex); component.eDiv.remove(); this.destroyBean(component.rowComponent); this.renderedRows.delete(rowIndex); } refreshRows() { const rowCount = this.model.getRowCount(); this.renderedRows.forEach((row, rowIndex) => { if (rowIndex >= rowCount) { this.removeRow(rowIndex); } else { const newValue = this.model.getRow(rowIndex); if (this.model.areRowsEqual?.(row.value, newValue)) { this.componentUpdater(newValue, row.rowComponent); } else { this.removeRow(rowIndex); } } }); } addScrollListener() { this.addGuiEventListener("scroll", () => this.drawVirtualRows(), { passive: true }); } setModel(model) { this.model = model; } getAriaElement() { return this.eContainer; } destroy() { if (!this.isAlive()) { return; } this.clearVirtualRows(); this.awaitStableCallbacks.length = 0; super.destroy(); } }; var agVirtualListDragFeature_default = '.ag-list-item-hovered:after{background-color:var(--ag-accent-color);content:"";height:1px;left:0;position:absolute;right:0}.ag-item-highlight-top:after{top:0}.ag-item-highlight-bottom:after{bottom:0}'; var LIST_ITEM_HOVERED = "ag-list-item-hovered"; var AgVirtualListDragFeature = class extends AgBeanStub { constructor(comp, virtualList, params) { super(); this.comp = comp; this.virtualList = virtualList; this.params = params; this.currentDragValue = null; this.lastHoveredListItem = null; } postConstruct() { this.beans.environment.addGlobalCSS(agVirtualListDragFeature_default, "component-AgVirtualListDragFeature"); this.params.addListeners(this, this.listItemDragStart.bind(this), this.listItemDragEnd.bind(this)); this.createDropTarget(); this.createAutoScrollService(); } listItemDragStart(event) { this.currentDragValue = this.params.getCurrentDragValue(event); this.moveBlocked = this.params.isMoveBlocked(this.currentDragValue); } listItemDragEnd() { window.setTimeout(() => { this.currentDragValue = null; this.moveBlocked = false; }, 10); } createDropTarget() { const dropTarget = { isInterestedIn: (type) => type === this.params.dragSourceType, getIconName: () => this.moveBlocked ? "pinned" : "move", getContainer: () => this.comp.getGui(), onDragging: (e) => this.onDragging(e), onDragStop: () => this.onDragStop(), onDragLeave: () => this.onDragLeave(), onDragCancel: () => this.onDragCancel() }; this.beans.dragAndDrop?.addDropTarget(dropTarget); } createAutoScrollService() { const virtualListGui = this.virtualList.getGui(); this.autoScrollService = new AutoScrollService({ scrollContainer: virtualListGui, scrollAxis: "y", getVerticalPosition: () => virtualListGui.scrollTop, setVerticalPosition: (position) => virtualListGui.scrollTop = position }); } onDragging(e) { if (!this.currentDragValue || this.moveBlocked) { return; } const hoveredListItem = this.getListDragItem(e); const comp = this.virtualList.getComponentAt(hoveredListItem.rowIndex); if (!comp) { return; } const el = comp.getGui().parentElement; if (this.lastHoveredListItem && this.lastHoveredListItem.rowIndex === hoveredListItem.rowIndex && this.lastHoveredListItem.position === hoveredListItem.position) { return; } this.autoScrollService.check(e.event); this.clearHoveredItems(); this.lastHoveredListItem = hoveredListItem; _radioCssClass(el, LIST_ITEM_HOVERED); _radioCssClass(el, `ag-item-highlight-${hoveredListItem.position}`); } getListDragItem(e) { const virtualListGui = this.virtualList.getGui(); const paddingTop = Number.parseFloat(window.getComputedStyle(virtualListGui).paddingTop); const rowHeight = this.virtualList.getRowHeight(); const scrollTop = this.virtualList.getScrollTop(); const rowIndex = Math.max(0, (e.y - paddingTop + scrollTop) / rowHeight); const maxLen = this.params.getNumRows(this.comp) - 1; const normalizedRowIndex = Math.min(maxLen, rowIndex) | 0; return { rowIndex: normalizedRowIndex, position: Math.round(rowIndex) > rowIndex || rowIndex > maxLen ? "bottom" : "top", component: this.virtualList.getComponentAt(normalizedRowIndex) }; } onDragStop() { if (this.moveBlocked) { return; } this.params.moveItem(this.currentDragValue, this.lastHoveredListItem); this.clearDragProperties(); } onDragCancel() { this.clearDragProperties(); } onDragLeave() { this.clearDragProperties(); } clearDragProperties() { this.clearHoveredItems(); this.autoScrollService.ensureCleared(); } clearHoveredItems() { const virtualListGui = this.virtualList.getGui(); for (const el of virtualListGui.querySelectorAll(`.${LIST_ITEM_HOVERED}`)) { for (const cls of [LIST_ITEM_HOVERED, "ag-item-highlight-top", "ag-item-highlight-bottom"]) { el.classList.remove(cls); } } this.lastHoveredListItem = null; } }; var agPanel_default = ".ag-panel{background-color:var(--ag-panel-background-color);display:flex;flex-direction:column;overflow:hidden;position:relative}.ag-dialog{border:var(--ag-dialog-border);border-radius:var(--ag-border-radius);box-shadow:var(--ag-dialog-shadow);position:absolute}.ag-panel-title-bar{align-items:center;background-color:var(--ag-panel-title-bar-background-color);border-bottom:var(--ag-panel-title-bar-border);color:var(--ag-panel-title-bar-text-color);cursor:default;display:flex;flex:none;font-family:var(--ag-panel-title-bar-font-family);font-size:var(--ag-panel-title-bar-font-size);font-weight:var(--ag-panel-title-bar-font-weight);height:var(--ag-panel-title-bar-height);padding:var(--ag-spacing) var(--ag-cell-horizontal-padding)}.ag-panel-title-bar-button{cursor:pointer;:where(.ag-icon){color:var(--ag-panel-title-bar-icon-color)}}:where(.ag-ltr) .ag-panel-title-bar-button{margin-left:calc(var(--ag-spacing)*2);margin-right:var(--ag-spacing)}:where(.ag-rtl) .ag-panel-title-bar-button{margin-left:var(--ag-spacing);margin-right:calc(var(--ag-spacing)*2)}.ag-panel-title-bar-title{flex:1 1 auto}.ag-panel-title-bar-buttons{display:flex}.ag-panel-content-wrapper{display:flex;flex:1 1 auto;overflow:hidden;position:relative}:where(.ag-dragging-fill-handle) .ag-dialog,:where(.ag-dragging-range-handle) .ag-dialog{opacity:.7;pointer-events:none}"; function getTemplate(cssIdentifier) { cssIdentifier ?? (cssIdentifier = cssIdentifier || "default"); return { tag: "div", cls: `ag-panel ag-${cssIdentifier}-panel`, attrs: { tabindex: "-1" }, children: [ { tag: "div", ref: "eTitleBar", cls: `ag-panel-title-bar ag-${cssIdentifier}-panel-title-bar ag-unselectable`, children: [ { tag: "span", ref: "eTitle", cls: `ag-panel-title-bar-title ag-${cssIdentifier}-panel-title-bar-title` }, { tag: "div", ref: "eTitleBarButtons", cls: `ag-panel-title-bar-buttons ag-${cssIdentifier}-panel-title-bar-buttons` } ] }, { tag: "div", ref: "eContentWrapper", cls: `ag-panel-content-wrapper ag-${cssIdentifier}-panel-content-wrapper` } ] }; } var AgPanel = class extends AgComponentStub { constructor(config) { super(getTemplate(config.cssIdentifier)); this.config = config; this.closable = true; this.eContentWrapper = RefPlaceholder; this.eTitleBar = RefPlaceholder; this.eTitleBarButtons = RefPlaceholder; this.eTitle = RefPlaceholder; this.registerCSS(agPanel_default); } postConstruct() { const { component, closable, hideTitleBar, title, minWidth = 250, width, minHeight = 250, height, centered, popup, x, y, postProcessPopupParams } = this.config; const beans = this.beans; const positionableFeature = this.createManagedBean(new AgPositionableFeature(this.getGui(), { minWidth, width, minHeight, height, centered, x, y, popup, calculateTopBuffer: () => this.positionableFeature.getHeight() - this.getBodyHeight() })); this.positionableFeature = positionableFeature; const eGui = this.getGui(); if (component) { this.setBodyComponent(component); } if (!hideTitleBar) { if (title) { this.setTitle(title); } this.setClosable(closable != null ? closable : this.closable); } else { _setDisplayed(this.eTitleBar, false); } this.addManagedElementListeners(this.eTitleBar, { mousedown: (e) => { if (eGui.contains(e.relatedTarget) || eGui.contains(_getActiveDomElement(beans)) || this.eTitleBarButtons.contains(e.target)) { e.preventDefault(); return; } const focusEl = this.eContentWrapper.querySelector("button, [href], input, select, textarea, [tabindex]"); if (focusEl) { focusEl.focus(); } } }); if (popup && positionableFeature.isPositioned()) { return; } if (this.renderComponent) { this.renderComponent(); } let postProcessCallback; if (postProcessPopupParams) { const { type, eventSource, mouseEvent } = postProcessPopupParams; postProcessCallback = () => beans.popupSvc?.callPostProcessPopup(postProcessPopupParams, type, eGui, eventSource, mouseEvent); } positionableFeature.initialisePosition(postProcessCallback); this.eContentWrapper.style.height = "0"; } renderComponent() { const eGui = this.getGui(); eGui.focus(); this.close = () => { eGui.remove(); this.destroy(); }; } getHeight() { return this.positionableFeature.getHeight(); } setHeight(height) { this.positionableFeature.setHeight(height); } getWidth() { return this.positionableFeature.getWidth(); } setWidth(width) { this.positionableFeature.setWidth(width); } setClosable(closable) { if (closable !== this.closable) { this.closable = closable; } if (closable) { const closeButtonComp = this.closeButtonComp = new AgComponentStub({ tag: "div", cls: "ag-button" }); this.createBean(closeButtonComp); const eGui = closeButtonComp.getGui(); const child = this.beans.iconSvc.createIconNoSpan("close", this.beans); child.classList.add("ag-panel-title-bar-button-icon"); eGui.appendChild(child); this.addTitleBarButton(closeButtonComp); closeButtonComp.addManagedElementListeners(eGui, { click: this.onBtClose.bind(this) }); } else if (this.closeButtonComp) { const eGui = this.closeButtonComp.getGui(); eGui.remove(); this.closeButtonComp = this.destroyBean(this.closeButtonComp); } } setBodyComponent(bodyComponent) { bodyComponent.setParentComponent(this); this.eContentWrapper.appendChild(bodyComponent.getGui()); } addTitleBarButton(button, position) { const eTitleBarButtons = this.eTitleBarButtons; const buttons = eTitleBarButtons.children; const len = buttons.length; if (position == null) { position = len; } position = Math.max(0, Math.min(position, len)); button.addCss("ag-panel-title-bar-button"); const eGui = button.getGui(); if (position === 0) { eTitleBarButtons.prepend(eGui); } else if (position === len) { eTitleBarButtons.append(eGui); } else { buttons[position - 1].after(eGui); } button.setParentComponent(this); } getBodyHeight() { return _getInnerHeight(this.eContentWrapper); } getBodyWidth() { return _getInnerWidth(this.eContentWrapper); } setTitle(title) { this.eTitle.innerText = title; } onBtClose() { this.close(); } destroy() { if (this.closeButtonComp) { this.closeButtonComp = this.destroyBean(this.closeButtonComp); } const eGui = this.getGui(); if (eGui && _isVisible(eGui)) { this.close(); } super.destroy(); } }; var AgDialog = class extends AgPanel { constructor(config, callbacks) { super({ ...config, popup: true }); this.callbacks = callbacks; this.isMaximizable = false; this.isMaximized = false; this.maximizeListeners = []; this.resizeListenerDestroy = null; this.lastPosition = { x: 0, y: 0, width: 0, height: 0 }; } wireBeans(beans) { this.popupSvc = beans.popupSvc; } postConstruct() { const eGui = this.getGui(); const { movable, resizable, maximizable, modal } = this.config; this.addCss("ag-dialog"); super.postConstruct(); this.tabGuardFeature = this.createManagedBean(new AgTabGuardFeature(this, this.callbacks?.stopPropagationCallbacks)); this.tabGuardFeature.initialiseTabGuard({ isFocusableContainer: true, onFocusIn: () => { this.popupSvc?.bringPopupToFront(eGui); }, onTabKeyDown: (e) => { if (modal) { return; } const backwards = e.shiftKey; const nextFocusableElement = _findNextFocusableElement(this.beans, eGui, false, backwards); if (!nextFocusableElement || this.tabGuardFeature.getTabGuardCtrl().isTabGuard(nextFocusableElement)) { if (this.callbacks?.focusNextContainer(this.beans, backwards)) { e.preventDefault(); } } } }); if (movable) { this.setMovable(movable); } if (maximizable) { this.setMaximizable(maximizable); } if (resizable) { this.setResizable(resizable); } if (!this.config.modal) { this.callbacks?.configureFocusableContainer(this.beans, this); } } setAllowFocus(allowFocus) { this.tabGuardFeature.getTabGuardCtrl().setAllowFocus(allowFocus); } renderComponent() { const eGui = this.getGui(); const { alwaysOnTop, modal, title, afterGuiAttached } = this.config; const translate = this.getLocaleTextFunc(); const addPopupRes = this.popupSvc?.addPopup({ modal, eChild: eGui, closeOnEsc: true, closedCallback: this.onClosed.bind(this), alwaysOnTop, ariaLabel: title || translate("ariaLabelDialog", "Dialog"), afterGuiAttached }); if (addPopupRes) { this.close = addPopupRes.hideFunc; } } onClosed(event) { this.destroy(); this.config.closedCallback?.(event); } setMaximized(maximized) { if (this.isMaximizable && maximized !== this.isMaximized) { this.toggleMaximize(); } } toggleMaximize() { const position = this.positionableFeature.getPosition(); if (this.isMaximized) { const { x, y, width, height } = this.lastPosition; this.setWidth(width); this.setHeight(height); this.positionableFeature.offsetElement(x, y); } else { this.lastPosition.width = this.getWidth(); this.lastPosition.height = this.getHeight(); this.lastPosition.x = position.x; this.lastPosition.y = position.y; this.positionableFeature.offsetElement(0, 0); this.setHeight("100%"); this.setWidth("100%"); } this.isMaximized = !this.isMaximized; this.refreshMaximizeIcon(); } refreshMaximizeIcon() { _setDisplayed(this.maximizeIcon, !this.isMaximized); _setDisplayed(this.minimizeIcon, this.isMaximized); } clearMaximizebleListeners() { if (this.maximizeListeners.length) { for (const destroyListener of this.maximizeListeners) { destroyListener(); } this.maximizeListeners.length = 0; } if (this.resizeListenerDestroy) { this.resizeListenerDestroy(); this.resizeListenerDestroy = null; } } destroy() { this.maximizeButtonComp = this.destroyBean(this.maximizeButtonComp); this.clearMaximizebleListeners(); super.destroy(); } setResizable(resizable) { this.positionableFeature.setResizable(resizable); } setMovable(movable) { this.positionableFeature.setMovable(movable, this.eTitleBar); } setMaximizable(maximizable) { if (!maximizable) { this.clearMaximizebleListeners(); if (this.maximizeButtonComp) { this.destroyBean(this.maximizeButtonComp); this.maximizeButtonComp = this.maximizeIcon = this.minimizeIcon = undefined; } return; } const eTitleBar = this.eTitleBar; if (!eTitleBar || maximizable === this.isMaximizable) { return; } this.isMaximizable = maximizable; const maximizeButtonComp = this.buildMaximizeAndMinimizeElements(); this.refreshMaximizeIcon(); maximizeButtonComp.addManagedElementListeners(maximizeButtonComp.getGui(), { click: this.toggleMaximize.bind(this) }); this.addTitleBarButton(maximizeButtonComp, 0); this.maximizeListeners.push(...this.addManagedElementListeners(eTitleBar, { dblclick: this.toggleMaximize.bind(this) })); [this.resizeListenerDestroy] = this.addManagedListeners(this.positionableFeature, { resize: () => { this.isMaximized = false; this.refreshMaximizeIcon(); } }); } buildMaximizeAndMinimizeElements() { const maximizeButtonComp = this.maximizeButtonComp = this.createBean(new AgComponentStub({ tag: "div", cls: "ag-dialog-button" })); const eGui = maximizeButtonComp.getGui(); const iconSvc = this.beans.iconSvc; this.maximizeIcon = iconSvc.createIconNoSpan("maximize"); eGui.appendChild(this.maximizeIcon); this.maximizeIcon.classList.add("ag-panel-title-bar-button-icon"); this.minimizeIcon = iconSvc.createIconNoSpan("minimize"); eGui.appendChild(this.minimizeIcon); this.minimizeIcon.classList.add("ag-panel-title-bar-button-icon"); return maximizeButtonComp; } }; var AgMenuPanel = class extends AgTabGuardComp { constructor(wrappedComponent) { super(); this.setTemplateFromElement(wrappedComponent.getGui(), undefined, undefined, true); } postConstruct() { this.initialiseTabGuard({ onTabKeyDown: (e) => this.onTabKeyDown(e), handleKeyDown: (e) => this.handleKeyDown(e) }); } handleKeyDown(e) { if (e.key === KeyCode.ESCAPE) { this.closePanel(); } } onTabKeyDown(e) { if (e.defaultPrevented) { return; } this.closePanel(); e.preventDefault(); } closePanel() { const menuItem = this.parentComponent; menuItem.closeSubMenu(); setTimeout(() => menuItem.getGui().focus(), 0); } }; var AgMenuItemComponent = class extends AgBeanStub { constructor(callbacks) { super(); this.callbacks = callbacks; this.ACTIVATION_DELAY = 80; this.isActive = false; this.subMenuIsOpen = false; this.subMenuIsOpening = false; this.suppressRootStyles = true; this.suppressAria = true; this.suppressFocus = true; } init(params) { const { menuItemDef, isAnotherSubMenuOpen, level, childComponent, contextParams } = params; this.params = params.menuItemDef; this.level = level; this.isAnotherSubMenuOpen = isAnotherSubMenuOpen; this.childComponent = childComponent; this.contextParams = contextParams; this.cssClassPrefix = this.params.menuItemParams?.cssClassPrefix ?? "ag-menu-option"; return this.callbacks.getMenuItemComp(this.beans, this.params, { ...menuItemDef, level, isAnotherSubMenuOpen, openSubMenu: (activateFirstItem) => this.openSubMenu(activateFirstItem), closeSubMenu: () => this.closeSubMenu(), closeMenu: (event) => this.closeMenu(event), updateTooltip: (tooltip, shouldDisplayTooltip) => this.refreshTooltip(tooltip, shouldDisplayTooltip), onItemActivated: () => this.onItemActivated() }).then((comp) => { if (!comp) { return; } this.menuItemComp = comp; const configureDefaults = comp.configureDefaults?.(); if (configureDefaults) { this.configureDefaults(configureDefaults === true ? undefined : configureDefaults); } }); } addListeners(eGui, params) { if (!params?.suppressClick) { this.addManagedElementListeners(eGui, { click: (e) => this.onItemSelected(e) }); } if (!params?.suppressKeyboardSelect) { this.addManagedElementListeners(eGui, { keydown: (e) => { if (e.key === KeyCode.ENTER || e.key === KeyCode.SPACE) { e.preventDefault(); this.onItemSelected(e); } } }); } if (!params?.suppressMouseDown) { this.addManagedElementListeners(eGui, { mousedown: (e) => { e.stopPropagation(); e.preventDefault(); } }); } if (!params?.suppressMouseOver) { this.addManagedElementListeners(eGui, { mouseenter: () => this.onMouseEnter(), mouseleave: () => this.onMouseLeave() }); } } isDisabled() { return !!this.params.disabled; } openSubMenu(activateFirstItem = false, event) { this.closeSubMenu(); if (!this.params.subMenu) { return; } this.subMenuIsOpening = true; const ePopup = _createElement({ tag: "div", cls: "ag-menu", role: "presentation" }); this.eSubMenuGui = ePopup; let destroySubMenu; let afterGuiAttached = () => { this.subMenuIsOpening = false; }; if (this.childComponent) { const menuPanel = this.createBean(new AgMenuPanel(this.childComponent)); menuPanel.setParentComponent(this); const subMenuGui = menuPanel.getGui(); const mouseEvent = "mouseenter"; const mouseEnterListener = () => this.cancelDeactivate(); subMenuGui.addEventListener(mouseEvent, mouseEnterListener); destroySubMenu = () => { subMenuGui.removeEventListener(mouseEvent, mouseEnterListener); this.destroyBean(menuPanel); }; ePopup.appendChild(subMenuGui); if (this.childComponent.afterGuiAttached) { afterGuiAttached = () => { this.childComponent.afterGuiAttached(); this.subMenuIsOpening = false; }; } } else if (this.params.subMenu) { const childMenu = this.createBean(new AgMenuList(this.level + 1, this.contextParams, this.callbacks)); childMenu.setParentComponent(this); childMenu.addMenuItems(this.params.subMenu); ePopup.appendChild(childMenu.getGui()); this.addManagedListeners(childMenu, { closeMenu: (e) => this.dispatchLocalEvent(e) }); childMenu.addGuiEventListener("mouseenter", () => this.cancelDeactivate()); destroySubMenu = () => this.destroyBean(childMenu); if (activateFirstItem) { afterGuiAttached = () => { childMenu.activateFirstItem(); this.subMenuIsOpening = false; }; } } const popupSvc = this.beans.popupSvc; const positionCallback = () => { const eventSource = this.eGui; popupSvc?.positionPopupForMenu({ eventSource, ePopup, event: event instanceof MouseEvent ? event : undefined, additionalParams: this.callbacks.getPostProcessPopupParams(this.contextParams) }); }; const translate = this.getLocaleTextFunc(); const addPopupRes = popupSvc?.addPopup({ modal: true, eChild: ePopup, positionCallback, anchorToElement: this.eGui, ariaLabel: translate("ariaLabelSubMenu", "SubMenu"), afterGuiAttached }); this.subMenuIsOpen = true; this.setAriaExpanded(true); this.hideSubMenu = () => { if (addPopupRes) { addPopupRes.hideFunc(); } this.subMenuIsOpen = false; this.setAriaExpanded(false); destroySubMenu(); this.menuItemComp.setExpanded?.(false); this.eSubMenuGui = undefined; }; this.menuItemComp.setExpanded?.(true); } setAriaExpanded(expanded) { if (!this.suppressAria) { _setAriaExpanded(this.eGui, expanded); } } closeSubMenu() { if (!this.hideSubMenu) { return; } this.hideSubMenu(); this.hideSubMenu = null; this.setAriaExpanded(false); } isSubMenuOpen() { return this.subMenuIsOpen; } isSubMenuOpening() { return this.subMenuIsOpening; } activate(openSubMenu, fromKeyNav) { this.cancelActivate(); if (this.params.disabled && !fromKeyNav) { return; } this.isActive = true; if (!this.suppressRootStyles) { this.eGui.classList.add(`${this.cssClassPrefix}-active`); } this.menuItemComp.setActive?.(true); if (!this.suppressFocus) { this.callbacks.preserveRangesWhile(this.beans, () => this.eGui.focus({ preventScroll: !fromKeyNav })); } if (openSubMenu && this.params.subMenu) { window.setTimeout(() => { if (this.isAlive() && this.isActive) { this.openSubMenu(); } }, 300); } this.onItemActivated(); } deactivate() { this.cancelDeactivate(); if (!this.suppressRootStyles) { this.eGui.classList.remove(`${this.cssClassPrefix}-active`); } this.menuItemComp.setActive?.(false); this.isActive = false; if (this.subMenuIsOpen) { this.closeSubMenu(); } } getGui() { return this.menuItemComp.getGui(); } getParentComponent() { return this.parentComponent; } setParentComponent(component) { this.parentComponent = component; } getSubMenuGui() { return this.eSubMenuGui; } onItemSelected(event) { this.menuItemComp.select?.(); if (this.params.action) { this.beans.frameworkOverrides.wrapOutgoing(() => this.params.action(this.gos.addCommon({ ...this.contextParams }))); } else { this.openSubMenu(event && event.type === "keydown", event); } if (this.params.subMenu && !this.params.action || this.params.suppressCloseOnSelect) { return; } this.closeMenu(event); } closeMenu(event) { const e = { type: "closeMenu" }; if (event) { if (event instanceof MouseEvent) { e.mouseEvent = event; } else { e.keyboardEvent = event; } } this.dispatchLocalEvent(e); } onItemActivated() { const event = { type: "menuItemActivated", menuItem: this }; this.dispatchLocalEvent(event); } cancelActivate() { if (this.activateTimeoutId) { window.clearTimeout(this.activateTimeoutId); this.activateTimeoutId = 0; } } cancelDeactivate() { if (this.deactivateTimeoutId) { window.clearTimeout(this.deactivateTimeoutId); this.deactivateTimeoutId = 0; } } onMouseEnter() { this.cancelDeactivate(); if (this.isAnotherSubMenuOpen()) { this.activateTimeoutId = window.setTimeout(() => this.activate(true), this.ACTIVATION_DELAY); } else { this.activate(true); } } onMouseLeave() { this.cancelActivate(); if (this.isSubMenuOpen()) { this.deactivateTimeoutId = window.setTimeout(() => this.deactivate(), this.ACTIVATION_DELAY); } else { this.deactivate(); } } refreshRootElementGui(suppressRootStyles) { let eGui = this.menuItemComp.getGui(); const { cssClassPrefix, params: { cssClasses, disabled } } = this; const rootElement = this.menuItemComp.getRootElement?.(); if (rootElement) { if (!suppressRootStyles) { eGui.classList.add("ag-menu-option-custom"); } eGui = rootElement; } this.suppressRootStyles = !!suppressRootStyles; if (!this.suppressRootStyles) { eGui.classList.add(cssClassPrefix); for (const it of cssClasses ?? []) { eGui.classList.add(it); } if (disabled) { eGui.classList.add(`${cssClassPrefix}-disabled`); } } return eGui; } applyAriaProperties(eGui) { const { params: { checked, subMenu, subMenuRole, disabled } } = this; const hasCheck = checked != null; _setAriaRole(eGui, hasCheck ? "menuitemcheckbox" : "menuitem"); if (subMenu) { _setAriaHasPopup(eGui, subMenuRole ?? "menu"); } if (disabled) { _setAriaDisabled(eGui, true); } } configureDefaults(configParams) { if (!this.menuItemComp) { setTimeout(() => this.configureDefaults(configParams)); return; } const { suppressRootStyles, suppressTooltip, suppressAria, suppressTabIndex, suppressFocus } = configParams || {}; const { params: { tooltip, disabled } } = this; const eGui = this.eGui = this.refreshRootElementGui(!!suppressRootStyles); this.suppressAria = !!suppressAria; if (!suppressAria) { this.applyAriaProperties(eGui); } if (!suppressTabIndex) { eGui.setAttribute("tabindex", "-1"); } if (!suppressTooltip) { this.refreshTooltip(tooltip); } if (!disabled) { this.addListeners(eGui, configParams); } this.suppressFocus = !!suppressFocus; } refreshTooltip(tooltip, shouldDisplayTooltip) { this.tooltip = tooltip; this.tooltipFeature = this.destroyBean(this.tooltipFeature); if (!tooltip || !this.menuItemComp) { return; } const tooltipFeature = this.beans.registry.createDynamicBean("tooltipFeature", false, { getGui: () => this.getGui(), getTooltipValue: () => this.tooltip, getLocation: () => "menu", shouldDisplayTooltip }); if (tooltipFeature) { this.tooltipFeature = this.createBean(tooltipFeature); } } destroy() { this.tooltipFeature = this.destroyBean(this.tooltipFeature); this.menuItemComp?.destroy?.(); super.destroy(); } }; var AgMenuList = class extends AgTabGuardComp { constructor(level = 0, menuActionParams, callbacks) { super({ tag: "div", cls: "ag-menu-list", role: "menu" }); this.level = level; this.menuActionParams = menuActionParams; this.callbacks = callbacks; this.menuItems = []; } postConstruct() { this.initialiseTabGuard({ onTabKeyDown: (e) => this.onTabKeyDown(e), handleKeyDown: (e) => this.callbacks.preserveRangesWhile(this.beans, () => this.handleKeyDown(e)), onFocusIn: (e) => this.handleFocusIn(e), onFocusOut: (e) => this.handleFocusOut(e) }); } onTabKeyDown(e) { const parent = this.getParentComponent(); const isManaged = parent?.getGui()?.classList.contains("ag-focus-managed"); if (!isManaged) { e.preventDefault(); } if (e.shiftKey) { this.closeIfIsChild(e); } } handleKeyDown(e) { switch (e.key) { case KeyCode.UP: case KeyCode.RIGHT: case KeyCode.DOWN: case KeyCode.LEFT: e.preventDefault(); this.handleNavKey(e.key); break; case KeyCode.ESCAPE: if (this.closeIfIsChild()) { this.callbacks.stopPropagationCallbacks.stopPropagation(e); } break; } } handleFocusIn(e) { const oldFocusedElement = e.relatedTarget; if (!this.tabGuardFeature.getTabGuardCtrl().isTabGuard(oldFocusedElement) && (this.getGui().contains(oldFocusedElement) || this.activeMenuItem?.getSubMenuGui()?.contains(oldFocusedElement))) { return; } if (this.activeMenuItem) { this.activeMenuItem.activate(); } else { this.activateFirstItem(); } } handleFocusOut(e) { const newFocusedElement = e.relatedTarget; if (!this.activeMenuItem || this.getGui().contains(newFocusedElement) || this.activeMenuItem.getSubMenuGui()?.contains(newFocusedElement)) { return; } if (!this.activeMenuItem.isSubMenuOpening()) { this.activeMenuItem.deactivate(); } } clearActiveItem() { if (this.activeMenuItem) { this.activeMenuItem.deactivate(); this.activeMenuItem = null; } } addMenuItems(menuItems) { if (menuItems == null) { return; } AgPromise.all(menuItems.map((menuItemOrString) => { if (menuItemOrString === "separator") { return AgPromise.resolve({ eGui: this.createSeparator() }); } else if (typeof menuItemOrString === "string") { this.callbacks.warnNoItem?.(menuItemOrString); return AgPromise.resolve({ eGui: null }); } else { return this.addItem(menuItemOrString); } })).then((elements) => { for (const element of elements ?? []) { if (element?.eGui) { this.appendChild(element.eGui); if (element.comp) { this.menuItems.push(element.comp); } } } }); } addItem(menuItemDef) { const menuItem = this.createManagedBean(new AgMenuItemComponent(this.callbacks)); return menuItem.init({ menuItemDef, isAnotherSubMenuOpen: () => this.menuItems.some((m) => m.isSubMenuOpen()), level: this.level, contextParams: this.menuActionParams }).then(() => { menuItem.setParentComponent(this); this.addManagedListeners(menuItem, { closeMenu: (event) => { this.dispatchLocalEvent(event); }, menuItemActivated: (event) => { if (this.activeMenuItem && this.activeMenuItem !== event.menuItem) { this.activeMenuItem.deactivate(); } this.activeMenuItem = event.menuItem; } }); return { comp: menuItem, eGui: menuItem.getGui() }; }); } activateFirstItem() { const item = this.menuItems.filter((currentItem) => !currentItem.isDisabled())[0]; if (!item) { return; } item.activate(); } createSeparator() { const part = { tag: "div", cls: "ag-menu-separator-part" }; return _createAgElement({ tag: "div", cls: "ag-menu-separator", attrs: { "aria-hidden": "true" }, children: [part, part, part, part] }); } handleNavKey(key) { switch (key) { case KeyCode.UP: case KeyCode.DOWN: { const nextItem = this.findNextItem(key === KeyCode.UP); if (nextItem && nextItem !== this.activeMenuItem) { nextItem.activate(false, true); } return; } } const left = this.gos.get("enableRtl") ? KeyCode.RIGHT : KeyCode.LEFT; if (key === left) { this.closeIfIsChild(); } else { this.openChild(); } } closeIfIsChild(e) { const parentItem = this.getParentComponent(); if (parentItem && parentItem instanceof AgMenuItemComponent) { if (e) { e.preventDefault(); } parentItem.closeSubMenu(); parentItem.getGui().focus(); return true; } return false; } openChild() { if (this.activeMenuItem) { this.activeMenuItem.openSubMenu(true); } } findNextItem(up) { const items = [...this.menuItems]; if (!items.length) { return; } if (!this.activeMenuItem) { return up ? _last(items) : items[0]; } if (up) { items.reverse(); } let nextItem; let foundCurrent = false; for (const item of items) { if (!foundCurrent) { if (item === this.activeMenuItem) { foundCurrent = true; } continue; } nextItem = item; break; } if (foundCurrent && !nextItem) { return items[0]; } return nextItem || this.activeMenuItem; } destroy() { this.clearActiveItem(); super.destroy(); } }; var CSS_MENU = "ag-menu"; var CSS_CONTEXT_MENU_LOADING_ICON = "ag-context-menu-loading-icon"; var AgContextMenuService = class extends AgBeanStub { constructor(params) { super(); this.params = params; this.destroyLoadingSpinner = null; this.lastPromise = 0; } hideActiveMenu() { this.destroyBean(this.activeMenu); } showMenu(menuActionParams, mouseEvent, anchorToElement) { const { getMenuItems, shouldBlockMenuOpen: shouldBlockMenu } = this.params; const menuItems = getMenuItems(menuActionParams, mouseEvent); if (_isPromise(menuItems)) { const currentPromise = this.lastPromise + 1; this.lastPromise = currentPromise; if (!this.destroyLoadingSpinner) { this.createLoadingIcon(mouseEvent); } menuItems.then((menuItems2) => { if (this.lastPromise !== currentPromise) { return; } const { target } = mouseEvent; const isFromFakeEvent = !target; const shouldShowMenu = menuItems2?.length && (isFromFakeEvent || _isVisible(target)) && !shouldBlockMenu?.(); if (shouldShowMenu) { this.createContextMenu({ menuItems: menuItems2, menuActionParams, mouseEvent, anchorToElement }); } this.destroyLoadingSpinner?.(); }); return true; } if (!menuItems?.length) { return false; } this.createContextMenu({ menuItems, menuActionParams, mouseEvent, anchorToElement }); return true; } createLoadingIcon(mouseEvent) { const { beans } = this; const translate = this.getLocaleTextFunc(); const loadingIcon = beans.iconSvc.createIconNoSpan("loadingMenuItems"); const wrapperEl = _createAgElement({ tag: "div", cls: CSS_CONTEXT_MENU_LOADING_ICON }); wrapperEl.appendChild(loadingIcon); const rootNode = _getRootNode(beans); const targetEl = _getPageBody(beans); if (!targetEl) { return; } targetEl.appendChild(wrapperEl); beans.ariaAnnounce?.announceValue(translate("ariaLabelLoadingContextMenu", "Loading Context Menu"), "contextmenu"); beans.environment.applyThemeClasses(wrapperEl); _anchorElementToMouseMoveEvent(wrapperEl, mouseEvent, beans); const mouseMoveCallback = (e) => { _anchorElementToMouseMoveEvent(wrapperEl, e, beans); }; rootNode.addEventListener("mousemove", mouseMoveCallback); this.destroyLoadingSpinner = () => { rootNode.removeEventListener("mousemove", mouseMoveCallback); wrapperEl.remove(); this.destroyLoadingSpinner = null; }; } createContextMenu(params) { const { mapMenuItems, menuItemCallbacks, beforeMenuOpen, onMenuClose, afterMenuDestroyed, onVisibleChanged, onMenuOpen } = this.params; const { menuItems, menuActionParams, mouseEvent, anchorToElement } = params; const popupSvc = this.beans.popupSvc; const getMenuItems = mapMenuItems ? (getGui) => mapMenuItems(menuItems, menuActionParams, getGui) : () => menuItems; const menu = new ContextMenu(getMenuItems, menuActionParams, menuItemCallbacks); this.createBean(menu); const eMenuGui = menu.getGui(); beforeMenuOpen?.(menuActionParams); const positionParams = { additionalParams: menuItemCallbacks.getPostProcessPopupParams(menuActionParams), type: "contextMenu", mouseEvent, ePopup: eMenuGui, nudgeY: 1 }; const translate = this.getLocaleTextFunc(); const addPopupRes = popupSvc?.addPopup({ modal: true, eChild: eMenuGui, closeOnEsc: true, closedCallback: (e) => { menuItemCallbacks.preserveRangesWhile(this.beans, () => { onMenuClose?.(); this.destroyBean(menu); afterMenuDestroyed?.(); onVisibleChanged?.(false, e === undefined ? "api" : "ui"); }); }, click: mouseEvent, positionCallback: () => { const isRtl = this.gos.get("enableRtl"); popupSvc?.positionPopupUnderMouseEvent({ ...positionParams, nudgeX: isRtl ? (eMenuGui.offsetWidth + 1) * -1 : 1 }); }, anchorToElement, ariaLabel: translate("ariaLabelContextMenu", "Context Menu") }); if (addPopupRes) { onMenuOpen?.(); menu.afterGuiAttached({ container: "contextMenu", hidePopup: addPopupRes.hideFunc }); } if (this.activeMenu) { this.hideActiveMenu(); } this.activeMenu = menu; menu.addEventListener("destroyed", () => { if (this.activeMenu === menu) { this.activeMenu = null; } }); if (addPopupRes) { menu.addEventListener("closeMenu", (e) => addPopupRes.hideFunc({ mouseEvent: e.mouseEvent ?? undefined, keyboardEvent: e.keyboardEvent ?? undefined, forceHide: true })); } const isApi = mouseEvent && mouseEvent instanceof MouseEvent && mouseEvent.type === "mousedown"; onVisibleChanged?.(true, isApi ? "api" : "ui"); } destroy() { this.destroyLoadingSpinner?.(); super.destroy(); } }; var ContextMenu = class extends AgComponentStub { constructor(getMenuItems, menuActionParams, callbacks) { super({ tag: "div", cls: CSS_MENU, role: "presentation" }); this.getMenuItems = getMenuItems; this.menuActionParams = menuActionParams; this.callbacks = callbacks; this.menuList = null; } postConstruct() { const menuList = this.createManagedBean(new AgMenuList(0, this.menuActionParams, this.callbacks)); const menuItemsMapped = this.getMenuItems(() => this.getGui()); menuList.addMenuItems(menuItemsMapped); this.appendChild(menuList); this.menuList = menuList; menuList.addEventListener("closeMenu", (e) => this.dispatchLocalEvent(e)); } afterGuiAttached({ hidePopup }) { if (hidePopup) { this.addDestroyFunc(hidePopup); } const menuList = this.menuList; if (menuList) { this.callbacks.preserveRangesWhile(this.beans, () => _focusInto(menuList.getGui())); } } }; var AgMenuItemRenderer = class extends AgComponentStub { constructor(callbacks) { super({ tag: "div" }); this.callbacks = callbacks; } init(params) { this.params = params; this.cssClassPrefix = this.params.cssClassPrefix ?? "ag-menu-option"; this.addAriaAttributes(); this.addIcon(); this.addName(); this.addShortcut(); this.addSubMenu(); } configureDefaults() { return true; } addAriaAttributes() { const { checked, subMenu } = this.params; const eGui = this.getGui(); if (checked) { _setAriaChecked(eGui, checked); } if (subMenu) { _setAriaExpanded(eGui, false); } } addIcon() { if (this.params.isCompact) { return; } const iconWrapper = _createAgElement({ tag: "span", ref: "eIcon", cls: `${this.getClassName("part")} ${this.getClassName("icon")}`, role: "presentation" }); const { checked, icon } = this.params; if (checked) { iconWrapper.appendChild(this.beans.iconSvc.createIconNoSpan("check")); } else if (icon) { if (_isNodeOrElement(icon)) { iconWrapper.appendChild(icon); } else if (typeof icon === "string") { iconWrapper.innerHTML = icon; } else { this.callbacks?.warnNoIcon?.(); } } this.getGui().appendChild(iconWrapper); } addName() { const name = _createAgElement({ tag: "span", ref: "eName", cls: `${this.getClassName("part")} ${this.getClassName("text")}`, children: this.params.name || "" }); this.getGui().appendChild(name); } addShortcut() { if (this.params.isCompact) { return; } const shortcut = _createAgElement({ tag: "span", ref: "eShortcut", cls: `${this.getClassName("part")} ${this.getClassName("shortcut")}`, children: this.params.shortcut || "" }); this.getGui().appendChild(shortcut); } addSubMenu() { const pointer = _createAgElement({ tag: "span", ref: "ePopupPointer", cls: `${this.getClassName("part")} ${this.getClassName("popup-pointer")}` }); const eGui = this.getGui(); if (this.params.subMenu) { const iconName = this.gos.get("enableRtl") ? "subMenuOpenRtl" : "subMenuOpen"; pointer.appendChild(this.beans.iconSvc.createIconNoSpan(iconName)); } eGui.appendChild(pointer); } getClassName(suffix) { return `${this.cssClassPrefix}-${suffix}`; } }; function findFocusableElementBeforeTabGuard(rootNode, referenceElement) { if (!referenceElement) { return null; } const focusableElements = _findFocusableElements(rootNode); const referenceIndex = focusableElements.indexOf(referenceElement); if (referenceIndex === -1) { return null; } let lastTabGuardIndex = -1; for (let i = referenceIndex - 1;i >= 0; i--) { if (focusableElements[i].classList.contains(TabGuardClassNames.TAB_GUARD_TOP)) { lastTabGuardIndex = i; break; } } if (lastTabGuardIndex <= 0) { return null; } return focusableElements[lastTabGuardIndex - 1]; } function isTargetUnderManagedComponent(rootNode, target) { if (!target) { return false; } const managedContainers = rootNode.querySelectorAll(`.${FOCUS_MANAGED_CLASS}`); if (!managedContainers.length) { return false; } for (let i = 0;i < managedContainers.length; i++) { if (managedContainers[i].contains(target)) { return true; } } return false; } function getTabbedLayoutTemplate(cssClass) { return { tag: "div", cls: `ag-tabs ${cssClass}`, children: [ { tag: "div", ref: "eHeader" }, { tag: "div", ref: "eBody", role: "presentation", cls: "ag-tabs-body" + cssClass ? ` ${cssClass}-body` : "" } ] }; } var AgTabbedLayout = class extends AgTabGuardComp { constructor(params) { super(getTabbedLayoutTemplate(params.cssClass)); this.eHeader = RefPlaceholder; this.eBody = RefPlaceholder; this.items = []; this.tabbedItemScrollMap = /* @__PURE__ */ new Map; this.params = params; } postConstruct() { this.setupHeader(); if (this.params.items) { for (const item of this.params.items) { this.addItem(item); } } this.initialiseTabGuard({ onTabKeyDown: this.onTabKeyDown.bind(this), handleKeyDown: this.handleKeyDown.bind(this), focusInnerElement: this.focusInnerElement.bind(this), focusTrapActive: true }); this.addDestroyFunc(() => this.activeItem?.tabbedItem?.afterDetachedCallback?.()); } setupHeader() { const { enableCloseButton, cssClass } = this.params; const addCssClasses = (el, suffix) => { el.classList.add(`ag-tabs-${suffix}`); if (cssClass) { el.classList.add(`${cssClass}-${suffix}`); } }; if (enableCloseButton) { this.setupCloseButton(addCssClasses); this.eTabHeader = _createAgElement({ tag: "div", role: "presentation" }); addCssClasses(this.eHeader, "header-wrapper"); this.eHeader.appendChild(this.eTabHeader); } else { this.eTabHeader = this.eHeader; } _setAriaRole(this.eTabHeader, "tablist"); addCssClasses(this.eTabHeader, "header"); } setupCloseButton(addCssClasses) { const eCloseButton = _createAgElement({ tag: "button" }); addCssClasses(eCloseButton, "close-button"); const eIcon = this.beans.iconSvc.createIconNoSpan("close"); _setAriaLabel(eCloseButton, this.params.closeButtonAriaLabel); eCloseButton.appendChild(eIcon); this.addManagedElementListeners(eCloseButton, { click: () => this.params.onCloseClicked?.() }); const eCloseButtonWrapper = _createAgElement({ tag: "div", role: "presentation" }); addCssClasses(eCloseButtonWrapper, "close-button-wrapper"); eCloseButtonWrapper.appendChild(eCloseButton); this.eHeader.appendChild(eCloseButtonWrapper); this.eCloseButton = eCloseButton; } handleKeyDown(e) { switch (e.key) { case KeyCode.RIGHT: case KeyCode.LEFT: { if (!this.eTabHeader.contains(_getActiveDomElement(this.beans))) { return; } const isRightKey = e.key === KeyCode.RIGHT; const isRtl = this.gos.get("enableRtl"); const currentPosition = this.items.indexOf(this.activeItem); const nextPosition = isRightKey !== isRtl ? Math.min(currentPosition + 1, this.items.length - 1) : Math.max(currentPosition - 1, 0); if (currentPosition === nextPosition) { return; } e.preventDefault(); const nextItem = this.items[nextPosition]; this.showItemWrapper(nextItem); nextItem.eHeaderButton.focus(); break; } case KeyCode.UP: case KeyCode.DOWN: e.stopPropagation(); break; } } onTabKeyDown(e) { if (e.defaultPrevented) { return; } const { beans, eHeader, eBody, activeItem, params } = this; const { suppressTrapFocus, enableCloseButton } = params; const activeElement = _getActiveDomElement(beans); const target = e.target; const backwards = e.shiftKey; if (eHeader.contains(activeElement)) { e.preventDefault(); if (enableCloseButton && backwards && !this.eCloseButton?.contains(activeElement)) { this.eCloseButton?.focus(); } else if (suppressTrapFocus && backwards) { findFocusableElementBeforeTabGuard(_getDocument(beans).body, target)?.focus(); } else { this.focusBody(e.shiftKey); } return; } let nextEl = null; if (isTargetUnderManagedComponent(eBody, target)) { if (backwards) { nextEl = findFocusableElementBeforeTabGuard(eBody, target); } if (!nextEl && !suppressTrapFocus) { nextEl = activeItem.eHeaderButton; } } if (!nextEl && eBody.contains(activeElement)) { nextEl = _findNextFocusableElement(beans, eBody, false, backwards); if (!nextEl) { if (suppressTrapFocus && !backwards) { this.forceFocusOutOfContainer(backwards); } else if (enableCloseButton && !backwards) { e.preventDefault(); this.eCloseButton?.focus(); } else { e.preventDefault(); this.focusHeader(); } return; } } if (nextEl) { e.preventDefault(); nextEl.focus(); } } focusInnerElement(fromBottom) { if (fromBottom) { return this.focusBody(true); } else { this.focusHeader(); return true; } } focusHeader(preventScroll) { this.activeItem.eHeaderButton.focus({ preventScroll }); } focusBody(fromBottom) { return _focusInto(this.eBody, fromBottom); } setAfterAttachedParams(params) { this.afterAttachedParams = params; } showFirstItem() { if (this.items.length > 0) { this.showItemWrapper(this.items[0]); } } addItem(item) { const eHeaderButton = _createAgElement({ tag: "span", cls: "ag-tab", role: "tab", attrs: { tabindex: "-1" } }); eHeaderButton.appendChild(item.title); this.eTabHeader.appendChild(eHeaderButton); _setAriaLabel(eHeaderButton, item.titleLabel); const wrapper = { tabbedItem: item, eHeaderButton }; this.items.push(wrapper); eHeaderButton.addEventListener("click", this.showItemWrapper.bind(this, wrapper)); } showItem(tabbedItem) { const itemWrapper = this.items.find((wrapper) => wrapper.tabbedItem === tabbedItem); if (itemWrapper) { this.showItemWrapper(itemWrapper); } } showItemWrapper(wrapper) { const { tabbedItem, eHeaderButton } = wrapper; this.params.onItemClicked?.({ item: tabbedItem }); if (this.activeItem === wrapper) { this.params.onActiveItemClicked?.(); return; } if (this.lastScrollListener) { this.lastScrollListener = this.lastScrollListener(); } _clearElement(this.eBody); tabbedItem.bodyPromise.then((body) => { this.eBody.appendChild(body); const onlyUnmanaged = !_isKeyboardMode(); if (!this.params.suppressFocusBodyOnOpen) { _focusInto(this.eBody, false, onlyUnmanaged); } if (tabbedItem.afterAttachedCallback) { tabbedItem.afterAttachedCallback(this.afterAttachedParams); } if (this.params.keepScrollPosition) { const scrollableContainer = tabbedItem.getScrollableContainer?.() || body; [this.lastScrollListener] = this.addManagedElementListeners(scrollableContainer, { scroll: () => { this.tabbedItemScrollMap.set(tabbedItem.name, scrollableContainer.scrollTop); } }); const scrollPosition = this.tabbedItemScrollMap.get(tabbedItem.name); if (scrollPosition !== undefined) { setTimeout(() => { scrollableContainer.scrollTop = scrollPosition; }, 0); } } }); if (this.activeItem) { this.activeItem.eHeaderButton.classList.remove("ag-tab-selected"); this.activeItem.tabbedItem.afterDetachedCallback?.(); } eHeaderButton.classList.add("ag-tab-selected"); this.activeItem = wrapper; } }; var agGroupComponent_default = ".ag-group{position:relative;width:100%}.ag-group-title-bar{align-items:center;display:flex;padding:var(--ag-spacing)}.ag-group-title{display:inline;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:where(.ag-group-title-bar) .ag-group-title{cursor:default}.ag-group-toolbar{align-items:center;display:flex;padding:var(--ag-spacing)}.ag-group-container{display:flex}.ag-disabled .ag-group-container{pointer-events:none}.ag-disabled-group-container,.ag-disabled-group-title-bar{opacity:.5}.ag-group-container-horizontal{flex-flow:row wrap}.ag-group-container-vertical{flex-direction:column}.ag-group-title-bar-icon{cursor:pointer;flex:none}:where(.ag-ltr) .ag-group-title-bar-icon{margin-right:var(--ag-spacing)}:where(.ag-rtl) .ag-group-title-bar-icon{margin-left:var(--ag-spacing)}:where(.ag-group-item-alignment-stretch) .ag-group-item{align-items:stretch}:where(.ag-group-item-alignment-start) .ag-group-item{align-items:flex-start}:where(.ag-group-item-alignment-end) .ag-group-item{align-items:flex-end}"; function getAgGroupComponentTemplate(params) { const cssIdentifier = params.cssIdentifier || "default"; const direction = params.direction || "vertical"; return { tag: "div", cls: `ag-group ag-${cssIdentifier}-group`, role: "presentation", children: [ { tag: "div", ref: "eToolbar", cls: `ag-group-toolbar ag-${cssIdentifier}-group-toolbar`, children: [{ tag: "ag-checkbox", ref: "cbGroupEnabled" }] }, { tag: "div", ref: "eContainer", cls: `ag-group-container ag-group-container-${direction} ag-${cssIdentifier}-group-container` } ] }; } var AgGroupComponent = class extends AgComponentStub { constructor(params = {}) { super(getAgGroupComponentTemplate(params), [AgCheckboxSelector]); this.params = params; this.suppressEnabledCheckbox = true; this.suppressToggleExpandOnEnableChange = false; this.eToolbar = RefPlaceholder; this.cbGroupEnabled = RefPlaceholder; this.eContainer = RefPlaceholder; this.registerCSS(agGroupComponent_default); const { enabled, items, suppressEnabledCheckbox, expanded, suppressToggleExpandOnEnableChange, useToggle: toggleMode } = params; this.cssIdentifier = params.cssIdentifier || "default"; this.enabled = enabled != null ? enabled : true; this.items = items || []; this.useToggle = toggleMode ?? false; this.alignItems = params.alignItems || "center"; this.expanded = expanded == null ? true : expanded; if (suppressEnabledCheckbox != null) { this.suppressEnabledCheckbox = suppressEnabledCheckbox; } if (suppressToggleExpandOnEnableChange != null) { this.suppressToggleExpandOnEnableChange = suppressToggleExpandOnEnableChange; } } postConstruct() { this.setupTitleBar(); if (this.items.length) { const initialItems = this.items; this.items = []; this.addItems(initialItems); } const localeTextFunc = this.getLocaleTextFunc(); this.cbGroupEnabled.setLabel(localeTextFunc("enabled", "Enabled")); if (this.enabled) { this.setEnabled(this.enabled, undefined, true); } this.setAlignItems(this.alignItems); const { onEnableChange, onExpandedChange, suppressOpenCloseIcons } = this.params; this.hideEnabledCheckbox(this.suppressEnabledCheckbox); this.hideOpenCloseIcons(suppressOpenCloseIcons ?? false); this.refreshChildDisplay(); _setDisplayed(this.eContainer, this.expanded); this.cbGroupEnabled.onValueChange((newSelection) => { this.setEnabled(newSelection, true, this.suppressToggleExpandOnEnableChange); this.dispatchEnableChangeEvent(newSelection); }); if (onEnableChange != null) { this.onEnableChange(onEnableChange); } if (onExpandedChange != null) { this.onExpandedChange(onExpandedChange); } } refreshChildDisplay() { _setDisplayed(this.eToolbar, this.expanded && !this.suppressEnabledCheckbox); this.eTitleBar?.refreshOnExpand(this.expanded); } isExpanded() { return this.expanded; } setAlignItems(alignment) { if (this.alignItems !== alignment) { this.removeCss(`ag-group-item-alignment-${this.alignItems}`); } this.alignItems = alignment; const newCls = `ag-group-item-alignment-${this.alignItems}`; this.addCss(newCls); return this; } toggleGroupExpand(expanded, silent) { if (this.eTitleBar?.isSuppressCollapse() && !this.useToggle) { expanded = true; silent = true; } else { expanded = expanded != null ? expanded : !this.expanded; if (this.expanded === expanded) { return this; } } this.expanded = expanded; this.refreshChildDisplay(); _setDisplayed(this.eContainer, expanded); if (!silent) { this.dispatchLocalEvent({ type: expanded ? "expanded" : "collapsed" }); } return this; } addItems(items) { for (const item of items) { this.addItem(item); } } prependItem(item) { this.insertItem(item, true); } addItem(item) { this.insertItem(item, false); } updateItems(newItems) { const oldItems = this.items; let newIndex = 0; for (let prevIndex = 0;prevIndex < oldItems.length; ++prevIndex) { const ePrevItem = oldItems[prevIndex]; if (ePrevItem === newItems[newIndex]) { newIndex++; } else { const el = _isComponent(ePrevItem) ? ePrevItem.getGui() : ePrevItem; _removeFromParent(el); } } while (newIndex < newItems.length) { this.insertItem(newItems[newIndex++]); } this.items = newItems; } insertItem(item, prepend) { const container = this.eContainer; const el = _isComponent(item) ? item.getGui() : item; el.classList.add("ag-group-item", `ag-${this.cssIdentifier}-group-item`); if (prepend) { container.prepend(el); this.items.unshift(el); } else { container.appendChild(el); this.items.push(el); } } hideItem(hide, index) { const itemToHide = this.items[index]; _setDisplayed(itemToHide, !hide); } getItemIndex(item) { const el = _isComponent(item) ? item.getGui() : item; return this.items.indexOf(el); } setTitle(title) { this.eTitleBar?.setTitle(title); return this; } addTitleBarWidget(el) { this.eTitleBar?.addWidget(el); return this; } addCssClassToTitleBar(cssClass) { this.eTitleBar?.addCss(cssClass); } dispatchEnableChangeEvent(enabled) { const event = { type: "enableChange", enabled }; this.dispatchLocalEvent(event); } setEnabled(enabled, skipToggle, skipExpand) { this.enabled = enabled; this.refreshDisabledStyles(); if (!skipExpand) { this.toggleGroupExpand(enabled); } if (!skipToggle) { this.cbGroupEnabled.setValue(enabled); this.eToggle?.setValue(enabled); } return this; } isEnabled() { return this.enabled; } onEnableChange(callbackFn) { this.addManagedListeners(this, { enableChange: (event) => callbackFn(event.enabled) }); return this; } onExpandedChange(callbackFn) { this.addManagedListeners(this, { expanded: () => callbackFn(true), collapsed: () => callbackFn(false) }); return this; } hideEnabledCheckbox(hide) { this.suppressEnabledCheckbox = hide; this.refreshChildDisplay(); this.refreshDisabledStyles(); return this; } hideOpenCloseIcons(hide) { this.eTitleBar?.hideOpenCloseIcons(hide); return this; } refreshDisabledStyles() { const disabled = !this.enabled; this.eContainer.classList.toggle("ag-disabled", disabled); this.eTitleBar?.refreshDisabledStyles(this.suppressEnabledCheckbox && disabled); this.eContainer.classList.toggle("ag-disabled-group-container", disabled); } setupTitleBar() { const titleBar = this.useToggle ? this.createToggleTitleBar() : this.createDefaultTitleBar(); this.eToolbar.insertAdjacentElement("beforebegin", titleBar.getGui()); } createDefaultTitleBar() { const titleBar = this.createManagedBean(new DefaultTitleBar(this.params)); this.eTitleBar = titleBar; titleBar.refreshOnExpand(this.expanded); this.addManagedListeners(titleBar, { expandedChanged: (event) => this.toggleGroupExpand(event.expanded) }); return titleBar; } createToggleTitleBar() { const eToggle = this.createManagedBean(new AgToggleButton({ value: this.enabled, label: this.params.title, labelAlignment: "left", labelWidth: "flex", onValueChange: (enabled) => { this.setEnabled(enabled, true); this.dispatchEnableChangeEvent(enabled); } })); eToggle.addCss("ag-group-title-bar"); eToggle.addCss(`ag-${this.params.cssIdentifier ?? "default"}-group-title-bar ag-unselectable`); this.eToggle = eToggle; this.toggleGroupExpand(this.enabled); return eToggle; } }; var TITLE_BAR_DISABLED_CLASS = "ag-disabled-group-title-bar"; function getDefaultTitleBarTemplate(params) { const cssIdentifier = params.cssIdentifier ?? "default"; return { tag: "div", cls: `ag-group-title-bar ag-${cssIdentifier}-group-title-bar ag-unselectable`, role: params.suppressKeyboardNavigation ? "presentation" : "group", children: [ { tag: "span", ref: "eGroupOpenedIcon", cls: `ag-group-title-bar-icon ag-${cssIdentifier}-group-title-bar-icon`, role: "presentation" }, { tag: "span", ref: "eGroupClosedIcon", cls: `ag-group-title-bar-icon ag-${cssIdentifier}-group-title-bar-icon`, role: "presentation" }, { tag: "span", ref: "eTitle", cls: `ag-group-title ag-${cssIdentifier}-group-title` } ] }; } var DefaultTitleBar = class extends AgComponentStub { constructor(params = {}) { super(getDefaultTitleBarTemplate(params)); this.suppressOpenCloseIcons = false; this.suppressKeyboardNavigation = false; this.eGroupOpenedIcon = RefPlaceholder; this.eGroupClosedIcon = RefPlaceholder; this.eTitle = RefPlaceholder; const { title, suppressOpenCloseIcons, suppressKeyboardNavigation } = params; if (!!title && title.length > 0) { this.title = title; } if (suppressOpenCloseIcons != null) { this.suppressOpenCloseIcons = suppressOpenCloseIcons; } this.suppressKeyboardNavigation = suppressKeyboardNavigation ?? false; } postConstruct() { this.setTitle(this.title); this.hideOpenCloseIcons(this.suppressOpenCloseIcons); this.setupExpandContract(); } setupExpandContract() { const iconSvc = this.beans.iconSvc; this.eGroupClosedIcon.appendChild(iconSvc.createIconNoSpan("accordionClosed")); this.eGroupOpenedIcon.appendChild(iconSvc.createIconNoSpan("accordionOpen")); this.addManagedElementListeners(this.getGui(), { click: () => this.dispatchExpandChanged(), keydown: (e) => { switch (e.key) { case KeyCode.ENTER: case KeyCode.SPACE: e.preventDefault(); this.dispatchExpandChanged(); break; case KeyCode.RIGHT: case KeyCode.LEFT: e.preventDefault(); this.dispatchExpandChanged(e.key === KeyCode.RIGHT); break; } } }); } refreshOnExpand(expanded) { this.refreshAriaStatus(expanded); this.refreshOpenCloseIcons(expanded); } refreshAriaStatus(expanded) { if (!this.suppressOpenCloseIcons) { _setAriaExpanded(this.getGui(), expanded); } } refreshOpenCloseIcons(expanded) { const showIcon = !this.suppressOpenCloseIcons; _setDisplayed(this.eGroupOpenedIcon, showIcon && expanded); _setDisplayed(this.eGroupClosedIcon, showIcon && !expanded); } isSuppressCollapse() { return this.suppressOpenCloseIcons; } dispatchExpandChanged(expanded) { const event = { type: "expandedChanged", expanded }; this.dispatchLocalEvent(event); } setTitle(title) { const eGui = this.getGui(); const hasTitle = !!title && title.length > 0; title = hasTitle ? title : undefined; this.eTitle.textContent = title ?? ""; _setDisplayed(eGui, hasTitle); if (title !== this.title) { this.title = title; } const disabled = eGui.classList.contains(TITLE_BAR_DISABLED_CLASS); this.refreshDisabledStyles(disabled); return this; } addWidget(el) { this.getGui().appendChild(el); return this; } hideOpenCloseIcons(hide) { this.suppressOpenCloseIcons = hide; if (hide) { this.dispatchExpandChanged(true); } return this; } refreshDisabledStyles(disabled) { const eGui = this.getGui(); if (disabled) { eGui.classList.add(TITLE_BAR_DISABLED_CLASS); eGui.removeAttribute("tabindex"); _setAriaRole(eGui, "presentation"); } else { eGui.classList.remove(TITLE_BAR_DISABLED_CLASS); if (typeof this.title === "string" && !this.suppressKeyboardNavigation) { this.activateTabIndex([eGui]); _setAriaRole(eGui, "group"); } else { eGui.removeAttribute("tabindex"); _setAriaRole(eGui, "presentation"); } } } }; var VERSION2 = "35.2.0"; var EnterpriseCoreModule = { moduleName: "EnterpriseCore", version: VERSION2, beans: [GridLicenseManager], icons: { accordionOpen: "tree-open", accordionClosed: "tree-closed", accordionIndeterminate: "tree-indeterminate", close: "cross", cancel: "cancel", maximize: "maximize", minimize: "minimize", columnDrag: "grip" }, dependsOn: [], setLicenseKey: GridLicenseManager.setLicenseKey }; var DIALOG_CALLBACKS = { stopPropagationCallbacks: STOP_PROPAGATION_CALLBACKS, focusNextContainer: (beans, backwards) => { return _focusNextGridCoreContainer(beans, backwards); }, configureFocusableContainer: (beans, dialog) => { const gridCtrl = beans.ctrlsSvc.get("gridCtrl"); gridCtrl.addFocusableContainer(dialog); dialog.addDestroyFunc(() => gridCtrl.removeFocusableContainer(dialog)); } }; var Dialog = class extends AgDialog { constructor(config) { super(config, DIALOG_CALLBACKS); } getFocusableContainerName() { return "dialog"; } }; var VirtualList = class extends AgVirtualList { constructor(params) { super(STOP_PROPAGATION_CALLBACKS, params); } }; var VirtualListDragFeature = class extends AgVirtualListDragFeature { }; function isSideBarVisible(beans) { return beans.sideBar?.comp.isDisplayed() ?? false; } function setSideBarVisible(beans, show) { beans.sideBar?.comp.setDisplayed(show); } function setSideBarPosition(beans, position) { beans.sideBar?.comp.setSideBarPosition(position); } function openToolPanel(beans, key, parent) { beans.sideBar?.comp.openToolPanel(key, "api", parent); } function closeToolPanel(beans) { beans.sideBar?.comp.close("api"); } function getOpenedToolPanel(beans) { return beans.sideBar?.comp.openedItem() ?? null; } function refreshToolPanel(beans) { beans.sideBar?.comp.refresh(); } function isToolPanelShowing(beans) { return beans.sideBar?.comp.isToolPanelShowing() ?? false; } function getToolPanelInstance(beans, id) { const comp = beans.sideBar?.comp.getToolPanelInstance(id); return _unwrapUserComp(comp); } function getSideBar(beans) { return beans.sideBar?.comp.getDef(); } var agSideBar_default = `.ag-tool-panel-wrapper{overflow:hidden;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--ag-horizontal-size,var(--ag-side-bar-panel-width))}.ag-tool-panel-content{display:flex;height:100%;overflow:hidden auto}.ag-tool-panel-wrapper.ag-tool-panel-animating{ /* !important required to override .ag-hidden to tool panel remains visible while animating */display:block!important;transition:width var(--ag-side-bar-panel-animation-duration) ease-in-out}@media (prefers-reduced-motion:reduce){.ag-tool-panel-wrapper.ag-tool-panel-animating{transition:none}}.ag-tool-panel-external{display:flex;flex-direction:row}:where(.ag-tool-panel-external) .ag-tool-panel-wrapper{flex-grow:1}.ag-select-agg-func-item{align-items:center;display:flex;flex:1 1 auto;flex-flow:row nowrap;height:100%;overflow:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap}.ag-tool-panel-horizontal-resize{cursor:ew-resize;height:100%;position:absolute;top:0;width:5px;z-index:1}.ag-side-bar{background-color:var(--ag-side-bar-background-color);display:flex;flex-direction:row-reverse;position:relative}:where(.ag-ltr) :where(.ag-side-bar-left) .ag-tool-panel-horizontal-resize{right:-3px}:where(.ag-rtl) :where(.ag-side-bar-left) .ag-tool-panel-horizontal-resize{left:-3px}:where(.ag-ltr) :where(.ag-side-bar-right) .ag-tool-panel-horizontal-resize{left:-3px}:where(.ag-rtl) :where(.ag-side-bar-right) .ag-tool-panel-horizontal-resize{right:-3px}.ag-side-bar-left{flex-direction:row;order:-1}.ag-side-buttons{background-color:var(--ag-side-button-bar-background-color);padding-top:var(--ag-side-button-bar-top-padding);position:relative}.ag-side-button{background-color:var(--ag-side-button-background-color);border-bottom:var(--ag-side-button-border);border-top:var(--ag-side-button-border);color:var(--ag-side-button-text-color);margin-top:-1px;position:relative}.ag-side-button:before{background-color:transparent;bottom:0;content:"";display:block;position:absolute;top:0;transition:background-color var(--ag-side-button-selected-underline-transition-duration);width:var(--ag-side-button-selected-underline-width)}:where(.ag-ltr) .ag-side-button:before{left:0}:where(.ag-rtl) .ag-side-button:before{right:0}.ag-side-button:hover{background-color:var(--ag-side-button-hover-background-color);color:var(--ag-side-button-hover-text-color)}.ag-side-button.ag-selected{background-color:var(--ag-side-button-selected-background-color);border-bottom:var(--ag-side-button-selected-border);border-top:var(--ag-side-button-selected-border);color:var(--ag-side-button-selected-text-color)}.ag-side-button.ag-selected:before{background-color:var(--ag-side-button-selected-underline-color)}.ag-side-button-button{align-items:center;display:flex;flex-direction:column;gap:var(--ag-spacing);position:relative;white-space:nowrap;width:100%;&:focus{box-shadow:none}}:where(.ag-ltr) .ag-side-button-button{padding:var(--ag-side-button-vertical-padding) var(--ag-side-button-right-padding) var(--ag-side-button-vertical-padding) var(--ag-side-button-left-padding)}:where(.ag-rtl) .ag-side-button-button{padding:var(--ag-side-button-vertical-padding) var(--ag-side-button-left-padding) var(--ag-side-button-vertical-padding) var(--ag-side-button-right-padding)}.ag-side-button-button:focus-visible{box-shadow:inset var(--ag-focus-shadow)}.ag-side-button-label{writing-mode:vertical-lr}@media (resolution <= 1.5x){.ag-side-button-label{font-family:"Segoe UI",var(--ag-font-family)}:where(.ag-ltr) .ag-side-button-label{transform:rotate(.05deg)}:where(.ag-rtl) .ag-side-button-label{transform:rotate(-.05deg)}}:where(.ag-ltr) .ag-side-bar-left,:where(.ag-rtl) .ag-side-bar-right{border-right:var(--ag-side-panel-border);:where(.ag-tool-panel-wrapper){border-left:var(--ag-side-panel-border)}}:where(.ag-ltr) .ag-side-bar-right,:where(.ag-rtl) .ag-side-bar-left{border-left:var(--ag-side-panel-border);:where(.ag-tool-panel-wrapper){border-right:var(--ag-side-panel-border)}}`; var SideBarButtonElement = { tag: "div", cls: "ag-side-button", role: "presentation", children: [ { tag: "button", ref: "eToggleButton", cls: "ag-button ag-side-button-button", role: "tab", attrs: { type: "button", tabindex: "-1", "aria-expanded": "false" }, children: [ { tag: "div", ref: "eIconWrapper", cls: "ag-side-button-icon-wrapper", attrs: { "aria-hidden": "true" } }, { tag: "span", ref: "eLabel", cls: "ag-side-button-label" } ] } ] }; var SideBarButtonComp = class extends Component { constructor(toolPanelDef) { super(); this.toolPanelDef = toolPanelDef; this.eToggleButton = RefPlaceholder; this.eIconWrapper = RefPlaceholder; this.eLabel = RefPlaceholder; } getToolPanelId() { return this.toolPanelDef.id; } postConstruct() { this.setTemplate(SideBarButtonElement, []); this.setLabel(); this.setIcon(); this.addManagedElementListeners(this.eToggleButton, { click: this.onButtonPressed.bind(this) }); this.eToggleButton.setAttribute("id", `ag-${this.getCompId()}-button`); } setLabel() { const def = this.toolPanelDef; const label = this.getLocaleTextFunc()(def.labelKey, def.labelDefault); this.eLabel.textContent = label; } setIcon() { this.eIconWrapper.insertAdjacentElement("afterbegin", _createIconNoSpan(this.toolPanelDef.iconKey, this.beans)); } onButtonPressed() { this.dispatchLocalEvent({ type: "toggleButtonClicked" }); } setSelected(selected) { this.toggleCss("ag-selected", selected); _setAriaExpanded(this.eToggleButton, selected); } }; var SideBarElement = { tag: "div", cls: "ag-side-buttons", role: "tablist" }; var AgSideBarButtons = class extends Component { constructor() { super(SideBarElement); this.buttonComps = []; } postConstruct() { this.addManagedElementListeners(this.getFocusableElement(), { keydown: this.handleKeyDown.bind(this) }); } handleKeyDown(e) { if (e.key !== KeyCode.TAB || !e.shiftKey) { return; } if (_focusNextGridCoreContainer(this.beans, true)) { e.preventDefault(); return; } _stopPropagationForAgGrid(e); } setActiveButton(id) { for (const comp of this.buttonComps) { comp.setSelected(id === comp.getToolPanelId()); } } addButtonComp(def) { const buttonComp = this.createBean(new SideBarButtonComp(def)); this.buttonComps.push(buttonComp); this.appendChild(buttonComp); buttonComp.addEventListener("toggleButtonClicked", () => { this.dispatchLocalEvent({ type: "sideBarButtonClicked", toolPanelId: def.id }); }); return buttonComp; } clearButtons() { this.buttonComps = this.destroyBeans(this.buttonComps); _clearElement(this.getGui()); } destroy() { this.clearButtons(); super.destroy(); } }; var AgSideBarButtonsSelector = { selector: "AG-SIDE-BAR-BUTTONS", component: AgSideBarButtons }; var DEFAULT_COLUMN_COMP = { id: "columns", labelDefault: "Columns", labelKey: "columns", iconKey: "columnsToolPanel", toolPanel: "agColumnsToolPanel" }; var DEFAULT_FILTER_COMP = { id: "filters", labelDefault: "Filters", labelKey: "filters", iconKey: "filtersToolPanel", toolPanel: "agFiltersToolPanel" }; var DEFAULT_NEW_FILTER_COMP = { id: "filters-new", labelDefault: "Filters", labelKey: "filters", iconKey: "filtersToolPanel", toolPanel: "agNewFiltersToolPanel" }; var DEFAULT_BY_KEY = { columns: DEFAULT_COLUMN_COMP, filters: DEFAULT_FILTER_COMP, "filters-new": DEFAULT_NEW_FILTER_COMP }; function parseSideBarDef(toParse) { if (!toParse) { return; } if (toParse === true) { return { toolPanels: [DEFAULT_COLUMN_COMP, DEFAULT_FILTER_COMP], defaultToolPanel: "columns" }; } if (typeof toParse === "string") { return parseSideBarDef([toParse]); } if (Array.isArray(toParse)) { const comps = []; for (const key of toParse) { const lookupResult = DEFAULT_BY_KEY[key]; if (!lookupResult) { _warn(215, { key, defaultByKey: DEFAULT_BY_KEY }); continue; } comps.push(lookupResult); } if (comps.length === 0) { return; } return { toolPanels: comps, defaultToolPanel: comps[0].id }; } return { toolPanels: parseComponents(toParse.toolPanels), defaultToolPanel: toParse.defaultToolPanel, hiddenByDefault: toParse.hiddenByDefault, position: toParse.position, hideButtons: toParse.hideButtons }; } function parseComponents(from) { const result = []; if (!from) { return result; } from.forEach((it) => { const parsed = parseOneComponent(it); if (!parsed) { return; } result.push(parsed); }); return result; } function parseOneComponent(it) { if (typeof it !== "string") { return it; } if (DEFAULT_BY_KEY[it]) { return DEFAULT_BY_KEY[it]; } _warn(215, { key: it, defaultByKey: DEFAULT_BY_KEY }); return null; } var AgHorizontalResize = class extends Component { constructor() { super({ tag: "div", cls: "ag-tool-panel-horizontal-resize" }); this.minWidth = 100; this.maxWidth = null; } postConstruct() { const finishedWithResizeFunc = this.beans.horizontalResizeSvc.addResizeBar({ eResizeBar: this.getGui(), dragStartPixels: 1, onResizeStart: this.onResizeStart.bind(this), onResizing: this.onResizing.bind(this), onResizeEnd: this.onResizeEnd.bind(this) }); this.addDestroyFunc(finishedWithResizeFunc); this.inverted = this.gos.get("enableRtl"); } dispatchResizeEvent(start, end, width) { this.eventSvc.dispatchEvent({ type: "toolPanelSizeChanged", width, started: start, ended: end }); } onResizeStart() { this.startingWidth = this.elementToResize.offsetWidth; this.dispatchResizeEvent(true, false, this.startingWidth); } onResizeEnd(delta) { return this.onResizing(delta, true); } onResizing(delta, isEnd = false) { const direction = this.inverted ? -1 : 1; let newWidth = Math.max(this.minWidth, Math.floor(this.startingWidth - delta * direction)); if (this.maxWidth != null) { newWidth = Math.min(this.maxWidth, newWidth); } this.elementToResize.style.setProperty("--ag-horizontal-size", `${newWidth}px`); this.dispatchResizeEvent(false, isEnd, newWidth); } }; function getToolPanelCompDetails(userCompFactory, toolPanelDef, params) { return userCompFactory.getCompDetails(toolPanelDef, ToolPanelComponent, undefined, params, true); } var ToolPanelComponent = { name: "toolPanel", optionalMethods: ["refresh", "getState"] }; var ToolPanelElement = { tag: "div", cls: "ag-tool-panel-wrapper", role: "tabpanel", children: [ { tag: "div", cls: "ag-tool-panel-content", ref: "eContent" } ] }; var ToolPanelWrapper = class extends Component { constructor() { super(ToolPanelElement); this.eContent = RefPlaceholder; this.animationId = 0; this.defParent = null; } postConstruct() { const eGui = this.getGui(); const resizeBar = this.resizeBar = this.createManagedBean(new AgHorizontalResize); eGui.setAttribute("id", `ag-${this.getCompId()}`); resizeBar.elementToResize = eGui; this.appendChild(resizeBar); } getToolPanelId() { return this.toolPanelId; } getDefParent() { return this.defParent; } setDefParent(parent) { this.defParent = parent; } setToolPanelDef(toolPanelDef, params) { const { id, minWidth, maxWidth, width, parent } = toolPanelDef; this.toolPanelId = id; this.defParent = parent ?? null; if (width) { this.getGui().style.setProperty("--ag-side-bar-panel-width", `${width}px`); } const compDetails = getToolPanelCompDetails(this.beans.userCompFactory, toolPanelDef, params); if (compDetails == null) { return false; } const componentPromise = compDetails.newAgStackInstance(); this.params = compDetails.params; componentPromise.then(this.setToolPanelComponent.bind(this)); const resizeBar = this.resizeBar; if (minWidth != null) { resizeBar.minWidth = minWidth; } if (maxWidth != null) { resizeBar.maxWidth = maxWidth; } return true; } setToolPanelComponent(compInstance) { this.toolPanelCompInstance = compInstance; const { eContent } = this; eContent.appendChild(compInstance.getGui()); this.addDestroyFunc(() => { this.destroyBean(compInstance); }); } getToolPanelInstance() { return this.toolPanelCompInstance; } setResizerSizerSide(side) { const isRtl = this.gos.get("enableRtl"); const isLeft = side === "left"; const inverted = isRtl ? isLeft : !isLeft; this.resizeBar.inverted = inverted; } refresh() { this.toolPanelCompInstance?.refresh(this.params); } animateDisplayed(displayed) { if (this.isDisplayed() === displayed) { return; } const id = ++this.animationId; const { eContent } = this; const cleanup2 = () => { if (this.animationId === id) { eGui.classList.remove("ag-tool-panel-animating"); eContent.style.width = ""; eGui.style.width = ""; } }; const eGui = this.getGui(); const currentWrapperWidth = eGui.offsetWidth; this.setDisplayed(displayed); eGui.classList.add("ag-tool-panel-animating"); const durationStr = getComputedStyle(eGui).transitionDuration; if (!parseFloat(durationStr)) { cleanup2(); return; } eGui.style.transition = "none"; eGui.style.width = ""; eContent.style.width = `${eContent.offsetWidth}px`; eGui.style.width = `${currentWrapperWidth}px`; const _ = eGui.offsetWidth; eGui.style.transition = ""; eGui.style.width = displayed ? "" : "0"; const fallbackTimeout = setTimeout(cleanup2, 100); eGui.addEventListener("transitionstart", () => clearTimeout(fallbackTimeout), { once: true }); eGui.addEventListener("transitionend", cleanup2, { once: true }); } }; var AgSideBarElement = { tag: "div", cls: "ag-side-bar ag-unselectable", children: [ { tag: "ag-side-bar-buttons", ref: "sideBarButtons" } ] }; var AgSideBar = class extends Component { constructor() { super(AgSideBarElement, [AgSideBarButtonsSelector]); this.sideBarButtons = RefPlaceholder; this.toolPanelWrappers = []; this.registerCSS(agSideBar_default); } postConstruct() { this.sideBarButtons.addEventListener("sideBarButtonClicked", this.onToolPanelButtonClicked.bind(this)); const { beans, gos } = this; const { sideBar: sideBarState } = gos.get("initialState") ?? {}; this.setSideBarDef({ sideBarDef: parseSideBarDef(gos.get("sideBar")), sideBarState }); this.addManagedPropertyListener("sideBar", () => this.setState()); beans.sideBar.comp = this; const eGui = this.getFocusableElement(); this.createManagedBean(new ManagedFocusFeature(eGui, { onTabKeyDown: this.onTabKeyDown.bind(this), handleKeyDown: this.handleKeyDown.bind(this) })); _addFocusableContainerListener(beans, this, eGui); this.addManagedPropertyListener("enableAdvancedFilter", this.onAdvancedFilterChanged.bind(this)); } getFocusableContainerName() { return "sideBar"; } onTabKeyDown(e) { if (e.defaultPrevented) { return; } const { beans, sideBarButtons } = this; const eGui = this.getGui(); const sideBarGui = sideBarButtons.getGui(); const activeElement = _getActiveDomElement(beans); const openPanel = eGui.querySelector(".ag-tool-panel-wrapper:not(.ag-hidden)"); const target = e.target; const backwards = e.shiftKey; if (!openPanel) { if (_focusNextGridCoreContainer(beans, backwards, true)) { e.preventDefault(); return true; } _skipFocusableContainerListenerForAgGrid(e); return false; } if (sideBarGui.contains(activeElement)) { if (_focusInto(openPanel, backwards)) { e.preventDefault(); } return; } if (!backwards) { return; } let nextEl = null; if (openPanel.contains(activeElement)) { nextEl = _findNextFocusableElement(beans, openPanel, undefined, true); } else if (isTargetUnderManagedComponent(openPanel, target)) { nextEl = findFocusableElementBeforeTabGuard(openPanel, target); } if (!nextEl) { nextEl = sideBarGui.querySelector(".ag-selected button"); nextEl = _isVisible(nextEl) ? nextEl : null; } if (nextEl && nextEl !== e.target) { e.preventDefault(); nextEl.focus(); } } handleKeyDown(e) { const currentButton = _getActiveDomElement(this.beans); const sideBarButtons = this.sideBarButtons; if (!sideBarButtons.getGui().contains(currentButton)) { return; } const sideBarGui = sideBarButtons.getGui(); const buttons = Array.prototype.slice.call(sideBarGui.querySelectorAll(".ag-side-button")); const currentPos = buttons.findIndex((button) => button.contains(currentButton)); let nextPos = null; switch (e.key) { case KeyCode.LEFT: case KeyCode.UP: nextPos = Math.max(0, currentPos - 1); break; case KeyCode.RIGHT: case KeyCode.DOWN: nextPos = Math.min(currentPos + 1, buttons.length - 1); break; } if (nextPos === null) { return; } const innerButton = buttons[nextPos].querySelector("button"); if (innerButton) { innerButton.focus(); e.preventDefault(); } } onToolPanelButtonClicked(event) { const id = event.toolPanelId; const openedItem = this.openedItem(); if (openedItem === id) { this.openToolPanel(undefined, "sideBarButtonClicked"); } else { this.openToolPanel(id, "sideBarButtonClicked"); } } clearDownUi() { this.sideBarButtons.clearButtons(); this.destroyToolPanelWrappers(); } setSideBarDef({ sideBarDef, sideBarState, existingToolPanelWrappers }) { this.setDisplayed(false); this.sideBar = sideBarDef; if (sideBarDef) { this.sideBarButtons.setDisplayed(!sideBarDef.hideButtons); } if (sideBarDef?.toolPanels) { const toolPanelDefs = sideBarDef.toolPanels; this.createToolPanelsAndSideButtons(toolPanelDefs, sideBarState, existingToolPanelWrappers); if (!this.toolPanelWrappers.length) { return; } const shouldDisplaySideBar = sideBarState ? sideBarState.visible : !sideBarDef.hiddenByDefault; this.setDisplayed(shouldDisplaySideBar); this.setSideBarPosition(sideBarState ? sideBarState.position : sideBarDef.position); if (shouldDisplaySideBar) { if (sideBarState) { const { openToolPanel: openToolPanel2 } = sideBarState; if (openToolPanel2) { this.openToolPanel(openToolPanel2, "sideBarInitializing"); } } else { this.openToolPanel(sideBarDef.defaultToolPanel, "sideBarInitializing"); } } } } getDef() { return this.sideBar; } setSideBarPosition(position) { if (!position) { position = "right"; } this.position = position; const isLeft = position === "left"; const resizerSide = isLeft ? "right" : "left"; this.toggleCss("ag-side-bar-left", isLeft); this.toggleCss("ag-side-bar-right", !isLeft); for (const wrapper of this.toolPanelWrappers) { wrapper.setResizerSizerSide(resizerSide); } this.dispatchSideBarUpdated(); return this; } setDisplayed(displayed, options) { super.setDisplayed(displayed, options); this.dispatchSideBarUpdated(); } getState() { const toolPanels = {}; for (const wrapper of this.toolPanelWrappers) { toolPanels[wrapper.getToolPanelId()] = wrapper.getToolPanelInstance()?.getState?.(); } return { visible: this.isDisplayed(), position: this.position, openToolPanel: this.openedItem(), toolPanels }; } createToolPanelsAndSideButtons(defs, sideBarState, existingToolPanelWrappers) { for (const def of defs) { this.createToolPanelAndSideButton(def, sideBarState?.toolPanels?.[def.id], existingToolPanelWrappers?.[def.id]); } } validateDef(def) { const { id, toolPanel } = def; if (id == null) { _warn(212); return false; } if (isFilterPanel(toolPanel)) { if (this.beans.filterManager?.isAdvFilterEnabled()) { _warn(213); return false; } } return true; } createToolPanelAndSideButton(def, initialState, existingToolPanelWrapper) { if (!this.validateDef(def)) { this.destroyBean(existingToolPanelWrapper); return; } let wrapper; if (existingToolPanelWrapper) { wrapper = existingToolPanelWrapper; wrapper.setDefParent(def.parent ?? null); } else { wrapper = this.createBean(new ToolPanelWrapper); const created = wrapper.setToolPanelDef(def, _addGridCommonParams(this.gos, { initialState, onStateUpdated: () => this.dispatchSideBarUpdated() })); if (!created) { return; } } wrapper.setDisplayed(false); this.renderToolPanelUnderParent(wrapper, def.parent); this.toolPanelWrappers.push(wrapper); const button = this.sideBarButtons.addButtonComp(def); _setAriaControlsAndLabel(button.eToggleButton, wrapper.getGui()); } refresh() { for (const wrapper of this.toolPanelWrappers) { wrapper.refresh(); } } renderToolPanelUnderParent(wrapper, externalParent) { const wrapperGui = wrapper.getGui(); if (externalParent) { this.beans.environment.applyThemeClasses(externalParent, ["ag-external", "ag-tool-panel-external"]); wrapperGui.classList.add(this.gos.get("enableRtl") ? "ag-rtl" : "ag-ltr"); } const correctParent = externalParent ?? wrapper.getDefParent() ?? this.getGui(); if (wrapperGui.parentElement !== correctParent) { correctParent.appendChild(wrapperGui); } } getWrapper(key) { return this.toolPanelWrappers.find((wrapper) => wrapper.getToolPanelId() === key); } openToolPanel(key, source = "api", parent) { const currentlyOpenedKey = this.openedItem(); const switchingToolPanel = !!key && !!currentlyOpenedKey; const skipAnimation = switchingToolPanel || source === "sideBarInitializing"; for (const wrapper of this.toolPanelWrappers) { const show = key === wrapper.getToolPanelId(); if (show) { this.renderToolPanelUnderParent(wrapper, parent ?? null); } if (skipAnimation) { wrapper.setDisplayed(show); } else { wrapper.animateDisplayed(show); } } const newlyOpenedKey = this.openedItem(); const openToolPanelChanged = currentlyOpenedKey !== newlyOpenedKey; if (openToolPanelChanged) { this.sideBarButtons.setActiveButton(key); this.raiseToolPanelVisibleEvent(key, currentlyOpenedKey ?? undefined, source); } } getToolPanelInstance(key) { const toolPanelWrapper = this.getWrapper(key); if (!toolPanelWrapper) { _warn(214, { key }); return; } return toolPanelWrapper.getToolPanelInstance(); } raiseToolPanelVisibleEvent(key, previousKey, source) { const switchingToolPanel = !!key && !!previousKey; const eventSvc = this.eventSvc; if (previousKey) { eventSvc.dispatchEvent({ type: "toolPanelVisibleChanged", source, key: previousKey, visible: false, switchingToolPanel }); } if (key) { eventSvc.dispatchEvent({ type: "toolPanelVisibleChanged", source, key, visible: true, switchingToolPanel }); } } close(source = "api") { this.openToolPanel(undefined, source); } isToolPanelShowing() { return !!this.openedItem(); } openedItem() { let activeToolPanel = null; for (const wrapper of this.toolPanelWrappers) { if (wrapper.isDisplayed()) { activeToolPanel = wrapper.getToolPanelId(); } } return activeToolPanel; } setState(sideBarState) { const sideBarDef = parseSideBarDef(this.gos.get("sideBar")); const existingToolPanelWrappers = {}; if (sideBarDef && this.sideBar) { sideBarDef.toolPanels?.forEach((toolPanelDef) => { const { id } = toolPanelDef; if (!id) { return; } const existingToolPanelDef = this.sideBar.toolPanels?.find((toolPanelDefToCheck) => toolPanelDefToCheck.id === id); if (!existingToolPanelDef || toolPanelDef.toolPanel !== existingToolPanelDef.toolPanel) { return; } const toolPanelWrapper = this.getWrapper(id); if (!toolPanelWrapper) { return; } const params = _addGridCommonParams(this.gos, { ...toolPanelDef.toolPanelParams ?? {}, initialState: sideBarState?.toolPanels?.[id], onStateUpdated: () => this.dispatchSideBarUpdated() }); const hasRefreshed = toolPanelWrapper.getToolPanelInstance()?.refresh(params); if (hasRefreshed !== true) { return; } this.toolPanelWrappers = this.toolPanelWrappers.filter((toolPanel) => toolPanel !== toolPanelWrapper); _removeFromParent(toolPanelWrapper.getGui()); existingToolPanelWrappers[id] = toolPanelWrapper; }); } this.clearDownUi(); this.setSideBarDef({ sideBarDef, sideBarState, existingToolPanelWrappers }); } dispatchSideBarUpdated() { this.eventSvc.dispatchEvent({ type: "sideBarUpdated" }); } destroyToolPanelWrappers() { for (const wrapper of this.toolPanelWrappers) { _removeFromParent(wrapper.getGui()); this.destroyBean(wrapper); } this.toolPanelWrappers.length = 0; } onAdvancedFilterChanged() { const needsRefresh = this.sideBar?.toolPanels?.some((toolPanel) => isFilterPanel(typeof toolPanel === "string" ? toolPanel : toolPanel.toolPanel)); if (needsRefresh) { this.setState(); } } destroy() { this.destroyToolPanelWrappers(); super.destroy(); } }; function isFilterPanel(toolPanel) { return toolPanel === "agFiltersToolPanel" || toolPanel === "agNewFiltersToolPanel"; } var AgSideBarSelector = { selector: "AG-SIDE-BAR", component: AgSideBar }; var SideBarService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "sideBar"; } getSelector() { return AgSideBarSelector; } }; var SideBarModule = { moduleName: "SideBar", version: VERSION2, beans: [SideBarService], apiFunctions: { isSideBarVisible, setSideBarVisible, setSideBarPosition, openToolPanel, closeToolPanel, getOpenedToolPanel, refreshToolPanel, isToolPanelShowing, getToolPanelInstance, getSideBar }, dependsOn: [EnterpriseCoreModule, HorizontalResizeModule] }; var menu_default = '.ag-menu-list{cursor:default;display:table;padding:var(--ag-spacing) 0;width:100%}.ag-menu-option,.ag-menu-separator{display:table-row}.ag-menu-option-part,.ag-menu-separator-part{display:table-cell;vertical-align:middle}.ag-menu-option{cursor:pointer;font-weight:500}:where(.ag-ltr) :where(.ag-menu-option-popup-pointer) .ag-icon{text-align:right}:where(.ag-rtl) :where(.ag-menu-option-popup-pointer) .ag-icon{text-align:left}.ag-menu-option-text{white-space:nowrap}.ag-menu-option-custom{display:contents}.ag-compact-menu-option{display:flex;flex-wrap:nowrap;width:100%}.ag-compact-menu-option-text{flex:1 1 auto;white-space:nowrap}.ag-menu-separator{height:calc(var(--ag-spacing)*2 + 1px)}.ag-menu-separator-part:after{border-top:solid var(--ag-border-width) var(--ag-menu-separator-color);content:"";display:block}.ag-compact-menu-option-active,.ag-menu-option-active{background-color:var(--ag-row-hover-color)}.ag-compact-menu-option-part,.ag-menu-option-part{line-height:var(--ag-icon-size);padding:calc(var(--ag-spacing) + 2px) 0}.ag-compact-menu-option-disabled,.ag-menu-option-disabled{cursor:not-allowed;opacity:.5}.ag-compact-menu-option-icon,.ag-menu-option-icon{width:var(--ag-icon-size)}:where(.ag-ltr) .ag-compact-menu-option-icon,:where(.ag-ltr) .ag-menu-option-icon{padding-left:calc(var(--ag-spacing)*2)}:where(.ag-rtl) .ag-compact-menu-option-icon,:where(.ag-rtl) .ag-menu-option-icon{padding-right:calc(var(--ag-spacing)*2)}.ag-compact-menu-option-text,.ag-menu-option-text{padding-left:calc(var(--ag-spacing)*2);padding-right:calc(var(--ag-spacing)*2)}:where(.ag-ltr) .ag-compact-menu-option-shortcut,:where(.ag-ltr) .ag-menu-option-shortcut{padding-right:var(--ag-spacing)}:where(.ag-rtl) .ag-compact-menu-option-shortcut,:where(.ag-rtl) .ag-menu-option-shortcut{padding-left:var(--ag-spacing)}:where(.ag-ltr) .ag-compact-menu-option-popup-pointer,:where(.ag-ltr) .ag-menu-option-popup-pointer{padding-right:var(--ag-spacing)}:where(.ag-rtl) .ag-compact-menu-option-popup-pointer,:where(.ag-rtl) .ag-menu-option-popup-pointer{padding-left:var(--ag-spacing)}.ag-menu-column-select-wrapper{height:265px;overflow:auto;:where(.ag-column-select){height:100%}}.ag-menu:where(.ag-tabs){min-width:290px}.ag-context-menu-loading-icon{pointer-events:none;position:absolute}'; var MenuItemRenderer = class extends AgMenuItemRenderer { constructor() { super({ warnNoIcon: () => _warn(227) }); } }; var MenuItemModule = { moduleName: "MenuItem", version: VERSION2, userComponents: { agMenuItem: MenuItemRenderer }, icons: { check: "tick", subMenuOpen: "small-right", subMenuOpenRtl: "small-left" }, css: [menu_default] }; var agPrimaryCols_default = ".ag-column-select{display:flex;flex:3 1 0px;flex-direction:column;overflow:hidden;position:relative}.ag-column-select-header{flex:none;height:var(--ag-header-height);padding-left:var(--ag-widget-container-horizontal-padding);padding-right:var(--ag-widget-container-horizontal-padding)}.ag-column-select-column,.ag-column-select-column-group,.ag-column-select-header{align-items:center;display:flex;gap:var(--ag-widget-horizontal-spacing);position:relative}.ag-column-select-column,.ag-column-select-column-group{height:100%}:where(.ag-ltr) .ag-column-select-column,:where(.ag-ltr) .ag-column-select-column-group{padding-left:calc(var(--ag-indentation-level)*var(--ag-column-select-indent-size))}:where(.ag-rtl) .ag-column-select-column,:where(.ag-rtl) .ag-column-select-column-group{padding-right:calc(var(--ag-indentation-level)*var(--ag-column-select-indent-size))}.ag-column-select-column-group:where(:not(:last-child)),.ag-column-select-column:where(:not(:last-child)){margin-bottom:var(--ag-widget-vertical-spacing)}.ag-column-select-header-icon{border-radius:var(--ag-border-radius);cursor:pointer;height:var(--ag-icon-size);position:relative;width:var(--ag-icon-size);&:focus-visible{box-shadow:var(--ag-focus-shadow)}}.ag-column-select-header-filter-wrapper{flex:1 1 auto}.ag-column-select-header-filter{width:100%}.ag-column-select-list{flex:1 1 0px;overflow:hidden}:where(.ag-ltr) .ag-column-select-add-group-indent{margin-left:calc(var(--ag-icon-size) + var(--ag-spacing)*1.5)}:where(.ag-rtl) .ag-column-select-add-group-indent{margin-right:calc(var(--ag-icon-size) + var(--ag-spacing)*1.5)}.ag-column-select-column-group-readonly,.ag-column-select-column-readonly{opacity:.5;pointer-events:none;.ag-icon{opacity:.5}&.ag-icon-grip{opacity:.35}}.ag-column-select-column-readonly{&.ag-icon-grip,.ag-icon-grip{opacity:.35}}.ag-column-select-virtual-list-viewport{padding:calc(var(--ag-widget-container-vertical-padding)*.5) 0}.ag-column-select-virtual-list-item{padding:0 var(--ag-widget-container-horizontal-padding)}.ag-column-select-column-label{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-column-select-checkbox{display:flex}"; var DEBOUNCE_DELAY = 300; var AgPrimaryColsHeaderElement = { tag: "div", cls: "ag-column-select-header", role: "presentation", children: [ { tag: "div", ref: "eExpand", cls: "ag-column-select-header-icon" }, { tag: "ag-checkbox", ref: "eSelect", cls: "ag-column-select-header-checkbox" }, { tag: "ag-input-text-field", ref: "eFilterTextField", cls: "ag-column-select-header-filter-wrapper" } ] }; var AgPrimaryColsHeader = class extends Component { constructor() { super(AgPrimaryColsHeaderElement, [AgCheckboxSelector, AgInputTextFieldSelector]); this.eExpand = RefPlaceholder; this.eSelect = RefPlaceholder; this.eFilterTextField = RefPlaceholder; } postConstruct() { this.createExpandIcons(); this.addManagedListeners(this.eExpand, { click: this.onExpandClicked.bind(this), keydown: (e) => { if (e.key === KeyCode.SPACE) { e.preventDefault(); this.onExpandClicked(); } } }); this.addManagedElementListeners(this.eSelect.getInputElement(), { click: this.onSelectClicked.bind(this) }); this.addManagedPropertyListener("functionsReadOnly", () => this.onFunctionsReadOnlyPropChanged()); this.eFilterTextField.setAutoComplete(false).onValueChange(() => this.onFilterTextChanged()); this.addManagedEventListeners({ newColumnsLoaded: this.showOrHideOptions.bind(this) }); const translate = this.getLocaleTextFunc(); this.eSelect.setInputAriaLabel(translate("ariaColumnSelectAll", "Toggle All Columns Visibility")); this.eFilterTextField.setInputAriaLabel(translate("ariaFilterColumnsInput", "Filter Columns Input")); this.activateTabIndex([this.eExpand]); } onFunctionsReadOnlyPropChanged() { const readOnly = this.gos.get("functionsReadOnly"); this.eSelect.setReadOnly(readOnly); this.eSelect.toggleCss("ag-column-select-column-readonly", readOnly); } init(params) { this.params = params; const readOnly = this.gos.get("functionsReadOnly"); this.eSelect.setReadOnly(readOnly); this.eSelect.toggleCss("ag-column-select-column-readonly", readOnly); if (this.beans.colModel.ready) { this.showOrHideOptions(); } } createExpandIcons() { const beans = this.beans; this.eExpand.appendChild(this.eExpandChecked = _createIconNoSpan("columnSelectOpen", beans)); this.eExpand.appendChild(this.eExpandUnchecked = _createIconNoSpan("columnSelectClosed", beans)); this.eExpand.appendChild(this.eExpandIndeterminate = _createIconNoSpan("columnSelectIndeterminate", beans)); this.setExpandState(0); } showOrHideOptions() { const params = this.params; const showFilter = !params.suppressColumnFilter; const showSelect = !params.suppressColumnSelectAll; const showExpand = !params.suppressColumnExpandAll; const groupsPresent = !!this.beans.colModel.colDefCols?.treeDepth; const translate = this.getLocaleTextFunc(); this.eFilterTextField.setInputPlaceholder(translate("searchOoo", "Search...")); _setDisplayed(this.eFilterTextField.getGui(), showFilter); _setDisplayed(this.eSelect.getGui(), showSelect); _setDisplayed(this.eExpand, showExpand && groupsPresent); } onFilterTextChanged() { if (!this.onFilterTextChangedDebounced) { this.onFilterTextChangedDebounced = _debounce(this, () => { const filterText = this.eFilterTextField.getValue(); this.dispatchLocalEvent({ type: "filterChanged", filterText }); }, DEBOUNCE_DELAY); } this.onFilterTextChangedDebounced(); } onSelectClicked() { this.dispatchLocalEvent({ type: this.selectState ? "unselectAll" : "selectAll" }); } onExpandClicked() { this.dispatchLocalEvent({ type: this.expandState === 0 ? "collapseAll" : "expandAll" }); } setExpandState(state) { this.expandState = state; _setDisplayed(this.eExpandChecked, state === 0); _setDisplayed(this.eExpandUnchecked, state === 1); _setDisplayed(this.eExpandIndeterminate, state === 2); } setSelectionState(state) { this.selectState = state; this.eSelect.setValue(this.selectState); } }; var AgPrimaryColsHeaderSelector = { selector: "AG-PRIMARY-COLS-HEADER", component: AgPrimaryColsHeader }; function isColGroupDef(colDef) { return !!colDef && typeof colDef.children !== "undefined"; } function getId(colDef) { return isColGroupDef(colDef) ? colDef.groupId : colDef.colId; } function addChildrenToGroup(tree, groupId, colDef) { const subGroupIsSplit = (currentSubGroup, currentSubGroupToAdd) => { const existingChildIds = currentSubGroup.children.map(getId); const childGroupAlreadyExists = existingChildIds.includes(getId(currentSubGroupToAdd)); const lastChild = _last(currentSubGroup.children); const lastChildIsDifferent = lastChild && getId(lastChild) !== getId(currentSubGroupToAdd); return childGroupAlreadyExists && lastChildIsDifferent; }; if (!isColGroupDef(tree)) { return true; } const currentGroup = tree; const groupToAdd = colDef; if (subGroupIsSplit(currentGroup, groupToAdd)) { currentGroup.children.push(groupToAdd); return true; } if (currentGroup.groupId === groupId) { const existingChildIds = currentGroup.children.map(getId); const colDefAlreadyPresent = existingChildIds.includes(getId(groupToAdd)); if (!colDefAlreadyPresent) { currentGroup.children.push(groupToAdd); return true; } } for (let i = currentGroup.children.length - 1;i >= 0; i--) { if (addChildrenToGroup(currentGroup.children[i], groupId, colDef)) { break; } } return false; } function mergeLeafPathTrees(leafPathTrees) { const matchingRootGroupIds = (pathA, pathB) => { const bothPathsAreGroups = isColGroupDef(pathA) && isColGroupDef(pathB); return bothPathsAreGroups && getId(pathA) === getId(pathB); }; const mergeTrees = (treeA, treeB) => { if (!isColGroupDef(treeB)) { return treeA; } const mergeResult = treeA; const groupToMerge = treeB; if (groupToMerge.children && groupToMerge.groupId) { const added = addChildrenToGroup(mergeResult, groupToMerge.groupId, groupToMerge.children[0]); if (added) { return mergeResult; } } for (const child of groupToMerge.children) { mergeTrees(mergeResult, child); } return mergeResult; }; const mergeColDefs = []; for (let i = 1;i <= leafPathTrees.length; i++) { const first = leafPathTrees[i - 1]; const second = leafPathTrees[i]; if (matchingRootGroupIds(first, second)) { leafPathTrees[i] = mergeTrees(first, second); } else { mergeColDefs.push(first); } } return mergeColDefs; } function toolPanelCreateColumnTree(colModel, colDefs) { const invalidColIds = []; const createDummyColGroup = (abstractColDef, depth) => { if (isColGroupDef(abstractColDef)) { const groupDef = abstractColDef; const groupId = typeof groupDef.groupId !== "undefined" ? groupDef.groupId : groupDef.headerName; const group = new AgProvidedColumnGroup(groupDef, groupId, false, depth); const children = []; for (const def of groupDef.children) { const child = createDummyColGroup(def, depth + 1); if (child) { children.push(child); } } group.setChildren(children); return group; } else { const colDef = abstractColDef; const key = colDef.colId ? colDef.colId : colDef.field; const column = colModel.getColDefCol(key); if (!column) { invalidColIds.push(colDef); } return column; } }; const mappedResults = []; for (const colDef of colDefs) { const result = createDummyColGroup(colDef, 0); if (result) { mappedResults.push(result); } } if (invalidColIds.length > 0) { _warn(217, { invalidColIds }); } return mappedResults; } function syncLayoutWithGrid(colModel, syncLayoutCallback) { const leafPathTrees = getLeafPathTrees(getGridPrimaryColumns(colModel)); const mergedColumnTrees = mergeLeafPathTrees(leafPathTrees); syncLayoutCallback(mergedColumnTrees); } function syncLayoutWithColumns(columns, syncLayoutCallback) { const leafPathTrees = getLeafPathTrees(columns); const mergedColumnTrees = mergeLeafPathTrees(leafPathTrees); syncLayoutCallback(mergedColumnTrees); } function getLeafPathTrees(columns) { const getLeafPathTree = (node, childDef) => { let leafPathTree; if (isProvidedColumnGroup(node)) { if (node.isPadding()) { leafPathTree = childDef; } else { const groupDef = Object.assign({}, node.getColGroupDef()); groupDef.groupId = node.getGroupId(); groupDef.children = [childDef]; leafPathTree = groupDef; } } else { const colDef = Object.assign({}, node.getColDef()); colDef.colId = node.getColId(); leafPathTree = colDef; } const parent = node.getOriginalParent(); if (parent) { return getLeafPathTree(parent, leafPathTree); } else { return leafPathTree; } }; return columns.map((col) => getLeafPathTree(col, col.getColDef())); } function getGridPrimaryColumns(colModel) { return colModel.getCols().filter((column) => { const colDef = column.getColDef(); return column.isPrimary() && !colDef.showRowGroup; }); } var ColumnModelItem = class { constructor(displayName, columnOrGroup, depth, group = false, expanded) { this.displayName = displayName; this.depth = depth; this.group = group; this.localEventService = new LocalEventService; if (group) { this.columnGroup = columnOrGroup; this._expanded = expanded; this.children = []; } else { this.column = columnOrGroup; } } get expanded() { return !!this._expanded; } set expanded(expanded) { if (expanded === this._expanded) { return; } this._expanded = expanded; this.localEventService.dispatchEvent({ type: "expandedChanged" }); } addEventListener(eventType, listener) { this.localEventService.addEventListener(eventType, listener); } removeEventListener(eventType, listener) { this.localEventService.removeEventListener(eventType, listener); } }; function isDeferredMode(params) { return !!params?.buttons?.includes("apply"); } function refreshDeferredToolPanelUi(beans, params) { if (!isDeferredMode(params)) { return; } const openedPanelId = beans.sideBar?.comp.openedItem(); if (!openedPanelId) { return; } const toolPanel = beans.sideBar?.comp.getToolPanelInstance(openedPanelId); toolPanel?.refreshDeferredUi(); } function selectAllChildren(beans, colTree, selectAllChecked, eventType, params) { const cols = extractAllLeafColumns(colTree); setAllColumns(beans, cols, selectAllChecked, eventType, params); } function setAllColumns(beans, cols, selectAllChecked, eventType, params) { const updateStrategy = beans.columnStateUpdateStrategy; const isPivotMode2 = updateStrategy.getPivotMode(isDeferredMode(params)); if (isPivotMode2) { setAllPivot(beans, cols, selectAllChecked, eventType, params); } else { setAllVisible(beans, cols, selectAllChecked, eventType, params); } } function extractAllLeafColumns(allItems) { const res = []; const recursiveFunc = (items) => { for (const item of items) { if (!item.passesFilter) { continue; } if (item.group) { recursiveFunc(item.children); } else { res.push(item.column); } } }; recursiveFunc(allItems); return res; } function setAllVisible(beans, columns, visible, eventType, params) { const updateStrategy = beans.columnStateUpdateStrategy; const colStateItems = []; for (const col of columns) { if (col.getColDef().lockVisible) { continue; } if (updateStrategy.isColumnVisibleInToolPanel(isDeferredMode(params), col) !== visible) { colStateItems.push({ colId: col.getId(), hide: !visible }); } } updateStrategy.applyColumnState(isDeferredMode(params), colStateItems, eventType); refreshDeferredToolPanelUi(beans, params); } function setAllPivot(beans, columns, value, eventType, params) { setAllPivotActive(beans, columns, value, eventType, params); } function setAllPivotActive(beans, columns, value, eventType, params) { const updateStrategy = beans.columnStateUpdateStrategy; const colStateItems = []; const turnOnAction = (col) => { if (updateStrategy.isColumnSelectedInPivotModeToolPanel(isDeferredMode(params), col)) { return; } if (col.isAllowValue()) { const aggFunc = typeof col.getAggFunc() === "string" ? col.getAggFunc() : beans.aggFuncSvc?.getDefaultAggFunc(col); colStateItems.push({ colId: col.getId(), aggFunc }); } else if (col.isAllowRowGroup()) { colStateItems.push({ colId: col.getId(), rowGroup: true }); } else if (col.isAllowPivot()) { colStateItems.push({ colId: col.getId(), pivot: true }); } }; const turnOffAction = (col) => { const isActive = updateStrategy.isColumnSelectedInPivotModeToolPanel(isDeferredMode(params), col); if (isActive) { colStateItems.push({ colId: col.getId(), pivot: false, rowGroup: false, aggFunc: null }); } }; const action = value ? turnOnAction : turnOffAction; columns.forEach(action); updateStrategy.applyColumnState(isDeferredMode(params), colStateItems, eventType); refreshDeferredToolPanelUi(beans, params); } function updateColumns(beans, params) { const { columns, visibleState, pivotState, eventType } = params; const updateStrategy = beans.columnStateUpdateStrategy; const isPivotMode2 = updateStrategy.getPivotMode(isDeferredMode(params)); const state = columns.map((column) => { const colId = column.getColId(); if (isPivotMode2) { const pivotStateForColumn = pivotState?.[colId]; return { colId, pivot: pivotStateForColumn?.pivot, rowGroup: pivotStateForColumn?.rowGroup, aggFunc: pivotStateForColumn?.aggFunc }; } else { return { colId, hide: !visibleState?.[colId] }; } }); updateStrategy.applyColumnState(isDeferredMode(params), state, eventType); refreshDeferredToolPanelUi(beans, params); } function createPivotState(column) { return { pivot: column.isPivotActive(), rowGroup: column.isRowGroupActive(), aggFunc: column.isValueActive() ? column.getAggFunc() : undefined }; } function createPivotStateForToolPanel(column, updateStrategy, deferApply) { if (!deferApply) { return createPivotState(column); } const rowGroup = updateStrategy.getRowGroupColumns(deferApply).includes(column); const pivot = updateStrategy.getPivotColumns(deferApply).includes(column); const value = updateStrategy.getValueColumns(deferApply).includes(column); return { pivot, rowGroup, aggFunc: value ? updateStrategy.getColumnAggFunc(deferApply, column) : undefined }; } var getNodesFromMappedSet = (mappedSet, keys) => { if (!keys) { return []; } let mapPointer = mappedSet; for (let i = 0, len = keys.length;i < len && mapPointer; ++i) { mapPointer = mapPointer[keys[i]]; } return Array.isArray(mapPointer) ? mapPointer : []; }; var setAggData = (rowNode, newAggData, colModel) => { const oldAggData = rowNode.aggData; if (oldAggData === newAggData) { return; } rowNode.aggData = newAggData; if (rowNode.__localEventService) { fireAggDataChangedEvents(rowNode, oldAggData, newAggData, colModel); } }; var setAggDataWithSiblings = (rowNode, newAggData, colModel) => { setAggData(rowNode, newAggData, colModel); const pinnedSibling = rowNode.pinnedSibling; if (pinnedSibling) { setAggData(pinnedSibling, newAggData, colModel); } const sibling = rowNode.sibling; if (sibling) { setAggData(sibling, newAggData, colModel); const siblingPinnedSibling = sibling.pinnedSibling; if (siblingPinnedSibling) { setAggData(siblingPinnedSibling, newAggData, colModel); } } }; var fireAggDataChangedEvents = (rowNode, oldAggData, newAggData, colModel) => { if (!newAggData) { if (!oldAggData) { return; } const oldKeys2 = Object.keys(oldAggData); for (let i = 0, len = oldKeys2.length;i < len; ++i) { const colId = oldKeys2[i]; const column = colModel.getColById(colId); if (column) { rowNode.dispatchCellChangedEvent(column, undefined, oldAggData[colId]); } } return; } const newKeys = Object.keys(newAggData); for (let i = 0, len = newKeys.length;i < len; ++i) { const colId = newKeys[i]; const value = newAggData[colId]; const oldValue = oldAggData ? oldAggData[colId] : undefined; if (value === oldValue) { continue; } const column = colModel.getColById(colId); if (column) { rowNode.dispatchCellChangedEvent(column, value, oldValue); } } if (!oldAggData) { return; } const oldKeys = Object.keys(oldAggData); for (let i = 0, len = oldKeys.length;i < len; ++i) { const colId = oldKeys[i]; if (colId in newAggData) { continue; } const column = colModel.getColById(colId); if (column) { rowNode.dispatchCellChangedEvent(column, undefined, oldAggData[colId]); } } }; var doSetRowNodeGroup = (rowNode, beans, group) => { if (!rowNode) { return; } const oldGroup = rowNode.group; if (oldGroup === group) { return; } rowNode.group = group; rowNode.updateHasChildren(); if (oldGroup && !group) { setAggData(rowNode, null, beans.colModel); rowNode.setAllChildrenCount(null); } beans.selectionSvc?.updateRowSelectable(rowNode); rowNode.dispatchRowEvent("groupChanged"); }; var setRowNodeGroup = (rowNode, beans, group) => { doSetRowNodeGroup(rowNode, beans, group); doSetRowNodeGroup(rowNode.pinnedSibling, beans, group); }; var isRowGroupColLocked = (column, beans) => { const { gos, rowGroupColsSvc } = beans; if (!rowGroupColsSvc || !column) { return false; } const groupLockGroupColumns = gos.get("groupLockGroupColumns"); if (!column.isRowGroupActive() || groupLockGroupColumns === 0) { return false; } if (groupLockGroupColumns === -1) { return true; } const colIndex = rowGroupColsSvc.columns.findIndex((groupCol) => groupCol.getColId() === column.getColId()); return groupLockGroupColumns > colIndex; }; var getGroupingLocaleText = (localeTextFunc, key, displayName) => { const prefix = key === "groupBy" ? "Group by" : "Un-Group by"; const localStr = localeTextFunc(key, `${prefix} ${displayName}`, [displayName]); if (localStr.indexOf(displayName) >= 0) { return localStr; } else { return `${localStr} ${displayName}`; } }; function _getTextSelectionRanges(beans) { const rootNode = _getRootNode(beans); const selection = "getSelection" in rootNode ? rootNode.getSelection() : null; const ranges = []; for (let i = 0;i < (selection?.rangeCount ?? 0); i++) { const range = selection?.getRangeAt(i); if (range) { ranges.push(range); } } return { selection, ranges }; } function _preserveRangesWhile(beans, fn) { const enableCellTextSelection = beans.gos.get("enableCellTextSelection"); if (!enableCellTextSelection) { return fn(); } if (!_isBrowserFirefox() && !_isBrowserSafari()) { return fn(); } const { selection, ranges } = _getTextSelectionRanges(beans); fn(); selection?.removeAllRanges(); for (const range of ranges) { selection?.addRange(range); } } var MenuItemComponentType = { name: "menuItem", optionalMethods: ["setActive", "select", "setExpanded", "configureDefaults"] }; var MENU_ITEM_CALLBACKS = { getMenuItemComp: (beans, def, params) => { const compDetails = beans.userCompFactory.getCompDetails(def, MenuItemComponentType, "agMenuItem", _addGridCommonParams(beans.gos, params), true); return compDetails?.newAgStackInstance() ?? AgPromise.resolve(); }, getPostProcessPopupParams: ({ column, node }) => ({ column, rowNode: node }), preserveRangesWhile: _preserveRangesWhile, stopPropagationCallbacks: STOP_PROPAGATION_CALLBACKS, warnNoItem: (menuItemOrString) => { _warn(228, { menuItemOrString }); } }; var MenuItemComponent = class extends AgMenuItemComponent { constructor() { super(MENU_ITEM_CALLBACKS); } }; var MenuList = class extends AgMenuList { constructor(level, menuActionParams = { column: null, node: null, value: null }) { super(level, menuActionParams, MENU_ITEM_CALLBACKS); } }; var ToolPanelContextMenu = class extends Component { constructor(column, mouseEventOrTouch, parentEl, params = {}) { super({ tag: "div", cls: "ag-menu" }); this.column = column; this.mouseEventOrTouch = mouseEventOrTouch; this.parentEl = parentEl; this.params = params; this.displayName = null; } postConstruct() { const { column, beans: { colNames } } = this; this.initializeProperties(column); let displayName; if (isColumn(column)) { displayName = colNames.getDisplayNameForColumn(column, "columnToolPanel"); } else { displayName = colNames.getDisplayNameForProvidedColumnGroup(null, column, "columnToolPanel"); } this.displayName = displayName; this.buildMenuItemMap(); if (this.isActive()) { const mouseEventOrTouch = this.mouseEventOrTouch; if ("preventDefault" in mouseEventOrTouch) { mouseEventOrTouch.preventDefault(); } const menuItemsMapped = this.getMappedMenuItems(); if (menuItemsMapped.length === 0) { return; } this.displayContextMenu(menuItemsMapped); } } initializeProperties(column) { const updateStrategy = this.beans.columnStateUpdateStrategy; let columns; if (isProvidedColumnGroup(column)) { columns = column.getLeafColumns(); } else { columns = [column]; } this.columns = columns; const isPivotMode2 = updateStrategy.getPivotMode(isDeferredMode(this.params)); this.allowScrollIntoView = !isPivotMode2 && columns.some(this.isColumnValidForScrollIntoView); this.allowGrouping = columns.some((col) => col.isPrimary() && col.isAllowRowGroup()); this.allowValues = columns.some((col) => col.isPrimary() && col.isAllowValue()); this.allowPivoting = isPivotMode2 && columns.some((col) => col.isPrimary() && col.isAllowPivot()); } buildMenuItemMap() { const localeTextFunc = this.getLocaleTextFunc(); const { beans, displayName } = this; const updateStrategy = this.beans.columnStateUpdateStrategy; const menuItemMap = /* @__PURE__ */ new Map; this.menuItemMap = menuItemMap; const deferMode = isDeferredMode(this.params); const isPivotMode2 = updateStrategy.getPivotMode(deferMode); const rowGroupColIdSet = new Set(updateStrategy.getRowGroupColumns(deferMode).map((col) => col.getColId())); const valueColIdSet = new Set(updateStrategy.getValueColumns(deferMode).map((col) => col.getColId())); const pivotColIdSet = new Set(updateStrategy.getPivotColumns(deferMode).map((col) => col.getColId())); menuItemMap.set("scrollIntoView", { allowedFunction: (col) => !col.isPinned() && !isPivotMode2 && this.isColumnValidForScrollIntoView(col), activeFunction: () => false, activateLabel: () => localeTextFunc("scrollColumnIntoView", `Scroll ${displayName} into View`, [displayName]), activateFunction: () => { const firstVisibleColumn = this.columns.find(this.isColumnValidForScrollIntoView); if (firstVisibleColumn) { this.beans.ctrlsSvc.getScrollFeature().ensureColumnVisible(firstVisibleColumn); } }, deActivateFunction: () => {}, addIcon: "ensureColumnVisible" }); const rowGroupAllowed = (col) => col.isPrimary() && col.isAllowRowGroup() && !isRowGroupColLocked(col, beans); menuItemMap.set("rowGroup", { allowedFunction: rowGroupAllowed, activeFunction: (col) => rowGroupColIdSet.has(col.getColId()), activateLabel: () => getGroupingLocaleText(localeTextFunc, "groupBy", displayName), deactivateLabel: () => getGroupingLocaleText(localeTextFunc, "ungroupBy", displayName), activateFunction: () => { const columns = this.addColumnsToList(updateStrategy.getRowGroupColumns(deferMode), rowGroupAllowed); updateStrategy.setRowGroupColumns(deferMode, columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.params); }, deActivateFunction: () => { const columns = this.removeColumnsFromList(updateStrategy.getRowGroupColumns(deferMode), rowGroupAllowed); updateStrategy.setRowGroupColumns(deferMode, columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.params); }, addIcon: "menuAddRowGroup", removeIcon: "menuRemoveRowGroup" }); const valueAllowed = (col) => col.isPrimary() && col.isAllowValue(); menuItemMap.set("value", { allowedFunction: valueAllowed, activeFunction: (col) => valueColIdSet.has(col.getColId()), activateLabel: () => localeTextFunc("addToValues", `Add ${displayName} to values`, [displayName]), deactivateLabel: () => localeTextFunc("removeFromValues", `Remove ${displayName} from values`, [displayName]), activateFunction: () => { const columns = this.addColumnsToList(updateStrategy.getValueColumns(deferMode), valueAllowed); updateStrategy.setValueColumns(deferMode, columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.params); }, deActivateFunction: () => { const columns = this.removeColumnsFromList(updateStrategy.getValueColumns(deferMode), valueAllowed); updateStrategy.setValueColumns(deferMode, columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.params); }, addIcon: "valuePanel", removeIcon: "valuePanel" }); const pivotAllowed = (col) => isPivotMode2 && col.isPrimary() && col.isAllowPivot(); menuItemMap.set("pivot", { allowedFunction: pivotAllowed, activeFunction: (col) => pivotColIdSet.has(col.getColId()), activateLabel: () => localeTextFunc("addToLabels", `Add ${displayName} to labels`, [displayName]), deactivateLabel: () => localeTextFunc("removeFromLabels", `Remove ${displayName} from labels`, [displayName]), activateFunction: () => { const columns = this.addColumnsToList(updateStrategy.getPivotColumns(deferMode), pivotAllowed); updateStrategy.setPivotColumns(deferMode, columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.params); }, deActivateFunction: () => { const columns = this.removeColumnsFromList(updateStrategy.getPivotColumns(deferMode), pivotAllowed); updateStrategy.setPivotColumns(deferMode, columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.params); }, addIcon: "pivotPanel", removeIcon: "pivotPanel" }); } isColumnValidForScrollIntoView(col) { const isVisible = col.isVisible(); if (!isVisible) { return false; } const parent = col.getParent(); if (!parent) { return true; } return parent.getDisplayedChildren()?.includes(col) ?? true; } addColumnsToList(columnList, predicate) { return [...columnList].concat(this.columns.filter((col) => predicate(col) && !columnList.includes(col))); } removeColumnsFromList(columnList, predicate) { return columnList.filter((col) => !predicate(col) || !this.columns.includes(col)); } displayContextMenu(menuItemsMapped) { const eGui = this.getGui(); const menuList = this.createBean(new MenuList); const localeTextFunc = this.getLocaleTextFunc(); let hideFunc = () => {}; eGui.appendChild(menuList.getGui()); menuList.addMenuItems(menuItemsMapped); menuList.addManagedListeners(menuList, { closeMenu: () => { this.parentEl.focus(); hideFunc(); } }); const popupSvc = this.beans.popupSvc; const addPopupRes = popupSvc.addPopup({ modal: true, eChild: eGui, closeOnEsc: true, afterGuiAttached: () => _focusInto(menuList.getGui()), ariaLabel: localeTextFunc("ariaLabelContextMenu", "Context Menu"), closedCallback: (e) => { if (e instanceof KeyboardEvent) { this.parentEl.focus(); } this.destroyBean(menuList); } }); if (addPopupRes) { hideFunc = addPopupRes.hideFunc; } popupSvc.positionPopupUnderMouseEvent({ type: "columnContextMenu", mouseEvent: this.mouseEventOrTouch, ePopup: eGui }); } isActive() { return this.allowScrollIntoView || this.allowGrouping || this.allowValues || this.allowPivoting; } getMappedMenuItems() { const ret = []; const { menuItemMap, columns, displayName, beans } = this; for (const val of menuItemMap.values()) { const isInactive = columns.some((col) => val.allowedFunction(col) && !val.activeFunction(col)); const isActive = columns.some((col) => val.allowedFunction(col) && val.activeFunction(col)); if (isInactive) { ret.push({ name: val.activateLabel(displayName), icon: _createIconNoSpan(val.addIcon, beans, null), action: () => val.activateFunction() }); } if (isActive && val.removeIcon && val.deactivateLabel) { ret.push({ name: val.deactivateLabel(displayName), icon: _createIconNoSpan(val.removeIcon, beans, null), action: () => val.deActivateFunction?.() }); } } return ret; } }; var ToolPanelColumnGroupElement = { tag: "div", cls: "ag-column-select-column-group", children: [ { tag: "span", ref: "eColumnGroupIcons", cls: "ag-column-group-icons", children: [ { tag: "span", ref: "eGroupClosedIcon", cls: "ag-column-group-closed-icon" }, { tag: "span", ref: "eGroupOpenedIcon", cls: "ag-column-group-opened-icon" } ] }, { tag: "ag-checkbox", ref: "cbSelect", cls: "ag-column-select-checkbox" }, { tag: "span", ref: "eLabel", cls: "ag-column-select-column-label" } ] }; var ToolPanelColumnGroupComp = class extends Component { constructor(modelItem, allowDragging, eventType, focusWrapper, params) { super(); this.modelItem = modelItem; this.allowDragging = allowDragging; this.eventType = eventType; this.focusWrapper = focusWrapper; this.params = params; this.cbSelect = RefPlaceholder; this.eLabel = RefPlaceholder; this.eGroupOpenedIcon = RefPlaceholder; this.eGroupClosedIcon = RefPlaceholder; this.eColumnGroupIcons = RefPlaceholder; this.processingColumnStateChange = false; const { columnGroup, depth, displayName } = modelItem; this.columnGroup = columnGroup; this.columnDepth = depth; this.displayName = displayName; } postConstruct() { this.setTemplate(ToolPanelColumnGroupElement, [AgCheckboxSelector]); const { beans, cbSelect, eLabel, displayName, columnDepth, modelItem, focusWrapper, columnGroup } = this; const { registry, gos } = beans; const eDragHandle = _createIconNoSpan("columnDrag", beans); this.eDragHandle = eDragHandle; eDragHandle.classList.add("ag-drag-handle", "ag-column-select-column-group-drag-handle"); const checkboxGui = cbSelect.getGui(); const checkboxInput = cbSelect.getInputElement(); checkboxGui.after(eDragHandle); checkboxInput.setAttribute("tabindex", "-1"); eLabel.textContent = displayName ?? ""; this.setupExpandContract(); this.addCss("ag-column-select-indent-" + columnDepth); this.getGui().style.setProperty("--ag-indentation-level", String(columnDepth)); this.tooltipFeature = this.createOptionalManagedBean(registry.createDynamicBean("tooltipFeature", false, { getGui: () => this.focusWrapper, getLocation: () => "columnToolPanelColumnGroup", shouldDisplayTooltip: _getShouldDisplayTooltip(gos, () => eLabel) })); this.addManagedEventListeners({ columnPivotModeChanged: this.onColumnStateChanged.bind(this) }); this.addManagedElementListeners(eLabel, { click: this.onLabelClicked.bind(this) }); this.addManagedListeners(cbSelect, { fieldValueChanged: this.onCheckboxChanged.bind(this) }); this.addManagedListeners(modelItem, { expandedChanged: this.onExpandChanged.bind(this) }); const touchListener = new TouchListener(this.getGui(), false); this.addManagedListeners(touchListener, { longTap: (e) => this.onContextMenu(e.touchStart) }); this.addDestroyFunc(touchListener.destroy.bind(touchListener)); this.addManagedListeners(focusWrapper, { keydown: this.handleKeyDown.bind(this), contextmenu: this.onContextMenu.bind(this) }); this.setOpenClosedIcons(); this.setupDragging(); this.onColumnStateChanged(); this.addVisibilityListenersToAllChildren(); this.refreshAriaExpanded(); this.refreshAriaLabel(); this.setupTooltip(); const classes = _getToolPanelClassesFromColDef(columnGroup.getColGroupDef(), gos, null, columnGroup); for (const c of classes) { this.toggleCss(c, true); } } getColumns() { return this.columnGroup.getLeafColumns(); } setupTooltip() { const colGroupDef = this.columnGroup.getColGroupDef(); if (!colGroupDef) { return; } const refresh = () => this.tooltipFeature?.setTooltipAndRefresh(colGroupDef.headerTooltip); refresh(); this.addManagedEventListeners({ newColumnsLoaded: refresh }); } handleKeyDown(e) { switch (e.key) { case KeyCode.LEFT: e.preventDefault(); this.modelItem.expanded = false; break; case KeyCode.RIGHT: e.preventDefault(); this.modelItem.expanded = true; break; case KeyCode.SPACE: e.preventDefault(); if (this.isSelectable()) { this.onSelectAllChanged(!this.isSelected()); } break; } } onContextMenu(e) { const { columnGroup, gos } = this; if (gos.get("functionsReadOnly")) { return; } const contextMenu = this.createBean(new ToolPanelContextMenu(columnGroup, e, this.focusWrapper, this.params)); this.addDestroyFunc(() => { if (contextMenu.isAlive()) { this.destroyBean(contextMenu); } }); } addVisibilityListenersToAllChildren() { const listener = this.onColumnStateChanged.bind(this); for (const column of this.columnGroup.getLeafColumns()) { this.addManagedListeners(column, { visibleChanged: listener, columnValueChanged: listener, columnPivotChanged: listener, columnRowGroupChanged: listener }); } } setupDragging() { if (!this.allowDragging) { _setDisplayed(this.eDragHandle, false); return; } const beans = this.beans; const { gos, eventSvc, dragAndDrop } = beans; let hideColumnOnExit = !gos.get("suppressDragLeaveHidesColumns"); const dragSource = { type: DragSourceType.ToolPanel, eElement: this.eDragHandle, dragItemName: this.displayName, getDefaultIconName: () => hideColumnOnExit ? "hide" : "notAllowed", getDragItem: () => this.createDragItem(), onDragStarted: () => { hideColumnOnExit = !gos.get("suppressDragLeaveHidesColumns"); eventSvc.dispatchEvent({ type: "columnPanelItemDragStart", column: this.columnGroup }); }, onDragStopped: () => { eventSvc.dispatchEvent({ type: "columnPanelItemDragEnd" }); }, onGridEnter: (dragItem) => { if (hideColumnOnExit) { updateColumns(beans, { columns: this.columnGroup.getLeafColumns(), visibleState: dragItem?.visibleState, pivotState: dragItem?.pivotState, eventType: this.eventType, buttons: this.params.buttons }); } }, onGridExit: () => { if (hideColumnOnExit) { this.onChangeCommon(false); } } }; dragAndDrop.addDragSource(dragSource, true); this.addDestroyFunc(() => dragAndDrop.removeDragSource(dragSource)); } createDragItem() { const columns = this.columnGroup.getLeafColumns(); const visibleState = {}; const pivotState = {}; const updateStrategy = this.beans.columnStateUpdateStrategy; const deferApply = isDeferredMode(this.params); for (const col of columns) { const colId = col.getId(); visibleState[colId] = col.isVisible(); pivotState[colId] = createPivotStateForToolPanel(col, updateStrategy, deferApply); } return { columns, visibleState, pivotState }; } setupExpandContract() { const { beans, eGroupClosedIcon, eGroupOpenedIcon, eColumnGroupIcons } = this; eGroupClosedIcon.appendChild(_createIcon("columnSelectClosed", beans, null)); eGroupOpenedIcon.appendChild(_createIcon("columnSelectOpen", beans, null)); const listener = this.onExpandOrContractClicked.bind(this); this.addManagedElementListeners(eGroupClosedIcon, { click: listener }); this.addManagedElementListeners(eGroupOpenedIcon, { click: listener }); const touchListener = new TouchListener(eColumnGroupIcons, true); this.addManagedListeners(touchListener, { tap: listener }); this.addDestroyFunc(touchListener.destroy.bind(touchListener)); } onLabelClicked() { const nextState = !this.cbSelect.getValue(); this.onChangeCommon(nextState); } onCheckboxChanged(event) { this.onChangeCommon(event.selected); } getVisibleLeafColumns() { const childColumns = []; const extractCols = (children) => { for (const child of children) { if (child.passesFilter) { if (child.group) { extractCols(child.children); } else { childColumns.push(child.column); } } } }; extractCols(this.modelItem.children); return childColumns; } onChangeCommon(nextState) { this.refreshAriaLabel(); if (this.processingColumnStateChange) { return; } selectAllChildren(this.beans, this.modelItem.children, nextState, this.eventType, this.params); } refreshAriaLabel() { const { cbSelect, focusWrapper, displayName } = this; const translate = this.getLocaleTextFunc(); const columnLabel = translate("ariaColumnGroup", "Column Group"); const checkboxValue = cbSelect.getValue(); const state = checkboxValue === undefined ? translate("ariaIndeterminate", "indeterminate") : checkboxValue ? translate("ariaVisible", "visible") : translate("ariaHidden", "hidden"); const visibilityLabel = translate("ariaToggleVisibility", "Press SPACE to toggle visibility"); _setAriaLabel(focusWrapper, `${displayName} ${columnLabel}`); cbSelect.setInputAriaLabel(`${visibilityLabel} (${state})`); _setAriaDescribedBy(focusWrapper, cbSelect.getInputElement().id); } onColumnStateChanged() { const selectedValue = this.workOutSelectedValue(); const readOnlyValue = this.workOutReadOnlyValue(); this.processingColumnStateChange = true; const cbSelect = this.cbSelect; cbSelect.setValue(selectedValue); cbSelect.setReadOnly(readOnlyValue); this.toggleCss("ag-column-select-column-group-readonly", readOnlyValue); this.processingColumnStateChange = false; } workOutSelectedValue() { const updateStrategy = this.beans.columnStateUpdateStrategy; const pivotMode = updateStrategy.getPivotMode(isDeferredMode(this.params)); const visibleLeafColumns = this.getVisibleLeafColumns(); let checkedCount = 0; let uncheckedCount = 0; for (const column of visibleLeafColumns) { if (pivotMode || !column.getColDef().lockVisible) { if (this.isColumnChecked(column)) { checkedCount++; } else { uncheckedCount++; } } } if (checkedCount > 0 && uncheckedCount > 0) { return; } return checkedCount > 0; } workOutReadOnlyValue() { const pivotMode = this.beans.columnStateUpdateStrategy.getPivotMode(isDeferredMode(this.params)); let colsThatCanAction = 0; for (const col of this.columnGroup.getLeafColumns()) { if (pivotMode) { if (col.isAnyFunctionAllowed()) { colsThatCanAction++; } } else if (!col.getColDef().lockVisible) { colsThatCanAction++; } } return colsThatCanAction === 0; } isColumnChecked(column) { const updateStrategy = this.beans.columnStateUpdateStrategy; if (updateStrategy.getPivotMode(isDeferredMode(this.params))) { return updateStrategy.isColumnSelectedInPivotModeToolPanel(isDeferredMode(this.params), column); } return updateStrategy.isColumnVisibleInToolPanel(isDeferredMode(this.params), column); } onExpandOrContractClicked() { const modelItem = this.modelItem; const oldState = modelItem.expanded; modelItem.expanded = !oldState; } onExpandChanged() { this.setOpenClosedIcons(); this.refreshAriaExpanded(); } setOpenClosedIcons() { const folderOpen = this.modelItem.expanded; _setDisplayed(this.eGroupClosedIcon, !folderOpen); _setDisplayed(this.eGroupOpenedIcon, folderOpen); } refreshAriaExpanded() { _setAriaExpanded(this.focusWrapper, this.modelItem.expanded); } getDisplayName() { return this.displayName; } onSelectAllChanged(value) { const cbSelect = this.cbSelect; const cbValue = cbSelect.getValue(); const readOnly = cbSelect.isReadOnly(); if (!readOnly && (value && !cbValue || !value && cbValue)) { cbSelect.toggle(); } } isSelected() { return this.cbSelect.getValue(); } isSelectable() { return !this.cbSelect.isReadOnly(); } setSelected(selected) { this.cbSelect.setValue(selected, true); } }; var getCurrentColumnsBeingMoved = (column) => { if (isProvidedColumnGroup(column)) { return column.getLeafColumns(); } return column ? [column] : []; }; var getMoveTargetIndex = (currentColumns, lastHoveredColumn, isBefore, allColumns) => { if (!lastHoveredColumn || !currentColumns) { return null; } const targetColumnIndex = allColumns.indexOf(lastHoveredColumn); const adjustedTarget = isBefore ? targetColumnIndex : targetColumnIndex + 1; const diff = getMoveDiff(allColumns, currentColumns, adjustedTarget); return adjustedTarget - diff; }; var getMoveDiff = (allColumns, currentColumns, end) => { if (!currentColumns) { return 0; } const targetColumn = currentColumns[0]; const span = currentColumns.length; const currentIndex = allColumns.indexOf(targetColumn); if (currentIndex < end) { return span; } return 0; }; var isMoveBlocked = (gos, beans, currentColumns, params) => { const deferMode = isDeferredMode(params); const preventMoving = gos.get("suppressMovableColumns") || beans.columnStateUpdateStrategy.getPivotMode(deferMode); if (preventMoving) { return true; } const hasNotMovable = currentColumns.find(({ colDef }) => !!colDef.suppressMovable || !!colDef.lockPosition); return !!hasNotMovable; }; var moveItem = (beans, currentColumns, lastHoveredListItem, params) => { if (!lastHoveredListItem) { return; } const { component } = lastHoveredListItem; let lastHoveredColumn = null; let isBefore = lastHoveredListItem.position === "top"; if (component instanceof ToolPanelColumnGroupComp) { const columns = component.getColumns(); lastHoveredColumn = columns[0]; isBefore = true; } else if (component) { lastHoveredColumn = component.column; } if (!lastHoveredColumn) { return; } const deferMode = isDeferredMode(params); const allColumns = deferMode ? beans.columnStateUpdateStrategy.getPrimaryColumns(deferMode) : beans.colModel.getCols(); const targetIndex = getMoveTargetIndex(currentColumns, lastHoveredColumn, isBefore, allColumns); if (targetIndex != null) { beans.columnStateUpdateStrategy.moveColumns(deferMode, currentColumns, targetIndex, "toolPanelUi"); refreshDeferredToolPanelUi(beans, params); } }; var getCurrentDragValue = (listItemDragStartEvent) => { return listItemDragStartEvent.column; }; var ToolPanelColumnElement = { tag: "div", cls: "ag-column-select-column", children: [ { tag: "ag-checkbox", ref: "cbSelect", cls: "ag-column-select-checkbox" }, { tag: "span", ref: "eLabel", cls: "ag-column-select-column-label" } ] }; var ToolPanelColumnComp = class extends Component { constructor(modelItem, allowDragging, groupsExist, focusWrapper, params) { super(); this.modelItem = modelItem; this.allowDragging = allowDragging; this.groupsExist = groupsExist; this.focusWrapper = focusWrapper; this.params = params; this.eLabel = RefPlaceholder; this.cbSelect = RefPlaceholder; this.processingColumnStateChange = false; const { column, depth, displayName } = modelItem; this.column = column; this.columnDepth = depth; this.displayName = displayName; } postConstruct() { this.setTemplate(ToolPanelColumnElement, [AgCheckboxSelector]); const { beans, cbSelect, displayName, eLabel, columnDepth: indent, groupsExist, column, gos, focusWrapper } = this; const eDragHandle = _createIconNoSpan("columnDrag", beans); this.eDragHandle = eDragHandle; eDragHandle.classList.add("ag-drag-handle", "ag-column-select-column-drag-handle"); const checkboxGui = cbSelect.getGui(); const checkboxInput = cbSelect.getInputElement(); checkboxGui.after(eDragHandle); checkboxInput.setAttribute("tabindex", "-1"); eLabel.textContent = displayName; if (groupsExist) { this.addCss("ag-column-select-add-group-indent"); } this.addCss(`ag-column-select-indent-${indent}`); this.getGui().style.setProperty("--ag-indentation-level", String(indent)); this.tooltipFeature = this.createOptionalManagedBean(beans.registry.createDynamicBean("tooltipFeature", false, { getGui: () => this.focusWrapper, getLocation: () => "columnToolPanelColumn", shouldDisplayTooltip: _getShouldDisplayTooltip(gos, () => eLabel), getAdditionalParams: () => ({ colDef: column.getColDef() }) })); this.setupDragging(); const onColStateChanged = this.onColumnStateChanged.bind(this); this.addManagedEventListeners({ columnPivotModeChanged: onColStateChanged }); this.addManagedListeners(column, { columnValueChanged: onColStateChanged, columnPivotChanged: onColStateChanged, columnRowGroupChanged: onColStateChanged, visibleChanged: onColStateChanged }); this.addManagedListeners(focusWrapper, { keydown: this.handleKeyDown.bind(this), contextmenu: this.onContextMenu.bind(this) }); const touchListener = new TouchListener(focusWrapper); this.addManagedListeners(touchListener, { longTap: (e) => this.onContextMenu(e.touchStart) }); this.addDestroyFunc(touchListener.destroy.bind(touchListener)); this.addManagedPropertyListener("functionsReadOnly", this.onColumnStateChanged.bind(this)); this.addManagedListeners(cbSelect, { fieldValueChanged: this.onCheckboxChanged.bind(this) }); this.addManagedElementListeners(eLabel, { click: this.onLabelClicked.bind(this) }); this.onColumnStateChanged(); this.refreshAriaLabel(); this.setupTooltip(); const classes = _getToolPanelClassesFromColDef(column.getColDef(), gos, column, null); for (const c of classes) { this.toggleCss(c, true); } } getColumn() { return this.column; } setupTooltip() { const refresh = () => this.tooltipFeature?.setTooltipAndRefresh(this.column.getColDef().headerTooltip); refresh(); this.addManagedEventListeners({ newColumnsLoaded: refresh }); } onContextMenu(e) { const { column, gos } = this; if (gos.get("functionsReadOnly")) { return; } const contextMenu = this.createBean(new ToolPanelContextMenu(column, e, this.focusWrapper, this.params)); this.addDestroyFunc(() => { if (contextMenu.isAlive()) { this.destroyBean(contextMenu); } }); } handleKeyDown(e) { if (e.key === KeyCode.SPACE) { e.preventDefault(); if (this.isSelectable()) { this.onSelectAllChanged(!this.isSelected()); } } } onLabelClicked() { if (this.gos.get("functionsReadOnly")) { return; } const nextState = !this.cbSelect.getValue(); this.onChangeCommon(nextState); } onCheckboxChanged(event) { this.onChangeCommon(event.selected); } onChangeCommon(nextState) { if (this.cbSelect.isReadOnly()) { return; } this.refreshAriaLabel(); if (this.processingColumnStateChange) { return; } setAllColumns(this.beans, [this.column], nextState, "toolPanelUi", this.params); } refreshAriaLabel() { const { cbSelect, focusWrapper, displayName } = this; const translate = this.getLocaleTextFunc(); const columnLabel = translate("ariaColumn", "Column"); const state = cbSelect.getValue() ? translate("ariaVisible", "visible") : translate("ariaHidden", "hidden"); const visibilityLabel = translate("ariaToggleVisibility", "Press SPACE to toggle visibility"); _setAriaLabel(focusWrapper, `${displayName} ${columnLabel}`); this.cbSelect.setInputAriaLabel(`${visibilityLabel} (${state})`); _setAriaDescribedBy(focusWrapper, cbSelect.getInputElement().id); } setupDragging() { const eDragHandle = this.eDragHandle; if (!this.allowDragging) { _setDisplayed(eDragHandle, false); return; } const beans = this.beans; const { gos, eventSvc, dragAndDrop } = beans; if (isDeferredMode(this.params)) { eDragHandle.setAttribute("data-column-tool-panel-deferred", ""); } let hideColumnOnExit = !gos.get("suppressDragLeaveHidesColumns"); const dragSource = { type: DragSourceType.ToolPanel, eElement: eDragHandle, dragItemName: this.displayName, getDefaultIconName: () => hideColumnOnExit && !isDeferredMode(this.params) ? "hide" : "notAllowed", getDragItem: () => this.createDragItem(), onDragStarted: () => { hideColumnOnExit = !gos.get("suppressDragLeaveHidesColumns"); eventSvc.dispatchEvent({ type: "columnPanelItemDragStart", column: this.column }); }, onDragStopped: () => { eventSvc.dispatchEvent({ type: "columnPanelItemDragEnd" }); }, onGridEnter: (dragItem) => { if (hideColumnOnExit && !isDeferredMode(this.params)) { updateColumns(beans, { columns: [this.column], visibleState: dragItem?.visibleState, pivotState: dragItem?.pivotState, eventType: "toolPanelUi", buttons: this.params.buttons }); } }, onGridExit: () => { if (hideColumnOnExit && !isDeferredMode(this.params)) { this.onChangeCommon(false); } } }; dragAndDrop.addDragSource(dragSource, true); this.addDestroyFunc(() => dragAndDrop.removeDragSource(dragSource)); } createDragItem() { const colId = this.column.getColId(); const visibleState = { [colId]: this.column.isVisible() }; const updateStrategy = this.beans.columnStateUpdateStrategy; const pivotState = { [colId]: createPivotStateForToolPanel(this.column, updateStrategy, isDeferredMode(this.params)) }; return { columns: [this.column], visibleState, pivotState }; } onColumnStateChanged() { this.processingColumnStateChange = true; const updateStrategy = this.beans.columnStateUpdateStrategy; const isPivotMode2 = updateStrategy.getPivotMode(isDeferredMode(this.params)); if (isPivotMode2) { const anyFunctionActive = updateStrategy.isColumnSelectedInPivotModeToolPanel(isDeferredMode(this.params), this.column); this.cbSelect.setValue(anyFunctionActive); } else { this.cbSelect.setValue(updateStrategy.isColumnVisibleInToolPanel(isDeferredMode(this.params), this.column)); } let canBeToggled = true; let canBeDragged = true; if (isPivotMode2) { const functionsReadOnly = this.gos.get("functionsReadOnly"); const noFunctionsAllowed = !this.column.isAnyFunctionAllowed(); canBeToggled = !functionsReadOnly && !noFunctionsAllowed; canBeDragged = canBeToggled; } else { const { enableRowGroup, enableValue, lockPosition, suppressMovable, lockVisible } = this.column.getColDef(); const forceDraggable = !!enableRowGroup || !!enableValue; const disableDraggable = !!lockPosition || !!suppressMovable; canBeToggled = !lockVisible; canBeDragged = forceDraggable || !disableDraggable; } this.cbSelect.setReadOnly(!canBeToggled); this.eDragHandle.classList.toggle("ag-column-select-column-readonly", !canBeDragged); this.toggleCss("ag-column-select-column-readonly", !canBeDragged && !canBeToggled); this.cbSelect.setPassive(false); this.processingColumnStateChange = false; } getDisplayName() { return this.displayName; } onSelectAllChanged(value) { const cbSelect = this.cbSelect; if (value !== cbSelect.getValue()) { if (!cbSelect.isReadOnly()) { cbSelect.toggle(); } } } isSelected() { return this.cbSelect.getValue(); } isSelectable() { return !this.cbSelect.isReadOnly(); } isExpandable() { return false; } setExpanded(_value) { _warn(158); } }; var UIColumnModel = class { constructor(items) { this.items = items; } getRowCount() { return this.items.length; } getRow(index) { return this.items[index]; } }; var PRIMARY_COLS_LIST_PANEL_CLASS = "ag-column-select-list"; var AgPrimaryColsList = class extends Component { constructor() { super({ tag: "div", cls: PRIMARY_COLS_LIST_PANEL_CLASS, role: "presentation" }); this.destroyColumnItemFuncs = []; this.hasLoadedInitialState = false; this.isInitialState = false; this.skipRefocus = false; } wireBeans(beans) { this.colModel = beans.colModel; } destroy() { this.destroyColumnTree(); super.destroy(); } destroyColumnTree() { this.allColsTree = []; for (const f of this.destroyColumnItemFuncs) { f(); } this.destroyColumnItemFuncs = []; } init(params, allowDragging, eventType) { this.params = params; const { suppressSyncLayoutWithGrid, contractColumnSelection, suppressColumnMove } = params; this.allowDragging = allowDragging; this.eventType = eventType; if (!suppressSyncLayoutWithGrid) { this.addManagedEventListeners({ columnMoved: this.onColumnsChanged.bind(this) }); } this.addManagedEventListeners({ newColumnsLoaded: this.onColumnsChanged.bind(this) }); const listener = this.fireSelectionChangedEvent.bind(this); this.addManagedEventListeners({ columnPivotChanged: listener, columnPivotModeChanged: listener, columnRowGroupChanged: listener, columnValueChanged: listener, columnVisible: listener, newColumnsLoaded: listener }); this.expandGroupsByDefault = !contractColumnSelection; const isPreventMove = suppressColumnMove || suppressSyncLayoutWithGrid; const virtualList = this.createManagedBean(new VirtualList({ cssIdentifier: "column-select", ariaRole: "tree", moveItemCallback: (item, isUp) => { if (isPreventMove) { return; } this.moveItems(item, isUp); } })); this.virtualList = virtualList; this.appendChild(virtualList.getGui()); virtualList.setComponentCreator((item, listItemElement) => { _setAriaLevel(listItemElement, item.depth + 1); return this.createComponentFromItem(item, listItemElement); }); if (this.colModel.ready) { this.onColumnsChanged(); } if (isPreventMove) { return; } this.createItemDragFeature(); } createItemDragFeature() { const { gos, beans, virtualList } = this; this.createManagedBean(new VirtualListDragFeature(this, virtualList, { dragSourceType: DragSourceType.ToolPanel, addListeners: (parent, listItemDragStart, listItemDragEnd) => { parent.addManagedEventListeners({ columnPanelItemDragStart: listItemDragStart, columnPanelItemDragEnd: listItemDragEnd }); }, getCurrentDragValue: (listItemDragStartEvent) => getCurrentDragValue(listItemDragStartEvent), isMoveBlocked: (currentDragValue) => isMoveBlocked(gos, beans, getCurrentColumnsBeingMoved(currentDragValue), this.params), getNumRows: (comp) => comp.getDisplayedColsList().length, moveItem: (currentDragValue, lastHoveredListItem) => moveItem(beans, getCurrentColumnsBeingMoved(currentDragValue), lastHoveredListItem, this.params) })); } moveItems(item, isUp) { const { gos, beans } = this; const { modelItem } = item; const { group, columnGroup, column, expanded } = modelItem; const currentColumns = getCurrentColumnsBeingMoved(group ? columnGroup : column); if (isMoveBlocked(gos, beans, currentColumns, this.params)) { return; } const currentIndex = this.displayedColsList.indexOf(modelItem); const diff = isUp ? -1 : 1; let movePadding = 0; if (isUp) { const children = item.columnDepth > 0 ? column.getParent()?.getChildren() : null; if (children?.length && column === children[0]) { movePadding = -1; } } else if (group) { movePadding = expanded ? modelItem.children.length : 0; } const nextItem = Math.min(Math.max(currentIndex + movePadding + diff, 0), this.displayedColsList.length - 1); this.skipRefocus = true; moveItem(beans, currentColumns, { rowIndex: nextItem, position: isUp ? "top" : "bottom", component: this.virtualList.getComponentAt(nextItem) }, this.params); this.focusRowIfAlive(nextItem - movePadding).then(() => { this.skipRefocus = false; }); } createComponentFromItem(item, listItemElement) { const allowDragging = this.allowDragging; if (item.group) { const renderedGroup = new ToolPanelColumnGroupComp(item, allowDragging, this.eventType, listItemElement, this.params); this.createBean(renderedGroup); return renderedGroup; } const columnComp = new ToolPanelColumnComp(item, allowDragging, this.groupsExist, listItemElement, this.params); this.createBean(columnComp); return columnComp; } onColumnsChanged() { const params = this.params; if (!this.hasLoadedInitialState) { this.hasLoadedInitialState = true; this.isInitialState = !!params.initialState; } const expandedStates = this.getExpandedStates(); const pivotModeActive = this.colModel.isPivotMode(); const deferApply = isDeferredMode(params); const hasDeferredColumnOrder = deferApply && this.beans.columnStateUpdateStrategy.hasDeferredColumnOrder(deferApply); const shouldSyncColumnLayoutWithGrid = (!params.suppressSyncLayoutWithGrid || deferApply) && !pivotModeActive || hasDeferredColumnOrder; if (shouldSyncColumnLayoutWithGrid) { this.buildTreeFromWhatGridIsDisplaying(); } else { this.buildTreeFromProvidedColumnDefs(); } this.setExpandedStates(expandedStates); this.markFilteredColumns(); this.flattenAndFilterModel(); this.isInitialState = false; } getDisplayedColsList() { return this.displayedColsList; } getExpandedStates() { const res = {}; if (this.isInitialState) { const { expandedGroupIds } = this.params.initialState; for (const id of expandedGroupIds) { res[id] = true; } return res; } if (!this.allColsTree) { return {}; } this.forEachItem((item) => { if (!item.group) { return; } const colGroup = item.columnGroup; if (colGroup) { res[colGroup.getId()] = item.expanded; } }); return res; } setExpandedStates(states) { if (!this.allColsTree) { return; } const { isInitialState } = this; this.forEachItem((item) => { if (!item.group) { return; } const colGroup = item.columnGroup; if (colGroup) { const expanded = states[colGroup.getId()]; const groupExistedLastTime = expanded != null; if (groupExistedLastTime || isInitialState) { item.expanded = !!expanded; } } }); } buildTreeFromWhatGridIsDisplaying() { const deferApply = isDeferredMode(this.params); if (deferApply && this.beans.columnStateUpdateStrategy.hasDeferredColumnOrder(deferApply)) { const columnOrder = this.beans.columnStateUpdateStrategy.getPrimaryColumns(deferApply); if (columnOrder.length > 0) { syncLayoutWithColumns(columnOrder, this.setColumnLayout.bind(this)); return; } } if (this.params.suppressSyncLayoutWithGrid) { this.buildTreeFromProvidedColumnDefs(); return; } syncLayoutWithGrid(this.colModel, this.setColumnLayout.bind(this)); } setColumnLayout(colDefs) { const columnTree = toolPanelCreateColumnTree(this.colModel, colDefs); this.buildListModel(columnTree); this.groupsExist = colDefs.some((colDef) => { return colDef && typeof colDef.children !== "undefined"; }); this.markFilteredColumns(); this.flattenAndFilterModel(); } buildTreeFromProvidedColumnDefs() { const colModel = this.colModel; this.buildListModel(colModel.getColDefColTree()); this.groupsExist = !!colModel.colDefCols?.treeDepth; } buildListModel(columnTree) { const columnExpandedListener = this.onColumnExpanded.bind(this); const addListeners = (item) => { item.addEventListener("expandedChanged", columnExpandedListener); const removeFunc = item.removeEventListener.bind(item, "expandedChanged", columnExpandedListener); this.destroyColumnItemFuncs.push(removeFunc); }; const colNames = this.beans.colNames; const recursivelyBuild = (tree, depth, parentList) => { for (const child of tree) { if (isProvidedColumnGroup(child)) { createGroupItem(child, depth, parentList); } else { createColumnItem(child, depth, parentList); } } }; const createGroupItem = (columnGroup, depth, parentList) => { const columnGroupDef = columnGroup.getColGroupDef(); const skipThisGroup = columnGroupDef?.suppressColumnsToolPanel; if (skipThisGroup) { return; } if (columnGroup.isPadding()) { recursivelyBuild(columnGroup.getChildren(), depth, parentList); return; } const displayName = colNames.getDisplayNameForProvidedColumnGroup(null, columnGroup, "columnToolPanel"); const item = new ColumnModelItem(displayName, columnGroup, depth, true, this.expandGroupsByDefault); parentList.push(item); addListeners(item); recursivelyBuild(columnGroup.getChildren(), depth + 1, item.children); }; const createColumnItem = (column, depth, parentList) => { const skipThisColumn = column.getColDef()?.suppressColumnsToolPanel; if (skipThisColumn) { return; } const displayName = colNames.getDisplayNameForColumn(column, "columnToolPanel"); parentList.push(new ColumnModelItem(displayName, column, depth)); }; this.destroyColumnTree(); recursivelyBuild(columnTree, 0, this.allColsTree); } onColumnExpanded() { this.flattenAndFilterModel(); } flattenAndFilterModel() { this.displayedColsList = []; const recursiveFunc = (item) => { if (!item.passesFilter) { return; } this.displayedColsList.push(item); if (item.group && item.expanded) { item.children.forEach(recursiveFunc); } }; const virtualList = this.virtualList; this.allColsTree.forEach(recursiveFunc); virtualList.setModel(new UIColumnModel(this.displayedColsList)); let focusedRow = null; if (!this.skipRefocus) { focusedRow = virtualList.getLastFocusedRow(); } virtualList.refresh(); if (focusedRow != null) { this.focusRowIfAlive(focusedRow); } this.notifyListeners(); this.refreshAriaLabel(); } refreshAriaLabel() { const translate = this.getLocaleTextFunc(); const columnListName = translate("ariaColumnPanelList", "Column List"); const localeColumns = translate("columns", "Columns"); const items = this.displayedColsList.length; _setAriaLabel(this.virtualList.getAriaElement(), `${columnListName} ${items} ${localeColumns}`); } focusRowIfAlive(rowIndex) { if (rowIndex === -1) { return Promise.resolve(); } return new Promise((res) => { window.setTimeout(() => { if (this.isAlive()) { this.virtualList.focusRow(rowIndex); } res(); }, 0); }); } forEachItem(callback) { const recursiveFunc = (items) => { for (const item of items) { callback(item); if (item.group) { recursiveFunc(item.children); } } }; const allColsTree = this.allColsTree; if (!allColsTree) { return; } recursiveFunc(allColsTree); } doSetExpandedAll(value) { this.forEachItem((item) => { if (item.group) { item.expanded = value; } }); } setGroupsExpanded(expand, groupIds) { if (!groupIds) { this.doSetExpandedAll(expand); return; } const expandedGroupIds = []; this.forEachItem((item) => { if (!item.group) { return; } const groupId = item.columnGroup.getId(); if (groupIds.indexOf(groupId) >= 0) { item.expanded = expand; expandedGroupIds.push(groupId); } }); const unrecognisedGroupIds = groupIds.filter((groupId) => !expandedGroupIds.includes(groupId)); if (unrecognisedGroupIds.length > 0) { _warn(157, { unrecognisedGroupIds }); } } getExpandState() { let expandedCount = 0; let notExpandedCount = 0; this.forEachItem((item) => { if (!item.group) { return; } if (item.expanded) { expandedCount++; } else { notExpandedCount++; } }); if (expandedCount > 0 && notExpandedCount > 0) { return 2; } if (notExpandedCount > 0) { return 1; } return 0; } doSetSelectedAll(selectAllChecked) { selectAllChildren(this.beans, this.allColsTree, selectAllChecked, this.eventType, this.params); this.syncVisibleSelectionState(); this.fireSelectionChangedEvent(); } syncVisibleSelectionState() { for (let i = 0;i < this.displayedColsList.length; i++) { const comp = this.virtualList.getComponentAt(i); comp?.onColumnStateChanged?.(); } } getSelectionState() { let checkedCount = 0; let uncheckedCount = 0; const updateStrategy = this.beans.columnStateUpdateStrategy; const pivotMode = updateStrategy.getPivotMode(isDeferredMode(this.params)); this.forEachItem((item) => { if (item.group) { return; } if (!item.passesFilter) { return; } const column = item.column; const colDef = column.getColDef(); let checked; if (pivotMode) { const noPivotModeOptionsAllowed = !column.isAllowPivot() && !column.isAllowRowGroup() && !column.isAllowValue(); if (noPivotModeOptionsAllowed) { return; } checked = updateStrategy.isColumnSelectedInPivotModeToolPanel(isDeferredMode(this.params), column) ?? false; } else { if (colDef.lockVisible) { return; } checked = updateStrategy.isColumnVisibleInToolPanel(isDeferredMode(this.params), column) ?? false; } if (checked) { checkedCount++; } else { uncheckedCount++; } }); if (checkedCount > 0 && uncheckedCount > 0) { return; } return !(checkedCount === 0 || uncheckedCount > 0); } setFilterText(filterText) { this.filterText = _exists(filterText) ? filterText.toLowerCase() : null; this.markFilteredColumns(); this.flattenAndFilterModel(); } markFilteredColumns() { const passesFilter = (item) => { if (!_exists(this.filterText)) { return true; } const displayName = item.displayName; return displayName == null || displayName.toLowerCase().indexOf(this.filterText) !== -1; }; const recursivelyCheckFilter = (item, parentPasses) => { let atLeastOneChildPassed = false; if (item.group) { const groupPasses = passesFilter(item); for (const child of item.children) { const childPasses = recursivelyCheckFilter(child, groupPasses || parentPasses); if (childPasses) { atLeastOneChildPassed = childPasses; } } } const filterPasses = parentPasses || atLeastOneChildPassed ? true : passesFilter(item); item.passesFilter = filterPasses; return filterPasses; }; for (const item of this.allColsTree) { recursivelyCheckFilter(item, false); } } notifyListeners() { this.fireGroupExpandedEvent(); this.fireSelectionChangedEvent(); } fireGroupExpandedEvent() { const expandState = this.getExpandState(); this.dispatchLocalEvent({ type: "groupExpanded", state: expandState }); } fireSelectionChangedEvent() { if (!this.allColsTree) { return; } const selectionState = this.getSelectionState(); this.dispatchLocalEvent({ type: "selectionChanged", state: selectionState }); } getExpandedGroups() { const expandedGroupIds = []; if (!this.allColsTree) { return expandedGroupIds; } this.forEachItem((item) => { if (item.group && item.expanded) { expandedGroupIds.push(item.columnGroup.getId()); } }); return expandedGroupIds; } }; var AgPrimaryColsListSelector = { selector: "AG-PRIMARY-COLS-LIST", component: AgPrimaryColsList }; var AgPrimaryColsElement = { tag: "div", cls: "ag-column-select", children: [ { tag: "ag-primary-cols-header", ref: "primaryColsHeaderPanel" }, { tag: "ag-primary-cols-list", ref: "primaryColsListPanel" } ] }; var AgPrimaryCols = class extends Component { constructor() { super(AgPrimaryColsElement, [AgPrimaryColsHeaderSelector, AgPrimaryColsListSelector]); this.primaryColsHeaderPanel = RefPlaceholder; this.primaryColsListPanel = RefPlaceholder; this.registerCSS(agPrimaryCols_default); } init(allowDragging, params, eventType) { const { primaryColsHeaderPanel, primaryColsListPanel } = this; primaryColsHeaderPanel.init(params); const hideFilter = params.suppressColumnFilter; const hideSelect = params.suppressColumnSelectAll; const hideExpand = params.suppressColumnExpandAll; if (hideExpand && hideFilter && hideSelect) { primaryColsHeaderPanel.setDisplayed(false); } this.addManagedListeners(primaryColsListPanel, { groupExpanded: (event) => { primaryColsHeaderPanel.setExpandState(event.state); params.onStateUpdated(); }, selectionChanged: (event) => primaryColsHeaderPanel.setSelectionState(event.state) }); primaryColsListPanel.init(params, allowDragging, eventType); this.addManagedListeners(primaryColsHeaderPanel, { expandAll: primaryColsListPanel.doSetExpandedAll.bind(primaryColsListPanel, true), collapseAll: primaryColsListPanel.doSetExpandedAll.bind(primaryColsListPanel, false), selectAll: primaryColsListPanel.doSetSelectedAll.bind(primaryColsListPanel, true), unselectAll: primaryColsListPanel.doSetSelectedAll.bind(primaryColsListPanel, false), filterChanged: (event) => primaryColsListPanel.setFilterText(event.filterText) }); this.positionableFeature = this.createManagedBean(new PositionableFeature(this.getGui(), { minHeight: 100 })); } toggleResizable(resizable) { this.positionableFeature.setResizable(resizable ? { bottom: true } : false); } expandGroups(groupIds) { this.primaryColsListPanel.setGroupsExpanded(true, groupIds); } collapseGroups(groupIds) { this.primaryColsListPanel.setGroupsExpanded(false, groupIds); } setColumnLayout(colDefs) { this.primaryColsListPanel.setColumnLayout(colDefs); } syncLayoutWithGrid() { this.primaryColsListPanel.onColumnsChanged(); } getExpandedGroups() { return this.primaryColsListPanel.getExpandedGroups(); } }; var columnToolPanel_default = ".ag-column-panel{display:flex;flex:1 1 auto;flex-direction:column;overflow:hidden}.ag-pivot-mode-panel{display:flex;height:var(--ag-header-height)}.ag-pivot-mode-select{align-items:center;display:flex}:where(.ag-ltr) .ag-pivot-mode-select{margin-left:var(--ag-widget-container-horizontal-padding)}:where(.ag-rtl) .ag-pivot-mode-select{margin-right:var(--ag-widget-container-horizontal-padding)}.ag-column-panel-column-select:where(:not(.ag-last-visible-child)){border-bottom:var(--ag-tool-panel-separator-border)}.ag-column-panel-column-select:where(:nth-child(n+2 of :not(.ag-hidden))){border-top:var(--ag-tool-panel-separator-border)}:where(.ag-column-panel) .ag-column-drop-vertical{flex:1 1 0px;min-height:50px}:where(.ag-column-panel) .ag-column-drop-vertical:where(:not(.ag-last-column-drop)){border-bottom:var(--ag-tool-panel-separator-border)}.ag-column-panel-buttons{display:flex;flex-wrap:wrap;gap:var(--ag-widget-vertical-spacing) var(--ag-widget-horizontal-spacing);justify-content:flex-end;overflow:hidden;padding:var(--ag-widget-container-vertical-padding) var(--ag-widget-container-horizontal-padding) 0;:where(.ag-standard-button){transition:background-color .25s ease-in-out,color .25s ease-in-out}}.ag-column-panel-buttons:where(:last-child){padding-bottom:var(--ag-widget-container-vertical-padding)}.ag-column-panel-buttons-button{line-height:1.5}:where(.ag-column-panel) .ag-column-panel-buttons-apply-button:not(:disabled){background-color:var(--ag-column-panel-apply-button-background-color);color:var(--ag-column-panel-apply-button-color)}"; var DEFERRED_TOOL_PANEL_CLASS = "ag-column-panel-deferred"; var ColumnToolPanel = class extends Component { constructor() { super({ tag: "div", cls: "ag-column-panel" }); this.initialised = false; this.childDestroyFuncs = []; this.isDeferModeEnabled = false; this.isCommitting = false; this.onDeferredApply = () => { this.isCommitting = true; try { this.beans.columnStateUpdateStrategy.commit(this.isDeferModeEnabled); } finally { this.isCommitting = false; } this.deferredButtonsComp?.updateValidity(false); this.lastKnownGridState = this.captureGridState(); }; this.onDeferredCancel = () => { this.beans.columnStateUpdateStrategy.reset(this.isDeferModeEnabled); this.deferredButtonsComp?.updateValidity(false); this.refreshToolPanelLayouts(); this.pivotModePanel?.refreshEditStrategy(); this.lastKnownGridState = this.captureGridState(); }; this.onPivotModePanelValueChanged = () => { this.refreshToolPanelLayouts(); this.setLastVisible(); this.deferredButtonsComp?.updateValidity(this.beans.columnStateUpdateStrategy.hasPendingChanges(this.isDeferModeEnabled)); }; this.onColumnEverythingChanged = () => { if (!this.isDeferModeEnabled || this.isCommitting) { return; } const currentState = this.captureGridState(); if (!this.beans.columnStateUpdateStrategy.hasPendingChanges(this.isDeferModeEnabled)) { this.lastKnownGridState = currentState; return; } const isNoOp = this.lastKnownGridState && this.isGridStateEqual(this.lastKnownGridState, currentState); this.lastKnownGridState = currentState; if (!isNoOp) { return; } this.resetDeferredState(); }; this.onExternalGridChange = () => { if (!this.isDeferModeEnabled || this.isCommitting) { return; } if (!this.beans.columnStateUpdateStrategy.hasPendingChanges(this.isDeferModeEnabled)) { return; } this.resetDeferredState(); this.lastKnownGridState = this.captureGridState(); }; this.registerCSS(columnToolPanel_default); } wireBeans(beans) { this.colToolPanelFactory = beans.colToolPanelFactory; } setVisible(visible) { super.setDisplayed(visible); if (visible && !this.initialised) { this.init(this.params); } } init(params) { const defaultParams = _addGridCommonParams(this.gos, { suppressColumnMove: false, suppressColumnSelectAll: false, suppressColumnFilter: false, suppressColumnExpandAll: false, contractColumnSelection: false, suppressPivotMode: false, suppressRowGroups: false, suppressValues: false, suppressPivots: false, suppressSyncLayoutWithGrid: false }); const mergedParams = { ...defaultParams, ...params }; this.params = mergedParams; const { childDestroyFuncs, colToolPanelFactory, gos } = this; const hasPivotModule = gos.isModuleRegistered("SharedPivot"); const hasRowGroupingModule = hasPivotModule || gos.isModuleRegistered("SharedRowGrouping"); this.isDeferModeEnabled = isDeferredMode(mergedParams); this.toggleCss(DEFERRED_TOOL_PANEL_CLASS, this.isDeferModeEnabled); if (!mergedParams.suppressPivotMode && colToolPanelFactory && hasPivotModule) { this.pivotModePanel = colToolPanelFactory.createPivotModePanel(this, childDestroyFuncs, mergedParams, this.onPivotModePanelValueChanged); } const primaryColsPanel = this.createBean(new AgPrimaryCols); this.primaryColsPanel = primaryColsPanel; childDestroyFuncs.push(() => this.destroyBean(this.primaryColsPanel)); primaryColsPanel.init(true, mergedParams, "toolPanelUi"); primaryColsPanel.addCss("ag-column-panel-column-select"); this.appendChild(primaryColsPanel); if (colToolPanelFactory) { if (!mergedParams.suppressRowGroups && hasRowGroupingModule) { this.rowGroupDropZonePanel = colToolPanelFactory.createRowGroupPanel(this, childDestroyFuncs, mergedParams); } if (!mergedParams.suppressValues && hasRowGroupingModule) { this.valuesDropZonePanel = colToolPanelFactory.createValuesPanel(this, childDestroyFuncs, mergedParams); } if (!mergedParams.suppressPivots && hasPivotModule) { this.pivotDropZonePanel = colToolPanelFactory.createPivotPanel(this, childDestroyFuncs, mergedParams); } this.setLastVisible(); const [pivotModeListener] = this.addManagedEventListeners({ columnPivotModeChanged: () => { this.resetChildrenHeight(); this.setLastVisible(); } }); childDestroyFuncs.push(() => pivotModeListener()); } if (this.isDeferModeEnabled) { const resetListener = this.onExternalGridChange; childDestroyFuncs.push(...this.addManagedEventListeners({ columnEverythingChanged: this.onColumnEverythingChanged, sortChanged: resetListener, columnVisible: resetListener, columnRowGroupChanged: resetListener, columnValueChanged: resetListener, columnPivotChanged: resetListener, columnPivotModeChanged: resetListener, newColumnsLoaded: resetListener, ...mergedParams.suppressSyncLayoutWithGrid ? {} : { columnMoved: resetListener } })); } if (mergedParams.buttons) { if (!mergedParams.buttons.includes("apply")) { _warn(298); } if (mergedParams.buttons.length) { this.initDeferredButtons(mergedParams.buttons); } } this.initialised = true; } initDeferredButtons(buttons) { const buttonComp = this.createBean(new FilterButtonComp({ className: "ag-column-panel-buttons" })); this.deferredButtonsComp = buttonComp; this.childDestroyFuncs.push(() => { this.deferredButtonsComp = this.destroyBean(this.deferredButtonsComp); }); const translate = this.getLocaleTextFunc(); const buttonDefs = buttons.map((type) => ({ type, label: translate(type === "apply" ? "applyColumnToolPanel" : "cancelColumnToolPanel", type === "apply" ? "Apply" : "Cancel") })); buttonComp.updateButtons(buttonDefs); buttonComp.updateValidity(false); buttonComp.addManagedListeners(buttonComp, { apply: this.onDeferredApply, cancel: this.onDeferredCancel }); this.appendChild(buttonComp); } resetDeferredState() { this.beans.columnStateUpdateStrategy.reset(this.isDeferModeEnabled); this.deferredButtonsComp?.updateValidity(false); this.refreshToolPanelLayouts(); this.pivotModePanel?.refreshEditStrategy(); } captureGridState() { const { beans } = this; const getColIds = (cols) => (cols ?? []).map((c) => c.getColId()); return { rowGroupColIds: getColIds(beans.rowGroupColsSvc?.columns), valueColIds: getColIds(beans.valueColsSvc?.columns), pivotColIds: getColIds(beans.pivotColsSvc?.columns), pivotMode: beans.colModel.isPivotMode(), columnOrder: beans.colModel.getCols().map((c) => c.getColId()), visibleColIds: beans.colModel.getCols().filter((c) => c.isVisible()).map((c) => c.getColId()), sortState: beans.colModel.getCols().filter((c) => c.getSort()).map((c) => `${c.getColId()}:${c.getSort()}:${c.getSortIndex()}`), aggFuncState: (beans.valueColsSvc?.columns ?? []).map((c) => c.getAggFunc()), widthState: beans.colModel.getCols().map((c) => `${c.getColId()}:${c.getActualWidth()}`) }; } isGridStateEqual(a, b) { return _areEqual(a.rowGroupColIds, b.rowGroupColIds) && _areEqual(a.valueColIds, b.valueColIds) && _areEqual(a.pivotColIds, b.pivotColIds) && a.pivotMode === b.pivotMode && _areEqual(a.columnOrder, b.columnOrder) && _areEqual(a.visibleColIds, b.visibleColIds) && _areEqual(a.sortState, b.sortState) && _areEqual(a.aggFuncState, b.aggFuncState) && _areEqual(a.widthState, b.widthState); } refreshDeferredUi() { this.refreshToolPanelLayouts(); this.setLastVisible(); this.pivotModePanel?.refreshEditStrategy(); this.deferredButtonsComp?.updateValidity(this.beans.columnStateUpdateStrategy.hasPendingChanges(this.isDeferModeEnabled)); } refreshToolPanelLayouts() { this.primaryColsPanel.syncLayoutWithGrid(); this.rowGroupDropZonePanel?.refreshGui(); this.valuesDropZonePanel?.refreshGui(); this.pivotDropZonePanel?.refresh(); } setPivotModeSectionVisible(visible) { const colToolPanelFactory = this.colToolPanelFactory; if (!colToolPanelFactory) { return; } this.pivotModePanel = colToolPanelFactory.setPanelVisible(this.pivotModePanel, visible, colToolPanelFactory.createPivotModePanel.bind(colToolPanelFactory, this, this.childDestroyFuncs, this.params, this.onPivotModePanelValueChanged, true)); this.setLastVisible(); } setRowGroupsSectionVisible(visible) { const colToolPanelFactory = this.colToolPanelFactory; if (!colToolPanelFactory) { return; } this.rowGroupDropZonePanel = colToolPanelFactory.setPanelVisible(this.rowGroupDropZonePanel, visible, colToolPanelFactory.createRowGroupPanel.bind(colToolPanelFactory, this, this.childDestroyFuncs, this.params)); this.setLastVisible(); } setValuesSectionVisible(visible) { const colToolPanelFactory = this.colToolPanelFactory; if (!colToolPanelFactory) { return; } this.valuesDropZonePanel = colToolPanelFactory.setPanelVisible(this.valuesDropZonePanel, visible, colToolPanelFactory.createValuesPanel.bind(colToolPanelFactory, this, this.childDestroyFuncs, this.params)); this.setLastVisible(); } setPivotSectionVisible(visible) { const colToolPanelFactory = this.colToolPanelFactory; if (!colToolPanelFactory) { return; } this.pivotDropZonePanel = colToolPanelFactory.setPanelVisible(this.pivotDropZonePanel, visible, colToolPanelFactory.createPivotPanel.bind(colToolPanelFactory, this, this.childDestroyFuncs, this.params)); this.pivotDropZonePanel?.setDisplayed(visible); this.setLastVisible(); } setResizers() { for (const panel of [ this.primaryColsPanel, this.rowGroupDropZonePanel, this.valuesDropZonePanel, this.pivotDropZonePanel ]) { if (!panel) { continue; } const eGui = panel.getGui(); panel.toggleResizable(!eGui.classList.contains("ag-last-column-drop") && !eGui.classList.contains("ag-hidden") && !eGui.classList.contains("ag-last-visible-child")); } } setLastVisible() { const eGui = this.getGui(); const columnDrops = Array.prototype.slice.call(eGui.querySelectorAll(".ag-column-drop")); for (const columnDrop of columnDrops) { columnDrop.classList.remove("ag-last-column-drop"); } const columnDropEls = eGui.querySelectorAll(".ag-column-drop:not(.ag-hidden)"); const lastVisible = _last(columnDropEls); if (lastVisible) { lastVisible.classList.add("ag-last-column-drop"); } this.primaryColsPanel.getGui().classList.toggle("ag-last-visible-child", !lastVisible); this.setResizers(); } resetChildrenHeight() { const eGui = this.getGui(); const children = eGui.children; for (let i = 0;i < children.length; i++) { const { style } = children[i]; style.removeProperty("height"); style.removeProperty("flex"); } } expandColumnGroups(groupIds) { this.primaryColsPanel.expandGroups(groupIds); } collapseColumnGroups(groupIds) { this.primaryColsPanel.collapseGroups(groupIds); } setColumnLayout(colDefs) { this.primaryColsPanel.setColumnLayout(colDefs); } syncLayoutWithGrid() { this.primaryColsPanel.syncLayoutWithGrid(); } destroyChildren() { const childDestroyFuncs = this.childDestroyFuncs; for (const func of childDestroyFuncs) { func(); } childDestroyFuncs.length = 0; _clearElement(this.getGui()); } refresh(params) { this.destroyChildren(); this.init(params); return true; } getState() { return { expandedGroupIds: this.primaryColsPanel.getExpandedGroups() }; } destroy() { this.destroyChildren(); super.destroy(); } }; var pillDropZonePanel_default = ".ag-column-drop{align-items:center;display:inline-flex;overflow:auto;position:relative;width:100%}.ag-column-drop-list{align-items:center;display:flex}.ag-column-drop-cell{align-items:center;background-color:var(--ag-column-drop-cell-background-color);border:var(--ag-column-drop-cell-border);border-radius:500px;color:var(--ag-column-drop-cell-text-color);display:flex;padding:calc(var(--ag-spacing)*.25);position:relative;&:focus-visible{box-shadow:var(--ag-focus-shadow)}:where(.ag-drag-handle){color:var(--ag-column-drop-cell-drag-handle-color)}}:where(.ag-ltr) .ag-column-drop-cell{padding-left:calc(var(--ag-spacing)*.75)}:where(.ag-rtl) .ag-column-drop-cell{padding-right:calc(var(--ag-spacing)*.75)}.ag-column-drop-cell-text{flex:1 1 auto;margin:0 var(--ag-spacing);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ag-column-drop-vertical{align-items:stretch;display:flex;flex-direction:column;min-height:75px;overflow:hidden}.ag-column-drop-vertical-title-bar{align-items:center;display:flex;flex:none;padding:var(--ag-widget-container-vertical-padding) calc(var(--ag-spacing)*2) 0}.ag-column-drop-vertical-list{align-items:stretch;flex-direction:column;flex-grow:1;overflow-x:auto;padding-bottom:var(--ag-spacing);padding-left:var(--ag-spacing);padding-right:var(--ag-spacing);position:relative}:where(.ag-column-drop-empty) .ag-column-drop-vertical-list{overflow:hidden}.ag-column-drop-cell-button{cursor:pointer;min-width:0;opacity:.75}:where(.ag-ltr) .ag-column-drop-cell-button{margin-right:calc(var(--ag-spacing)/4)}:where(.ag-rtl) .ag-column-drop-cell-button{margin-left:calc(var(--ag-spacing)/4)}.ag-column-drop-cell-button:hover{opacity:1}:where(.ag-ltr) .ag-column-drop-cell-drag-handle{margin-left:calc(var(--ag-spacing)/4)}:where(.ag-rtl) .ag-column-drop-cell-drag-handle{margin-right:calc(var(--ag-spacing)/4)}.ag-column-drop-wrapper{display:flex}.ag-column-drop-horizontal-half-width{width:50%!important}.ag-column-drop-cell-ghost{opacity:.5}.ag-column-drop-horizontal{background-color:var(--ag-header-background-color);border-bottom:var(--ag-header-row-border);gap:var(--ag-cell-widget-spacing);height:var(--ag-header-height);overflow:hidden;white-space:nowrap}:where(.ag-ltr) .ag-column-drop-horizontal{padding-left:var(--ag-cell-horizontal-padding)}:where(.ag-rtl) .ag-column-drop-horizontal{padding-right:var(--ag-cell-horizontal-padding)}.ag-column-drop-horizontal-list{gap:var(--ag-cell-widget-spacing)}.ag-column-drop-vertical-cell{margin-top:var(--ag-spacing)}:where(.ag-ltr) .ag-column-drop-vertical-icon{margin-right:var(--ag-widget-horizontal-spacing)}:where(.ag-rtl) .ag-column-drop-vertical-icon{margin-left:var(--ag-widget-horizontal-spacing)}.ag-select-agg-func-popup{background:var(--ag-background-color);border:solid var(--ag-border-width) var(--ag-border-color);border-radius:var(--ag-border-radius);box-shadow:var(--ag-dropdown-shadow);height:calc(var(--ag-spacing)*5*3.5);padding:0;position:absolute}.ag-select-agg-func-virtual-list-item{cursor:default}:where(.ag-ltr) .ag-select-agg-func-virtual-list-item{padding-left:calc(var(--ag-spacing)*2)}:where(.ag-rtl) .ag-select-agg-func-virtual-list-item{padding-right:calc(var(--ag-spacing)*2)}.ag-select-agg-func-virtual-list-item:hover{background-color:var(--ag-selected-row-background-color)}:where(.ag-ltr) .ag-column-drop-horizontal-half-width:where(:not(:last-child)){border-right:solid var(--ag-border-width) var(--ag-border-color)}:where(.ag-rtl) .ag-column-drop-horizontal-half-width:where(:not(:last-child)){border-left:solid var(--ag-border-width) var(--ag-border-color)}"; function _insertArrayIntoArray(dest, src, toIndex) { if (dest == null || src == null) { return; } dest.splice(toIndex, 0, ...src); } var PillDropZonePanelElement = { tag: "div", cls: "ag-unselectable", role: "presentation" }; var PillDropZonePanel = class extends Component { constructor(horizontal) { super(PillDropZonePanelElement); this.horizontal = horizontal; this.state = "notDragging"; this.guiDestroyFunctions = []; this.childPillComponents = []; this.resizeEnabled = false; this.addElementClasses(this.getGui()); this.ePillDropList = _createElement({ tag: "div" }); this.addElementClasses(this.ePillDropList, "list"); this.registerCSS(pillDropZonePanel_default); } toggleResizable(resizable) { this.positionableFeature.setResizable(resizable ? { bottom: true } : false); this.resizeEnabled = resizable; } isSourceEventFromTarget(draggingEvent) { const { dropZoneTarget, dragSource } = draggingEvent; return dropZoneTarget.contains(dragSource.eElement); } destroy() { this.destroyGui(); super.destroy(); } destroyGui() { for (const func of this.guiDestroyFunctions) { func(); } this.guiDestroyFunctions.length = 0; this.childPillComponents.length = 0; _clearElement(this.getGui()); _clearElement(this.ePillDropList); } init(params) { this.params = params ?? {}; this.createManagedBean(new ManagedFocusFeature(this.getFocusableElement(), { onTabKeyDown: this.onTabKeyDown.bind(this), handleKeyDown: this.onKeyDown.bind(this) })); this.setupDropTarget(); this.positionableFeature = new PositionableFeature(this.getGui()); this.createManagedBean(this.positionableFeature); this.refreshGui(); _setAriaLabel(this.ePillDropList, this.getAriaLabel()); } onTabKeyDown(e) { const focusableElements = _findFocusableElements(this.getFocusableElement(), null, true); const len = focusableElements.length; if (len === 0) { return; } const { shiftKey } = e; const activeEl = _getActiveDomElement(this.beans); const isFirstFocused = activeEl === focusableElements[0]; const isLastFocused = activeEl === _last(focusableElements); const shouldAllowDefaultTab = len === 1 || isFirstFocused && shiftKey || isLastFocused && !shiftKey; if (!shouldAllowDefaultTab) { focusableElements[shiftKey ? 0 : len - 1].focus(); } } onKeyDown(e) { const { key } = e; const isVertical = !this.horizontal; let isNext = key === KeyCode.DOWN; let isPrevious = key === KeyCode.UP; if (!isVertical) { const isRtl = this.gos.get("enableRtl"); isNext = !isRtl && key === KeyCode.RIGHT || isRtl && key === KeyCode.LEFT; isPrevious = !isRtl && key === KeyCode.LEFT || isRtl && key === KeyCode.RIGHT; } if (!isNext && !isPrevious) { return; } e.preventDefault(); if (e.shiftKey) { this.moveFocusedItem(isPrevious); } else { const el = _findNextFocusableElement(this.beans, this.getFocusableElement(), false, isPrevious); if (el) { el.focus(); } } } moveFocusedItem(isPrevious) { const currentItemIndex = this.getFocusedItem(); if (currentItemIndex === -1) { return; } const diff = isPrevious ? -1 : 1; const changed = this.normalizeAndUpdateInsertIndex(currentItemIndex, currentItemIndex + diff); if (!changed) { return; } const comp = this.childPillComponents[currentItemIndex]; if (!comp.isMovable()) { return; } const currentItem = comp.getItem(); this.focusItemAtIndex(this.insertIndex); this.rearrangeItems([currentItem], true); } addElementClasses(el, suffix) { suffix = suffix ? `-${suffix}` : ""; const direction = this.horizontal ? "horizontal" : "vertical"; el.classList.add(`ag-column-drop${suffix}`, `ag-column-drop-${direction}${suffix}`); } setupDropTarget() { this.dropTarget = { getContainer: this.getGui.bind(this), getIconName: this.getIconName.bind(this), onDragging: this.onDragging.bind(this), onDragEnter: this.onDragEnter.bind(this), onDragLeave: this.onDragLeave.bind(this), onDragStop: this.onDragStop.bind(this), onDragCancel: this.onDragCancel.bind(this), isInterestedIn: this.isInterestedIn.bind(this) }; this.beans.dragAndDrop?.addDropTarget(this.dropTarget); } minimumAllowedNewInsertIndex() { return 0; } checkInsertIndex(draggingEvent) { const newIndex = this.getNewInsertIndex(draggingEvent); if (newIndex < 0) { return false; } return this.normalizeAndUpdateInsertIndex(this.insertIndex, newIndex); } normalizeAndUpdateInsertIndex(currentIndex, index) { const minimumAllowedIndex = this.minimumAllowedNewInsertIndex(); const newAdjustedIndex = Math.max(minimumAllowedIndex, index); const changed = newAdjustedIndex !== currentIndex; if (changed) { this.insertIndex = newAdjustedIndex; } return changed; } getNewInsertIndex(draggingEvent) { const mouseEvent = draggingEvent.event; const mouseLocation = this.horizontal ? mouseEvent.clientX : mouseEvent.clientY; const boundsList = this.childPillComponents.map((comp) => comp.getGui().getBoundingClientRect()); const hoveredIndex = boundsList.findIndex((rect) => this.horizontal ? rect.right > mouseLocation && rect.left < mouseLocation : rect.top < mouseLocation && rect.bottom > mouseLocation); if (hoveredIndex === -1) { const enableRtl = this.gos.get("enableRtl"); const isLast = boundsList.every((rect) => mouseLocation > (this.horizontal ? rect.right : rect.bottom)); if (isLast) { return enableRtl && this.horizontal ? 0 : this.childPillComponents.length; } const isFirst = boundsList.every((rect) => mouseLocation < (this.horizontal ? rect.left : rect.top)); if (isFirst) { return enableRtl && this.horizontal ? this.childPillComponents.length : 0; } return this.insertIndex; } if (this.insertIndex <= hoveredIndex) { return hoveredIndex + 1; } return hoveredIndex; } checkDragStartedBySelf(draggingEvent) { if (this.state !== "notDragging") { return; } this.state = "rearrangeItems"; this.potentialDndItems = this.getItems(draggingEvent.dragSource.getDragItem()); this.refreshGui(); this.checkInsertIndex(draggingEvent); this.refreshGui(); } onDragging(draggingEvent) { this.checkDragStartedBySelf(draggingEvent); if (this.checkInsertIndex(draggingEvent)) { this.refreshGui(); } } handleDragEnterEnd(_) {} onDragEnter(draggingEvent) { const dragItems = this.getItems(draggingEvent.dragSource.getDragItem()); this.state = "newItemsIn"; const goodDragItems = dragItems.filter((item) => this.isItemDroppable(item, draggingEvent)); const alreadyPresent = goodDragItems.every((item) => this.childPillComponents.map((cmp) => cmp.getItem()).indexOf(item) !== -1); if (goodDragItems.length === 0) { return; } this.potentialDndItems = goodDragItems; if (alreadyPresent) { this.state = "notDragging"; return; } this.handleDragEnterEnd(draggingEvent); this.checkInsertIndex(draggingEvent); this.refreshGui(); } isPotentialDndItems() { return !!this.potentialDndItems?.length; } handleDragLeaveEnd(_) {} onDragLeave(draggingEvent) { if (this.state === "rearrangeItems") { const items = this.getItems(draggingEvent.dragSource.getDragItem()); this.removeItems(items); } if (this.isPotentialDndItems()) { this.handleDragLeaveEnd(draggingEvent); this.potentialDndItems = []; this.refreshGui(); } this.state = "notDragging"; } onDragCancel(draggingEvent) { if (this.isPotentialDndItems()) { if (this.state === "newItemsIn") { this.handleDragLeaveEnd(draggingEvent); } this.potentialDndItems = []; this.refreshGui(); } this.state = "notDragging"; } onDragStop() { if (this.isPotentialDndItems()) { if (this.state === "newItemsIn") { this.addItems(this.potentialDndItems); } else { this.rearrangeItems(this.potentialDndItems); } this.potentialDndItems = []; this.refreshGui(); } this.state = "notDragging"; } removeItems(itemsToRemove) { const newItemList = this.getExistingItems().filter((item) => !itemsToRemove.includes(item)); this.updateItems(newItemList); this.refreshGui(); } addItems(itemsToAdd) { if (!itemsToAdd) { return; } const newItemList = this.getExistingItems().slice(); const itemsToAddNoDuplicates = itemsToAdd.filter((item) => newItemList.indexOf(item) < 0); _insertArrayIntoArray(newItemList, itemsToAddNoDuplicates, this.insertIndex); this.updateItems(newItemList); this.refreshGui(); } addItem(item) { this.insertIndex = this.getExistingItems().length; this.addItems([item]); } rearrangeItems(itemsToAdd, fromKeyboard) { let newItemList; if (!fromKeyboard) { newItemList = this.getNonGhostItems().slice(); } else { newItemList = this.getExistingItems().filter((item) => itemsToAdd.indexOf(item) === -1); } _insertArrayIntoArray(newItemList, itemsToAdd, this.insertIndex); if (_areEqual(newItemList, this.getExistingItems())) { return false; } this.updateItems(newItemList); this.refreshGui(); return true; } refreshGui() { let scrollTop = 0; if (!this.horizontal) { scrollTop = this.ePillDropList.scrollTop; } const resizeEnabled = this.resizeEnabled; const focusedIndex = this.getFocusedItem(); const { eGridDiv } = this.beans; const isKeyboardMode = _isKeyboardMode(); let alternateElement = null; if (isKeyboardMode) { alternateElement = _findNextFocusableElement(this.beans, eGridDiv) ?? _findNextFocusableElement(this.beans, eGridDiv, false, true); } this.toggleResizable(false); this.destroyGui(); this.addIconAndTitleToGui(); this.addEmptyMessageToGui(); this.addItemsToGui(); if (scrollTop !== 0) { this.ePillDropList.scrollTop = scrollTop; } if (resizeEnabled) { this.toggleResizable(resizeEnabled); } if (isKeyboardMode) { this.restoreFocus(focusedIndex, alternateElement); } } getFocusedItem() { const eGui = this.getGui(); const activeElement = _getActiveDomElement(this.beans); if (!eGui.contains(activeElement)) { return -1; } const items = Array.from(eGui.querySelectorAll(".ag-column-drop-cell")); return items.indexOf(activeElement); } focusItemAtIndex(index) { const eGui = this.getGui(); const items = Array.from(eGui.querySelectorAll(".ag-column-drop-cell")); const item = items[index]; if (!item) { return; } item.focus({ preventScroll: true }); } restoreFocus(index, alternateElement) { const eGui = this.getGui(); const items = Array.from(eGui.querySelectorAll(".ag-column-drop-cell")); if (index === -1) { return; } if (items.length === 0) { alternateElement.focus(); } const indexToFocus = Math.min(items.length - 1, index); const el = items[indexToFocus]; if (el) { el.focus(); } } focusList(fromBottom) { const index = fromBottom ? this.childPillComponents.length - 1 : 0; this.restoreFocus(index, this.getFocusableElement()); } getNonGhostItems() { const existingItems = this.getExistingItems(); if (this.isPotentialDndItems()) { return existingItems.filter((item) => !this.potentialDndItems.includes(item)); } return existingItems; } addItemsToGui() { const nonGhostItems = this.getNonGhostItems(); const itemsToAddToGui = nonGhostItems.map((item) => this.createItemComponent(item, false)); if (this.isPotentialDndItems()) { const dndItems = this.potentialDndItems.map((item) => this.createItemComponent(item, true)); if (this.insertIndex >= itemsToAddToGui.length) { itemsToAddToGui.push(...dndItems); } else { itemsToAddToGui.splice(this.insertIndex, 0, ...dndItems); } } this.appendChild(this.ePillDropList); itemsToAddToGui.forEach((itemComponent, index) => { if (index > 0) { this.addArrow(this.ePillDropList); } this.ePillDropList.appendChild(itemComponent.getGui()); }); this.addAriaLabelsToComponents(); } addAriaLabelsToComponents() { const { childPillComponents, ePillDropList } = this; const len = childPillComponents.length; _setAriaRole(ePillDropList, len === 0 ? "presentation" : "listbox"); for (let i = 0;i < len; i++) { const comp = childPillComponents[i]; const eGui = comp.getGui(); _setAriaPosInSet(eGui, i + 1); _setAriaSetSize(eGui, len); } } createItemComponent(item, ghost) { const itemComponent = this.createPillComponent(item, this.dropTarget, ghost, this.horizontal); itemComponent.addEventListener("columnRemove", this.removeItems.bind(this, [item])); this.createBean(itemComponent); this.guiDestroyFunctions.push(() => this.destroyBean(itemComponent)); if (!ghost) { this.childPillComponents.push(itemComponent); } return itemComponent; } addIconAndTitleToGui() { const { title, icon: eGroupIcon } = this.params; if (!title || !eGroupIcon) { return; } const eTitleBar = _createElement({ tag: "div" }); _setAriaHidden(eTitleBar, true); this.addElementClasses(eTitleBar, "title-bar"); this.addElementClasses(eGroupIcon, "icon"); this.toggleCss("ag-column-drop-empty", this.isExistingItemsEmpty()); eTitleBar.appendChild(eGroupIcon); if (!this.horizontal) { const eTitle = _createElement({ tag: "span" }); this.addElementClasses(eTitle, "title"); eTitle.textContent = title; eTitleBar.appendChild(eTitle); } this.appendChild(eTitleBar); } isExistingItemsEmpty() { return this.getExistingItems().length === 0; } addEmptyMessageToGui() { const { emptyMessage } = this.params; if (!emptyMessage || !this.isExistingItemsEmpty() || this.isPotentialDndItems()) { return; } const eMessage = _createElement({ tag: "span" }); eMessage.textContent = emptyMessage; this.addElementClasses(eMessage, "empty-message"); this.ePillDropList.appendChild(eMessage); } addArrow(eParent) { if (this.horizontal) { const enableRtl = this.gos.get("enableRtl"); const icon = _createIconNoSpan(enableRtl ? "panelDelimiterRtl" : "panelDelimiter", this.beans); this.addElementClasses(icon, "cell-separator"); eParent.appendChild(icon); } } }; var PillDragCompElement = { tag: "span", role: "option", children: [ { tag: "span", ref: "eDragHandle", cls: "ag-drag-handle ag-column-drop-cell-drag-handle", role: "presentation" }, { tag: "span", ref: "eText", cls: "ag-column-drop-cell-text", attrs: { "aria-hidden": "true" } }, { tag: "span", ref: "eButton", cls: "ag-column-drop-cell-button", role: "presentation" } ] }; var PillDragComp = class extends Component { constructor(dragSourceDropTarget, ghost, horizontal, template, agComponents) { super(); this.dragSourceDropTarget = dragSourceDropTarget; this.ghost = ghost; this.horizontal = horizontal; this.template = template; this.agComponents = agComponents; this.eText = RefPlaceholder; this.eDragHandle = RefPlaceholder; this.eButton = RefPlaceholder; } postConstruct() { this.setTemplate(this.template ?? PillDragCompElement, this.agComponents); const eGui = this.getGui(); const { beans, eDragHandle, eText, eButton } = this; this.addElementClasses(eGui); this.addElementClasses(eDragHandle, "drag-handle"); this.addElementClasses(eText, "text"); this.addElementClasses(eButton, "button"); eDragHandle.appendChild(_createIconNoSpan("columnDrag", beans)); eButton.appendChild(_createIconNoSpan("cancel", beans)); this.tooltipFeature = this.createOptionalManagedBean(beans.registry.createDynamicBean("tooltipFeature", false, { getGui: () => this.getGui() })); this.setupComponents(); if (!this.ghost && this.isDraggable()) { this.addDragSource(); } this.setupAria(); this.setupTooltip(); this.activateTabIndex(); this.refreshDraggable(); } isDraggable() { return true; } refreshDraggable() { this.eDragHandle.classList.toggle("ag-column-select-column-readonly", !this.isDraggable()); } setupAria() { const translate = this.getLocaleTextFunc(); const ariaInstructions = [this.getAriaDisplayName()]; this.addAdditionalAriaInstructions(ariaInstructions, translate); _setAriaLabel(this.getGui(), ariaInstructions.join(". ")); } addAdditionalAriaInstructions(ariaInstructions, translate) { if (this.isRemovable()) { const deleteAria = translate("ariaDropZoneColumnComponentDescription", "Press DELETE to remove"); ariaInstructions.push(deleteAria); } } setupTooltip() { const refresh = () => this.tooltipFeature?.setTooltipAndRefresh(this.getTooltip()); refresh(); this.addManagedEventListeners({ newColumnsLoaded: refresh }); } getDragSourceId() { return; } getDefaultIconName() { return "notAllowed"; } addDragSource() { const { beans: { dragAndDrop }, eDragHandle } = this; const getDragItem = this.createGetDragItem(); const defaultIconName = this.getDefaultIconName(); const dragSource = { type: this.getDragSourceType(), sourceId: this.getDragSourceId(), eElement: eDragHandle, getDefaultIconName: () => defaultIconName, getDragItem, dragItemName: this.getDisplayName() }; dragAndDrop?.addDragSource(dragSource, true); this.addDestroyFunc(() => dragAndDrop?.removeDragSource(dragSource)); } setupComponents() { this.eText.textContent = this.getDisplayValue(); this.setupRemove(); if (this.ghost) { this.addCss("ag-column-drop-cell-ghost"); } } isRemovable() { return true; } refreshRemove() { _setDisplayed(this.eButton, this.isRemovable()); } setupRemove() { this.refreshRemove(); const agEvent = { type: "columnRemove" }; this.addGuiEventListener("keydown", (e) => this.onKeyDown(e)); this.addManagedElementListeners(this.eButton, { click: (mouseEvent) => { this.dispatchLocalEvent(agEvent); mouseEvent.stopPropagation(); } }); const touchListener = new TouchListener(this.eButton); this.addManagedListeners(touchListener, { tap: () => this.dispatchLocalEvent(agEvent) }); this.addDestroyFunc(touchListener.destroy.bind(touchListener)); } onKeyDown(e) { const isDelete = e.key === KeyCode.DELETE; if (isDelete) { if (this.isRemovable()) { e.preventDefault(); this.dispatchLocalEvent({ type: "columnRemove" }); } } } getDisplayValue() { return this.getDisplayName(); } addElementClasses(el, suffix) { suffix = suffix ? `-${suffix}` : ""; const direction = this.horizontal ? "horizontal" : "vertical"; el.classList.add(`ag-column-drop-cell${suffix}`, `ag-column-drop-${direction}-cell${suffix}`); } destroy() { super.destroy(); this.dragSourceDropTarget = null; } }; var DropZoneColumnComp = class extends PillDragComp { constructor(column, dragSourceDropTarget, ghost, dropZonePurpose, horizontal, updateParams) { super(dragSourceDropTarget, ghost, horizontal); this.column = column; this.dropZonePurpose = dropZonePurpose; this.updateParams = updateParams; this.eSortIndicator = RefPlaceholder; this.popupShowing = false; this.deferApply = isDeferredMode(updateParams); } postConstruct() { const { sortSvc, colNames } = this.beans; this.template = { tag: "span", role: "option", children: [ { tag: "span", ref: "eDragHandle", cls: "ag-drag-handle ag-column-drop-cell-drag-handle", role: "presentation" }, { tag: "span", ref: "eText", cls: "ag-column-drop-cell-text", attrs: { "aria-hidden": "true" } }, sortSvc ? { tag: "ag-sort-indicator", ref: "eSortIndicator" } : undefined, { tag: "span", ref: "eButton", cls: "ag-column-drop-cell-button", role: "presentation" } ] }; if (sortSvc) { this.agComponents = [sortSvc.getSortIndicatorSelector()]; } this.displayName = colNames.getDisplayNameForColumn(this.column, "columnDrop"); super.postConstruct(); if (this.deferApply) { this.eDragHandle.setAttribute("data-column-tool-panel-deferred", ""); } if (sortSvc) { this.setupSort(); this.addManagedEventListeners({ sortChanged: () => { this.setupAria(); } }); } if (this.isGroupingZone()) { this.addManagedPropertyListener("groupLockGroupColumns", () => { this.refreshRemove(); this.refreshDraggable(); this.setupAria(); }); } } getItem() { return this.column; } getDisplayName() { return this.displayName; } getTooltip() { return this.column.getColDef().headerTooltip; } addAdditionalAriaInstructions(ariaInstructions, translate) { const isSortSuppressed = this.gos.get("rowGroupPanelSuppressSort"); const isFunctionsReadOnly = this.gos.get("functionsReadOnly"); if (this.isAggregationZone() && !isFunctionsReadOnly) { const aggregationMenuAria = translate("ariaDropZoneColumnValueItemDescription", "Press ENTER to change the aggregation type"); ariaInstructions.push(aggregationMenuAria); } if (this.isGroupingZone() && this.column.isSortable() && !isSortSuppressed) { const sortProgressAria = translate("ariaDropZoneColumnGroupItemDescription", "Press ENTER to sort"); ariaInstructions.push(sortProgressAria); } super.addAdditionalAriaInstructions(ariaInstructions, translate); } isMovable() { return this.isDraggable(); } isDraggable() { return this.isReadOnly(); } isRemovable() { return this.isReadOnly(); } isReadOnly() { return !this.isGroupingAndLocked() && !this.gos.get("functionsReadOnly"); } getAriaDisplayName() { const translate = this.getLocaleTextFunc(); const { name, aggFuncName } = this.getColumnAndAggFuncName(); const aggSeparator = translate("ariaDropZoneColumnComponentAggFuncSeparator", " of "); const sortDirection = { asc: translate("ariaDropZoneColumnComponentSortAscending", "ascending"), desc: translate("ariaDropZoneColumnComponentSortDescending", "descending") }; const columnSort = this.getCurrentSortDirection(this.column); const isSortSuppressed = this.gos.get("rowGroupPanelSuppressSort"); return [ aggFuncName && `${aggFuncName}${aggSeparator}`, name, this.isGroupingZone() && !isSortSuppressed && columnSort && `, ${sortDirection[columnSort]}` ].filter((part) => !!part).join(""); } getColumnAndAggFuncName() { const name = this.displayName; let aggFuncName = ""; if (this.isAggregationZone()) { const aggFunc = this.beans.columnStateUpdateStrategy.getColumnAggFunc(this.deferApply, this.column); const aggFuncString = typeof aggFunc === "string" ? aggFunc : "agg"; const localeTextFunc = this.getLocaleTextFunc(); aggFuncName = localeTextFunc(aggFuncString, aggFuncString); } return { name, aggFuncName }; } setupSort() { if (!this.column.isSortable() || !this.isGroupingZone()) { return; } const { gos, column, eSortIndicator } = this; if (!gos.get("rowGroupPanelSuppressSort")) { eSortIndicator.setupSort(column, true, this.getSortDefOverride.bind(this)); const performSort = (event) => { event.preventDefault(); this.beans.columnStateUpdateStrategy.progressSortFromEvent(this.deferApply, column, event); eSortIndicator.refresh(); this.setupAria(); refreshDeferredToolPanelUi(this.beans, this.updateParams); }; this.addGuiEventListener("click", performSort); this.addGuiEventListener("keydown", (e) => { const isEnter = e.key === KeyCode.ENTER; if (isEnter && this.isGroupingZone()) { performSort(e); } }); } } getCurrentSortDirection(column) { return this.beans.columnStateUpdateStrategy.getSortDef(this.deferApply, column)?.direction ?? null; } getSortDefOverride() { if (!this.deferApply) { return; } return this.beans.columnStateUpdateStrategy.getSortDef(this.deferApply, this.column); } getDefaultIconName() { return "hide"; } createGetDragItem() { const { column } = this; return () => { const visibleState = {}; visibleState[column.getId()] = column.isVisible(); return { columns: [column], visibleState }; }; } setupComponents() { super.setupComponents(); if (this.isAggregationZone() && !this.gos.get("functionsReadOnly")) { this.addGuiEventListener("click", this.onShowAggFuncSelection.bind(this)); } } onKeyDown(e) { super.onKeyDown(e); const isEnter = e.key === KeyCode.ENTER; if (isEnter && this.isAggregationZone() && !this.gos.get("functionsReadOnly")) { e.preventDefault(); this.onShowAggFuncSelection(); } } getDisplayValue() { const { name, aggFuncName } = this.getColumnAndAggFuncName(); return this.isAggregationZone() ? `${aggFuncName}(${name})` : name; } onShowAggFuncSelection() { if (this.popupShowing) { return; } this.popupShowing = true; const { aggFuncSvc, popupSvc } = this.beans; const virtualList = new VirtualList({ cssIdentifier: "select-agg-func" }); const rows = aggFuncSvc.getFuncNames(this.column); const eGui = this.getGui(); const virtualListGui = virtualList.getGui(); virtualList.setModel({ getRow: function(index) { return rows[index]; }, getRowCount: function() { return rows.length; } }); this.createBean(virtualList); const ePopup = _createElement({ tag: "div", cls: "ag-select-agg-func-popup" }); ePopup.style.top = "0px"; ePopup.style.left = "0px"; ePopup.appendChild(virtualListGui); ePopup.style.width = `${eGui.clientWidth}px`; const [focusoutListener] = this.addManagedElementListeners(ePopup, { focusout: (e) => { if (!ePopup.contains(e.relatedTarget) && addPopupRes) { addPopupRes.hideFunc(); } } }); const popupHiddenFunc = (callbackEvent) => { this.destroyBean(virtualList); this.popupShowing = false; if (callbackEvent?.key === "Escape") { eGui.focus(); } if (focusoutListener) { focusoutListener(); } }; const translate = this.getLocaleTextFunc(); const addPopupRes = popupSvc.addPopup({ modal: true, eChild: ePopup, closeOnEsc: true, closedCallback: popupHiddenFunc, ariaLabel: translate("ariaLabelAggregationFunction", "Aggregation Function") }); if (addPopupRes) { virtualList.setComponentCreator(this.createAggSelect.bind(this, addPopupRes.hideFunc)); } virtualList.addGuiEventListener("keydown", (e) => { if (e.key === KeyCode.ENTER || e.key === KeyCode.SPACE) { const row = virtualList.getLastFocusedRow(); if (row == null) { return; } const comp = virtualList.getComponentAt(row); if (comp) { comp.selectItem(); } } }); popupSvc.positionPopupByComponent({ type: "aggFuncSelect", eventSource: eGui, ePopup, keepWithinBounds: true, additionalParams: { column: this.column }, position: "under" }); virtualList.refresh(); const currentAggFunc = this.beans.columnStateUpdateStrategy.getColumnAggFunc(this.deferApply, this.column); let rowToFocus = rows.findIndex((r) => r === currentAggFunc); if (rowToFocus === -1) { rowToFocus = 0; } virtualList.focusRow(rowToFocus); } createAggSelect(hidePopup, value) { const itemSelected = () => { hidePopup(); this.getGui().focus(); this.beans.columnStateUpdateStrategy.setColumnAggFunc(this.deferApply, this.column, value, "toolPanelDragAndDrop"); if (this.column) { const eText = this.getGui().querySelector(".ag-column-drop-cell-text"); if (eText) { eText.textContent = this.getDisplayValue(); } this.setupAria(); } refreshDeferredToolPanelUi(this.beans, this.updateParams); }; const localeTextFunc = this.getLocaleTextFunc(); const aggFuncString = (value || "").toString(); const aggFuncStringTranslated = localeTextFunc(aggFuncString, aggFuncString); const comp = new AggItemComp(itemSelected, aggFuncStringTranslated); return comp; } isGroupingAndLocked() { return this.isGroupingZone() && isRowGroupColLocked(this.column, this.beans); } isAggregationZone() { return this.dropZonePurpose === "aggregation"; } isGroupingZone() { return this.dropZonePurpose === "rowGroup"; } getDragSourceType() { return DragSourceType.ToolPanel; } destroy() { super.destroy(); this.column = null; } }; var AggItemComp = class extends Component { constructor(itemSelected, value) { super({ tag: "div", cls: "ag-select-agg-func-item", children: value }); this.selectItem = itemSelected; this.addGuiEventListener("click", this.selectItem); } }; var BaseDropZonePanel = class extends PillDropZonePanel { constructor(horizontal, dropZonePurpose, updateParams) { super(horizontal); this.dropZonePurpose = dropZonePurpose; this.updateParams = updateParams; this.addElementClasses(this.getGui(), this.dropZonePurpose.toLowerCase()); } init(params) { super.init(params); this.addManagedEventListeners({ newColumnsLoaded: this.refreshGui.bind(this) }); this.addManagedPropertyListeners(["functionsReadOnly", "rowGroupPanelSuppressSort", "groupLockGroupColumns"], this.refreshGui.bind(this)); } getItems(dragItem) { return dragItem.columns ?? []; } isInterestedIn(type, sourceElement) { if (type === DragSourceType.HeaderCell) { return true; } if (type !== DragSourceType.ToolPanel) { return false; } if (!this.horizontal) { return true; } return !sourceElement.hasAttribute("data-column-tool-panel-deferred"); } minimumAllowedNewInsertIndex() { const { gos, rowGroupColsSvc } = this.beans; const numberOfLockedCols = gos.get("groupLockGroupColumns"); const numberOfGroupCols = rowGroupColsSvc?.columns.length ?? 0; if (numberOfLockedCols === -1) { return numberOfGroupCols; } return Math.min(numberOfLockedCols, numberOfGroupCols); } showOrHideColumnOnExit(draggingEvent) { return this.isRowGroupPanel() && _shouldUpdateColVisibilityAfterGroup(this.gos, true) && !draggingEvent.fromNudge; } handleDragEnterEnd(draggingEvent) { const hideColumnOnExit = this.showOrHideColumnOnExit(draggingEvent); if (hideColumnOnExit) { const dragItem = draggingEvent.dragSource.getDragItem(); const columns = dragItem.columns; this.setColumnsVisible(columns, false, "uiColumnDragged"); } } handleDragLeaveEnd(draggingEvent) { const showColumnOnExit = this.showOrHideColumnOnExit(draggingEvent); if (showColumnOnExit) { const dragItem = draggingEvent.dragSource.getDragItem(); this.setColumnsVisible(dragItem.columns, true, "uiColumnDragged"); } } setColumnsVisible(columns, visible, source) { if (!columns) { return; } if (isDeferredMode(this.updateParams)) { return; } const allowedCols = columns.filter((c) => !c.getColDef().lockVisible); this.beans.columnStateUpdateStrategy.setColumnsVisible(false, allowedCols, visible, source); } isRowGroupPanel() { return this.dropZonePurpose === "rowGroup"; } createPillComponent(column, dropTarget, ghost, horizontal) { return new DropZoneColumnComp(column, dropTarget, ghost, this.dropZonePurpose, horizontal, this.updateParams); } }; var PivotDropZonePanel = class extends BaseDropZonePanel { constructor(horizontal, params) { super(horizontal, "pivot", params); } postConstruct() { const localeTextFunc = this.getLocaleTextFunc(); const emptyMessage = localeTextFunc("pivotColumnsEmptyMessage", "Drag here to set column labels"); const title = localeTextFunc("pivots", "Column Labels"); super.init({ icon: _createIconNoSpan("pivotPanel", this.beans, null), emptyMessage, title }); if (this.horizontal) { _addFocusableContainerListener(this.beans, this, this.getGui()); } this.addManagedEventListeners({ newColumnsLoaded: this.refresh.bind(this), columnPivotChanged: this.refresh.bind(this), columnPivotModeChanged: this.checkVisibility.bind(this) }); this.refresh(); } getAriaLabel() { const translate = this.getLocaleTextFunc(); return translate("ariaPivotDropZonePanelLabel", "Column Labels"); } refresh() { this.checkVisibility(); this.refreshGui(); } checkVisibility() { const colModel = this.beans.colModel; const pivotMode = colModel.isPivotMode(); if (this.horizontal) { switch (this.gos.get("pivotPanelShow")) { case "always": this.setDisplayed(pivotMode); break; case "onlyWhenPivoting": { const pivotActive = colModel.isPivotActive(); this.setDisplayed(pivotMode && pivotActive); break; } default: this.setDisplayed(false); break; } } else { this.setDisplayed(this.beans.columnStateUpdateStrategy.getPivotMode(isDeferredMode(this.updateParams))); } } isItemDroppable(column, draggingEvent) { if (this.gos.get("functionsReadOnly") || !column.isPrimary()) { return false; } const isActive = this.beans.columnStateUpdateStrategy.getPivotColumns(isDeferredMode(this.updateParams)).includes(column); return column.isAllowPivot() && (!isActive || this.isSourceEventFromTarget(draggingEvent)); } updateItems(columns) { this.beans.columnStateUpdateStrategy.setPivotColumns(isDeferredMode(this.updateParams), columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.updateParams); } getIconName() { return this.isPotentialDndItems() ? "pivot" : "notAllowed"; } getExistingItems() { return this.beans.columnStateUpdateStrategy.getPivotColumns(isDeferredMode(this.updateParams)); } getFocusableContainerName() { return "pivotToolbar"; } }; var RowGroupDropZonePanel = class extends BaseDropZonePanel { constructor(horizontal, params) { super(horizontal, "rowGroup", params); } postConstruct() { const localeTextFunc = this.getLocaleTextFunc(); const emptyMessage = localeTextFunc("rowGroupColumnsEmptyMessage", "Drag here to set row groups"); const title = localeTextFunc("groups", "Row Groups"); super.init({ icon: _createIconNoSpan("rowGroupPanel", this.beans, null), emptyMessage, title }); if (this.horizontal) { _addFocusableContainerListener(this.beans, this, this.getGui()); } this.addManagedEventListeners({ columnRowGroupChanged: this.refreshGui.bind(this) }); } getAriaLabel() { const translate = this.getLocaleTextFunc(); const label = translate("ariaRowGroupDropZonePanelLabel", "Row Groups"); return label; } isItemDroppable(column, draggingEvent) { if (this.gos.get("functionsReadOnly") || !column.isPrimary() || column.colDef.showRowGroup) { return false; } const isActive = this.beans.columnStateUpdateStrategy.getRowGroupColumns(isDeferredMode(this.updateParams)).includes(column); return column.isAllowRowGroup() && (!isActive || this.isSourceEventFromTarget(draggingEvent)); } updateItems(columns) { this.beans.columnStateUpdateStrategy.setRowGroupColumns(isDeferredMode(this.updateParams), columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.updateParams); } getIconName() { return this.isPotentialDndItems() ? "group" : "notAllowed"; } getExistingItems() { return this.beans.columnStateUpdateStrategy.getRowGroupColumns(isDeferredMode(this.updateParams)); } getFocusableContainerName() { return "rowGroupToolbar"; } }; var ValuesDropZonePanel = class extends BaseDropZonePanel { constructor(horizontal, params) { super(horizontal, "aggregation", params); } postConstruct() { const localeTextFunc = this.getLocaleTextFunc(); const emptyMessage = localeTextFunc("valueColumnsEmptyMessage", "Drag here to aggregate"); const title = localeTextFunc("values", "Values"); super.init({ icon: _createIconNoSpan("valuePanel", this.beans, null), emptyMessage, title }); this.addManagedEventListeners({ columnValueChanged: this.refreshGui.bind(this) }); } getAriaLabel() { const translate = this.getLocaleTextFunc(); const label = translate("ariaValuesDropZonePanelLabel", "Values"); return label; } getIconName() { return this.isPotentialDndItems() ? "aggregate" : "notAllowed"; } isItemDroppable(column, draggingEvent) { if (this.gos.get("functionsReadOnly") || !column.isPrimary()) { return false; } const isActive = this.beans.columnStateUpdateStrategy.getValueColumns(isDeferredMode(this.updateParams)).includes(column); return column.isAllowValue() && (!isActive || this.isSourceEventFromTarget(draggingEvent)); } updateItems(columns) { this.beans.columnStateUpdateStrategy.setValueColumns(isDeferredMode(this.updateParams), columns, "toolPanelUi"); refreshDeferredToolPanelUi(this.beans, this.updateParams); } getExistingItems() { return this.beans.columnStateUpdateStrategy.getValueColumns(isDeferredMode(this.updateParams)); } }; var PivotModePanelElement = { tag: "div", cls: "ag-pivot-mode-panel", children: [ { tag: "ag-toggle-button", ref: "cbPivotMode", cls: "ag-pivot-mode-select" } ] }; var PivotModePanel = class extends Component { constructor(params, onPivotModeValueChanged) { super(); this.params = params; this.onPivotModeValueChanged = onPivotModeValueChanged; this.cbPivotMode = RefPlaceholder; } getCurrentPivotMode() { return this.beans.columnStateUpdateStrategy.getPivotMode(isDeferredMode(this.params)); } syncFromGrid() { this.cbPivotMode.setValue(this.getCurrentPivotMode()); } refreshEditStrategy() { this.syncFromGrid(); } postConstruct() { this.setTemplate(PivotModePanelElement, [AgToggleButtonSelector]); const cbPivotMode = this.cbPivotMode; cbPivotMode.setValue(this.getCurrentPivotMode()); const localeTextFunc = this.getLocaleTextFunc(); cbPivotMode.setLabel(localeTextFunc("pivotMode", "Pivot Mode")); const onBtPivotMode = () => { const newValue = !!cbPivotMode.getValue(); this.beans.columnStateUpdateStrategy.setPivotMode(isDeferredMode(this.params), newValue, "toolPanelUi"); this.onPivotModeValueChanged?.(); }; const onPivotModeChanged = () => { cbPivotMode.setValue(this.getCurrentPivotMode()); }; this.addManagedListeners(cbPivotMode, { fieldValueChanged: onBtPivotMode }); this.addManagedEventListeners({ newColumnsLoaded: onPivotModeChanged, columnPivotModeChanged: onPivotModeChanged }); } }; var ColumnToolPanelFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colToolPanelFactory"; } setPanelVisible(existingPanel, visible, createFunc) { if (existingPanel) { existingPanel.setDisplayed(visible); } else if (visible) { existingPanel = createFunc(); } return existingPanel; } createRowGroupPanel(parent, destroyFuncs, params) { return this.createPanel(parent, destroyFuncs, new RowGroupDropZonePanel(false, params)); } createValuesPanel(parent, destroyFuncs, params) { return this.createPanel(parent, destroyFuncs, new ValuesDropZonePanel(false, params)); } createPivotPanel(parent, destroyFuncs, params) { return this.createPanel(parent, destroyFuncs, new PivotDropZonePanel(false, params)); } createPivotModePanel(parent, destroyFuncs, params, onPivotModeValueChanged, prepend) { return this.createPanel(parent, destroyFuncs, new PivotModePanel(params, onPivotModeValueChanged), prepend); } createPanel(parent, destroyFuncs, panel, prepend) { panel = parent.createBean(panel); destroyFuncs.push(() => parent.destroyBean(panel)); if (prepend) { parent.prependChild(panel); } else { parent.appendChild(panel); } return panel; } }; var noop = () => {}; var ColumnStateUpdateExecutionStrategy = class extends BeanStub { constructor() { super(...arguments); this.beanName = "columnStateUpdateExecutionStrategy"; } applyColumnState(deferMode, state, eventType) { this.getUpdateStrategy(deferMode).applyColumnState(state, eventType); } commit(deferMode) { this.getUpdateStrategy(deferMode).commit(); } hasPendingChanges(deferMode) { return this.getUpdateStrategy(deferMode).hasPendingChanges(); } moveColumns(deferMode, columns, targetIndex, eventType) { this.getUpdateStrategy(deferMode).moveColumns(columns, targetIndex, eventType); } reset(deferMode) { this.getUpdateStrategy(deferMode).reset(); } setColumnsVisible(deferMode, columns, visible, eventType) { this.getUpdateStrategy(deferMode).setColumnsVisible(columns, visible, eventType); } isColumnVisibleInToolPanel(deferMode, column) { return this.getUpdateStrategy(deferMode).isColumnVisibleInToolPanel(column); } setRowGroupColumns(deferMode, columns, eventType) { this.getUpdateStrategy(deferMode).setRowGroupColumns(columns, eventType); } getRowGroupColumns(deferMode) { return this.getUpdateStrategy(deferMode).getRowGroupColumns(); } getPrimaryColumns(deferMode) { return this.getUpdateStrategy(deferMode).getPrimaryColumns(); } hasDeferredColumnOrder(deferMode) { return this.getUpdateStrategy(deferMode).hasDeferredColumnOrder(); } setValueColumns(deferMode, columns, eventType) { this.getUpdateStrategy(deferMode).setValueColumns(columns, eventType); } getValueColumns(deferMode) { return this.getUpdateStrategy(deferMode).getValueColumns(); } setColumnAggFunc(deferMode, column, aggFunc, eventType) { this.getUpdateStrategy(deferMode).setColumnAggFunc(column, aggFunc, eventType); } getColumnAggFunc(deferMode, column) { return this.getUpdateStrategy(deferMode).getColumnAggFunc(column); } setPivotColumns(deferMode, columns, eventType) { this.getUpdateStrategy(deferMode).setPivotColumns(columns, eventType); } getPivotColumns(deferMode) { return this.getUpdateStrategy(deferMode).getPivotColumns(); } setPivotMode(deferMode, pivotMode, eventType) { this.getUpdateStrategy(deferMode).setPivotMode(pivotMode, eventType); } getPivotMode(deferMode) { return this.getUpdateStrategy(deferMode).getPivotMode(); } isColumnSelectedInPivotModeToolPanel(deferMode, column) { return this.getUpdateStrategy(deferMode).isColumnSelectedInPivotModeToolPanel(column); } progressSortFromEvent(deferMode, column, event) { this.getUpdateStrategy(deferMode).progressSortFromEvent(column, event); } getSortDef(deferMode, column) { return this.getUpdateStrategy(deferMode).getSortDef(column); } getUpdateStrategy(deferApply) { return deferApply ? this.getDeferredUpdateStrategy() : this.getSyncUpdateStrategy(); } getSyncUpdateStrategy() { return this.syncUpdateStrategy ?? (this.syncUpdateStrategy = new SynchronousColumnStateUpdateStrategy(this.beans)); } getDeferredUpdateStrategy() { return this.deferredUpdateStrategy ?? (this.deferredUpdateStrategy = new DeferredColumnStateUpdateStrategy(this.beans)); } }; var SynchronousColumnStateUpdateStrategy = class { constructor(beans) { this.beans = beans; this.lastPivotColIds = []; this.reset = noop; this.commit = noop; this.hasPendingChanges = () => false; this.hasDeferredColumnOrder = () => false; } applyColumnState(state, eventType) { if (state.length === 0) { return; } _applyColumnState(this.beans, { state }, eventType); } moveColumns(columns, targetIndex, eventType) { this.beans.colMoves?.moveColumns(columns, targetIndex, eventType); syncPrimaryColDefOrderFromCurrentColumns(this.beans); } setColumnsVisible(columns, visible, eventType) { const allowedCols = columns.filter((column) => !column.getColDef().lockVisible); this.beans.colModel.setColsVisible(allowedCols, visible, eventType); } setRowGroupColumns(columns, eventType) { this.beans.rowGroupColsSvc?.setColumns(columns, eventType); } getRowGroupColumns() { return this.beans.rowGroupColsSvc?.columns ?? []; } getPrimaryColumns() { return getPrimaryColumns(this.beans); } setValueColumns(columns, eventType) { this.beans.valueColsSvc?.setColumns(columns, eventType); } getValueColumns() { return this.beans.valueColsSvc?.columns ?? []; } setColumnAggFunc(column, aggFunc, eventType) { this.beans.valueColsSvc?.setColumnAggFunc?.(column, aggFunc, eventType); } getColumnAggFunc(column) { return column.getAggFunc(); } setPivotColumns(columns, eventType) { this.lastPivotColIds = columns.map((column) => column.getColId()); this.beans.pivotColsSvc?.setColumns(columns, eventType); } getPivotColumns() { return this.beans.pivotColsSvc?.columns ?? []; } setPivotMode(pivotMode, eventType) { const { colModel, gos, ctrlsSvc } = this.beans; if (pivotMode === colModel.isPivotMode()) { return; } const currentPivotColIds = this.beans.pivotColsSvc?.columns.map((col) => col.getColId()) ?? []; if (currentPivotColIds.length > 0) { this.lastPivotColIds = currentPivotColIds; } if (!pivotMode) { const cols = this.beans.colModel.getColDefCols() ?? []; _applyColumnState(this.beans, { state: cols.map((col) => ({ colId: col.getColId(), pivot: false, pivotIndex: null })) }, eventType); } gos.updateGridOptions({ options: { pivotMode }, source: eventType }); if (pivotMode && this.lastPivotColIds.length > 0) { this.beans.pivotColsSvc?.setColumns(this.lastPivotColIds, eventType); } for (const c of ctrlsSvc.getHeaderRowContainerCtrls()) { c.refresh(); } } progressSortFromEvent(column, event) { this.beans.sortSvc?.progressSortFromEvent(column, event); } isColumnVisibleInToolPanel(column) { return column.isVisible(); } isColumnSelectedInPivotModeToolPanel(column) { return column.isAnyFunctionActive(); } getPivotMode() { return this.beans.colModel.isPivotMode(); } getSortDef(column) { return column.getSortDef(); } }; var DeferredColumnStateUpdateStrategy = class { constructor(beans) { this.beans = beans; this.state = {}; this.sequence = 0; this.lastPivotColIds = []; } reset() { this.sequence = 0; this.state = {}; } hasPendingChanges() { const { state, beans } = this; const { columnState, columnOrder, rowGroup, aggregation, pivot, pivotMode, sort, aggFuncs } = state; const getColIds = (cols) => (cols ?? []).map((c) => c.getColId()); if (columnState) { for (const [colId, patch] of columnState.patches) { const column = beans.colModel.getColDefCol(colId); if (!column) { continue; } if (patch.hide !== undefined && patch.hide !== !column.isVisible() || patch.rowGroup !== undefined && !!patch.rowGroup !== column.isRowGroupActive() || patch.pivot !== undefined && !!patch.pivot !== column.isPivotActive() || patch.aggFunc !== undefined && (patch.aggFunc ?? null) !== (column.getAggFunc() ?? null)) { return true; } } } if (columnOrder && !_areEqual(columnOrder.colIds, getPrimaryColumnIds(beans))) { return true; } if (rowGroup && !_areEqual(rowGroup.colIds, getColIds(beans.rowGroupColsSvc?.columns))) { return true; } if (aggregation && !_areEqual(aggregation.colIds, getColIds(beans.valueColsSvc?.columns))) { return true; } if (pivot && !_areEqual(pivot.colIds, getColIds(beans.pivotColsSvc?.columns))) { return true; } if (pivotMode && pivotMode.pivotMode !== beans.colModel.isPivotMode()) { return true; } if (sort) { for (const [colId, sortDef] of sort.sortDefsByColId) { const column = beans.colModel.getColDefCol(colId); if (!column) { continue; } if ((sortDef?.direction ?? null) !== (column.getSortDef()?.direction ?? null)) { return true; } } if (sort.baselineCleared) { const primaryColumns = getPrimaryColumns(beans); for (const col of primaryColumns) { if (!sort.sortDefsByColId.has(col.getColId()) && col.getSortDef() !== null) { return true; } } } } if (aggFuncs) { for (const [colId, aggFunc] of aggFuncs.values) { const column = beans.colModel.getColDefCol(colId); if (!column) { continue; } if (aggFunc !== column.getAggFunc()) { return true; } } } return false; } commit() { const { beans, state } = this; const operations = []; for (const type of Object.keys(state)) { const operation = state[type]; if (operation) { operations.push({ type, ...operation }); } } const sortedEntries = operations.sort((a, b) => a.seq - b.seq); for (const operation of sortedEntries) { switch (operation.type) { case "columnState": { _applyColumnState(beans, { state: [...operation.patches.values()] }, operation.eventType); break; } case "columnOrder": { const orderedColumns = operation.colIds.map((colId) => beans.colModel.getColDefCol(colId)).filter((column) => !!column && isPrimaryColDefColumn(column)); if (!beans.colModel.isPivotMode()) { for (let i = 0;i < orderedColumns.length; i++) { const column = orderedColumns[i]; const allColumns = beans.colModel.getCols(); const nonPrimaryPrefix = allColumns.findIndex((col) => isPrimaryColDefColumn(col)); const targetIndex = (nonPrimaryPrefix >= 0 ? nonPrimaryPrefix : 0) + i; if (allColumns[targetIndex] !== column) { beans.colMoves?.moveColumns([column], targetIndex, operation.eventType, true); } } } syncPrimaryColDefOrder(beans, orderedColumns); break; } case "rowGroup": { beans.rowGroupColsSvc?.setColumns(operation.colIds, operation.eventType); break; } case "aggregation": { beans.valueColsSvc?.setColumns(operation.colIds, operation.eventType); break; } case "pivot": { this.lastPivotColIds = operation.colIds; beans.pivotColsSvc?.setColumns(operation.colIds, operation.eventType); break; } case "pivotMode": { const { colModel, ctrlsSvc, gos, stateSvc } = beans; if (operation.pivotMode !== colModel.isPivotMode()) { const currentPivotColIds = beans.pivotColsSvc?.columns.map((col) => col.getColId()) ?? []; if (currentPivotColIds.length > 0) { this.lastPivotColIds = currentPivotColIds; } const previousPivotColIds = stateSvc?.getState().pivot?.pivotColIds ?? currentPivotColIds; const pivotColIds = operation.pivotMode ? this.state.pivot?.colIds ?? this.lastPivotColIds : previousPivotColIds; stateSvc?.setState({ ...stateSvc.getState(), pivot: { pivotMode: operation.pivotMode, pivotColIds } }, ["pivot"]); if (!operation.pivotMode) { const cols = beans.colModel.getColDefCols() ?? []; _applyColumnState(beans, { state: cols.map((col) => ({ colId: col.getColId(), pivot: false, pivotIndex: null })) }, operation.eventType); } gos.updateGridOptions({ options: { pivotMode: operation.pivotMode }, source: operation.eventType }); if (operation.pivotMode && pivotColIds.length > 0) { beans.pivotColsSvc?.setColumns(pivotColIds, operation.eventType); } for (const c of ctrlsSvc.getHeaderRowContainerCtrls()) { c.refresh(); } } break; } case "sort": { const sortState = []; let sortIndex = 0; for (const [colId, sortDef] of operation.sortDefsByColId) { sortState.push({ colId, sort: sortDef?.direction ?? null, sortIndex: sortDef?.direction ? sortIndex++ : null, sortType: sortDef?.type ?? undefined }); } _applyColumnState(beans, { state: sortState, defaultState: operation.baselineCleared ? { sort: null, sortIndex: null, sortType: undefined } : undefined }, operation.eventType); break; } case "aggFuncs": { for (const [colId, aggFunc] of operation.values) { const column = beans.colModel.getColDefCol(colId); if (!column) { continue; } beans.valueColsSvc?.setColumnAggFunc?.(column, aggFunc, operation.eventType); } break; } } } this.reset(); } applyColumnState(state, eventType) { for (const patch of state) { mergeColumnStatePatch(this.state, patch); } const columnState = ensureColumnStateDraft(this.state); columnState.seq = nextSeq(this.sequence); this.sequence = columnState.seq; columnState.eventType = eventType; } moveColumns(columns, targetIndex, eventType) { const movingColIds = new Set(columns.map((column) => column.getColId())); const orderedColIds = this.state.columnOrder?.colIds ?? getPrimaryColumnIds(this.beans); const remaining = orderedColIds.filter((colId) => !movingColIds.has(colId)); const movedIds = columns.map((column) => column.getColId()); const seq = nextSeq(this.sequence); this.sequence = seq; this.state.columnOrder = { colIds: [...remaining.slice(0, targetIndex), ...movedIds, ...remaining.slice(targetIndex)], eventType, seq }; } setColumnsVisible(columns, visible, eventType) { for (const column of columns) { if (column.getColDef().lockVisible) { continue; } mergeColumnStatePatch(this.state, { colId: column.getColId(), hide: !visible }); } const columnState = ensureColumnStateDraft(this.state); columnState.seq = nextSeq(this.sequence); this.sequence = columnState.seq; columnState.eventType = eventType; } setRowGroupColumns(columns, eventType) { clearDeferredFunctionPatches(this.state, "rowGroup"); const seq = nextSeq(this.sequence); this.sequence = seq; this.state.rowGroup = { colIds: columns.map((column) => column.getColId()), eventType, seq }; } setValueColumns(columns, eventType) { clearDeferredFunctionPatches(this.state, "aggFunc"); const liveValueColIds = new Set((this.beans.valueColsSvc?.columns ?? []).map((col) => col.getColId())); const aggFuncs = ensureAggFuncsDraft(this.state); for (const col of columns) { if (!liveValueColIds.has(col.getColId()) && !aggFuncs.values.has(col.getColId())) { const existingAggFunc = col.getAggFunc(); const aggFunc = existingAggFunc != null ? existingAggFunc : this.beans.aggFuncSvc?.getDefaultAggFunc(col); if (aggFunc != null) { aggFuncs.values.set(col.getColId(), aggFunc); } } } const seq = nextSeq(this.sequence); this.sequence = seq; aggFuncs.seq = seq; aggFuncs.eventType = eventType; this.state.aggregation = { colIds: columns.map((column) => column.getColId()), eventType, seq }; } setColumnAggFunc(column, aggFunc, eventType) { mergeColumnStatePatch(this.state, { colId: column.getColId(), aggFunc }); const columnState = ensureColumnStateDraft(this.state); columnState.seq = nextSeq(this.sequence); this.sequence = columnState.seq; columnState.eventType = eventType; const aggFuncs = ensureAggFuncsDraft(this.state); aggFuncs.seq = columnState.seq; aggFuncs.eventType = eventType; aggFuncs.values.set(column.getColId(), aggFunc); } getColumnAggFunc(column) { const colId = column.getColId(); if (this.state.aggFuncs?.values.has(colId)) { return this.state.aggFuncs.values.get(colId); } return column.getAggFunc(); } isColumnVisibleInToolPanel(column) { const columnState = this.state.columnState?.patches.get(column.getColId()); if (columnState?.hide !== undefined) { return !columnState.hide; } return column.isVisible(); } isColumnSelectedInPivotModeToolPanel(column) { const colId = column.getColId(); const columnState = this.state.columnState?.patches.get(colId); let rowGroupActive; if (columnState?.rowGroup !== undefined) { rowGroupActive = !!columnState.rowGroup; } else if (this.state.rowGroup) { rowGroupActive = this.state.rowGroup.colIds.includes(colId); } else { rowGroupActive = column.isRowGroupActive(); } let pivotActive; if (columnState?.pivot !== undefined) { pivotActive = !!columnState.pivot; } else if (this.state.pivot) { pivotActive = this.state.pivot.colIds.includes(colId); } else { pivotActive = column.isPivotActive(); } let valueActive; if (columnState?.aggFunc !== undefined) { valueActive = columnState.aggFunc != null; } else if (this.state.aggregation) { valueActive = this.state.aggregation.colIds.includes(colId); } else { valueActive = column.isValueActive(); } return rowGroupActive || pivotActive || valueActive; } setPivotColumns(columns, eventType) { clearDeferredFunctionPatches(this.state, "pivot"); const seq = nextSeq(this.sequence); this.sequence = seq; this.state.pivot = { colIds: columns.map((column) => column.getColId()), eventType, seq }; } setPivotMode(pivotMode, eventType) { const seq = nextSeq(this.sequence); this.sequence = seq; this.state.pivotMode = { pivotMode, eventType, seq }; } getRowGroupColumns() { return getDraftColumns(this.beans, getDraftFunctionColumnIds(this.state.rowGroup?.colIds, this.beans.rowGroupColsSvc?.columns, this.state.columnState?.patches, (patch) => patch.rowGroup == null ? undefined : !!patch.rowGroup)); } getPrimaryColumns() { return getDraftColumns(this.beans, this.state.columnOrder?.colIds ?? getPrimaryColumnIds(this.beans)); } hasDeferredColumnOrder() { return !!this.state.columnOrder; } getValueColumns() { return getDraftColumns(this.beans, getDraftFunctionColumnIds(this.state.aggregation?.colIds, this.beans.valueColsSvc?.columns, this.state.columnState?.patches, (patch) => patch.aggFunc === undefined ? undefined : patch.aggFunc != null)); } getPivotColumns() { if (!this.getPivotMode()) { return []; } const livePivotColumns = this.beans.pivotColsSvc?.columns; const fallbackColumns = livePivotColumns?.length ? livePivotColumns : getDraftColumns(this.beans, this.lastPivotColIds); return getDraftColumns(this.beans, getDraftFunctionColumnIds(this.state.pivot?.colIds, fallbackColumns, this.state.columnState?.patches, (patch) => patch.pivot == null ? undefined : !!patch.pivot)); } getPivotMode() { return this.state.pivotMode?.pivotMode ?? this.beans.colModel.isPivotMode(); } getSortDef(column) { const draftSortState = this.state.sort; const colId = column.getColId(); const sortDefsByColId = draftSortState?.sortDefsByColId; if (sortDefsByColId?.has(colId)) { return sortDefsByColId.get(colId) ?? null; } if (draftSortState?.baselineCleared) { return null; } return column.getSortDef(); } progressSortFromEvent(column, event) { const currentDraft = this.state.sort ?? { sortDefsByColId: /* @__PURE__ */ new Map, baselineCleared: false, seq: 0, eventType: "toolPanelUi" }; const { sortSvc } = this.beans; const colId = column.getColId(); let currentSortDef; if (currentDraft.sortDefsByColId.has(colId)) { currentSortDef = currentDraft.sortDefsByColId.get(colId); } else if (currentDraft.baselineCleared) { currentSortDef = null; } else { currentSortDef = column.getSortDef(); } const nextSortDef = sortSvc?.getNextSortDirection(column, currentSortDef); if (!nextSortDef) { return; } const { gos } = this.beans; const sortUsingCtrl = gos.get("multiSortKey") === "ctrl"; const multiSort = sortUsingCtrl ? event.ctrlKey || event.metaKey : event.shiftKey; const doingMultiSort = (multiSort || gos.get("alwaysMultiSort")) && !gos.get("suppressMultiSort"); if (!doingMultiSort) { currentDraft.sortDefsByColId.clear(); currentDraft.baselineCleared = true; } currentDraft.sortDefsByColId.set(colId, nextSortDef.direction ? nextSortDef : null); currentDraft.seq = nextSeq(this.sequence); this.sequence = currentDraft.seq; this.state.sort = currentDraft; } }; function getDraftColumns(beans, colIds) { if (!colIds) { return []; } return colIds.map((colId) => beans.colModel.getColDefCol(colId)).filter((column) => !!column); } function getDraftFunctionColumnIds(draftColIds, liveColumns, columnStatePatches, getPatchState) { const colIds = [...draftColIds ?? liveColumns?.map((column) => column.getColId()) ?? []]; if (!columnStatePatches?.size) { return colIds; } const colIdsSet = new Set(colIds); for (const [colId, patch] of columnStatePatches) { const nextState = getPatchState(patch); if (nextState === undefined) { continue; } if (nextState) { if (!colIdsSet.has(colId)) { colIds.push(colId); colIdsSet.add(colId); } continue; } if (!colIdsSet.has(colId)) { continue; } colIdsSet.delete(colId); const index = colIds.indexOf(colId); if (index >= 0) { colIds.splice(index, 1); } } return colIds; } function syncPrimaryColDefOrderFromCurrentColumns(beans) { const orderedPrimaryColumns = beans.colModel.getCols().filter((column) => isPrimaryColDefColumn(column)).map((column) => beans.colModel.getColDefCol(column.getColId())).filter((column) => !!column); syncPrimaryColDefOrder(beans, orderedPrimaryColumns); } function syncPrimaryColDefOrder(beans, orderedPrimaryColumns) { const colDefCols = getMutablePrimaryColDefCollection(beans); if (!colDefCols) { return; } const orderedSet = new Set(orderedPrimaryColumns); colDefCols.list = [ ...orderedPrimaryColumns, ...colDefCols.list.filter((col) => isPrimaryColDefColumn(col) && !orderedSet.has(col)) ]; } function getPrimaryColumnIds(beans) { return getPrimaryColumns(beans).map((column) => column.getColId()); } function getPrimaryColumns(beans) { return (beans.colModel.getColDefCols() ?? beans.colModel.getCols()).filter((column) => isPrimaryColDefColumn(column)); } function getMutablePrimaryColDefCollection(beans) { const colDefCols = beans.colModel.colDefCols; const colDefList = colDefCols?.list; if (!Array.isArray(colDefList)) { return; } return colDefCols; } function isPrimaryColDefColumn(column) { if (!column.isPrimary()) { return false; } return !isColumnGroupAutoCol(column) && !isSpecialCol(column); } function nextSeq(sequence) { return sequence + 1; } function mergeColumnStatePatch(state, patch) { const columnState = ensureColumnStateDraft(state); const existing = columnState.patches.get(patch.colId); columnState.patches.set(patch.colId, existing ? { ...existing, ...patch } : patch); } function clearDeferredFunctionPatches(state, patchKey) { const patches = state.columnState?.patches; if (!patches?.size) { return; } for (const [colId, patch] of patches) { if (!(patchKey in patch)) { continue; } const nextPatch = { ...patch }; delete nextPatch[patchKey]; if (Object.keys(nextPatch).length === 1) { patches.delete(colId); continue; } patches.set(colId, nextPatch); } } function ensureColumnStateDraft(state) { let { columnState } = state; if (!columnState) { columnState = { patches: /* @__PURE__ */ new Map, seq: 0, eventType: "toolPanelUi" }; state.columnState = columnState; } return columnState; } function ensureAggFuncsDraft(state) { let { aggFuncs } = state; if (!aggFuncs) { aggFuncs = { values: /* @__PURE__ */ new Map, seq: 0, eventType: "toolPanelUi" }; state.aggFuncs = aggFuncs; } return aggFuncs; } var ColumnStateUpdateStrategy = class extends BeanStub { constructor() { super(...arguments); this.beanName = "columnStateUpdateStrategy"; } applyColumnState(deferMode, state, eventType) { this.delegate("applyColumnState", deferMode, state, eventType); } commit(deferMode) { this.delegate("commit", deferMode); } hasPendingChanges(deferMode) { return this.delegate("hasPendingChanges", deferMode); } moveColumns(deferMode, columns, targetIndex, eventType) { this.delegate("moveColumns", deferMode, columns, targetIndex, eventType); } reset(deferMode) { this.delegate("reset", deferMode); } setColumnsVisible(deferMode, columns, visible, eventType) { this.delegate("setColumnsVisible", deferMode, columns, visible, eventType); } isColumnVisibleInToolPanel(deferMode, column) { return this.delegate("isColumnVisibleInToolPanel", deferMode, column); } setRowGroupColumns(deferMode, columns, eventType) { this.delegate("setRowGroupColumns", deferMode, columns, eventType); } getRowGroupColumns(deferMode) { return this.delegate("getRowGroupColumns", deferMode); } getPrimaryColumns(deferMode) { return this.delegate("getPrimaryColumns", deferMode); } hasDeferredColumnOrder(deferMode) { return this.delegate("hasDeferredColumnOrder", deferMode); } setValueColumns(deferMode, columns, eventType) { this.delegate("setValueColumns", deferMode, columns, eventType); } getValueColumns(deferMode) { return this.delegate("getValueColumns", deferMode); } setColumnAggFunc(deferMode, column, aggFunc, eventType) { this.delegate("setColumnAggFunc", deferMode, column, aggFunc, eventType); } getColumnAggFunc(deferMode, column) { return this.delegate("getColumnAggFunc", deferMode, column); } setPivotColumns(deferMode, columns, eventType) { this.delegate("setPivotColumns", deferMode, columns, eventType); } getPivotColumns(deferMode) { return this.delegate("getPivotColumns", deferMode); } setPivotMode(deferMode, pivotMode, eventType) { this.delegate("setPivotMode", deferMode, pivotMode, eventType); } getPivotMode(deferMode) { return this.delegate("getPivotMode", deferMode); } isColumnSelectedInPivotModeToolPanel(deferMode, column) { return this.delegate("isColumnSelectedInPivotModeToolPanel", deferMode, column); } progressSortFromEvent(deferMode, column, event) { this.delegate("progressSortFromEvent", deferMode, column, event); } getSortDef(deferMode, column) { return this.delegate("getSortDef", deferMode, column); } getUpdateStrategy() { return this.executionStrategy ?? (this.executionStrategy = this.createManagedBean(new ColumnStateUpdateExecutionStrategy)); } delegate(method, ...args) { const strategy = this.getUpdateStrategy(); const fn = strategy[method].bind(strategy); return fn(...args); } }; var SharedColumnStateUpdateStrategyModule = { moduleName: "SharedColumnStateUpdateStrategy", version: VERSION2, beans: [ColumnStateUpdateStrategy], dependsOn: [EnterpriseCoreModule] }; var ColumnsToolPanelModule = { moduleName: "ColumnsToolPanel", version: VERSION2, beans: [ColumnToolPanelFactory], userComponents: { agColumnsToolPanel: ColumnToolPanel }, icons: { ensureColumnVisible: "column-arrow", columnsToolPanel: "columns", menuAddRowGroup: "group", menuRemoveRowGroup: "group", pivotPanel: "pivot", rowGroupPanel: "group", valuePanel: "aggregation", columnSelectClosed: "tree-closed", columnSelectOpen: "tree-open", columnSelectIndeterminate: "tree-indeterminate" }, dependsOn: [ EnterpriseCoreModule, SharedColumnStateUpdateStrategyModule, SideBarModule, ColumnMoveModule, SharedDragAndDropModule, PopupModule, MenuItemModule ] }; var ChartMenuItemMapper = class extends BeanStub { constructor() { super(...arguments); this.beanName = "chartMenuItemMapper"; } getChartItems(key) { const beans = this.beans; const chartSvc = beans.chartSvc; const isPivot = key === "pivotChart"; if (!chartSvc) { return null; } const getLocaleTextFunc = this.getLocaleTextFunc.bind(this); const builder = isPivot ? new PivotMenuItemMapper(beans, chartSvc, getLocaleTextFunc) : new RangeMenuItemMapper(beans, chartSvc, getLocaleTextFunc); const isEnterprise = chartSvc.isEnterprise(); let topLevelMenuItem = builder.getMenuItem(); if (topLevelMenuItem?.subMenu && !isEnterprise) { const filterEnterpriseItems = (m) => ({ ...m, subMenu: m.subMenu?.filter((menu) => !menu._enterprise).map((menu) => filterEnterpriseItems(menu)) }); topLevelMenuItem = filterEnterpriseItems(topLevelMenuItem); } const chartGroupsDef = this.gos.get("chartToolPanelsDef")?.settingsPanel?.chartGroupsDef; if (chartGroupsDef) { topLevelMenuItem = this.filterAndOrderChartMenu(topLevelMenuItem, chartGroupsDef, builder.getConfigLookup()); } return this.cleanInternals(topLevelMenuItem); } cleanInternals(menuItem) { if (!menuItem) { return menuItem; } const removeKeys = (m) => { delete m?._key; delete m?._enterprise; for (const s2 of m?.subMenu ?? []) { removeKeys(s2); } return m; }; return removeKeys(menuItem); } buildLookup(menuItem) { const itemLookup = {}; const addItem = (item) => { itemLookup[item._key] = item; if (item.subMenu) { for (const s2 of item.subMenu) { addItem(s2); } } }; addItem(menuItem); return itemLookup; } filterAndOrderChartMenu(topLevelMenuItem, chartGroupsDef, configLookup) { const menuItemLookup = this.buildLookup(topLevelMenuItem); const orderedAndFiltered = { ...topLevelMenuItem, subMenu: [] }; for (const group of Object.keys(chartGroupsDef)) { const chartTypes = chartGroupsDef[group]; const chartConfigGroup = configLookup[group]; if (chartConfigGroup === null) { continue; } if (chartConfigGroup == undefined) { _warn(173, { group }); continue; } const menuItem = menuItemLookup[chartConfigGroup._key]; if (menuItem) { if (menuItem.subMenu) { const subMenus = chartTypes.map((chartType) => { const itemKey = chartConfigGroup[chartType]; if (itemKey == undefined) { _warn(174, { group, chartType }); return; } return menuItemLookup[itemKey]; }).filter((s2) => s2 !== undefined); if (subMenus.length > 0) { menuItem.subMenu = subMenus; orderedAndFiltered.subMenu?.push(menuItem); } } else { orderedAndFiltered.subMenu?.push(menuItem); } } } if (orderedAndFiltered.subMenu?.length == 0) { return null; } return orderedAndFiltered; } }; var PivotMenuItemMapper = class { constructor(beans, chartSvc, getLocaleTextFunc) { this.beans = beans; this.chartSvc = chartSvc; this.getLocaleTextFunc = getLocaleTextFunc; } getMenuItem() { const localeTextFunc = this.getLocaleTextFunc(); const getMenuItem = (localeKey, defaultText, chartType, key, enterprise = false) => { return { name: localeTextFunc(localeKey, defaultText + "‎"), action: () => this.chartSvc.createPivotChart({ chartType }), _key: key, _enterprise: enterprise }; }; return { name: localeTextFunc("pivotChart", "Pivot Chart"), _key: "pivotChart", subMenu: [ { _key: "pivotColumnChart", name: localeTextFunc("columnChart", "Column"), subMenu: [ getMenuItem("groupedColumn", "Grouped", "groupedColumn", "pivotGroupedColumn"), getMenuItem("stackedColumn", "Stacked", "stackedColumn", "pivotStackedColumn"), getMenuItem("normalizedColumn", "100% Stacked", "normalizedColumn", "pivotNormalizedColumn") ] }, { _key: "pivotBarChart", name: localeTextFunc("barChart", "Bar"), subMenu: [ getMenuItem("groupedBar", "Grouped", "groupedBar", "pivotGroupedBar"), getMenuItem("stackedBar", "Stacked", "stackedBar", "pivotStackedBar"), getMenuItem("normalizedBar", "100% Stacked", "normalizedBar", "pivotNormalizedBar") ] }, { _key: "pivotPieChart", name: localeTextFunc("pieChart", "Pie"), subMenu: [ getMenuItem("pie", "Pie", "pie", "pivotPie"), getMenuItem("donut", "Donut", "donut", "pivotDonut") ] }, { _key: "pivotLineChart", name: localeTextFunc("lineChart", "Line"), subMenu: [ getMenuItem("lineChart", "Line", "line", "pivotLineChart"), getMenuItem("stackedLine", "Stacked", "stackedLine", "pivotStackedLine"), getMenuItem("normalizedLine", "100% Stacked", "normalizedLine", "pivotNormalizedLine") ] }, { _key: "pivotAreaChart", name: localeTextFunc("areaChart", "Area"), subMenu: [ getMenuItem("areaChart", "Area", "area", "pivotArea"), getMenuItem("stackedArea", "Stacked", "stackedArea", "pivotStackedArea"), getMenuItem("normalizedArea", "100% Stacked", "normalizedArea", "pivotNormalizedArea") ] }, { _key: "pivotXYChart", name: localeTextFunc("xyChart", "X Y (Scatter)"), subMenu: [ getMenuItem("scatter", "Scatter", "scatter", "pivotScatter"), getMenuItem("bubble", "Bubble", "bubble", "pivotBubble") ] }, { _key: "pivotStatisticalChart", _enterprise: false, name: localeTextFunc("statisticalChart", "Statistical"), subMenu: [getMenuItem("histogramChart", "Histogram", "histogram", "pivotHistogram", false)] }, { _key: "pivotHierarchicalChart", _enterprise: true, name: localeTextFunc("hierarchicalChart", "Hierarchical"), subMenu: [ getMenuItem("treemapChart", "Treemap", "treemap", "pivotTreemap", true), getMenuItem("sunburstChart", "Sunburst", "sunburst", "pivotSunburst", true) ] }, { _key: "pivotFunnel", name: localeTextFunc("funnel", "Funnel"), subMenu: [ getMenuItem("funnel", "Funnel", "funnel", "pivotFunnel"), getMenuItem("coneFunnel", "Cone Funnel", "coneFunnel", "pivotConeFunnel"), getMenuItem("pyramid", "Pyramid", "pyramid", "pivotPyramid") ] }, { _key: "pivotCombinationChart", name: localeTextFunc("combinationChart", "Combination"), subMenu: [ getMenuItem("columnLineCombo", "Column & Line", "columnLineCombo", "pivotColumnLineCombo"), getMenuItem("AreaColumnCombo", "Area & Column", "areaColumnCombo", "pivotAreaColumnCombo") ] } ], icon: _createIconNoSpan("chart", this.beans, undefined) }; } getConfigLookup() { return { columnGroup: { _key: "pivotColumnChart", column: "pivotGroupedColumn", stackedColumn: "pivotStackedColumn", normalizedColumn: "pivotNormalizedColumn" }, barGroup: { _key: "pivotBarChart", bar: "pivotGroupedBar", stackedBar: "pivotStackedBar", normalizedBar: "pivotNormalizedBar" }, pieGroup: { _key: "pivotPieChart", pie: "pivotPie", donut: "pivotDonut", doughnut: "pivotDonut" }, lineGroup: { _key: "pivotLineChart", line: "pivotLineChart", stackedLine: "pivotStackedLine", normalizedLine: "pivotNormalizedLine" }, areaGroup: { _key: "pivotAreaChart", area: "pivotArea", stackedArea: "pivotStackedArea", normalizedArea: "pivotNormalizedArea" }, scatterGroup: { _key: "pivotXYChart", bubble: "pivotBubble", scatter: "pivotScatter" }, combinationGroup: { _key: "pivotCombinationChart", columnLineCombo: "pivotColumnLineCombo", areaColumnCombo: "pivotAreaColumnCombo", customCombo: null }, hierarchicalGroup: { _key: "pivotHierarchicalChart", treemap: "pivotTreemap", sunburst: "pivotSunburst" }, statisticalGroup: { _key: "pivotStatisticalChart", histogram: "pivotHistogram", rangeBar: null, rangeArea: null, boxPlot: null }, funnelGroup: { _key: "pivotFunnel", funnel: "pivotFunnel", coneFunnel: "pivotConeFunnel", pyramid: "pivotPyramid" }, polarGroup: null, specializedGroup: null }; } }; var RangeMenuItemMapper = class { constructor(beans, chartSvc, getLocaleTextFunc) { this.beans = beans; this.chartSvc = chartSvc; this.getLocaleTextFunc = getLocaleTextFunc; } getMenuItem() { const localeTextFunc = this.getLocaleTextFunc(); const getMenuItem = (localeKey, defaultText, chartType, key, enterprise = false) => { return { name: localeTextFunc(localeKey, defaultText), action: () => this.chartSvc.createChartFromCurrentRange(chartType), _key: key, _enterprise: enterprise }; }; return { name: localeTextFunc("chartRange", "Chart Range"), _key: "chartRange", subMenu: [ { name: localeTextFunc("columnChart", "Column"), subMenu: [ getMenuItem("groupedColumn", "Grouped", "groupedColumn", "rangeGroupedColumn"), getMenuItem("stackedColumn", "Stacked", "stackedColumn", "rangeStackedColumn"), getMenuItem("normalizedColumn", "100% Stacked", "normalizedColumn", "rangeNormalizedColumn") ], _key: "rangeColumnChart" }, { name: localeTextFunc("barChart", "Bar"), subMenu: [ getMenuItem("groupedBar", "Grouped", "groupedBar", "rangeGroupedBar"), getMenuItem("stackedBar", "Stacked", "stackedBar", "rangeStackedBar"), getMenuItem("normalizedBar", "100% Stacked", "normalizedBar", "rangeNormalizedBar") ], _key: "rangeBarChart" }, { name: localeTextFunc("pieChart", "Pie"), subMenu: [ getMenuItem("pie", "Pie", "pie", "rangePie"), getMenuItem("donut", "Donut", "donut", "rangeDonut") ], _key: "rangePieChart" }, { name: localeTextFunc("lineChart", "Line"), subMenu: [ getMenuItem("lineChart", "Line", "line", "rangeLineChart"), getMenuItem("stackedLine", "Stacked", "stackedLine", "rangeStackedLine"), getMenuItem("normalizedLine", "100% Stacked", "normalizedLine", "rangeNormalizedLine") ], _key: "rangeLineChart" }, { name: localeTextFunc("areaChart", "Area"), subMenu: [ getMenuItem("areaChart", "Area", "area", "rangeArea"), getMenuItem("stackedArea", "Stacked", "stackedArea", "rangeStackedArea"), getMenuItem("normalizedArea", "100% Stacked", "normalizedArea", "rangeNormalizedArea") ], _key: "rangeAreaChart" }, { name: localeTextFunc("xyChart", "X Y (Scatter)"), subMenu: [ getMenuItem("scatter", "Scatter", "scatter", "rangeScatter"), getMenuItem("bubble", "Bubble", "bubble", "rangeBubble") ], _key: "rangeXYChart" }, { name: localeTextFunc("polarChart", "Polar"), subMenu: [ getMenuItem("radarLine", "Radar Line", "radarLine", "rangeRadarLine"), getMenuItem("radarArea", "Radar Area", "radarArea", "rangeRadarArea"), getMenuItem("nightingale", "Nightingale", "nightingale", "rangeNightingale"), getMenuItem("radialColumn", "Radial Column", "radialColumn", "rangeRadialColumn"), getMenuItem("radialBar", "Radial Bar", "radialBar", "rangeRadialBar") ], _key: "rangePolarChart", _enterprise: true }, { name: localeTextFunc("statisticalChart", "Statistical"), subMenu: [ getMenuItem("boxPlot", "Box Plot", "boxPlot", "rangeBoxPlot", true), getMenuItem("histogramChart", "Histogram", "histogram", "rangeHistogram", false), getMenuItem("rangeBar", "Range Bar", "rangeBar", "rangeRangeBar", true), getMenuItem("rangeArea", "Range Area", "rangeArea", "rangeRangeArea", true) ], _key: "rangeStatisticalChart", _enterprise: false }, { name: localeTextFunc("hierarchicalChart", "Hierarchical"), subMenu: [ getMenuItem("treemap", "Treemap", "treemap", "rangeTreemap"), getMenuItem("sunburst", "Sunburst", "sunburst", "rangeSunburst") ], _key: "rangeHierarchicalChart", _enterprise: true }, { name: localeTextFunc("specializedChart", "Specialized"), subMenu: [ getMenuItem("heatmap", "Heatmap", "heatmap", "rangeHeatmap"), getMenuItem("waterfall", "Waterfall", "waterfall", "rangeWaterfall") ], _key: "rangeSpecializedChart", _enterprise: true }, { name: localeTextFunc("funnel", "Funnel"), subMenu: [ getMenuItem("funnel", "Funnel", "funnel", "rangeFunnel"), getMenuItem("coneFunnel", "Cone Funnel", "coneFunnel", "rangeConeFunnel"), getMenuItem("pyramid", "Pyramid", "pyramid", "rangePyramid") ], _key: "rangeFunnel", _enterprise: true }, { name: localeTextFunc("combinationChart", "Combination"), subMenu: [ getMenuItem("columnLineCombo", "Column & Line", "columnLineCombo", "rangeColumnLineCombo"), getMenuItem("AreaColumnCombo", "Area & Column", "areaColumnCombo", "rangeAreaColumnCombo") ], _key: "rangeCombinationChart" } ], icon: _createIconNoSpan("chart", this.beans, undefined) }; } getConfigLookup() { return { columnGroup: { _key: "rangeColumnChart", column: "rangeGroupedColumn", stackedColumn: "rangeStackedColumn", normalizedColumn: "rangeNormalizedColumn" }, barGroup: { _key: "rangeBarChart", bar: "rangeGroupedBar", stackedBar: "rangeStackedBar", normalizedBar: "rangeNormalizedBar" }, pieGroup: { _key: "rangePieChart", pie: "rangePie", donut: "rangeDonut", doughnut: "rangeDonut" }, lineGroup: { _key: "rangeLineChart", line: "rangeLineChart", stackedLine: "rangeStackedLine", normalizedLine: "rangeNormalizedLine" }, areaGroup: { _key: "rangeAreaChart", area: "rangeArea", stackedArea: "rangeStackedArea", normalizedArea: "rangeNormalizedArea" }, scatterGroup: { _key: "rangeXYChart", bubble: "rangeBubble", scatter: "rangeScatter" }, polarGroup: { _key: "rangePolarChart", radarLine: "rangeRadarLine", radarArea: "rangeRadarArea", nightingale: "rangeNightingale", radialColumn: "rangeRadialColumn", radialBar: "rangeRadialBar" }, statisticalGroup: { _key: "rangeStatisticalChart", boxPlot: "rangeBoxPlot", histogram: "rangeHistogram", rangeBar: "rangeRangeBar", rangeArea: "rangeRangeArea" }, hierarchicalGroup: { _key: "rangeHierarchicalChart", treemap: "rangeTreemap", sunburst: "rangeSunburst" }, specializedGroup: { _key: "rangeSpecializedChart", heatmap: "rangeHeatmap", waterfall: "rangeWaterfall" }, funnelGroup: { _key: "rangeFunnel", funnel: "rangeFunnel", coneFunnel: "rangeConeFunnel", pyramid: "rangePyramid" }, combinationGroup: { _key: "rangeCombinationChart", columnLineCombo: "rangeColumnLineCombo", areaColumnCombo: "rangeAreaColumnCombo", customCombo: null } }; } }; var ColumnChooserFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colChooserFactory"; } createColumnSelectPanel(parent, column, draggable, params) { const columnSelectPanel = parent.createManagedBean(new AgPrimaryCols); const columnChooserParams = params ?? column?.getColDef().columnChooserParams ?? {}; const { contractColumnSelection, suppressColumnExpandAll, suppressColumnFilter, suppressColumnSelectAll, suppressSyncLayoutWithGrid, columnLayout } = columnChooserParams; columnSelectPanel.init(!!draggable, _addGridCommonParams(this.gos, { suppressColumnMove: false, suppressValues: false, suppressPivots: false, suppressRowGroups: false, suppressPivotMode: false, contractColumnSelection: !!contractColumnSelection, suppressColumnExpandAll: !!suppressColumnExpandAll, suppressColumnFilter: !!suppressColumnFilter, suppressColumnSelectAll: !!suppressColumnSelectAll, suppressSyncLayoutWithGrid: !!columnLayout || !!suppressSyncLayoutWithGrid, onStateUpdated: () => {} }), "columnMenu"); if (columnLayout) { columnSelectPanel.setColumnLayout(columnLayout); } return columnSelectPanel; } showColumnChooser({ column, chooserParams, eventSource, headerPosition: providedHeaderPosition }) { this.hideActiveColumnChooser(); const columnSelectPanel = this.createColumnSelectPanel(this, column, true, chooserParams); const translate = this.getLocaleTextFunc(); const beans = this.beans; const { visibleCols, focusSvc, menuUtils } = beans; const columnIndex = visibleCols.allCols.indexOf(column); const headerPosition = column ? focusSvc.focusedHeader ?? providedHeaderPosition ?? null : null; this.activeColumnChooserDialog = this.createBean(new Dialog({ title: translate("chooseColumns", "Choose Columns"), component: columnSelectPanel, width: 300, height: 300, resizable: true, movable: true, centered: true, closable: true, afterGuiAttached: () => { _findNextFocusableElement(beans, columnSelectPanel.getGui())?.focus({ preventScroll: true }); this.dispatchVisibleChangedEvent(true, column); }, closedCallback: (event) => { const eComp = this.activeColumnChooser.getGui(); this.destroyBean(this.activeColumnChooser); this.activeColumnChooser = undefined; this.activeColumnChooserDialog = undefined; this.dispatchVisibleChangedEvent(false, column); if (column) { menuUtils.restoreFocusOnClose({ column, headerPosition, columnIndex, eventSource }, eComp, event, true); } }, postProcessPopupParams: { type: "columnChooser", column, eventSource } })); this.activeColumnChooser = columnSelectPanel; } hideActiveColumnChooser() { this.destroyBean(this.activeColumnChooserDialog); } dispatchVisibleChangedEvent(visible, column) { this.eventSvc.dispatchEvent({ type: "columnMenuVisibleChanged", visible, switchingTab: false, key: "columnChooser", column: column ?? null }); } }; var MENU_ITEM_MODULES = { pinSubMenu: "PinnedColumn", pinLeft: "PinnedColumn", pinRight: "PinnedColumn", clearPinned: "PinnedColumn", pinRowSubMenu: "PinnedRow", pinBottom: "PinnedRow", pinTop: "PinnedRow", unpinRow: "PinnedRow", valueAggSubMenu: "SharedAggregation", autoSizeThis: "ColumnAutoSize", autoSizeAll: "ColumnAutoSize", rowGroup: "SharedRowGrouping", rowUnGroup: "SharedRowGrouping", resetColumns: "CommunityCore", expandAll: ["ClientSideRowModelHierarchy", "ServerSideRowModel"], contractAll: ["ClientSideRowModelHierarchy", "ServerSideRowModel"], copy: "Clipboard", copyWithHeaders: "Clipboard", copyWithGroupHeaders: "Clipboard", cut: "Clipboard", paste: "Clipboard", export: ["CsvExport", "ExcelExport"], csvExport: "CsvExport", excelExport: "ExcelExport", separator: "CommunityCore", pivotChart: "IntegratedCharts", chartRange: "IntegratedCharts", columnFilter: "ColumnFilter", columnChooser: "ColumnMenu", sortAscending: "Sort", sortDescending: "Sort", sortAbsoluteAscending: "Sort", sortAbsoluteDescending: "Sort", sortUnSort: "Sort" }; function validateMenuItem(gos, key) { const moduleName4 = MENU_ITEM_MODULES[key]; if (moduleName4) { gos.assertModuleRegistered(moduleName4, `menu item '${key}'`); } } var MENU_ITEM_SEPARATOR = "separator"; function _removeRepeatsFromArray(array, object) { if (!array) { return; } for (let index = array.length - 2;index >= 0; index--) { const thisOneMatches = array[index] === object; const nextOneMatches = array[index + 1] === object; if (thisOneMatches && nextOneMatches) { array.splice(index + 1, 1); } } } var SORT_MENU_ITEM_TO_MENU_ACTION_PARAMS = { sortAscending: { fallback: "Sort Ascending", getSortDef: () => ({ type: "default", direction: "asc" }) }, sortDescending: { fallback: "Sort Descending", getSortDef: () => ({ type: "default", direction: "desc" }) }, sortAbsoluteAscending: { fallback: "Sort Absolute Ascending", getSortDef: () => ({ type: "absolute", direction: "asc" }) }, sortAbsoluteDescending: { fallback: "Sort Absolute Descending", getSortDef: () => ({ type: "absolute", direction: "desc" }) }, sortUnSort: { fallback: "Clear Sort", getSortDef: (column) => ({ type: _normalizeSortType(column.getSortDef()?.type), direction: null }) } }; var MenuItemMapper = class extends BeanStub { constructor() { super(...arguments); this.beanName = "menuItemMapper"; } mapWithStockItems(originalList, column, node, sourceElement, source) { if (!originalList) { return []; } const resultList = []; const localeTextFunc = this.getLocaleTextFunc(); const { beans, gos } = this; const { pinnedCols, colAutosize, aggFuncSvc, rowGroupColsSvc, colNames, colModel, clipboardSvc, expansionSvc, focusSvc, csvCreator, excelCreator, menuSvc, colChooserFactory, sortSvc, chartMenuItemMapper, valueColsSvc, pinnedRowModel } = beans; const getStockMenuItem = (key, column2, sourceElement2, source2) => { validateMenuItem(gos, key); switch (key) { case "pinSubMenu": return pinnedCols && column2 ? { name: localeTextFunc("pinColumn", "Pin Column"), icon: _createIconNoSpan("menuPin", beans, null), subMenu: ["clearPinned", "pinLeft", "pinRight"] } : null; case "pinLeft": return pinnedCols && column2 ? { name: localeTextFunc("pinLeft", "Pin Left"), action: () => pinnedCols.setColsPinned([column2], "left", source2), checked: !!column2 && column2.isPinnedLeft() } : null; case "pinRight": return pinnedCols && column2 ? { name: localeTextFunc("pinRight", "Pin Right"), action: () => pinnedCols.setColsPinned([column2], "right", source2), checked: !!column2 && column2.isPinnedRight() } : null; case "clearPinned": return pinnedCols && column2 ? { name: localeTextFunc("noPin", "No Pin"), action: () => pinnedCols.setColsPinned([column2], null, source2), checked: !!column2 && !column2.isPinned() } : null; case "pinRowSubMenu": { const enableRowPinning = gos.get("enableRowPinning"); const subMenu = []; const pinned = node?.rowPinned ?? node?.pinnedSibling?.rowPinned; if (pinned) { subMenu.push("unpinRow"); } if (enableRowPinning && enableRowPinning !== "bottom" && pinned != "top") { subMenu.push("pinTop"); } if (enableRowPinning && enableRowPinning !== "top" && pinned != "bottom") { subMenu.push("pinBottom"); } return pinnedRowModel?.isManual() ? { name: localeTextFunc("pinRow", "Pin Row"), icon: _createIconNoSpan("rowPin", beans, column2), subMenu } : null; } case "pinTop": return pinnedRowModel?.isManual() ? { name: localeTextFunc("pinTop", "Pin to Top"), icon: _createIconNoSpan("rowPinTop", beans, column2), action: ({ node: node2, column: column3 }) => node2 && pinnedRowModel.pinRow(node2, "top", column3) } : null; case "pinBottom": return pinnedRowModel?.isManual() ? { name: localeTextFunc("pinBottom", "Pin to Bottom"), icon: _createIconNoSpan("rowPinBottom", beans, column2), action: ({ node: node2, column: column3 }) => node2 && pinnedRowModel.pinRow(node2, "bottom", column3) } : null; case "unpinRow": return pinnedRowModel?.isManual() ? { name: localeTextFunc("unpinRow", "Unpin Row"), icon: _createIconNoSpan("rowUnpin", beans, column2), action: ({ node: node2, column: column3 }) => node2 && pinnedRowModel.pinRow(node2, null, column3) } : null; case "valueAggSubMenu": if (aggFuncSvc && valueColsSvc && (column2?.isPrimary() || column2?.getColDef().pivotValueColumn)) { return { name: localeTextFunc("valueAggregation", "Value Aggregation"), icon: _createIconNoSpan("menuValue", beans, null), subMenu: createAggregationSubMenu(column2, aggFuncSvc, valueColsSvc, localeTextFunc), disabled: gos.get("functionsReadOnly") }; } else { return null; } case "autoSizeThis": return colAutosize ? { name: localeTextFunc("autosizeThisColumn", "Autosize This Column"), action: () => column2 && colAutosize.autoSizeColumn(column2, source2, gos.get("skipHeaderOnAutoSize")) } : null; case "autoSizeAll": return colAutosize ? { name: localeTextFunc("autosizeAllColumns", "Autosize All Columns"), action: () => colAutosize.autoSizeAllColumns({ source: source2, skipHeader: gos.get("skipHeaderOnAutoSize") }) } : null; case "rowGroup": return rowGroupColsSvc ? { name: getGroupingLocaleText(localeTextFunc, "groupBy", colNames.getDisplayNameForColumn(column2, "header")), disabled: gos.get("functionsReadOnly") || column2?.isRowGroupActive() || !column2?.getColDef().enableRowGroup, action: () => rowGroupColsSvc.addColumns([column2], source2), icon: _createIconNoSpan("menuAddRowGroup", beans, null) } : null; case "rowUnGroup": { if (rowGroupColsSvc && gos.isModuleRegistered("SharedRowGrouping")) { const showRowGroup = column2?.getColDef().showRowGroup; const lockedGroups = gos.get("groupLockGroupColumns"); let name; let disabled; let action; if (showRowGroup === true) { name = localeTextFunc("ungroupAll", "Un-Group All"); disabled = gos.get("functionsReadOnly") || lockedGroups === -1 || lockedGroups >= (rowGroupColsSvc.columns.length ?? 0); action = () => rowGroupColsSvc.setColumns(rowGroupColsSvc.columns.slice(0, lockedGroups), source2); } else if (typeof showRowGroup === "string") { const underlyingColumn = colModel.getColDefCol(showRowGroup); const ungroupByName = underlyingColumn != null ? colNames.getDisplayNameForColumn(underlyingColumn, "header") : showRowGroup; name = getGroupingLocaleText(localeTextFunc, "ungroupBy", ungroupByName); disabled = gos.get("functionsReadOnly") || isRowGroupColLocked(underlyingColumn, beans); action = () => { rowGroupColsSvc.removeColumns([showRowGroup], source2); }; } else { name = getGroupingLocaleText(localeTextFunc, "ungroupBy", colNames.getDisplayNameForColumn(column2, "header")); disabled = gos.get("functionsReadOnly") || !column2?.isRowGroupActive() || !column2?.getColDef().enableRowGroup || isRowGroupColLocked(column2, beans); action = () => rowGroupColsSvc.removeColumns([column2], source2); } return { name, disabled, action, icon: _createIconNoSpan("menuRemoveRowGroup", beans, null) }; } else { return null; } } case "resetColumns": return { name: localeTextFunc("resetColumns", "Reset Columns"), action: () => _resetColumnState(beans, source2) }; case "expandAll": return expansionSvc ? { name: localeTextFunc("expandAll", "Expand All Row Groups"), action: () => expansionSvc.expandAll(true) } : null; case "contractAll": return expansionSvc ? { name: localeTextFunc("collapseAll", "Collapse All Row Groups"), action: () => expansionSvc.expandAll(false) } : null; case "copy": return clipboardSvc ? { name: localeTextFunc("copy", "Copy"), shortcut: localeTextFunc("ctrlC", "Ctrl+C"), icon: _createIconNoSpan("clipboardCopy", beans, null), action: () => clipboardSvc.copyToClipboard() } : null; case "copyWithHeaders": return clipboardSvc ? { name: localeTextFunc("copyWithHeaders", "Copy with Headers"), icon: _createIconNoSpan("clipboardCopy", beans, null), action: () => clipboardSvc.copyToClipboard({ includeHeaders: true }) } : null; case "copyWithGroupHeaders": return clipboardSvc ? { name: localeTextFunc("copyWithGroupHeaders", "Copy with Group Headers"), icon: _createIconNoSpan("clipboardCopy", beans, null), action: () => clipboardSvc.copyToClipboard({ includeHeaders: true, includeGroupHeaders: true }) } : null; case "cut": if (clipboardSvc) { const focusedCell = focusSvc.getFocusedCell(); const rowNode = focusedCell ? _getRowNode(beans, focusedCell) : null; const isEditable = rowNode ? focusedCell?.column.isCellEditable(rowNode) : false; return { name: localeTextFunc("cut", "Cut"), shortcut: localeTextFunc("ctrlX", "Ctrl+X"), icon: _createIconNoSpan("clipboardCut", beans, null), disabled: !isEditable || gos.get("suppressCutToClipboard"), action: () => clipboardSvc.cutToClipboard(undefined, "contextMenu") }; } else { return null; } case "paste": if (clipboardSvc) { const isPasteBlocked = gos.get("suppressClipboardApi") || gos.get("suppressClipboardPaste") || !column2 || !node || !column2.isCellEditable(node) || column2.isSuppressPaste(node); return { name: localeTextFunc("paste", "Paste"), shortcut: localeTextFunc("ctrlV", "Ctrl+V"), icon: _createIconNoSpan("clipboardPaste", beans, null), disabled: isPasteBlocked, action: () => clipboardSvc.pasteFromClipboard() }; } else { return null; } case "export": { const exportSubMenuItems = []; if (!gos.get("suppressCsvExport") && csvCreator) { exportSubMenuItems.push("csvExport"); } if (!gos.get("suppressExcelExport") && excelCreator) { exportSubMenuItems.push("excelExport"); } return exportSubMenuItems.length ? { name: localeTextFunc("export", "Export"), subMenu: exportSubMenuItems, icon: _createIconNoSpan("save", beans, null) } : null; } case "csvExport": return csvCreator ? { name: localeTextFunc("csvExport", "CSV Export"), icon: _createIconNoSpan("csvExport", beans, null), action: () => csvCreator.exportDataAsCsv() } : null; case "excelExport": return excelCreator ? { name: localeTextFunc("excelExport", "Excel Export"), icon: _createIconNoSpan("excelExport", beans, null), action: () => excelCreator.exportDataAsExcel() } : null; case "separator": return key; case "pivotChart": case "chartRange": return chartMenuItemMapper.getChartItems(key); case "columnFilter": return menuSvc && column2 ? { name: localeTextFunc("columnFilter", "Column Filter"), icon: _createIconNoSpan("filter", beans, null), action: () => menuSvc.showFilterMenu({ column: column2, buttonElement: sourceElement2(), containerType: "columnFilter", positionBy: "button" }) } : null; case "columnChooser": { const headerPosition = focusSvc.focusedHeader; return colChooserFactory ? { name: localeTextFunc("columnChooser", "Choose Columns"), icon: _createIconNoSpan("columns", beans, null), action: () => colChooserFactory.showColumnChooser({ column: column2, eventSource: sourceElement2(), headerPosition }) } : null; } case "sortUnSort": case "sortAscending": case "sortDescending": case "sortAbsoluteAscending": case "sortAbsoluteDescending": { if (!sortSvc || !column2) { return null; } const { fallback, getSortDef } = SORT_MENU_ITEM_TO_MENU_ACTION_PARAMS[key]; return { name: localeTextFunc(key, fallback), icon: _createIconNoSpan(key, beans, null), action: () => sortSvc.setSortForColumn(column2, getSortDef(column2), false, source2) }; } default: { _warn(176, { key }); return null; } } }; for (const menuItemOrString of originalList) { let result; if (typeof menuItemOrString === "string") { result = getStockMenuItem(menuItemOrString, column, sourceElement, source); } else { result = { ...menuItemOrString }; } if (!result) { continue; } const resultDef = result; const { subMenu } = resultDef; if (subMenu && subMenu instanceof Array) { resultDef.subMenu = this.mapWithStockItems(subMenu, column, node, sourceElement, source); } if (result != null) { resultList.push(result); } } _removeRepeatsFromArray(resultList, MENU_ITEM_SEPARATOR); return resultList; } }; function createAggregationSubMenu(column, aggFuncSvc, valueColsSvc, localeTextFunc) { let columnToUse; if (column.isPrimary()) { columnToUse = column; } else { const pivotValueColumn = column.getColDef().pivotValueColumn; columnToUse = _exists(pivotValueColumn) ? pivotValueColumn : undefined; } const result = []; if (columnToUse) { const columnIsAlreadyAggValue = columnToUse.isValueActive(); const funcNames = aggFuncSvc.getFuncNames(columnToUse); result.push({ name: localeTextFunc("noAggregation", "None"), action: () => { valueColsSvc.removeColumns([columnToUse], "contextMenu"); valueColsSvc.setColumnAggFunc(columnToUse, undefined, "contextMenu"); }, checked: !columnIsAlreadyAggValue }); for (const funcName of funcNames) { result.push({ name: localeTextFunc(funcName, aggFuncSvc.getDefaultFuncLabel(funcName)), action: () => { valueColsSvc.setColumnAggFunc(columnToUse, funcName, "contextMenu"); valueColsSvc.addColumns([columnToUse], "contextMenu"); }, checked: columnIsAlreadyAggValue && columnToUse.getAggFunc() === funcName }); } } return result; } var ColumnMenuFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "colMenuFactory"; } createMenu(parent, menuItems, column, sourceElement) { const menuList = parent.createManagedBean(new MenuList(0, { column: column ?? null, node: null, value: null })); const menuItemsMapped = this.beans.menuItemMapper.mapWithStockItems(menuItems, column ?? null, null, sourceElement, "columnMenu"); menuList.addMenuItems(menuItemsMapped); return menuList; } getMenuItems(column = null, columnGroup = null) { const defaultItems = this.getDefaultMenuOptions(column); let result; const columnMainMenuItems = (column?.getColDef() ?? columnGroup?.getColGroupDef())?.mainMenuItems; if (Array.isArray(columnMainMenuItems)) { result = columnMainMenuItems; } else if (typeof columnMainMenuItems === "function") { result = columnMainMenuItems(_addGridCommonParams(this.gos, { column, columnGroup, defaultItems })); } else { const userFunc = this.gos.getCallback("getMainMenuItems"); if (userFunc) { result = userFunc({ column, columnGroup, defaultItems }); } else { result = defaultItems; } } _removeRepeatsFromArray(result, MENU_ITEM_SEPARATOR); return result; } getDefaultMenuOptions(column) { const result = []; const { beans, gos } = this; const { colChooserFactory, rowGroupColsSvc, colModel, expansionSvc, sortSvc, menuSvc, pinnedCols, aggFuncSvc, colAutosize } = beans; const isLegacyMenuEnabled = _isLegacyMenuEnabled(gos); const addColumnItems = () => { if (!isLegacyMenuEnabled && colChooserFactory) { result.push("columnChooser"); } result.push("resetColumns"); }; if (!column) { addColumnItems(); return result; } const { colDef } = column; const allowPinning = pinnedCols && !colDef.lockPinned; const rowGroupCount = rowGroupColsSvc?.columns.length ?? 0; const doingGrouping = rowGroupCount > 0; const grandTotalRow = _getGrandTotalRow(gos); const treeData = gos.get("treeData"); const isPrimary = column.isPrimary(); const allowValueAgg = !isPrimary || aggFuncSvc && column.isAllowValue() && (doingGrouping || grandTotalRow || treeData); if (sortSvc && !isLegacyMenuEnabled && column.isSortable()) { const { isDefaultSortAllowed, isAbsoluteSortAllowed, isAbsoluteSort, isDefaultSort, isAscending, isDescending, direction } = _getDisplaySortForColumn(column, beans); if (isDefaultSortAllowed && !(isAscending && isDefaultSort)) { result.push("sortAscending"); } if (isDefaultSortAllowed && !(isDescending && isDefaultSort)) { result.push("sortDescending"); } if (isAbsoluteSortAllowed && !(isAscending && isAbsoluteSort)) { result.push("sortAbsoluteAscending"); } if (isAbsoluteSortAllowed && !(isDescending && isAbsoluteSort)) { result.push("sortAbsoluteDescending"); } if (direction) { result.push("sortUnSort"); } result.push(MENU_ITEM_SEPARATOR); } if (menuSvc?.isFilterMenuItemEnabled(column)) { result.push("columnFilter"); result.push(MENU_ITEM_SEPARATOR); } if (allowPinning) { result.push("pinSubMenu"); } if (allowValueAgg) { result.push("valueAggSubMenu"); } if (allowPinning || allowValueAgg) { result.push(MENU_ITEM_SEPARATOR); } if (colAutosize) { if (!colDef.suppressAutoSize) { result.push("autoSizeThis"); } result.push("autoSizeAll"); result.push(MENU_ITEM_SEPARATOR); } if (rowGroupColsSvc && gos.isModuleRegistered("SharedRowGrouping")) { const numItems = result.length; const showRowGroup = colDef.showRowGroup; if (showRowGroup) { result.push("rowUnGroup"); } else if (column.isAllowRowGroup() && isPrimary) { if (column.isRowGroupActive()) { const groupLocked = isRowGroupColLocked(column, beans); if (!groupLocked) { result.push("rowUnGroup"); } } else { result.push("rowGroup"); } } if (result.length > numItems) { result.push(MENU_ITEM_SEPARATOR); } } addColumnItems(); if (expansionSvc && (_isClientSideRowModel(gos) || gos.get("ssrmExpandAllAffectsAllRows")) && (treeData || rowGroupCount > (colModel.isPivotMode() ? 1 : 0))) { result.push("expandAll"); result.push("contractAll"); } return result; } }; var CSS_CONTEXT_MENU_OPEN = "ag-context-menu-open"; var ContextMenuService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "contextMenuSvc"; this.focusedCell = null; } postConstruct() { this.menu = this.createManagedBean(new AgContextMenuService({ menuItemCallbacks: MENU_ITEM_CALLBACKS, getMenuItems: this.getMenuItems.bind(this), mapMenuItems: this.mapWithStockItems.bind(this), beforeMenuOpen: this.beforeMenuOpen.bind(this), onMenuOpen: this.onMenuOpen.bind(this), onMenuClose: this.onMenuClose.bind(this), afterMenuDestroyed: this.afterMenuDestroyed.bind(this), onVisibleChanged: this.dispatchVisibleChangedEvent.bind(this), shouldBlockMenuOpen: () => !!this.beans.overlays?.exclusive })); } hideActiveMenu() { this.menu.hideActiveMenu(); } getMenuItems(menuActionParams, mouseEvent) { const { column, node, value } = menuActionParams; const defaultMenuOptions = []; const { clipboardSvc, chartSvc, csvCreator, excelCreator, colModel, rangeSvc, gos } = this.beans; if (_exists(node) && clipboardSvc) { if (column) { if (!gos.get("suppressCutToClipboard")) { defaultMenuOptions.push("cut"); } defaultMenuOptions.push("copy", "copyWithHeaders", "copyWithGroupHeaders", "paste", "separator"); } } if (gos.get("enableCharts") && chartSvc) { if (colModel.isPivotMode()) { defaultMenuOptions.push("pivotChart"); } if (rangeSvc && !rangeSvc.isEmpty()) { defaultMenuOptions.push("chartRange"); } } if (_exists(node)) { const enableRowPinning = gos.get("enableRowPinning"); const isRowPinnable = gos.get("isRowPinnable"); if (enableRowPinning) { const isGroupTotalRow = node.level > -1 && node.footer; const isGrandTotalRow = node.level === -1 && node.footer; const grandTotalRow = _getGrandTotalRow(gos); const isGrandTotalRowFixed = grandTotalRow === "pinnedBottom" || grandTotalRow === "pinnedTop"; if (isGrandTotalRow && !isGrandTotalRowFixed || !isGrandTotalRow && !isGroupTotalRow) { const pinnable = isRowPinnable?.(node) ?? true; if (pinnable) { defaultMenuOptions.push("pinRowSubMenu"); } } } const suppressExcel = gos.get("suppressExcelExport") || !excelCreator; const suppressCsv = gos.get("suppressCsvExport") || !csvCreator; const onIPad = _isIOSUserAgent(); const anyExport = !onIPad && (!suppressExcel || !suppressCsv); if (anyExport) { defaultMenuOptions.push("export"); } } const defaultItems = defaultMenuOptions.length ? defaultMenuOptions : undefined; const columnContextMenuItems = column?.getColDef().contextMenuItems; if (Array.isArray(columnContextMenuItems)) { return columnContextMenuItems; } if (typeof columnContextMenuItems === "function") { return columnContextMenuItems(_addGridCommonParams(gos, { column, node, value, defaultItems, event: mouseEvent })); } const userFunc = gos.getCallback("getContextMenuItems"); return userFunc?.({ column, node, value, defaultItems, event: mouseEvent }) ?? defaultMenuOptions; } getContextMenuPosition(rowNode, column) { const rowCtrl = this.getRowCtrl(rowNode); const eGui = this.getCellGui(rowCtrl, column); if (!eGui) { return { x: 0, y: rowCtrl?.getRowYPosition() ?? 0 }; } const rect = eGui.getBoundingClientRect(); return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 }; } showContextMenu(params) { const rowNode = params.rowNode ?? null; const column = params.column ?? null; let { anchorToElement, value, source } = params; if (rowNode && column && value == null) { value = this.beans.valueSvc.getValueForDisplay({ column, node: rowNode, from: "edit" }).value; } if (anchorToElement == null) { anchorToElement = this.getContextMenuAnchorElement(rowNode, column); } this.beans.menuUtils.onContextMenu({ mouseEvent: params.mouseEvent ?? null, touchEvent: params.touchEvent ?? null, showMenuCallback: (eventOrTouch) => this.menu.showMenu({ node: rowNode, column, value }, eventOrTouch, anchorToElement), source }); } handleContextMenuMouseEvent(mouseEvent, touchEvent, rowCtrl, cellCtrl) { const rowNode = cellCtrl?.rowNode ?? rowCtrl?.rowNode ?? null; const column = cellCtrl?.column ?? rowCtrl?.findFullWidthInfoForEvent(mouseEvent || touchEvent)?.column ?? null; const { valueSvc, ctrlsSvc } = this.beans; const value = column ? valueSvc.getValue(column, rowNode, "edit") : null; const gridBodyCon = ctrlsSvc.getGridBodyCtrl(); const anchorToElement = cellCtrl ? cellCtrl.eGui : gridBodyCon.eGridBody; this.showContextMenu({ mouseEvent, touchEvent, rowNode, column, value, anchorToElement, source: "ui" }); } beforeMenuOpen(menuActionParams) { if (!menuActionParams.column) { this.beans.focusSvc.clearFocusedCell(); } } onMenuOpen() { const { ctrlsSvc, focusSvc } = this.beans; ctrlsSvc.getGridBodyCtrl().eGridBody.classList.add(CSS_CONTEXT_MENU_OPEN); this.focusedCell = focusSvc.getFocusedCell(); } onMenuClose() { this.beans.ctrlsSvc.getGridBodyCtrl().eGridBody.classList.remove(CSS_CONTEXT_MENU_OPEN); } afterMenuDestroyed() { const { beans, focusedCell } = this; _attemptToRestoreCellFocus(beans, focusedCell); } dispatchVisibleChangedEvent(visible, source) { this.eventSvc.dispatchEvent({ type: "contextMenuVisibleChanged", visible, source }); } getRowCtrl(rowNode) { const { rowIndex, rowPinned } = rowNode || {}; if (rowIndex == null) { return; } return this.beans.rowRenderer.getRowByPosition({ rowIndex, rowPinned }) || undefined; } getCellGui(rowCtrl, column) { if (!rowCtrl || !column) { return; } const cellCtrl = rowCtrl.getCellCtrl(column); return cellCtrl?.eGui || undefined; } getContextMenuAnchorElement(rowNode, column) { const gridBodyEl = this.beans.ctrlsSvc.getGridBodyCtrl().eGridBody; const rowCtrl = this.getRowCtrl(rowNode); if (!rowCtrl) { return gridBodyEl; } const cellGui = this.getCellGui(rowCtrl, column); if (cellGui) { return cellGui; } if (rowCtrl.isFullWidth()) { return rowCtrl.getFullWidthElement(); } return gridBodyEl; } mapWithStockItems(menuItems, menuActionParams, getGui) { const { column, node } = menuActionParams; return this.beans.menuItemMapper.mapWithStockItems(menuItems, column, node, getGui, "contextMenu"); } }; var TAB_FILTER = "filterMenuTab"; var TAB_GENERAL = "generalMenuTab"; var TAB_COLUMNS = "columnsMenuTab"; var TABS_DEFAULT = [TAB_GENERAL, TAB_FILTER, TAB_COLUMNS]; var EnterpriseMenuFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "enterpriseMenuFactory"; } hideActiveMenu() { this.destroyBean(this.activeMenu); } showMenuAfterMouseEvent(columnOrGroup, mouseEvent, containerType, onClosedCallback, filtersOnly) { const { column, columnGroup } = this.splitColumnOrGroup(columnOrGroup); const defaultTab = filtersOnly ? "filterMenuTab" : undefined; this.showMenu(column, columnGroup, (menu) => { const ePopup = menu.getGui(); this.beans.popupSvc.positionPopupUnderMouseEvent({ type: containerType, additionalParams: { column }, mouseEvent, ePopup }); if (defaultTab) { menu.showTab?.(defaultTab); } this.dispatchVisibleChangedEvent(true, false, column, columnGroup, defaultTab); }, containerType, defaultTab, undefined, mouseEvent.target, onClosedCallback); } splitColumnOrGroup(columnOrGroup) { const colIsColumn = columnOrGroup && isColumn(columnOrGroup); const column = colIsColumn ? columnOrGroup : undefined; const columnGroup = colIsColumn ? undefined : columnOrGroup; return { column, columnGroup }; } showMenuAfterButtonClick(columnOrGroup, eventSource, containerType, onClosedCallback, filtersOnly) { let multiplier = -1; let alignSide = "left"; if (this.gos.get("enableRtl")) { multiplier = 1; alignSide = "right"; } const defaultTab = filtersOnly ? "filterMenuTab" : undefined; const restrictToTabs = defaultTab ? [defaultTab] : undefined; const isLegacyMenuEnabled = _isLegacyMenuEnabled(this.gos); const nudgeX = (isLegacyMenuEnabled ? 9 : 4) * multiplier; const nudgeY = isLegacyMenuEnabled ? -23 : 4; const { column, columnGroup } = this.splitColumnOrGroup(columnOrGroup); this.showMenu(column, columnGroup, (menu) => { const ePopup = menu.getGui(); this.beans.popupSvc.positionPopupByComponent({ type: containerType, additionalParams: { column }, eventSource, ePopup, alignSide, nudgeX, nudgeY, position: "under", keepWithinBounds: true }); if (defaultTab) { menu.showTab?.(defaultTab); } this.dispatchVisibleChangedEvent(true, false, column, columnGroup, defaultTab); }, containerType, defaultTab, restrictToTabs, eventSource, onClosedCallback); } showMenu(column, columnGroup, positionCallback, containerType, defaultTab, restrictToTabs, eventSource, onClosedCallback) { const menuParams = this.getMenuParams(column, columnGroup, restrictToTabs, eventSource); if (!menuParams) { return; } const { menu, eMenuGui, anchorToElement, restoreFocusParams } = menuParams; const closedFuncs = []; const { menuUtils, popupSvc } = this.beans; closedFuncs.push((e) => { const eComp = menu.getGui(); this.destroyBean(menu); if (column) { _setColMenuVisible(column, false, "contextMenu"); menuUtils.restoreFocusOnClose(restoreFocusParams, eComp, e); } onClosedCallback?.(); }); const translate = this.getLocaleTextFunc(); popupSvc.addPopup({ modal: true, eChild: eMenuGui, closeOnEsc: true, closedCallback: (e) => { for (const f of closedFuncs) { f(e); } this.dispatchVisibleChangedEvent(false, false, column, columnGroup, defaultTab); }, afterGuiAttached: (params) => menu.afterGuiAttached(Object.assign({}, { container: containerType }, params)), positionCallback: defaultTab ? () => positionCallback(menu) : undefined, ariaLabel: translate("ariaLabelColumnMenu", "Column Menu") }); if (!defaultTab) { menu.showTabBasedOnPreviousSelection?.(); positionCallback(menu); } if (_isColumnMenuAnchoringEnabled(this.gos)) { const stopAnchoringPromise = popupSvc.setPopupPositionRelatedToElement(eMenuGui, anchorToElement); if (stopAnchoringPromise && column) { this.addStopAnchoring(stopAnchoringPromise, column, closedFuncs); } } menu.addEventListener("tabSelected", (event) => { this.dispatchVisibleChangedEvent(false, true, column); this.lastSelectedTab = event.key; this.dispatchVisibleChangedEvent(true, true, column); }); if (column) { _setColMenuVisible(column, true, "contextMenu"); } this.activeMenu = menu; menu.addEventListener("destroyed", () => { if (this.activeMenu === menu) { this.activeMenu = null; } }); } addStopAnchoring(stopAnchoringPromise, column, closedFuncsArr) { stopAnchoringPromise.then((stopAnchoringFunc) => { column.__addEventListener("leftChanged", stopAnchoringFunc); column.__addEventListener("visibleChanged", stopAnchoringFunc); closedFuncsArr.push(() => { column.__removeEventListener("leftChanged", stopAnchoringFunc); column.__removeEventListener("visibleChanged", stopAnchoringFunc); }); }); } getMenuParams(column, columnGroup, restrictToTabs, eventSource) { const { focusSvc, visibleCols, ctrlsSvc } = this.beans; const restoreFocusParams = { column, headerPosition: focusSvc.focusedHeader, columnIndex: visibleCols.allCols.indexOf(column), eventSource }; const menu = this.createMenu(column, columnGroup, restoreFocusParams, restrictToTabs, eventSource); return menu ? { menu, eMenuGui: menu.getGui(), anchorToElement: eventSource || ctrlsSvc.getGridBodyCtrl().eGridBody, restoreFocusParams } : undefined; } createMenu(column, columnGroup, restoreFocusParams, restrictToTabs, eventSource) { if (_isLegacyMenuEnabled(this.gos)) { return this.createBean(new TabbedColumnMenu(column, restoreFocusParams, this.lastSelectedTab, restrictToTabs, eventSource)); } else { const menuItems = this.beans.colMenuFactory.getMenuItems(column, columnGroup); return menuItems.length ? this.createBean(new ColumnContextMenu(menuItems, column, restoreFocusParams, eventSource)) : undefined; } } dispatchVisibleChangedEvent(visible, switchingTab, column, columnGroup, defaultTab) { this.eventSvc.dispatchEvent({ type: "columnMenuVisibleChanged", visible, switchingTab, key: this.lastSelectedTab ?? defaultTab ?? (_isLegacyMenuEnabled(this.gos) ? TAB_GENERAL : "columnMenu"), column: column ?? null, columnGroup: columnGroup ?? null }); } isMenuEnabled(column) { if (!_isLegacyMenuEnabled(this.gos)) { return true; } const isFilterDisabled = !this.beans.filterManager?.isFilterAllowed(column); const tabs = column.getColDef().menuTabs ?? TABS_DEFAULT; const numActiveTabs = isFilterDisabled && tabs.includes(TAB_FILTER) ? tabs.length - 1 : tabs.length; return numActiveTabs > 0; } showMenuAfterContextMenuEvent(column, mouseEvent, touchEvent) { this.beans.menuUtils.onContextMenu({ mouseEvent, touchEvent, source: "ui", showMenuCallback: (eventOrTouch) => { this.showMenuAfterMouseEvent(column, eventOrTouch, "columnMenu"); return true; } }); } }; var TabbedColumnMenu = class extends BeanStub { constructor(column, restoreFocusParams, initialSelection, restrictTo, sourceElement) { super(); this.column = column; this.restoreFocusParams = restoreFocusParams; this.initialSelection = initialSelection; this.restrictTo = restrictTo; this.sourceElement = sourceElement; this.tabFactories = {}; this.includeChecks = {}; const { tabFactories, includeChecks } = this; tabFactories[TAB_GENERAL] = this.createMainPanel.bind(this); tabFactories[TAB_FILTER] = this.createFilterPanel.bind(this); tabFactories[TAB_COLUMNS] = this.createColumnsPanel.bind(this); includeChecks[TAB_GENERAL] = () => true; includeChecks[TAB_FILTER] = () => column ? !!this.beans.filterManager?.isFilterAllowed(column) : false; includeChecks[TAB_COLUMNS] = () => true; } postConstruct() { const tabs = this.getTabsToCreate().map((name) => this.createTab(name)); const tabbedLayout = new AgTabbedLayout({ items: tabs, cssClass: "ag-menu", onActiveItemClicked: this.onHidePopup.bind(this), onItemClicked: this.onTabItemClicked.bind(this) }); this.tabbedLayout = this.createBean(tabbedLayout); this.mainMenuList?.setParentComponent(tabbedLayout); this.addDestroyFunc(() => this.destroyBean(tabbedLayout)); } getTabsToCreate() { if (this.restrictTo) { return this.restrictTo; } return (this.column?.getColDef().menuTabs ?? TABS_DEFAULT).filter((tabName) => this.isValidMenuTabItem(tabName) && this.isNotSuppressed(tabName)); } isValidMenuTabItem(menuTabName) { let isValid = true; let itemsToConsider = TABS_DEFAULT; if (this.restrictTo != null) { isValid = this.restrictTo.indexOf(menuTabName) > -1; itemsToConsider = this.restrictTo; } isValid = isValid && TABS_DEFAULT.indexOf(menuTabName) > -1; if (!isValid) { _warn(175, { menuTabName, itemsToConsider }); } return isValid; } isNotSuppressed(menuTabName) { return this.includeChecks[menuTabName](); } createTab(name) { return this.tabFactories[name](); } showTabBasedOnPreviousSelection() { this.showTab(this.initialSelection); } showTab(toShow) { const { tabItemColumns, tabbedLayout, tabItemFilter, tabItemGeneral } = this; if (tabItemColumns && toShow === TAB_COLUMNS) { tabbedLayout.showItem(tabItemColumns); } else if (tabItemFilter && toShow === TAB_FILTER) { tabbedLayout.showItem(tabItemFilter); } else if (tabItemGeneral && toShow === TAB_GENERAL) { tabbedLayout.showItem(tabItemGeneral); } else { tabbedLayout.showFirstItem(); } } onTabItemClicked(event) { let key = null; switch (event.item) { case this.tabItemColumns: key = TAB_COLUMNS; break; case this.tabItemFilter: key = TAB_FILTER; break; case this.tabItemGeneral: key = TAB_GENERAL; break; } if (key) { this.activateTab(key); } } activateTab(tab) { const ev = { type: "tabSelected", key: tab }; this.dispatchLocalEvent(ev); } createMainPanel() { const { beans, column } = this; const colMenuFactory = beans.colMenuFactory; const mainMenuList = colMenuFactory.createMenu(this, colMenuFactory.getMenuItems(column), this.column, () => this.sourceElement ?? this.getGui()); this.mainMenuList = mainMenuList; mainMenuList.addEventListener("closeMenu", this.onHidePopup.bind(this)); const tabItemGeneral = { title: _createIconNoSpan("legacyMenu", beans, column), titleLabel: TAB_GENERAL.replace("MenuTab", ""), bodyPromise: AgPromise.resolve(mainMenuList.getGui()), name: TAB_GENERAL }; this.tabItemGeneral = tabItemGeneral; return tabItemGeneral; } onHidePopup(event) { this.beans.menuUtils.closePopupAndRestoreFocusOnSelect(this.hidePopupFunc, this.restoreFocusParams, event); } createFilterPanel() { const comp = this.column ? this.createBean(new FilterComp(this.column, "COLUMN_MENU")) : null; this.filterComp = comp; if (!comp?.hasFilter()) { _error(119); } const afterAttachedCallback = (params) => comp?.afterGuiAttached(params); const afterDetachedCallback = () => comp?.afterGuiDetached(); this.tabItemFilter = { title: _createIconNoSpan("filterTab", this.beans, this.column), titleLabel: TAB_FILTER.replace("MenuTab", ""), bodyPromise: AgPromise.resolve(comp?.getGui()), afterAttachedCallback, afterDetachedCallback, name: TAB_FILTER }; return this.tabItemFilter; } createColumnsPanel() { const eWrapperDiv = _createElement({ tag: "div", cls: "ag-menu-column-select-wrapper" }); const { beans, column } = this; const columnSelectPanel = beans.colChooserFactory.createColumnSelectPanel(this, column); const columnSelectPanelGui = columnSelectPanel.getGui(); columnSelectPanelGui.classList.add("ag-menu-column-select"); eWrapperDiv.appendChild(columnSelectPanelGui); const tabItemColumns = { title: _createIconNoSpan("columns", beans, column), titleLabel: TAB_COLUMNS.replace("MenuTab", ""), bodyPromise: AgPromise.resolve(eWrapperDiv), name: TAB_COLUMNS }; this.tabItemColumns = tabItemColumns; return tabItemColumns; } afterGuiAttached(params) { const { container, hidePopup } = params; this.tabbedLayout.setAfterAttachedParams({ container, hidePopup }); if (hidePopup) { this.hidePopupFunc = hidePopup; this.addDestroyFunc(hidePopup); } } getGui() { return this.tabbedLayout.getGui(); } destroy() { super.destroy(); this.destroyBean(this.filterComp); } }; var ColumnContextMenu = class extends Component { constructor(menuItems, column, restoreFocusParams, sourceElement) { super({ tag: "div", ref: "eColumnMenu", cls: "ag-menu ag-column-menu", role: "presentation" }); this.menuItems = menuItems; this.column = column; this.restoreFocusParams = restoreFocusParams; this.sourceElement = sourceElement; this.eColumnMenu = RefPlaceholder; } postConstruct() { const mainMenuList = this.beans.colMenuFactory.createMenu(this, this.menuItems, this.column, () => this.sourceElement ?? this.getGui()); this.mainMenuList = mainMenuList; mainMenuList.addEventListener("closeMenu", this.onHidePopup.bind(this)); this.eColumnMenu.appendChild(mainMenuList.getGui()); } onHidePopup(event) { this.beans.menuUtils.closePopupAndRestoreFocusOnSelect(this.hidePopupFunc, this.restoreFocusParams, event); } afterGuiAttached({ hidePopup }) { if (hidePopup) { this.hidePopupFunc = hidePopup; this.addDestroyFunc(hidePopup); } _focusInto(this.mainMenuList.getGui()); } }; function showContextMenu(beans, params) { const { contextMenuSvc } = beans; if (!contextMenuSvc) { return; } const { rowNode, column, value, x, y } = params || {}; let { x: clientX, y: clientY } = contextMenuSvc.getContextMenuPosition(rowNode, column); if (x != null) { clientX = x; } if (y != null) { clientY = y; } contextMenuSvc.showContextMenu({ mouseEvent: new MouseEvent("mousedown", { clientX, clientY }), rowNode, column, value, source: "api" }); } function showColumnChooser(beans, params) { beans.colChooserFactory?.showColumnChooser({ chooserParams: params }); } function hideColumnChooser(beans) { beans.colChooserFactory?.hideActiveColumnChooser(); } var MenuUtils = class extends BeanStub { constructor() { super(...arguments); this.beanName = "menuUtils"; } restoreFocusOnClose(restoreFocusParams, eComp, e, restoreIfMouseEvent) { const { eventSource } = restoreFocusParams; const isKeyboardEvent = e instanceof KeyboardEvent; if (!restoreIfMouseEvent && !isKeyboardEvent || !eventSource) { return; } const activeEl = _getActiveDomElement(this.beans); if (!eComp.contains(activeEl) && !_isNothingFocused(this.beans)) { return; } this.focusHeaderCell(restoreFocusParams); } closePopupAndRestoreFocusOnSelect(hidePopupFunc, restoreFocusParams, event) { let keyboardEvent; if (event?.keyboardEvent) { keyboardEvent = event.keyboardEvent; } hidePopupFunc(keyboardEvent && { keyboardEvent }); const beans = this.beans; const focusSvc = beans.focusSvc; const focusedCell = focusSvc.getFocusedCell(); if (_isNothingFocused(beans)) { if (focusedCell) { const { rowIndex, rowPinned, column } = focusedCell; focusSvc.setFocusedCell({ rowIndex, column, rowPinned, forceBrowserFocus: true, preventScrollOnBrowserFocus: true }); } else { this.focusHeaderCell(restoreFocusParams); } } } onContextMenu(params) { const { mouseEvent, touchEvent, showMenuCallback, source } = params; if (!this.gos.get("allowContextMenuWithControlKey")) { if (mouseEvent && (mouseEvent.ctrlKey || mouseEvent.metaKey)) { return; } } if (mouseEvent) { this.blockMiddleClickScrollsIfNeeded(mouseEvent); } if (source === "ui" && this.gos.get("suppressContextMenu")) { return; } const eventOrTouch = mouseEvent ?? touchEvent.touches[0]; if (showMenuCallback(eventOrTouch)) { const event = mouseEvent ?? touchEvent; if (event?.cancelable) { event.preventDefault(); } } } async focusHeaderCell(restoreFocusParams) { const { column, columnIndex, headerPosition, eventSource } = restoreFocusParams; const { visibleCols, headerNavigation, focusSvc } = this.beans; const isColumnStillVisible = await visibleCols.allCols.some((col) => col === column); if (!this.isAlive()) { return; } if (column?.isAlive() && isColumnStillVisible && eventSource && _isVisible(eventSource)) { const focusableEl = _findTabbableParent(eventSource); if (focusableEl) { headerNavigation?.scrollToColumn(column); focusableEl.focus(); } } else if (headerPosition && columnIndex !== -1) { const allColumns = visibleCols.allCols; const columnToFocus = allColumns[columnIndex] || _last(allColumns); if (columnToFocus) { focusSvc.focusHeaderPosition({ headerPosition: { headerRowIndex: headerPosition.headerRowIndex, column: columnToFocus } }); } } } blockMiddleClickScrollsIfNeeded(mouseEvent) { if (this.gos.get("suppressMiddleClickScrolls") && mouseEvent.which === 2) { mouseEvent.preventDefault(); } } }; var MenuCoreModule = { moduleName: "MenuCore", version: VERSION2, beans: [MenuItemMapper, ChartMenuItemMapper, MenuUtils], icons: { chart: "chart", columns: "columns", loadingMenuItems: "loading", menuPin: "pin", menuValue: "aggregation", menuAddRowGroup: "group", menuRemoveRowGroup: "group", clipboardCopy: "copy", clipboardCut: "cut", clipboardPaste: "paste", save: "save", csvExport: "csv", excelExport: "excel", sortAscending: "asc", sortDescending: "desc", sortAbsoluteAscending: "aasc", sortAbsoluteDescending: "adesc", sortUnSort: "none" }, dependsOn: [EnterpriseCoreModule, PopupModule, SharedMenuModule, MenuItemModule] }; var ColumnMenuModule = { moduleName: "ColumnMenu", version: VERSION2, beans: [EnterpriseMenuFactory, ColumnMenuFactory, ColumnChooserFactory], icons: { ensureColumnVisible: "column-arrow", legacyMenu: "menu", filterTab: "filter", columnSelectClosed: "tree-closed", columnSelectOpen: "tree-open", columnSelectIndeterminate: "tree-indeterminate" }, apiFunctions: { showColumnChooser, hideColumnChooser }, dependsOn: [MenuCoreModule, SharedDragAndDropModule, ColumnMoveModule] }; var ContextMenuModule = { moduleName: "ContextMenu", version: VERSION2, beans: [ContextMenuService], apiFunctions: { showContextMenu }, dependsOn: [MenuCoreModule] }; var SET_FILTER_SELECT_ALL = "__AG_SELECT_ALL__"; var SET_FILTER_ADD_SELECTION_TO_FILTER = "__AG_ADD_SELECTION_TO_FILTER__"; var FlatSetDisplayValueModel = class { constructor(valueSvc, getValueFormatter, formatter, column) { this.valueSvc = valueSvc; this.getValueFormatter = getValueFormatter; this.formatter = formatter; this.column = column; this.displayedKeys = []; } updateDisplayedValuesToAllAvailable(_getValue, _allKeys, availableKeys) { this.displayedKeys = Array.from(availableKeys); } updateDisplayedValuesToMatchMiniFilter(getValue, _allKeys, availableKeys, matchesFilter, nullMatchesFilter) { this.displayedKeys = []; const valueFormatter = this.getValueFormatter(); for (const key of availableKeys) { if (key == null) { if (nullMatchesFilter) { this.displayedKeys.push(key); } } else { const value = getValue(key); const valueFormatterValue = this.valueSvc.formatValue(this.column, null, value, valueFormatter, false); const textFormatterValue = this.formatter(valueFormatterValue); if (matchesFilter(textFormatterValue)) { this.displayedKeys.push(key); } } } } getDisplayedValueCount() { return this.displayedKeys.length; } getDisplayedItem(index) { return this.displayedKeys[index]; } getSelectAllItem() { return SET_FILTER_SELECT_ALL; } getAddSelectionToFilterItem() { return SET_FILTER_ADD_SELECTION_TO_FILTER; } getDisplayedKeys() { return this.displayedKeys; } forEachDisplayedKey(func) { this.displayedKeys.forEach(func); } someDisplayedKey(func) { return this.displayedKeys.some(func); } hasGroups() { return false; } refresh() {} }; var SetFilterGroupElement = { tag: "div", cls: "ag-set-filter-item", attrs: { "aria-hidden": "true" }, children: [ { tag: "span", cls: "ag-set-filter-group-icons", children: [ { tag: "span", ref: "eGroupClosedIcon", cls: "ag-set-filter-group-closed-icon" }, { tag: "span", ref: "eGroupOpenedIcon", cls: "ag-set-filter-group-opened-icon" }, { tag: "span", ref: "eGroupIndeterminateIcon", cls: "ag-set-filter-group-indeterminate-icon" } ] }, { tag: "ag-checkbox", ref: "eCheckbox", cls: "ag-set-filter-item-checkbox" } ] }; var SetFilterElement = { tag: "div", cls: "ag-set-filter-item", children: [{ tag: "ag-checkbox", ref: "eCheckbox", cls: "ag-set-filter-item-checkbox" }] }; var SetFilterListItem = class extends Component { constructor(params) { super(params.isGroup ? SetFilterGroupElement : SetFilterElement, [AgCheckboxSelector]); this.eCheckbox = RefPlaceholder; this.eGroupOpenedIcon = RefPlaceholder; this.eGroupClosedIcon = RefPlaceholder; this.eGroupIndeterminateIcon = RefPlaceholder; this.formattedValue = null; this.focusWrapper = params.focusWrapper; this.value = params.value; this.params = params.params; this.translate = params.translate; this.valueFormatter = params.valueFormatter; this.item = params.item; this.isSelected = params.isSelected; this.isTree = params.isTree; this.depth = params.depth ?? 0; this.isGroup = params.isGroup; this.groupsExist = params.groupsExist; this.isExpanded = params.isExpanded; this.hasIndeterminateExpandState = params.hasIndeterminateExpandState; } postConstruct() { this.tooltipFeature = this.createOptionalManagedBean(this.beans.registry.createDynamicBean("tooltipFeature", false, { getGui: () => this.focusWrapper, getLocation: () => "setFilterValue", shouldDisplayTooltip: () => this.shouldDisplayTooltip?.() ?? true, getAdditionalParams: () => { const { colDef, column } = this.params; const additionalParams = { colDef, column, valueFormatted: this.formattedValue ?? undefined }; if (this.isTree) { additionalParams.level = this.depth; } return additionalParams; } })); this.addDestroyFunc(() => this.destroyCellRendererComponent?.()); this.render(); this.eCheckbox.setLabelEllipsis(true).setValue(this.isSelected, true).setDisabled(!!this.params.readOnly).getInputElement().setAttribute("tabindex", "-1"); this.refreshVariableAriaLabels(); if (this.isTree) { if (this.depth > 0) { this.addCss("ag-set-filter-indent-" + this.depth); this.getGui().style.setProperty("--ag-indentation-level", String(this.depth)); } if (this.isGroup) { this.setupExpansion(); } else if (this.groupsExist) { this.addCss("ag-set-filter-add-group-indent"); } _setAriaLevel(this.getAriaElement(), this.depth + 1); } this.refreshAriaChecked(); if (this.params.readOnly) { return; } this.eCheckbox.onValueChange((value) => this.onCheckboxChanged(!!value)); } getFocusableElement() { return this.focusWrapper; } setupExpansion() { const { eGroupClosedIcon, eGroupOpenedIcon, eGroupIndeterminateIcon, hasIndeterminateExpandState, beans } = this; eGroupClosedIcon.appendChild(_createIcon("setFilterGroupClosed", beans, null)); eGroupOpenedIcon.appendChild(_createIcon("setFilterGroupOpen", beans, null)); const listener = this.onExpandOrContractClicked.bind(this); this.addManagedElementListeners(eGroupClosedIcon, { click: listener }); this.addManagedElementListeners(eGroupOpenedIcon, { click: listener }); if (hasIndeterminateExpandState) { eGroupIndeterminateIcon.appendChild(_createIcon("setFilterGroupIndeterminate", beans, null)); this.addManagedElementListeners(eGroupIndeterminateIcon, { click: listener }); } this.setExpandedIcons(); this.refreshAriaExpanded(); } onExpandOrContractClicked() { this.setExpanded(!this.isExpanded); } setExpanded(isExpanded, silent) { if (this.isGroup && isExpanded !== this.isExpanded) { this.isExpanded = isExpanded; const event = { type: "expandedChanged", isExpanded: !!isExpanded, item: this.item }; if (!silent) { this.dispatchLocalEvent(event); } this.setExpandedIcons(); this.refreshAriaExpanded(); } } setExpandedIcons() { const { isExpanded, hasIndeterminateExpandState, eGroupClosedIcon, eGroupOpenedIcon, eGroupIndeterminateIcon } = this; _setDisplayed(eGroupClosedIcon, hasIndeterminateExpandState ? isExpanded === false : !isExpanded); _setDisplayed(eGroupOpenedIcon, isExpanded === true); if (hasIndeterminateExpandState) { _setDisplayed(eGroupIndeterminateIcon, isExpanded === undefined); } } onCheckboxChanged(isSelected) { this.isSelected = isSelected; const event = { type: "selectionChanged", isSelected, item: this.item }; this.dispatchLocalEvent(event); this.refreshVariableAriaLabels(); this.refreshAriaChecked(); } toggleSelected() { if (this.params.readOnly) { return; } this.setSelected(!this.isSelected); } setSelected(isSelected, silent) { this.isSelected = isSelected; this.eCheckbox.setValue(isSelected, silent); this.refreshAriaChecked(); } refreshVariableAriaLabels() { if (!this.isTree) { return; } const translate = this.getLocaleTextFunc(); const checkboxValue = this.eCheckbox.getValue(); const state = checkboxValue === undefined ? translate("ariaIndeterminate", "indeterminate") : checkboxValue ? translate("ariaVisible", "visible") : translate("ariaHidden", "hidden"); const visibilityLabel = translate("ariaToggleVisibility", "Press SPACE to toggle visibility"); _setAriaLabelledBy(this.eCheckbox.getInputElement(), undefined); this.eCheckbox.setInputAriaLabel(`${visibilityLabel} (${state})`); } setupFixedAriaLabels(value) { if (!this.isTree) { return; } const translate = this.getLocaleTextFunc(); const itemLabel = translate("ariaFilterValue", "Filter Value"); const ariaEl = this.getAriaElement(); _setAriaLabel(ariaEl, `${value} ${itemLabel}`); _setAriaDescribedBy(ariaEl, this.eCheckbox.getInputElement().id); } refreshAriaChecked() { const ariaEl = this.getAriaElement(); _setAriaChecked(ariaEl, this.eCheckbox.getValue()); } refreshAriaExpanded() { _setAriaExpanded(this.getAriaElement(), !!this.isExpanded); } refresh(item, isSelected, isExpanded) { this.item = item; if (isSelected !== this.isSelected) { this.setSelected(isSelected, true); } this.setExpanded(isExpanded, true); const { cellRendererComponent, cellRendererParams, beans, params } = this; if (this.valueFunction) { const value = this.valueFunction(); this.setTooltipAndCellRendererParams(value, value); if (!cellRendererComponent) { this.renderCellWithoutCellRenderer(); } } if (cellRendererComponent) { const compDetails = _getCellRendererDetails(beans.userCompFactory, params, cellRendererParams); const success = cellRendererComponent.refresh?.(compDetails?.params ?? cellRendererParams); if (!success) { const oldComponent = cellRendererComponent; this.renderCell(); this.destroyBean(oldComponent); } } } render() { const { params: { column } } = this; let { value } = this; let formattedValue = null; if (typeof value === "function") { this.valueFunction = value; formattedValue = this.valueFunction(); value = formattedValue; } else if (this.isTree) { formattedValue = _toStringOrNull(value); } else { formattedValue = this.getFormattedValue(column, value); } this.formattedValue = formattedValue; this.setTooltipAndCellRendererParams(value, formattedValue); this.renderCell(); } setTooltipAndCellRendererParams(value, formattedValue) { const gos = this.gos; if (this.params.showTooltips && (!_isShowTooltipWhenTruncated(gos) || !this.params.cellRenderer)) { const newTooltipText = formattedValue != null ? formattedValue : _toStringOrNull(value); this.shouldDisplayTooltip = _getShouldDisplayTooltip(gos, () => this.eCheckbox.getGui().querySelector(".ag-label")); this.tooltipFeature?.setTooltipAndRefresh(newTooltipText); } this.cellRendererParams = _addGridCommonParams(gos, { value, valueFormatted: formattedValue, colDef: this.params.colDef, column: this.params.column, setTooltip: (value2, shouldDisplayTooltip) => { gos.assertModuleRegistered("Tooltip", 3); this.shouldDisplayTooltip = shouldDisplayTooltip; this.tooltipFeature?.setTooltipAndRefresh(value2); } }); } getFormattedValue(column, value) { return this.beans.valueSvc.formatValue(column, null, value, this.valueFormatter, false); } renderCell() { const compDetails = _getCellRendererDetails(this.beans.userCompFactory, this.params, this.cellRendererParams); const cellRendererPromise = compDetails?.newAgStackInstance(); if (cellRendererPromise == null) { this.renderCellWithoutCellRenderer(); return; } cellRendererPromise.then((component) => { if (component) { this.cellRendererComponent = component; this.eCheckbox.setLabel(component.getGui()); this.destroyCellRendererComponent = () => this.destroyBean(component); } }); } renderCellWithoutCellRenderer() { const { valueFormatted, value } = this.cellRendererParams; let valueToRender = (valueFormatted == null ? value : valueFormatted) ?? this.translate("blanks"); if (typeof valueToRender !== "string") { _warn(208); valueToRender = ""; } this.eCheckbox.setLabel(valueToRender); this.setupFixedAriaLabels(valueToRender); } getComponentHolder() { return this.params.column.getColDef(); } }; var DEFAULT_LOCALE_TEXT = { loadingOoo: "Loading...", blanks: "(Blanks)", searchOoo: "Search...", selectAll: "(Select All)", selectAllSearchResults: "(Select All Search Results)", addCurrentSelectionToFilter: "Add current selection to filter", noMatches: "No matches.", ariaSearchFilterValues: "Search filter values", ariaFilterList: "Filter List", filterSummaryListInactive: "is (All)", filterSummaryListSeparator: ", ", filterSummaryListShort: (variableValues) => `is (${variableValues[0]})`, filterSummaryListLong: (variableValues) => `is (${variableValues[0]}) and ${variableValues[1]} more` }; function processDataPath(dataPath, treeData, groupAllowUnbalanced) { let processedDataPath = dataPath; if (!processedDataPath) { return null; } processedDataPath = processedDataPath.map((treeKey) => _toStringOrNull(_makeNull(treeKey))); if (!treeData && groupAllowUnbalanced && processedDataPath.some((treeKey) => treeKey == null)) { if (_last(processedDataPath) == null) { return null; } return processedDataPath.filter((treeKey) => treeKey != null); } return processedDataPath; } function translateForSetFilter(bean, key, variableValues) { return _translate(bean, DEFAULT_LOCALE_TEXT, key, variableValues); } function applyExcelModeOptions(params) { if (params.excelMode === "windows") { if (!params.buttons) { params.buttons = ["apply", "cancel"]; } if (params.closeOnApply == null) { params.closeOnApply = true; } } else if (params.excelMode === "mac") { if (!params.buttons) { params.buttons = ["reset"]; } if (params.applyMiniFilterWhileTyping == null) { params.applyMiniFilterWhileTyping = true; } if (params.debounceMs == null) { params.debounceMs = 500; } } if (params.excelMode && params.defaultToNothingSelected) { params.defaultToNothingSelected = false; _warn(207); } } function createTreeDataOrGroupingComparator() { return ([_aKey, aValue], [_bKey, bValue]) => { if (aValue == null) { return bValue == null ? 0 : -1; } else if (bValue == null) { return 1; } for (let i = 0;i < aValue.length; i++) { if (i >= bValue.length) { return 1; } const diff = _defaultComparator(aValue[i], bValue[i]); if (diff !== 0) { return diff; } } return 0; }; } var TreeSetDisplayValueModel = class { constructor(formatter, treeListPathGetter, treeListFormatter, treeDataOrGrouping) { this.formatter = formatter; this.treeListPathGetter = treeListPathGetter; this.treeListFormatter = treeListFormatter; this.treeDataOrGrouping = treeDataOrGrouping; this.allDisplayedItemsTree = /* @__PURE__ */ new Map; this.activeDisplayedItemsFlat = []; this.selectAllItem = { depth: 0, filterPasses: true, available: true, treeKey: SET_FILTER_SELECT_ALL, children: this.allDisplayedItemsTree, expanded: true, key: SET_FILTER_SELECT_ALL, parentTreeKeys: [] }; this.addSelectionToFilterItem = { depth: 0, filterPasses: true, available: true, treeKey: SET_FILTER_ADD_SELECTION_TO_FILTER, expanded: true, key: SET_FILTER_ADD_SELECTION_TO_FILTER, parentTreeKeys: [] }; } updateParams(treeListPathGetter, treeListFormatter) { this.treeListPathGetter = treeListPathGetter; this.treeListFormatter = treeListFormatter; } updateDisplayedValuesToAllAvailable(getValue, allKeys, availableKeys, source) { if (source === "reload") { this.generateItemTree(getValue, allKeys, availableKeys); } else if (source === "otherFilter") { this.updateAvailable(availableKeys); this.updateExpandAll(); } else if (source === "miniFilter") { this.resetFilter(); this.updateExpandAll(); } this.flattenItems(); } updateDisplayedValuesToMatchMiniFilter(getValue, allKeys, availableKeys, matchesFilter, nullMatchesFilter, source) { if (source === "reload") { this.generateItemTree(getValue, allKeys, availableKeys); } else if (source === "otherFilter") { this.updateAvailable(availableKeys); } this.updateFilter(matchesFilter, nullMatchesFilter); this.updateExpandAll(); this.flattenItems(); } generateItemTree(getValue, allKeys, availableKeys) { const allDisplayedItemsTree = /* @__PURE__ */ new Map; this.allDisplayedItemsTree = allDisplayedItemsTree; let groupsExist = false; const treeListPathGetter = this.getTreeListPathGetter(getValue, availableKeys); for (const key of allKeys) { const value = getValue(key); const dataPath = treeListPathGetter(value) ?? [null]; const dataPathLength = dataPath.length; if (dataPathLength > 1) { groupsExist = true; } const available = availableKeys.has(key); let children = allDisplayedItemsTree; let item; let parentTreeKeys = []; for (let depth = 0;depth < dataPathLength; depth++) { const treeKey = dataPath[depth]; if (!children) { children = /* @__PURE__ */ new Map; item.children = children; } const treeKeyUpper = treeKey?.toUpperCase() ?? null; item = children.get(treeKeyUpper); if (!item) { item = { treeKey, depth, filterPasses: true, expanded: false, available, parentTreeKeys }; if (depth === dataPath.length - 1) { item.key = key; } children.set(treeKeyUpper, item); } children = item.children; parentTreeKeys = [...parentTreeKeys, treeKey]; } } this.groupsExist = groupsExist; this.updateAvailable(availableKeys); this.selectAllItem.children = allDisplayedItemsTree; this.selectAllItem.expanded = false; } getTreeListPathGetter(getValue, availableKeys) { if (this.treeListPathGetter) { return this.treeListPathGetter; } if (this.treeDataOrGrouping) { return (value) => value; } let isDate = false; for (const availableKey of availableKeys) { const value = getValue(availableKey); if (value instanceof Date) { isDate = true; break; } else if (value != null) { break; } } if (isDate) { return (value) => _getDateParts(value, false); } _warn(211); return (value) => [String(value)]; } flattenItems() { this.activeDisplayedItemsFlat = []; const recursivelyFlattenDisplayedItems = (items) => { for (const item of items.values()) { if (!item.filterPasses || !item.available) { continue; } this.activeDisplayedItemsFlat.push(item); if (item.children && item.expanded) { recursivelyFlattenDisplayedItems(item.children); } } }; recursivelyFlattenDisplayedItems(this.allDisplayedItemsTree); } resetFilter() { const recursiveFilterReset = (item) => { const children = item.children; if (children) { for (const child of children.values()) { recursiveFilterReset(child); } } item.filterPasses = true; }; for (const item of this.allDisplayedItemsTree.values()) { recursiveFilterReset(item); } } updateFilter(matchesFilter, nullMatchesFilter) { const passesFilter = (item) => { if (!item.available) { return false; } if (item.treeKey == null) { return nullMatchesFilter; } return matchesFilter(this.formatter(this.treeListFormatter ? this.treeListFormatter(item.treeKey, item.depth, item.parentTreeKeys) : item.treeKey)); }; for (const item of this.allDisplayedItemsTree.values()) { this.recursiveItemCheck(item, false, passesFilter, "filterPasses"); } } getDisplayedValueCount() { return this.activeDisplayedItemsFlat.length; } getDisplayedItem(index) { return this.activeDisplayedItemsFlat[index]; } getSelectAllItem() { return this.selectAllItem; } getAddSelectionToFilterItem() { return this.addSelectionToFilterItem; } getDisplayedKeys() { const displayedKeys = []; this.forEachDisplayedKey((key) => displayedKeys.push(key)); return displayedKeys; } forEachDisplayedKey(func) { const recursiveForEachItem = (item, topParentExpanded) => { const children = item.children; if (children) { if (!item.expanded || !topParentExpanded) { for (const child of children.values()) { if (child.filterPasses) { recursiveForEachItem(child, false); } } } } else { func(item.key); } }; for (const item of this.activeDisplayedItemsFlat) { recursiveForEachItem(item, true); } } someDisplayedKey(func) { const recursiveSomeItem = (item, topParentExpanded) => { const children = item.children; if (children) { if (!item.expanded || !topParentExpanded) { for (const child of children.values()) { if (child.filterPasses && recursiveSomeItem(child, false)) { return true; } } return false; } } else { return func(item.key); } return false; }; return this.activeDisplayedItemsFlat.some((item) => recursiveSomeItem(item, true)); } hasGroups() { return this.groupsExist; } refresh() { this.updateExpandAll(); this.flattenItems(); } updateExpandAll() { const recursiveExpansionCheck = (items, someTrue, someFalse) => { for (const item2 of items.values()) { if (!item2.filterPasses || !item2.available || !item2.children) { continue; } someTrue = someTrue || !!item2.expanded; someFalse = someFalse || !item2.expanded; if (someTrue && someFalse) { return; } const childExpanded = recursiveExpansionCheck(item2.children, someTrue, someFalse); if (childExpanded === undefined) { return; } else if (childExpanded) { someTrue = true; } else { someFalse = true; } } return someTrue && someFalse ? undefined : someTrue; }; const item = this.getSelectAllItem(); item.expanded = recursiveExpansionCheck(item.children, false, false); } recursiveItemCheck(item, parentPasses, checkFunction, itemProp) { let atLeastOneChildPassed = false; const children = item.children; if (children) { for (const child of children.values()) { const childPasses = this.recursiveItemCheck(child, parentPasses || checkFunction(item), checkFunction, itemProp); atLeastOneChildPassed = atLeastOneChildPassed || childPasses; } } const itemPasses = parentPasses || atLeastOneChildPassed || checkFunction(item); item[itemProp] = itemPasses; return itemPasses; } updateAvailable(availableKeys) { const isAvailable = (item) => availableKeys.has(item.key); for (const item of this.allDisplayedItemsTree.values()) { this.recursiveItemCheck(item, false, isAvailable, "available"); } } }; var SetFilter = class extends ProvidedFilter { constructor() { super("setFilter", "set-filter"); this.filterType = "set"; this.eMiniFilter = RefPlaceholder; this.eFilterLoading = RefPlaceholder; this.eFilterLoadingIcon = RefPlaceholder; this.eSetFilterList = RefPlaceholder; this.eFilterNoMatches = RefPlaceholder; this.hardRefreshVirtualList = false; this.miniFilterText = null; this.addCurrentSelectionToFilter = false; this.selectedKeys = /* @__PURE__ */ new Set; } setParams(params) { super.setParams(params); const handler = this.updateHandler(params.getHandler()); const { column, textFormatter, treeList, treeListPathGetter, treeListFormatter } = params; this.formatter = textFormatter ?? ((value) => value ?? null); this.displayValueModel = treeList ? new TreeSetDisplayValueModel(this.formatter, treeListPathGetter, treeListFormatter, handler.isTreeDataOrGrouping()) : new FlatSetDisplayValueModel(this.beans.valueSvc, () => this.handler.valueFormatter, this.formatter, column); handler.valueModel.allKeys.then((values) => { if (!this.isAlive()) { return; } this.updateDisplayedValues("reload", values ?? []); this.resetSelectionState(values ?? []); }); if (handler.valueModel.isLoading()) { this.setIsLoading(true); } this.initialiseFilterBodyUi(); } refresh(legacyNewParams) { if (this.params.treeList !== legacyNewParams.treeList) { return false; } this.updateHandler(legacyNewParams.getHandler()); return super.refresh(legacyNewParams); } updateParams(newParams, oldParams) { super.updateParams(newParams, oldParams); this.updateMiniFilter(); if (newParams.suppressSelectAll !== oldParams.suppressSelectAll) { this.createVirtualListModel(newParams); } const { textFormatter, treeListPathGetter, treeListFormatter } = newParams; this.formatter = textFormatter ?? ((value) => value ?? null); if (this.displayValueModel instanceof TreeSetDisplayValueModel) { this.displayValueModel.updateParams(treeListPathGetter, treeListFormatter); } this.handler.refreshFilterValues(true); } updateHandler(handler) { const oldHandler = this.handler; if (oldHandler !== handler) { for (const func of this.handlerDestroyFuncs ?? []) { func(); } this.handlerDestroyFuncs = [ ...this.addManagedListeners(handler, { anyFilterChanged: (event) => { handler.valueModel.allKeys.then((values) => { if (this.isAlive()) { this.updateDisplayedValues("otherFilter", values ?? []); if (event.updated) { this.checkAndRefreshVirtualList(); this.showOrHideResults(); } } }); }, dataChanged: ({ hardRefresh }) => { handler.valueModel.allKeys.then((values) => { if (this.isAlive()) { this.updateDisplayedValues("reload", values ?? []); this.setSelectedModel(this.state.model?.values ?? null); if (hardRefresh) { this.hardRefreshVirtualList = true; } this.checkAndRefreshVirtualList(); } }); } }), ...this.addManagedListeners(handler.valueModel, { loadingStart: () => this.setIsLoading(true), loadingEnd: () => this.setIsLoading(false) }) ]; this.handler = handler; } return handler; } updateUiVisibility() {} createBodyTemplate() { return { tag: "div", cls: "ag-set-filter", children: [ { tag: "div", ref: "eFilterLoading", cls: "ag-filter-loading ag-loading ag-hidden", children: [ { tag: "span", ref: "eFilterLoadingIcon", cls: "ag-loading-icon" }, { tag: "span", cls: "ag-loading-text", children: translateForSetFilter(this, "loadingOoo") } ] }, { tag: "ag-input-text-field", ref: "eMiniFilter", cls: "ag-mini-filter" }, { tag: "div", ref: "eFilterNoMatches", cls: "ag-filter-no-matches ag-hidden", children: translateForSetFilter(this, "noMatches") }, { tag: "div", ref: "eSetFilterList", cls: "ag-set-filter-list", role: "presentation" } ] }; } getAgComponents() { return [AgInputTextFieldSelector]; } handleKeyDown(e) { super.handleKeyDown(e); if (e.defaultPrevented) { return; } const getComponentForKeyEvent = () => { if (!this.eSetFilterList.contains(_getActiveDomElement(this.beans))) { return; } const currentItem = this.virtualList.getLastFocusedRow(); if (currentItem == null) { return; } const component = this.virtualList.getComponentAt(currentItem); if (component == null) { return; } e.preventDefault(); const { readOnly } = this.params; if (readOnly) { return; } return component; }; switch (e.key) { case KeyCode.SPACE: getComponentForKeyEvent()?.toggleSelected(); break; case KeyCode.ENTER: this.handleKeyEnter(e); break; case KeyCode.LEFT: getComponentForKeyEvent()?.setExpanded(false); break; case KeyCode.RIGHT: getComponentForKeyEvent()?.setExpanded(true); break; } } handleKeyEnter(e) { e.preventDefault(); const { excelMode, readOnly } = this.params; if (!excelMode || !!readOnly) { return; } this.params.onAction("apply", undefined, e); if (this.params.excelMode === "mac") { this.eMiniFilter.getInputElement().select(); } } setModelAndRefresh(values) { return this.setSelectedModel(values).then(() => { if (this.isAlive()) { this.checkAndRefreshVirtualList(); } }); } setModelIntoUi(model) { this.setMiniFilter(this.params.state.state?.miniFilterValue ?? null, true); const values = model == null ? null : model.values; return this.setModelAndRefresh(values); } getModelFromUi() { const values = this.getSelectedModel(); if (!values) { return null; } return { values, filterType: this.filterType }; } areNonNullModelsEqual(a, b) { return _areEqual(a.values, b.values); } setIsLoading(isLoading) { _setDisplayed(this.eFilterLoading, isLoading); if (!isLoading) { this.hardRefreshVirtualList = true; } } initialiseFilterBodyUi() { this.initVirtualList(); this.initMiniFilter(); this.initLoading(); } initLoading() { const loadingIcon = _createIconNoSpan("setFilterLoading", this.beans, this.params.column); if (loadingIcon) { this.eFilterLoadingIcon.appendChild(loadingIcon); } } initVirtualList() { const filterListName = translateForSetFilter(this, "ariaFilterList"); const isTree = !!this.params.treeList; const virtualList = this.virtualList = this.createBean(new VirtualList({ cssIdentifier: "filter", ariaRole: isTree ? "tree" : "listbox", listName: filterListName })); const eSetFilterList = this.eSetFilterList; if (isTree) { eSetFilterList.classList.add("ag-set-filter-tree-list"); } eSetFilterList.appendChild(virtualList.getGui()); const { cellHeight } = this.params; if (cellHeight != null) { virtualList.setRowHeight(cellHeight); } const componentCreator = (item, listItemElement) => this.createSetListItem(item, isTree, listItemElement); virtualList.setComponentCreator(componentCreator); const componentUpdater = (item, component) => this.updateSetListItem(item, component); virtualList.setComponentUpdater(componentUpdater); this.createVirtualListModel(this.params); } createVirtualListModel(params) { let model; if (params.suppressSelectAll) { model = new ModelWrapper(this.displayValueModel); } else { model = new ModelWrapperWithSelectAll(this.displayValueModel, this.showAddCurrentSelectionToFilter.bind(this)); } if (params.treeList) { model = new TreeModelWrapper(model); } this.virtualList.setModel(model); } getSelectAllLabel() { const key = this.miniFilterText == null || !this.params.excelMode ? "selectAll" : "selectAllSearchResults"; return translateForSetFilter(this, key); } getAddSelectionToFilterLabel() { return translateForSetFilter(this, "addCurrentSelectionToFilter"); } createSetListItem(item, isTree, focusWrapper) { const groupsExist = this.displayValueModel.hasGroups(); const { isSelected, isExpanded } = this.isSelectedExpanded(item); const { value, depth, isGroup, hasIndeterminateExpandState, selectedListener, expandedListener } = this.newSetListItemAttributes(item); const itemParams = { focusWrapper, value, params: this.params, translate: (translateKey) => translateForSetFilter(this, translateKey), valueFormatter: this.handler.valueFormatter, item, isSelected, isTree, depth, groupsExist, isGroup, isExpanded, hasIndeterminateExpandState }; const listItem = this.createBean(new SetFilterListItem(itemParams)); listItem.addEventListener("selectionChanged", selectedListener); if (expandedListener) { listItem.addEventListener("expandedChanged", expandedListener); } return listItem; } newSetTreeItemAttributes(item) { const groupsExist = this.displayValueModel.hasGroups(); if (item.key === SET_FILTER_SELECT_ALL) { return { value: () => this.getSelectAllLabel(), isGroup: groupsExist, depth: item.depth, hasIndeterminateExpandState: true, selectedListener: (e) => this.onSelectAll(e.isSelected), expandedListener: (e) => this.onExpandAll(e.item, e.isExpanded) }; } if (item.key === SET_FILTER_ADD_SELECTION_TO_FILTER) { return { value: () => this.getAddSelectionToFilterLabel(), depth: item.depth, isGroup: false, hasIndeterminateExpandState: false, selectedListener: (e) => { this.addCurrentSelectionToFilter = e.isSelected; this.refreshAfterSelection(); } }; } if (item.children) { return { value: this.params.treeListFormatter?.(item.treeKey, item.depth, item.parentTreeKeys) ?? item.treeKey, depth: item.depth, isGroup: true, selectedListener: (e) => this.onGroupItemSelected(e.item, e.isSelected), expandedListener: (e) => this.onExpandedChanged(e.item, e.isExpanded) }; } return { value: this.params.treeListFormatter?.(item.treeKey, item.depth, item.parentTreeKeys) ?? item.treeKey, depth: item.depth, selectedListener: (e) => this.onItemSelected(e.item.key, e.isSelected) }; } newSetListItemAttributes(item) { if (this.isSetFilterModelTreeItem(item)) { return this.newSetTreeItemAttributes(item); } if (item === SET_FILTER_SELECT_ALL) { return { value: () => this.getSelectAllLabel(), selectedListener: (e) => this.onSelectAll(e.isSelected) }; } if (item === SET_FILTER_ADD_SELECTION_TO_FILTER) { return { value: () => this.getAddSelectionToFilterLabel(), selectedListener: (e) => { this.addCurrentSelectionToFilter = e.isSelected; this.refreshAfterSelection(); } }; } return { value: this.handler.valueModel.allValues.get(item) ?? null, selectedListener: (e) => this.onItemSelected(e.item, e.isSelected) }; } updateSetListItem(item, component) { const { isSelected, isExpanded } = this.isSelectedExpanded(item); component.refresh(item, isSelected, isExpanded); } isSelectedExpanded(item) { let isSelected; let isExpanded; if (this.isSetFilterModelTreeItem(item)) { isExpanded = item.expanded; if (item.key === SET_FILTER_SELECT_ALL) { isSelected = this.isSelectAllSelected(); } else if (item.key === SET_FILTER_ADD_SELECTION_TO_FILTER) { isSelected = this.isAddCurrentSelectionToFilterChecked(); } else if (item.children) { isSelected = this.areAllChildrenSelected(item); } else { isSelected = this.selectedKeys.has(item.key); } } else if (item === SET_FILTER_SELECT_ALL) { isSelected = this.isSelectAllSelected(); } else if (item === SET_FILTER_ADD_SELECTION_TO_FILTER) { isSelected = this.isAddCurrentSelectionToFilterChecked(); } else { isSelected = this.selectedKeys.has(item); } return { isSelected, isExpanded }; } isSetFilterModelTreeItem(item) { return item?.treeKey !== undefined; } initMiniFilter() { const { eMiniFilter } = this; this.updateMiniFilter(); eMiniFilter.onValueChange(() => this.onMiniFilterInput()); eMiniFilter.setInputAriaLabel(translateForSetFilter(this, "ariaSearchFilterValues")); this.addManagedElementListeners(eMiniFilter.getInputElement(), { keydown: (e) => this.onMiniFilterKeyDown(e) }); } updateMiniFilter() { const { eMiniFilter, miniFilterText, params } = this; eMiniFilter.setDisplayed(!params.suppressMiniFilter); eMiniFilter.setValue(miniFilterText); } afterGuiAttached(params) { super.afterGuiAttached(params); this.resetExpansion(); this.refreshVirtualList(); const { eMiniFilter } = this; eMiniFilter.setInputPlaceholder(translateForSetFilter(this, "searchOoo")); if (!params?.suppressFocus) { if (eMiniFilter.isDisplayed()) { eMiniFilter.getFocusableElement().focus(); } else { this.virtualList.awaitStable(() => this.virtualList.focusRow(0)); } } } afterGuiDetached() { super.afterGuiDetached(); const { column, excelMode, model, onStateChange } = this.params; if (this.beans.colFilter?.shouldKeepStateOnDetach(column)) { return; } if (excelMode) { this.resetMiniFilter(); } if (excelMode || model !== this.state.model) { onStateChange({ model, state: this.getState() }); this.showOrHideResults(); } } canApply(model) { return this.params.excelMode ? model == null || model.values.length > 0 : true; } onNewRowsLoaded() {} setFilterValues(values) { _warn(283); this.handler.setFilterValues(values); } resetFilterValues() { _warn(283); this.handler.resetFilterValues(); } refreshFilterValues() { _warn(283); this.doRefreshFilterValues(); } doRefreshFilterValues() { this.handler.refreshFilterValues(); } onAnyFilterChanged() {} onMiniFilterInput(silent) { if (!this.doSetMiniFilter(this.eMiniFilter.getValue())) { return; } if (silent) { this.showOrHideResults(); return; } const { applyMiniFilterWhileTyping, readOnly, excelMode } = this.params; const updateSelections = !readOnly && (applyMiniFilterWhileTyping || !!excelMode); const apply = applyMiniFilterWhileTyping && !readOnly ? "debounce" : undefined; this.updateUiAfterMiniFilterChange(updateSelections, apply); } updateUiAfterMiniFilterChange(updateSelections, apply) { if (updateSelections) { const { excelMode, readOnly, model } = this.params; if (excelMode && !readOnly && this.miniFilterText == null) { this.setModelAndRefresh(model?.values ?? null); } else { this.selectAllMatchingMiniFilter(true); } } this.checkAndRefreshVirtualList(); this.onUiChanged(updateSelections ? apply : "prevent"); this.showOrHideResults(); } showOrHideResults() { const hideResults = this.miniFilterText != null && this.displayValueModel.getDisplayedValueCount() < 1; _setDisplayed(this.eFilterNoMatches, hideResults); _setDisplayed(this.eSetFilterList, !hideResults); } resetMiniFilter() { this.eMiniFilter.setValue(null, true); this.doSetMiniFilter(null); } onMiniFilterKeyDown(e) { const { excelMode, readOnly } = this.params; if (e.key === KeyCode.ENTER && !excelMode && !readOnly) { this.updateUiAfterMiniFilterChange(true, "immediately"); } } focusRowIfAlive(rowIndex) { if (rowIndex == null) { return Promise.resolve(); } return new Promise((res) => { window.setTimeout(() => { if (this.isAlive()) { this.virtualList.focusRow(rowIndex); } res(); }, 0); }); } onSelectAll(isSelected) { if (isSelected) { this.selectAllMatchingMiniFilter(); } else { this.deselectAllMatchingMiniFilter(); } this.refreshAfterSelection(); } onGroupItemSelected(item, isSelected) { const recursiveGroupSelection = (i) => { if (!i.filterPasses) { return; } const children = i.children; if (children) { for (const childItem of children.values()) { recursiveGroupSelection(childItem); } } else { this.setKeySelected(i.key, isSelected); } }; recursiveGroupSelection(item); this.refreshAfterSelection(); } onItemSelected(key, isSelected) { this.setKeySelected(key, isSelected); this.refreshAfterSelection(); } onExpandAll(item, isExpanded) { const recursiveExpansion = (i) => { if (i.filterPasses && i.available && i.children) { for (const childItem of i.children.values()) { recursiveExpansion(childItem); } i.expanded = isExpanded; } }; recursiveExpansion(item); this.refreshAfterExpansion(); } onExpandedChanged(item, isExpanded) { item.expanded = isExpanded; this.refreshAfterExpansion(); } refreshAfterExpansion() { const focusedRow = this.virtualList.getLastFocusedRow(); this.updateDisplayedValues("expansion"); this.checkAndRefreshVirtualList(); this.focusRowIfAlive(focusedRow); } refreshAfterSelection() { const focusedRow = this.virtualList.getLastFocusedRow(); this.checkAndRefreshVirtualList(); this.onUiChanged(); this.focusRowIfAlive(focusedRow); } setMiniFilter(newMiniFilter, silent) { this.eMiniFilter.setValue(newMiniFilter, silent); this.onMiniFilterInput(silent); } doSetMiniFilter(value) { value = _makeNull(value); if (this.miniFilterText === value) { return false; } if (value === null) { this.addCurrentSelectionToFilter = false; } this.miniFilterText = value; this.updateDisplayedValues("miniFilter"); return true; } getMiniFilter() { return this.miniFilterText; } getUiChangeEventParams() { return { miniFilterValue: this.miniFilterText }; } getState() { const miniFilterValue = this.miniFilterText; return miniFilterValue ? { miniFilterValue } : undefined; } checkAndRefreshVirtualList() { this.virtualList.refresh(!this.hardRefreshVirtualList); if (this.hardRefreshVirtualList) { this.hardRefreshVirtualList = false; } } getFilterKeys() { _warn(283); return this.handler.getFilterKeys(); } getFilterValues() { _warn(283); return this.handler.getFilterValues(); } refreshVirtualList() { if (this.params.refreshValuesOnOpen) { this.doRefreshFilterValues(); } else { this.checkAndRefreshVirtualList(); } } isSelectAllSelected() { if (!this.params.defaultToNothingSelected) { if (this.hasSelections() && this.isNothingVisibleSelected()) { return false; } if (this.isEverythingVisibleSelected()) { return true; } } else { if (this.hasSelections() && this.isEverythingVisibleSelected()) { return true; } if (this.isNothingVisibleSelected()) { return false; } } return; } areAllChildrenSelected(item) { const recursiveChildSelectionCheck = (i) => { if (i.children) { let someTrue = false; let someFalse = false; for (const child of i.children.values()) { if (!child.filterPasses || !child.available) { continue; } const childSelected = recursiveChildSelectionCheck(child); if (childSelected === undefined) { return; } if (childSelected) { someTrue = true; } else { someFalse = true; } if (someTrue && someFalse) { return; } } return someTrue; } else { return this.selectedKeys.has(i.key); } }; if (!this.params.defaultToNothingSelected) { return recursiveChildSelectionCheck(item); } else { return this.hasSelections() && recursiveChildSelectionCheck(item); } } resetExpansion() { if (!this.params.treeList) { return; } const selectAllItem = this.displayValueModel.getSelectAllItem(); if (this.isSetFilterModelTreeItem(selectAllItem)) { const recursiveCollapse = (i) => { const children = i.children; if (children) { for (const childItem of children.values()) { recursiveCollapse(childItem); } i.expanded = false; } }; recursiveCollapse(selectAllItem); this.updateDisplayedValues("expansion"); } } getModelAsString(model) { return this.handler.getModelAsString(model); } getPositionableElement() { return this.eSetFilterList; } updateDisplayedValues(source, allKeys) { if (source === "expansion") { this.displayValueModel.refresh(); return; } const handler = this.handler; const valueModel = handler.valueModel; if (this.miniFilterText == null) { this.displayValueModel.updateDisplayedValuesToAllAvailable((key) => valueModel.allValues.get(key) ?? null, allKeys, valueModel.availableKeys, source); return; } const formattedFilterText = handler.caseFormat(this.formatter(this.miniFilterText) || ""); const matchesFilter = (valueToCheck) => valueToCheck != null && handler.caseFormat(valueToCheck).includes(formattedFilterText); const nullMatchesFilter = !!this.params.excelMode && matchesFilter(translateForSetFilter(this, "blanks")); this.displayValueModel.updateDisplayedValuesToMatchMiniFilter((key) => valueModel.allValues.get(key) ?? null, allKeys, valueModel.availableKeys, matchesFilter, nullMatchesFilter, source); } hasSelections() { return this.params.defaultToNothingSelected ? this.selectedKeys.size > 0 : this.handler.valueModel.allValues.size !== this.selectedKeys.size; } isInWindowsExcelMode() { return this.params.excelMode === "windows"; } isAddCurrentSelectionToFilterChecked() { return this.isInWindowsExcelMode() && this.addCurrentSelectionToFilter; } showAddCurrentSelectionToFilter() { return this.isInWindowsExcelMode() && _exists(this.miniFilterText) && this.miniFilterText.length > 0; } selectAllMatchingMiniFilter(clearExistingSelection = false) { if (this.miniFilterText == null) { this.selectedKeys = new Set(this.handler.valueModel.allValues.keys()); } else { if (clearExistingSelection) { this.selectedKeys.clear(); } this.displayValueModel.forEachDisplayedKey((key) => this.selectedKeys.add(key)); } } deselectAllMatchingMiniFilter() { if (this.miniFilterText == null) { this.selectedKeys.clear(); } else { this.displayValueModel.forEachDisplayedKey((key) => this.selectedKeys.delete(key)); } } setKeySelected(key, selected) { if (selected) { this.selectedKeys.add(key); } else { if (this.params.excelMode && this.isEverythingVisibleSelected()) { this.resetSelectionState(this.displayValueModel.getDisplayedKeys()); } this.selectedKeys.delete(key); } } isEverythingVisibleSelected() { return !this.displayValueModel.someDisplayedKey((it) => !this.selectedKeys.has(it)); } isNothingVisibleSelected() { return !this.displayValueModel.someDisplayedKey((it) => this.selectedKeys.has(it)); } getSelectedModel() { if (!this.hasSelections()) { return null; } const filteringKeys = this.isAddCurrentSelectionToFilterChecked() ? this.params.model?.values : undefined; if (filteringKeys?.length) { if (this.selectedKeys) { const modelKeys = /* @__PURE__ */ new Set([...filteringKeys, ...this.selectedKeys]); return Array.from(modelKeys); } return Array.from(filteringKeys); } return Array.from(this.selectedKeys); } setSelectedModel(model) { const handler = this.handler; const valueModel = handler.valueModel; return valueModel.allKeys.then((keys) => { if (model == null) { this.resetSelectionState(keys ?? []); } else { this.selectedKeys.clear(); const existingFormattedKeys = /* @__PURE__ */ new Map; valueModel.allValues.forEach((_value, key) => { existingFormattedKeys.set(handler.caseFormat(key), key); }); model.forEach((unformattedKey) => { const formattedKey = handler.caseFormat(_makeNull(unformattedKey)); const existingUnformattedKey = existingFormattedKeys.get(formattedKey); if (existingUnformattedKey !== undefined) { this.selectedKeys.add(existingUnformattedKey); } }); } }); } resetSelectionState(keys) { if (this.params.defaultToNothingSelected) { this.selectedKeys.clear(); } else { this.selectedKeys = new Set(keys); } } getFilterHandler() { return this.handler; } destroy() { this.virtualList = this.destroyBean(this.virtualList); for (const func of this.handlerDestroyFuncs ?? []) { func(); } this.handler = undefined; this.displayValueModel = undefined; this.selectedKeys.clear(); super.destroy(); } }; var ModelWrapper = class { constructor(model) { this.model = model; } getRowCount() { return this.model.getDisplayedValueCount(); } getRow(index) { return this.model.getDisplayedItem(index); } areRowsEqual(oldRow, newRow) { return oldRow === newRow; } }; var ModelWrapperWithSelectAll = class { constructor(model, showAddCurrentSelectionToFilter) { this.model = model; this.showAddCurrentSelectionToFilter = showAddCurrentSelectionToFilter; } getRowCount() { const showAddCurrentSelectionToFilter = this.showAddCurrentSelectionToFilter(); const outboundItems = showAddCurrentSelectionToFilter ? 2 : 1; return this.model.getDisplayedValueCount() + outboundItems; } getRow(index) { if (index === 0) { return this.model.getSelectAllItem(); } const showAddCurrentSelectionToFilter = this.showAddCurrentSelectionToFilter(); const outboundItems = showAddCurrentSelectionToFilter ? 2 : 1; if (index === 1 && showAddCurrentSelectionToFilter) { return this.model.getAddSelectionToFilterItem(); } return this.model.getDisplayedItem(index - outboundItems); } areRowsEqual(oldRow, newRow) { return oldRow === newRow; } }; var TreeModelWrapper = class { constructor(model) { this.model = model; } getRowCount() { return this.model.getRowCount(); } getRow(index) { return this.model.getRow(index); } areRowsEqual(oldRow, newRow) { if (oldRow == null && newRow == null) { return true; } return oldRow != null && newRow != null && oldRow.treeKey === newRow.treeKey && oldRow.depth === newRow.depth; } }; var ClientSideValuesExtractor = class extends BeanStub { constructor(createKey, caseFormat, getValue, isTreeDataOrGrouping, isTreeData) { super(); this.createKey = createKey; this.caseFormat = caseFormat; this.getValue = getValue; this.isTreeDataOrGrouping = isTreeDataOrGrouping; this.isTreeData = isTreeData; } extractUniqueValuesAsync(predicate, existingValues) { return new AgPromise((resolve) => { if (this.beans.rowModel.rowCountReady) { resolve(this.extractUniqueValues(predicate, existingValues)); } else { const [destroyFunc] = this.addManagedEventListeners({ rowCountReady: () => { destroyFunc?.(); resolve(this.extractUniqueValues(predicate, existingValues)); } }); } }); } extractUniqueValues(predicate, existingValues) { const values = /* @__PURE__ */ new Map; const existingFormattedKeys = this.extractExistingFormattedKeys(existingValues); const formattedKeys = /* @__PURE__ */ new Set; const treeData = this.isTreeData(); const treeDataOrGrouping = this.isTreeDataOrGrouping(); const groupedCols = this.beans.rowGroupColsSvc?.columns; const groupAllowUnbalanced = this.gos.get("groupAllowUnbalanced"); const addValue = (unformattedKey, value) => { const formattedKey = this.caseFormat(unformattedKey); if (!formattedKeys.has(formattedKey)) { formattedKeys.add(formattedKey); let keyToAdd = unformattedKey; let valueToAdd = _makeNull(value); const existingUnformattedKey = existingFormattedKeys?.get(formattedKey); if (existingUnformattedKey != null) { keyToAdd = existingUnformattedKey; valueToAdd = existingValues.get(existingUnformattedKey); } values.set(keyToAdd, valueToAdd); } }; this.beans.rowModel.forEachLeafNode((node) => { if (!node.data || !predicate(node)) { return; } if (treeDataOrGrouping) { this.addValueForTreeDataOrGrouping(node, treeData, groupedCols, addValue, groupAllowUnbalanced); return; } const value = this.getValue(node); if (value != null && Array.isArray(value)) { for (const x of value) { addValue(this.createKey(x, node), x); } if (value.length === 0) { addValue(null, null); } } else { addValue(this.createKey(value, node), value); } }); return values; } addValueForTreeDataOrGrouping(node, treeData, groupedCols = [], addValue, groupAllowUnbalanced) { let dataPath; if (treeData) { if (node.childrenAfterGroup?.length) { return; } dataPath = node.getRoute() ?? [node.key ?? node.id]; } else { dataPath = groupedCols.map((groupCol) => this.beans.valueSvc.getKeyForNode(groupCol, node)); dataPath.push(this.getValue(node)); } const processedDataPath = processDataPath(dataPath, treeData, groupAllowUnbalanced); addValue(this.createKey(processedDataPath), processedDataPath); } extractExistingFormattedKeys(existingValues) { if (!existingValues) { return null; } const existingFormattedKeys = /* @__PURE__ */ new Map; existingValues.forEach((_value, key) => { existingFormattedKeys.set(this.caseFormat(key), key); }); return existingFormattedKeys; } }; var SetFilterAppliedModel = class { constructor(caseFormat) { this.caseFormat = caseFormat; this.keys = null; } isNull() { return this.keys == null; } isEmpty() { return !this.keys?.size; } update(appliedModel) { const keys = /* @__PURE__ */ new Set; this.keys = keys; const values = appliedModel?.values; if (values) { const caseFormat = this.caseFormat; for (let i = 0, len = values.length;i < len; i++) { keys.add(caseFormat(values[i])); } } } has(key) { return !!this.keys?.has(this.caseFormat(key)); } destroy() { this.keys = null; } }; var SetFilterModelValuesType = /* @__PURE__ */ ((SetFilterModelValuesType2) => { SetFilterModelValuesType2[SetFilterModelValuesType2["PROVIDED_LIST"] = 0] = "PROVIDED_LIST"; SetFilterModelValuesType2[SetFilterModelValuesType2["PROVIDED_CALLBACK"] = 1] = "PROVIDED_CALLBACK"; SetFilterModelValuesType2[SetFilterModelValuesType2["TAKEN_FROM_GRID_VALUES"] = 2] = "TAKEN_FROM_GRID_VALUES"; return SetFilterModelValuesType2; })(SetFilterModelValuesType || {}); var setValueModel_default = SetFilterModelValuesType; var SetValueModel = class extends BeanStub { constructor(clientSideValuesExtractor, caseFormat, createKey, isTreeDataOrGrouping, params) { super(); this.clientSideValuesExtractor = clientSideValuesExtractor; this.caseFormat = caseFormat; this.createKey = createKey; this.isTreeDataOrGrouping = isTreeDataOrGrouping; this.params = params; this.allValues = /* @__PURE__ */ new Map; this.availableKeys = /* @__PURE__ */ new Set; this.providedValues = null; this.initialised = false; } postConstruct() { const params = this.params; const values = params.handlerParams.filterParams.values; this.updateParams(params); if (values == null) { this.valuesType = 2; } else { this.valuesType = Array.isArray(values) ? 0 : 1; this.providedValues = values; } this.updateAllValues(); } refresh(params) { const handlerParams = params.handlerParams; if (handlerParams.source !== "colDef") { return; } const { values, suppressSorting } = handlerParams.filterParams; const currentProvidedValues = this.providedValues; const currentSuppressSorting = this.params.handlerParams.filterParams.suppressSorting; this.params = params; this.updateParams(params); this.providedValues = values ?? null; if (this.providedValues !== currentProvidedValues || suppressSorting !== currentSuppressSorting) { if (!values || values.length === 0) { this.valuesType = 2; this.providedValues = null; } else { this.valuesType = Array.isArray(values) ? 0 : 1; } this.updateAllValues(); } } updateParams(params) { const { handlerParams: { colDef, filterParams: { comparator, treeList, treeListPathGetter } }, usingComplexObjects } = params; const keyComparator = comparator ?? colDef.comparator; const treeDataOrGrouping = this.isTreeDataOrGrouping(); let entryComparator; if (treeDataOrGrouping && !keyComparator) { entryComparator = createTreeDataOrGroupingComparator(); } else if (treeList && !treeListPathGetter && !keyComparator) { entryComparator = ([_aKey, aValue], [_bKey, bValue]) => _defaultComparator(aValue, bValue); } else { entryComparator = ([_aKey, aValue], [_bKey, bValue]) => keyComparator(aValue, bValue); } this.entryComparator = entryComparator; this.keyComparator = keyComparator ?? _defaultComparator; this.compareByValue = !!(usingComplexObjects && keyComparator || treeDataOrGrouping || treeList && !treeListPathGetter); } updateAllValues() { this.allKeys = new AgPromise((resolve) => { switch (this.valuesType) { case 2: this.getValuesFromRowsAsync().then((values) => resolve(this.processAllValues(values))); break; case 0: { resolve(this.processAllValues(this.uniqueValues(this.validateProvidedValues(this.providedValues)))); break; } case 1: { this.dispatchLocalEvent({ type: "loadingStart" }); const callback = this.providedValues; const { column, colDef } = this.params.handlerParams; const params = _addGridCommonParams(this.gos, { success: (values) => { this.dispatchLocalEvent({ type: "loadingEnd" }); resolve(this.processAllValues(this.uniqueValues(this.validateProvidedValues(values)))); }, colDef, column }); window.setTimeout(() => callback(params), 0); break; } } }); this.allKeys.then((values) => { this.updateAvailableKeys(values ?? []); this.initialised = true; }); return this.allKeys; } getAvailableValues(predicate) { return this.sortKeys(this.getValuesFromRows(predicate)); } overrideValues(valuesToUse) { return this.allKeys.then(() => { this.valuesType = 0; this.providedValues = valuesToUse; }); } refreshAvailable() { return new AgPromise((resolve) => { if (this.showAvailableOnly()) { this.allKeys.then((keys) => { const updatedKeys = keys ?? []; this.updateAvailableKeys(updatedKeys); resolve(true); }); return; } resolve(false); }); } refreshAll() { return new AgPromise((resolve) => { this.allKeys.then(() => { this.updateAllValues().then(() => { resolve(); }); }); }); } isLoading() { return !this.initialised && this.valuesType === 1; } isInitialised() { return this.initialised; } getValueForFormatter(key) { return this.initialised ? this.allValues.get(key) : key; } getAvailableKeys(values) { return this.initialised ? values.filter((v) => this.availableKeys.has(v)) : values; } getParamsForValuesFromRows(removeUnavailableValues) { if (!this.clientSideValuesExtractor) { _error(113); return; } const existingValues = removeUnavailableValues && !this.params.handlerParams.filterParams.caseSensitive ? this.allValues : undefined; return existingValues; } getValuesFromRows(predicate) { const existingValues = this.getParamsForValuesFromRows(true); return this.clientSideValuesExtractor?.extractUniqueValues(predicate, existingValues) ?? null; } getValuesFromRowsAsync() { const existingValues = this.getParamsForValuesFromRows(false); return this.clientSideValuesExtractor?.extractUniqueValuesAsync(() => true, existingValues) ?? AgPromise.resolve(null); } processAllValues(values) { const sortedKeys = this.sortKeys(values); this.allValues = values ?? /* @__PURE__ */ new Map; return sortedKeys; } uniqueValues(values) { const uniqueValues = /* @__PURE__ */ new Map; const formattedKeys = /* @__PURE__ */ new Set; const { caseFormat, createKey } = this; for (const value of values ?? []) { const valueToUse = _makeNull(value); const unformattedKey = createKey(valueToUse); const formattedKey = caseFormat(unformattedKey); if (!formattedKeys.has(formattedKey)) { formattedKeys.add(formattedKey); uniqueValues.set(unformattedKey, valueToUse); } } return uniqueValues; } validateProvidedValues(values) { if (this.params.usingComplexObjects && values?.length) { const firstValue = values[0]; if (firstValue && typeof firstValue !== "object" && typeof firstValue !== "function") { const firstKey = this.createKey(firstValue); if (firstKey == null) { _warn(209); } else { _warn(210); } } } return values; } sortKeys(nullableValues) { const values = nullableValues ?? /* @__PURE__ */ new Map; const filterParams = this.params.handlerParams.filterParams; if (filterParams.suppressSorting) { return Array.from(values.keys()); } let sortedKeys; if (this.compareByValue) { sortedKeys = Array.from(values.entries()).sort(this.entryComparator).map(([key]) => key); } else { sortedKeys = Array.from(values.keys()).sort(this.keyComparator); } if (filterParams.excelMode && values.has(null)) { sortedKeys = sortedKeys.filter((v) => v != null); sortedKeys.push(null); } return sortedKeys; } showAvailableOnly() { return this.valuesType === 2; } updateAvailableKeys(allKeys) { const availableKeys = this.showAvailableOnly() ? this.getAvailableValues((node) => this.params.handlerParams.doesRowPassOtherFilter(node)) : allKeys; this.availableKeys = new Set(availableKeys); window.setTimeout(() => { if (this.isAlive()) { this.dispatchLocalEvent({ type: "availableValuesChanged" }); } }); } }; var SetFilterHandler = class extends BeanStub { constructor() { super(...arguments); this.filterType = "set"; this.treeDataTreeList = false; this.groupingTreeList = false; this.caseSensitive = false; this.noValueFormatterSupplied = false; } init(params) { this.updateParams(params); const isTreeDataOrGrouping = this.isTreeDataOrGrouping.bind(this); const isTreeData = () => this.treeDataTreeList; const createKey = this.createKey; const caseFormat = this.caseFormat.bind(this); const { gos, beans } = this; const clientSideValuesExtractor = _isClientSideRowModel(gos, beans.rowModel) ? this.createManagedBean(new ClientSideValuesExtractor(createKey, caseFormat, params.getValue, isTreeDataOrGrouping, isTreeData)) : undefined; const valueModel = this.createManagedBean(new SetValueModel(clientSideValuesExtractor, caseFormat, createKey, isTreeDataOrGrouping, { handlerParams: params, usingComplexObjects: !!(params.filterParams.keyCreator ?? params.colDef.keyCreator) })); this.addManagedListeners(valueModel, { availableValuesChanged: params.onModelAsStringChange }); this.valueModel = valueModel; this.appliedModel = new SetFilterAppliedModel(this.caseFormat.bind(this)); this.appliedModel.update(params.model); this.validateModel(params); this.addEventListenersForDataChanges(); } refresh(params) { this.updateParams(params); this.valueModel.refresh({ handlerParams: params, usingComplexObjects: !!(params.filterParams.keyCreator ?? params.colDef.keyCreator) }); this.appliedModel.update(params.model); this.validateModel(params); } updateParams(params) { this.params = params; const { colDef, filterParams: { caseSensitive, treeList, keyCreator, valueFormatter } } = params; this.caseSensitive = !!caseSensitive; const isGroupCol = !!colDef.showRowGroup; this.treeDataTreeList = this.gos.get("treeData") && !!treeList && isGroupCol; this.groupingTreeList = !!this.beans.rowGroupColsSvc?.columns.length && !!treeList && isGroupCol; const resolvedKeyCreator = keyCreator ?? colDef.keyCreator; this.createKey = this.generateCreateKey(resolvedKeyCreator, this.isTreeDataOrGrouping()); this.setValueFormatter(valueFormatter, resolvedKeyCreator, !!treeList, !!colDef.refData); } doesFilterPass(params) { const { appliedModel, treeDataTreeList, groupingTreeList } = this; if (appliedModel.isNull()) { return true; } if (appliedModel.isEmpty()) { return false; } const { node } = params; if (treeDataTreeList) { return this.doesFilterPassForTreeData(node); } if (groupingTreeList) { return this.doesFilterPassForGrouping(node); } const value = this.params.getValue(node); if (value != null && Array.isArray(value)) { if (value.length === 0) { return appliedModel.has(null); } return value.some((v) => appliedModel.has(this.createKey(v, node))); } return appliedModel.has(this.createKey(value, node)); } getFormattedValue(key) { let value = this.valueModel.getValueForFormatter(key); if (this.noValueFormatterSupplied && this.isTreeDataOrGrouping() && Array.isArray(value)) { value = _last(value); } const formattedValue = this.beans.valueSvc.formatValue(this.params.column, null, value, this.valueFormatter, false); return (formattedValue == null ? _toStringOrNull(value) : formattedValue) ?? translateForSetFilter(this, "blanks"); } getModelAsString(model, source) { const { values } = model ?? {}; const forToolPanel = source === "filterToolPanel"; if (values == null) { return forToolPanel ? translateForSetFilter(this, "filterSummaryListInactive") : ""; } const availableKeys = this.valueModel.getAvailableKeys(values); const numValues = availableKeys.length; const numToDisplay = forToolPanel ? 3 : 10; const formattedValues = availableKeys.slice(0, numToDisplay).map((key) => this.getFormattedValue(key)); if (forToolPanel) { const valueList = formattedValues.join(translateForSetFilter(this, "filterSummaryListSeparator")); if (numValues > 3) { return translateForSetFilter(this, "filterSummaryListLong", [valueList, String(numValues - 3)]); } else { return translateForSetFilter(this, "filterSummaryListShort", [valueList]); } } return `(${numValues}) ${formattedValues.join(",")}${numValues > 10 ? ",..." : ""}`; } onAnyFilterChanged() { window.setTimeout(() => { if (!this.isAlive()) { return; } this.valueModel.refreshAvailable().then((updated) => { this.dispatchLocalEvent({ type: "anyFilterChanged", updated: !!updated }); }); }); } onNewRowsLoaded() { this.syncAfterDataChange(); } setFilterValues(values) { this.valueModel.overrideValues(values).then(() => { this.refreshFilterValues(); }); } resetFilterValues() { this.valueModel.valuesType = setValueModel_default.TAKEN_FROM_GRID_VALUES; this.syncAfterDataChange(); } refreshFilterValues(suppressAvailableValuesCheck) { if (!this.valueModel.isInitialised()) { return; } this.valueModel.refreshAll().then(() => { this.dispatchLocalEvent({ type: "dataChanged", hardRefresh: true }); this.validateModel(this.params, undefined, !suppressAvailableValuesCheck); }); } getFilterKeys() { return Array.from(this.valueModel.allValues.keys()); } getFilterValues() { return Array.from(this.valueModel.allValues.values()); } isTreeDataOrGrouping() { return this.treeDataTreeList || this.groupingTreeList; } caseFormat(valueToFormat) { if (valueToFormat == null || typeof valueToFormat !== "string") { return valueToFormat; } return this.caseSensitive ? valueToFormat : valueToFormat.toUpperCase(); } addEventListenersForDataChanges() { this.addManagedPropertyListeners(["groupAllowUnbalanced"], () => this.syncAfterDataChange()); const syncAfterDataChangeDebounced = _debounce(this, this.syncAfterDataChange.bind(this), 0); this.addManagedEventListeners({ cellValueChanged: (event) => { if (event.column === this.params.column) { syncAfterDataChangeDebounced(); } } }); } syncAfterDataChange() { if (!this.isValuesTakenFromGrid()) { return; } this.valueModel.refreshAll().then(() => { this.dispatchLocalEvent({ type: "dataChanged" }); this.validateModel(this.params, { afterDataChange: true }); }); } validateModel(params, additionalEventAttributes, restrictToAvailableValues) { const valueModel = this.valueModel; valueModel.allKeys.then(() => { const model = params.model; if (model == null) { return; } const existingFormattedKeys = /* @__PURE__ */ new Map; const addKey = (key) => existingFormattedKeys.set(this.caseFormat(key), key); if (restrictToAvailableValues) { for (const key of valueModel.availableKeys) { addKey(key); } } else { valueModel.allValues.forEach((_value, key) => addKey(key)); } const newValues = []; let updated = false; for (const unformattedKey of model.values) { const formattedKey = this.caseFormat(_makeNull(unformattedKey)); const existingUnformattedKey = existingFormattedKeys.get(formattedKey); if (existingUnformattedKey !== undefined) { newValues.push(existingUnformattedKey); if (existingUnformattedKey !== unformattedKey) { updated = true; } } else { updated = true; } } const numNewValues = newValues.length; const filterParams = params.filterParams; if (numNewValues === 0 && filterParams.excelMode) { params.onModelChange(null, additionalEventAttributes); return; } const clearOnAllSelected = !filterParams.defaultToNothingSelected && (this.valueModel.valuesType === setValueModel_default.TAKEN_FROM_GRID_VALUES || !filterParams.suppressClearModelOnRefreshValues); const allSelected = clearOnAllSelected && numNewValues === existingFormattedKeys.size; if (updated || !model.filterType || allSelected) { const newModel = allSelected ? null : { filterType: this.filterType, values: newValues }; params.onModelChange(newModel, additionalEventAttributes); } }); } isValuesTakenFromGrid() { return this.valueModel.valuesType === setValueModel_default.TAKEN_FROM_GRID_VALUES; } doesFilterPassForTreeData(node) { if (node.childrenAfterGroup?.length) { return false; } const { gos, appliedModel } = this; return appliedModel.has(this.createKey(processDataPath(node.getRoute() ?? [node.key ?? node.id], true, gos.get("groupAllowUnbalanced")))); } doesFilterPassForGrouping(node) { const { appliedModel, params, gos, beans: { rowGroupColsSvc, valueSvc } } = this; const dataPath = (rowGroupColsSvc?.columns ?? []).map((groupCol) => valueSvc.getKeyForNode(groupCol, node)); dataPath.push(params.getValue(node)); return appliedModel.has(this.createKey(processDataPath(dataPath, false, gos.get("groupAllowUnbalanced")))); } generateCreateKey(keyCreator, treeDataOrGrouping) { if (treeDataOrGrouping && !keyCreator) { _error(250); return () => null; } if (keyCreator) { return (value, node = null) => { const params = this.getKeyCreatorParams(value, node); return _makeNull(keyCreator(params)); }; } return (value) => _makeNull(_toStringOrNull(value)); } getKeyCreatorParams(value, node = null) { const { colDef, column } = this.params; return _addGridCommonParams(this.gos, { value, colDef, column, node, data: node?.data }); } setValueFormatter(providedValueFormatter, keyCreator, treeList, isRefData) { let valueFormatter = providedValueFormatter; if (!valueFormatter) { if (keyCreator && !treeList) { _error(249); return; } this.noValueFormatterSupplied = true; if (!isRefData) { valueFormatter = (params) => _toStringOrNull(params.value); } } this.valueFormatter = valueFormatter; } getCrossFilterModel(callback) { const { createKey, valueModel, params } = this; return callback(createKey, valueModel.availableKeys, params.model?.values); } destroy() { this.appliedModel.destroy(); super.destroy(); this.valueModel = undefined; } }; var SetFloatingFilterElement = { tag: "div", cls: "ag-floating-filter-input ag-set-floating-filter-input", role: "presentation", children: [ { tag: "ag-input-text-field", ref: "eFloatingFilterText" } ] }; var SetFloatingFilterComp = class extends Component { constructor() { super(SetFloatingFilterElement, [AgInputTextFieldSelector]); this.eFloatingFilterText = RefPlaceholder; } init(params) { this.params = params; this.eFloatingFilterText.setDisabled(true).addGuiEventListener("click", () => this.params.showParentFilter()); this.setParams(params); } setParams(params) { const displayName = this.beans.colNames.getDisplayNameForColumn(params.column, "header", true); const translate = this.getLocaleTextFunc(); this.eFloatingFilterText.setInputAriaLabel(`${displayName} ${translate("ariaFilterInput", "Filter Input")}`); if (this.gos.get("enableFilterHandlers")) { const reactiveParams = params; this.updateFloatingFilterText(reactiveParams.model); } } refresh(params) { this.params = params; this.setParams(params); } onParentModelChanged(parentModel) { this.updateFloatingFilterText(parentModel); } parentSetFilterInstance(cb) { this.params.parentFilterInstance((filter) => { if (!(filter instanceof SetFilter)) { _error(248); return; } cb(filter); }); } updateFloatingFilterText(parentModel) { if (parentModel == null) { this.eFloatingFilterText.setValue(""); } else if (this.gos.get("enableFilterHandlers")) { this.eFloatingFilterText.setValue(this.params.getHandler().getModelAsString?.(parentModel) ?? ""); } else { this.parentSetFilterInstance((setFilter) => { this.eFloatingFilterText.setValue(setFilter.getModelAsString(parentModel)); }); } } }; var SetFilterModule = { moduleName: "SetFilter", version: VERSION2, userComponents: { agSetColumnFilter: { classImp: SetFilter, params: { useForm: true }, processParams: (params) => { applyExcelModeOptions(params); return params; } }, agSetColumnFloatingFilter: SetFloatingFilterComp }, dynamicBeans: { agSetColumnFilterHandler: SetFilterHandler }, icons: { setFilterGroupClosed: "tree-closed", setFilterGroupOpen: "tree-open", setFilterGroupIndeterminate: "tree-indeterminate", setFilterLoading: "loading" }, dependsOn: [EnterpriseCoreModule, ColumnFilterModule] }; var agStatusBar_default = ".ag-status-bar{border-top:var(--ag-footer-row-border);display:flex;justify-content:space-between;line-height:1.5;overflow:hidden;padding-left:calc(var(--ag-spacing)*4);padding-right:calc(var(--ag-spacing)*4)}.ag-status-panel,:where(.ag-status-panel.ag-status-panel-aggregations .ag-status-name-value){display:inline-flex}.ag-status-name-value{color:var(--ag-status-bar-label-color);font-weight:var(--ag-status-bar-label-font-weight);margin-left:var(--ag-spacing);margin-right:var(--ag-spacing);padding-bottom:var(--ag-widget-container-vertical-padding);padding-top:var(--ag-widget-container-vertical-padding);white-space:nowrap}.ag-status-name-value-value{color:var(--ag-status-bar-value-color);font-weight:var(--ag-status-bar-value-font-weight)}.ag-status-bar-left{display:inline-flex}.ag-status-bar-center{display:inline-flex;text-align:center}.ag-status-bar-right{display:inline-flex}"; function getStatusPanelCompDetails(userCompFactory, def, params) { return userCompFactory.getCompDetails(def, StatusPanelComponent, undefined, params, true); } var StatusPanelComponent = { name: "statusPanel", optionalMethods: ["refresh"] }; var AgStatusBarValidationMap = { agAggregationComponent: { rowModels: ["clientSide", "serverSide"], warnArgs: [221] }, agFilteredRowCountComponent: { rowModels: ["clientSide"], warnArgs: [222] }, agSelectedRowCountComponent: { rowModels: ["clientSide", "serverSide"], warnArgs: [223] }, agTotalAndFilteredRowCountComponent: { rowModels: ["clientSide"], warnArgs: [224] }, agTotalRowCountComponent: { rowModels: ["clientSide"], warnArgs: [225] } }; var AgStatusBarElement = { tag: "div", cls: "ag-status-bar", children: [ { tag: "div", ref: "eStatusBarLeft", cls: "ag-status-bar-left", role: "status" }, { tag: "div", ref: "eStatusBarCenter", cls: "ag-status-bar-center", role: "status" }, { tag: "div", ref: "eStatusBarRight", cls: "ag-status-bar-right", role: "status" } ] }; var AgStatusBar = class extends Component { constructor() { super(AgStatusBarElement); this.updateQueued = false; this.panelsPromise = AgPromise.resolve(); this.eStatusBarLeft = RefPlaceholder; this.eStatusBarCenter = RefPlaceholder; this.eStatusBarRight = RefPlaceholder; this.compDestroyFunctions = {}; this.registerCSS(agStatusBar_default); } wireBeans(beans) { this.userCompFactory = beans.userCompFactory; this.statusBarSvc = beans.statusBarSvc; } postConstruct() { this.processStatusPanels(/* @__PURE__ */ new Map); this.addManagedPropertyListeners(["statusBar"], this.handleStatusBarChanged.bind(this)); _addFocusableContainerListener(this.beans, this, this.getGui()); } getFocusableContainerName() { return "statusBar"; } getValidPanels() { const gos = this.gos; const statusPanels = gos.get("statusBar")?.statusPanels; if (!statusPanels) { return statusPanels; } return statusPanels.filter((panel) => { const { rowModels, warnArgs } = AgStatusBarValidationMap[panel.statusPanel] ?? {}; if (!rowModels) { return true; } if (rowModels.includes(gos.get("rowModelType"))) { return true; } _warn(...warnArgs); return false; }); } processStatusPanels(existingStatusPanelsToReuse) { const statusPanels = this.getValidPanels(); if (statusPanels) { const leftStatusPanelComponents = statusPanels.filter((componentConfig) => componentConfig.align === "left"); const centerStatusPanelComponents = statusPanels.filter((componentConfig) => componentConfig.align === "center"); const rightStatusPanelComponents = statusPanels.filter((componentConfig) => !componentConfig.align || componentConfig.align === "right"); this.panelsPromise = AgPromise.all([ this.createAndRenderComponents(leftStatusPanelComponents, this.eStatusBarLeft, existingStatusPanelsToReuse), this.createAndRenderComponents(centerStatusPanelComponents, this.eStatusBarCenter, existingStatusPanelsToReuse), this.createAndRenderComponents(rightStatusPanelComponents, this.eStatusBarRight, existingStatusPanelsToReuse) ]); } else { this.setDisplayed(false); } } handleStatusBarChanged() { if (this.updateQueued) { return; } this.updateQueued = true; this.panelsPromise.then(() => { this.updateStatusBar(); this.updateQueued = false; }); } updateStatusBar() { const statusPanels = this.getValidPanels(); const validStatusBarPanelsProvided = Array.isArray(statusPanels) && statusPanels.length > 0; this.setDisplayed(validStatusBarPanelsProvided); const existingStatusPanelsToReuse = /* @__PURE__ */ new Map; if (validStatusBarPanelsProvided) { for (const statusPanelConfig of statusPanels) { const key = statusPanelConfig.key ?? statusPanelConfig.statusPanel; const existingStatusPanel = this.statusBarSvc.getStatusPanel(key); if (existingStatusPanel?.refresh) { const newParams = _addGridCommonParams(this.gos, { ...statusPanelConfig.statusPanelParams ?? {}, key }); const hasRefreshed = existingStatusPanel.refresh(newParams); if (hasRefreshed) { existingStatusPanelsToReuse.set(key, existingStatusPanel); delete this.compDestroyFunctions[key]; _removeFromParent(existingStatusPanel.getGui()); } } } } this.resetStatusBar(); if (validStatusBarPanelsProvided) { this.processStatusPanels(existingStatusPanelsToReuse); } } resetStatusBar() { _clearElement(this.eStatusBarLeft); _clearElement(this.eStatusBarCenter); _clearElement(this.eStatusBarRight); this.destroyComponents(); this.statusBarSvc.unregisterAllComponents(); } destroy() { this.destroyComponents(); super.destroy(); } destroyComponents() { for (const func of Object.values(this.compDestroyFunctions)) { func(); } this.compDestroyFunctions = {}; } createAndRenderComponents(statusBarComponents, ePanelComponent, existingStatusPanelsToReuse) { const componentDetails = []; for (const componentConfig of statusBarComponents) { const key = componentConfig.key || componentConfig.statusPanel; const existingStatusPanel = existingStatusPanelsToReuse.get(key); let promise; if (existingStatusPanel) { promise = AgPromise.resolve(existingStatusPanel); } else { const compDetails = getStatusPanelCompDetails(this.userCompFactory, componentConfig, _addGridCommonParams(this.gos, { key })); if (compDetails == null) { continue; } promise = compDetails.newAgStackInstance(); } componentDetails.push({ key, promise }); } return AgPromise.all(componentDetails.map((details) => details.promise)).then(() => { for (const componentDetail of componentDetails) { componentDetail.promise.then((component) => { const destroyFunc = () => { this.destroyBean(component); }; if (this.isAlive()) { this.statusBarSvc.registerStatusPanel(componentDetail.key, component); ePanelComponent.appendChild(component.getGui()); this.compDestroyFunctions[componentDetail.key] = destroyFunc; } else { destroyFunc(); } }); } }); } }; var AgStatusBarSelector = { selector: "AG-STATUS-BAR", component: AgStatusBar }; var AgNameValueElement = { tag: "div", cls: "ag-status-name-value", children: [ { tag: "span", ref: "eLabel" }, ": ", { tag: "span", ref: "eValue", cls: "ag-status-name-value-value" } ] }; var MIN_SAFE_BIGINT = BigInt(Number.MIN_SAFE_INTEGER); var MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER); var AgNameValue = class extends Component { constructor() { super(AgNameValueElement); this.eLabel = RefPlaceholder; this.eValue = RefPlaceholder; } setLabel(key, defaultValue) { this.setDisplayed(false); this.eLabel.textContent = this.getLocaleTextFunc()(key, defaultValue); } setValue(value, totalRows) { let numericValue = null; let bigintValue; if (typeof value === "bigint") { bigintValue = value; if (value >= MIN_SAFE_BIGINT && value <= MAX_SAFE_BIGINT) { numericValue = Number(value); } } else { numericValue = value; } this.eValue.textContent = this.valueFormatter(_addGridCommonParams(this.gos, { value: numericValue, bigintValue, totalRows, key: this.key })); } }; var AgNameValueSelector = { selector: "AG-NAME-VALUE", component: AgNameValue }; var _getFilteredRowCount = (rowModel) => { let filteredRowCount = 0; rowModel.forEachNodeAfterFilter((node) => { if (node.data) { filteredRowCount++; } }); return filteredRowCount; }; var _getTotalRowCount = (rowModel) => { let totalRowCount = 0; rowModel.forEachNode((node) => { if (node.data) { totalRowCount++; } }); return totalRowCount; }; function _formatNumberTwoDecimalPlacesAndCommas(value, getLocaleTextFunc) { if (typeof value !== "number") { return ""; } return _formatNumberCommas(Math.round(value * 100) / 100, getLocaleTextFunc); } var AggregationCompElement = { tag: "div", cls: "ag-status-panel ag-status-panel-aggregations", children: [ { tag: "ag-name-value", ref: "avgAggregationComp" }, { tag: "ag-name-value", ref: "countAggregationComp" }, { tag: "ag-name-value", ref: "minAggregationComp" }, { tag: "ag-name-value", ref: "maxAggregationComp" }, { tag: "ag-name-value", ref: "sumAggregationComp" } ] }; var AggregationComp = class extends Component { constructor() { super(AggregationCompElement, [AgNameValueSelector]); this.sumAggregationComp = RefPlaceholder; this.countAggregationComp = RefPlaceholder; this.minAggregationComp = RefPlaceholder; this.maxAggregationComp = RefPlaceholder; this.avgAggregationComp = RefPlaceholder; } postConstruct() { this.avgAggregationComp.setLabel("avg", "Average"); this.countAggregationComp.setLabel("count", "Count"); this.minAggregationComp.setLabel("min", "Min"); this.maxAggregationComp.setLabel("max", "Max"); this.sumAggregationComp.setLabel("sum", "Sum"); this.addManagedEventListeners({ cellSelectionChanged: this.onCellSelectionChanged.bind(this), modelUpdated: this.onCellSelectionChanged.bind(this) }); } init(params) { this.refresh(params); } refresh(params) { this.params = params; const valueFormatter = params.valueFormatter ?? ((params2) => { const { value, bigintValue } = params2; if (bigintValue != null) { return bigintValue.toString(); } return _formatNumberTwoDecimalPlacesAndCommas(value, this.getLocaleTextFunc.bind(this)); }); const aggFuncNames = ["avg", "count", "min", "max", "sum"]; for (const key of aggFuncNames) { const comp = this.getAllowedAggregationValueComponent(key); if (comp) { comp.key = key; comp.valueFormatter = valueFormatter.bind(this); } } this.onCellSelectionChanged(); return true; } setAggregationComponentValue(aggFuncName, value, visible) { const statusBarValueComponent = this.getAllowedAggregationValueComponent(aggFuncName); const totalRow = _getTotalRowCount(this.beans.rowModel); if (_exists(statusBarValueComponent) && statusBarValueComponent) { statusBarValueComponent.setValue(value, totalRow); statusBarValueComponent.setDisplayed(visible); } else { this.getAggregationValueComponent(aggFuncName)?.setDisplayed(false); } } getAllowedAggregationValueComponent(aggFuncName) { const { aggFuncs } = this.params; if (!aggFuncs || aggFuncs.includes(aggFuncName)) { return this.getAggregationValueComponent(aggFuncName); } return null; } getAggregationValueComponent(aggFuncName) { const refComponentName = `${aggFuncName}AggregationComp`; return this[refComponentName]; } onCellSelectionChanged() { const beans = this.beans; const { rangeSvc, valueSvc } = beans; const cellRanges = rangeSvc?.getCellRanges(); let sum = 0; let sumBigint = 0n; let hasBigInt = false; let seenNonInteger = false; let count = 0; let numericCount = 0; let min = null; let max = null; let minBigint = null; let maxBigint = null; const addValue = (value) => { if (typeof value === "number") { sum += value; if (min === null || value < min) { min = value; } if (max === null || value > max) { max = value; } if (!Number.isInteger(value) || !Number.isSafeInteger(value)) { seenNonInteger = true; } else { const bigintValue = BigInt(value); sumBigint += bigintValue; if (minBigint === null || bigintValue < minBigint) { minBigint = bigintValue; } if (maxBigint === null || bigintValue > maxBigint) { maxBigint = bigintValue; } } } else { hasBigInt = true; sumBigint += value; if (minBigint === null || value < minBigint) { minBigint = value; } if (maxBigint === null || value > maxBigint) { maxBigint = value; } const numberValue = Number(value); sum += numberValue; if (min === null || numberValue < min) { min = numberValue; } if (max === null || numberValue > max) { max = numberValue; } } numericCount++; }; const cellsSoFar = {}; if (cellRanges?.length && rangeSvc) { for (let i = 0;i < cellRanges.length; i++) { const cellRange = cellRanges[i]; let currentRow = rangeSvc.getRangeStartRow(cellRange); const lastRow = rangeSvc.getRangeEndRow(cellRange); while (true) { const finishedAllRows = _missing(currentRow) || !currentRow || _isRowBefore(lastRow, currentRow); if (finishedAllRows || !currentRow || !cellRange.columns) { break; } cellRange.columns.forEach((col) => { if (currentRow === null) { return; } const cellId = _createCellId({ rowPinned: currentRow.rowPinned, column: col, rowIndex: currentRow.rowIndex }); if (cellsSoFar[cellId]) { return; } cellsSoFar[cellId] = true; const rowNode = _getRowNode(beans, currentRow); if (_missing(rowNode)) { return; } let value = valueSvc.getValue(col, rowNode, "data"); if (_missing(value) || value === "") { return; } count++; if (typeof value === "object" && "value" in value) { value = value.value; if (value === "") { return; } } if (typeof value === "string") { const trimmedValue = value.trim(); if (trimmedValue === "") { return; } const asNumber = Number(trimmedValue); if (!Number.isFinite(asNumber)) { return; } if (sum + asNumber >= Number.MAX_SAFE_INTEGER || sum + asNumber <= Number.MIN_SAFE_INTEGER || asNumber >= Number.MAX_SAFE_INTEGER || asNumber <= Number.MIN_SAFE_INTEGER) { value = _parseBigIntOrNull(trimmedValue); if (value === null) { value = asNumber; } } else { value = asNumber; } } if (typeof value === "number" && !isNaN(value) || typeof value === "bigint") { addValue(value); } }); currentRow = _getRowBelow(beans, currentRow); } } } const moreThanOneValue = count > 1; const moreThanOneNum = numericCount > 1; const useBigintAggregation = hasBigInt && !seenNonInteger; let avg; if (useBigintAggregation) { avg = sumBigint / BigInt(numericCount); } else { avg = sum / numericCount; } const sumValue = moreThanOneNum ? useBigintAggregation ? sumBigint : sum : null; const minValue = moreThanOneNum ? useBigintAggregation ? minBigint : min : null; const maxValue = moreThanOneNum ? useBigintAggregation ? maxBigint : max : null; const avgValue = moreThanOneNum ? avg : null; const showAvg = moreThanOneNum; this.setAggregationComponentValue("count", count, moreThanOneValue); this.setAggregationComponentValue("sum", sumValue, moreThanOneNum); this.setAggregationComponentValue("min", minValue, moreThanOneNum); this.setAggregationComponentValue("max", maxValue, moreThanOneNum); this.setAggregationComponentValue("avg", avgValue, showAvg); } }; var FilteredRowsComp = class extends AgNameValue { postConstruct() { this.setLabel("filteredRows", "Filtered"); this.addCss("ag-status-panel"); this.addCss("ag-status-panel-filtered-row-count"); this.setDisplayed(true); const listener = this.onDataChanged.bind(this); this.addManagedEventListeners({ modelUpdated: listener }); } onDataChanged() { const { rowModel } = this.beans; const totalRowCountValue = _getTotalRowCount(rowModel); const filteredRowCountValue = _getFilteredRowCount(rowModel); this.setValue(filteredRowCountValue, totalRowCountValue); this.setDisplayed(totalRowCountValue !== filteredRowCountValue); } init(params) { this.refresh(params); this.onDataChanged(); } updateValueFormatter(valueFormatter) { this.valueFormatter = valueFormatter ?? (({ value }) => _formatNumberCommas(value, this.getLocaleTextFunc.bind(this))); } refresh(params) { const { key, valueFormatter } = params; this.key = key; this.updateValueFormatter(valueFormatter); return true; } }; var SelectedRowsComp = class extends AgNameValue { postConstruct() { this.setLabel("selectedRows", "Selected"); this.addCss("ag-status-panel"); this.addCss("ag-status-panel-selected-row-count"); const eventListener = this.onRowSelectionChanged.bind(this); this.addManagedEventListeners({ modelUpdated: eventListener, selectionChanged: eventListener }); } onRowSelectionChanged() { const { selectionSvc, rowModel } = this.beans; const selectedRowCount = selectionSvc?.getSelectionCount() ?? 0; const totalRowCount = _getTotalRowCount(rowModel); this.setValue(selectedRowCount, totalRowCount); if (selectedRowCount < 0) { this.setDisplayed(true); return; } this.setDisplayed(selectedRowCount > 0); } init(params) { this.refresh(params); this.onRowSelectionChanged(); } updateValueFormatter(valueFormatter) { this.valueFormatter = valueFormatter ?? (({ value }) => { if (value == null || value >= 0) { return _formatNumberCommas(value, this.getLocaleTextFunc.bind(this)); } return this.getLocaleTextFunc()("statusBarLastRowUnknown", "?"); }); } refresh(params) { const { key, valueFormatter } = params; this.key = key; this.updateValueFormatter(valueFormatter); return true; } }; var TotalAndFilteredRowsComp = class extends AgNameValue { postConstruct() { this.setLabel("totalAndFilteredRows", "Rows"); this.addCss("ag-status-panel"); this.addCss("ag-status-panel-total-and-filtered-row-count"); this.setDisplayed(true); this.addManagedEventListeners({ modelUpdated: this.onDataChanged.bind(this) }); } onDataChanged() { const { rowModel } = this.beans; const rowCount = _getFilteredRowCount(rowModel); const totalRowCount = _getTotalRowCount(rowModel); this.setValue(rowCount, totalRowCount); } init(params) { this.refresh(params); this.onDataChanged(); } updateValueFormatter(valueFormatter) { this.valueFormatter = valueFormatter ?? (({ value, totalRows }) => { const getLocaleTextFunc = this.getLocaleTextFunc.bind(this); const rowCount = _formatNumberCommas(value, getLocaleTextFunc); const totalRowCount = _formatNumberCommas(totalRows ?? value, getLocaleTextFunc); if (value === totalRows) { return rowCount; } const localeTextFunc = getLocaleTextFunc(); return `${rowCount} ${localeTextFunc("of", "of")} ${totalRowCount}`; }); } refresh(params) { const { key, valueFormatter } = params; this.key = key; this.updateValueFormatter(valueFormatter); return true; } }; var TotalRowsComp = class extends AgNameValue { postConstruct() { this.setLabel("totalRows", "Total Rows"); this.addCss("ag-status-panel"); this.addCss("ag-status-panel-total-row-count"); this.setDisplayed(true); this.addManagedEventListeners({ modelUpdated: this.onDataChanged.bind(this) }); } onDataChanged() { const totalRow = _getTotalRowCount(this.beans.rowModel); this.setValue(totalRow, totalRow); } init(params) { this.refresh(params); this.onDataChanged(); } updateValueFormatter(valueFormatter) { this.valueFormatter = valueFormatter ?? (({ value }) => _formatNumberCommas(value, this.getLocaleTextFunc.bind(this))); } refresh(params) { const { key, valueFormatter } = params; this.key = key; this.updateValueFormatter(valueFormatter); return true; } }; function getStatusPanel(beans, key) { const comp = beans.statusBarSvc?.getStatusPanel(key); return _unwrapUserComp(comp); } var StatusBarService = class extends BeanStub { constructor() { super(); this.beanName = "statusBarSvc"; this.comps = /* @__PURE__ */ new Map; } registerStatusPanel(key, component) { this.comps.set(key, component); } unregisterStatusPanel(key) { this.comps.delete(key); } unregisterAllComponents() { this.comps.clear(); } getStatusPanel(key) { return this.comps.get(key); } destroy() { this.unregisterAllComponents(); super.destroy(); } }; var StatusBarModule = { moduleName: "StatusBar", version: VERSION2, beans: [StatusBarService], userComponents: { agAggregationComponent: AggregationComp, agTotalRowCountComponent: TotalRowsComp, agFilteredRowCountComponent: FilteredRowsComp, agTotalAndFilteredRowCountComponent: TotalAndFilteredRowsComp, agSelectedRowCountComponent: SelectedRowsComp }, selectors: [AgStatusBarSelector], apiFunctions: { getStatusPanel }, dependsOn: [EnterpriseCoreModule, KeyboardNavigationModule] }; function assertNotExcelMultiSheet(beans) { if (beans.excelCreator?.getFactoryMode() === "MULTI_SHEET") { _warn(161); return false; } return true; } function getDataAsExcel(beans, params) { if (assertNotExcelMultiSheet(beans)) { return beans.excelCreator?.getDataAsExcel(params); } return; } function exportDataAsExcel(beans, params) { if (assertNotExcelMultiSheet(beans)) { beans.excelCreator?.exportDataAsExcel(params); } } function getSheetDataForExcel(beans, params) { beans.excelCreator?.setFactoryMode("MULTI_SHEET"); return beans.excelCreator?.getSheetDataForExcel(params); } function getMultipleSheetsAsExcel2(beans, params) { return beans.excelCreator?.getMultipleSheetsAsExcel(params); } function exportMultipleSheetsAsExcel2(beans, params) { beans.excelCreator?.exportMultipleSheetsAsExcel(params); } var ExcelExportModule = { moduleName: "ExcelExport", version: VERSION2, beans: [ExcelCreator], apiFunctions: { getDataAsExcel, exportDataAsExcel, getSheetDataForExcel, getMultipleSheetsAsExcel: getMultipleSheetsAsExcel2, exportMultipleSheetsAsExcel: exportMultipleSheetsAsExcel2 }, dependsOn: [SharedExportModule, EnterpriseCoreModule] }; function getMultiFilterDefs(params) { const { filters } = params; return filters && filters.length > 0 ? filters : [{ filter: "agTextColumnFilter" }, { filter: "agSetColumnFilter" }]; } function forEachReverse(list, action) { if (list == null) { return; } for (let i = list.length - 1;i >= 0; i--) { action(list[i], i); } } function getFilterTitle(filter, filterDef) { if (filterDef.title != null) { return filterDef.title; } return filter instanceof ProvidedFilter ? filter.getFilterTitle() : "Filter"; } function getUpdatedMultiFilterModel(existingModel, numFilters, newModel, index) { const filterModels = []; const existingFilterModels = existingModel?.filterModels; for (let i = 0;i < numFilters; i++) { filterModels[i] = (i === index ? newModel : existingFilterModels?.[i]) ?? null; } return filterModels.every((childModel) => childModel == null) ? null : { filterType: "multi", filterModels }; } function getFilterModelForIndex(model, index) { return model?.filterModels?.[index] ?? null; } function updateGetValue(beans, column, filterDef, existingGetValue) { const filterValueGetter = filterDef.filterValueGetter; return filterValueGetter ? beans.colFilter.createGetValue(column, filterValueGetter) : existingGetValue; } var BaseMultiFilter = class extends TabGuardComp { constructor() { super({ tag: "div", cls: "ag-multi-filter ag-menu-list-compact" }); this.filterDefs = []; this.guiDestroyFuncs = []; this.filterGuis = []; this.lastActivatedMenuItem = null; } postConstruct() { this.initialiseTabGuard({ onFocusIn: (e) => this.onFocusIn(e) }); } refreshGui(container) { if (container === this.lastOpenedInContainer) { return AgPromise.resolve(); } this.tabGuardFeature.removeAllChildrenExceptTabGuards(); this.destroyChildren(); return AgPromise.all(this.getFilterWrappers().map((wrapper, index) => { if (!wrapper) { return AgPromise.resolve(null); } const filter = this.getFilterFromWrapper(wrapper); const comp = this.getCompFromWrapper(wrapper); const filterDef = this.filterDefs[index]; const filterTitle = getFilterTitle(filter, filterDef); let filterGuiPromise; if (filterDef.display === "subMenu" && container !== "toolPanel") { filterGuiPromise = this.insertFilterMenu(comp, filter, filterTitle).then((menuItem) => menuItem.getGui()); } else if (filterDef.display === "subMenu" || filterDef.display === "accordion") { const group = this.insertFilterGroup(filter, comp, filterTitle); filterGuiPromise = AgPromise.resolve(group.getGui()); } else { filterGuiPromise = AgPromise.resolve(comp.getGui()); } return filterGuiPromise; })).then((filterGuis) => { filterGuis.forEach((filterGui, index) => { if (!filterGui) { return; } if (index > 0) { this.appendChild(_createElement({ tag: "div", cls: "ag-filter-separator" })); } this.appendChild(filterGui); }); this.filterGuis = filterGuis; this.lastOpenedInContainer = container; }); } destroyChildren() { for (const func of this.guiDestroyFuncs) { func(); } this.guiDestroyFuncs.length = 0; this.filterGuis.length = 0; } insertFilterMenu(comp, filter, name) { const eGui = comp.getGui(); _setAriaRole(eGui, "dialog"); const menuItem = this.createBean(new MenuItemComponent); const childComponent = { getGui: () => comp.getGui(), afterGuiAttached: (params) => { comp.afterGuiAttached?.(params); if (comp !== filter) { filter.afterGuiAttached?.(params); } } }; return menuItem.init({ menuItemDef: { name, subMenu: [], subMenuRole: "dialog", cssClasses: ["ag-multi-filter-menu-item"], menuItem: MenuItemRenderer, menuItemParams: { cssClassPrefix: "ag-compact-menu-option", isCompact: true } }, level: 0, isAnotherSubMenuOpen: () => false, childComponent, contextParams: { column: null, node: null, value: null } }).then(() => { menuItem.setParentComponent(this); this.guiDestroyFuncs.push(() => this.destroyBean(menuItem)); this.addManagedListeners(menuItem, { menuItemActivated: (event) => { if (this.lastActivatedMenuItem && this.lastActivatedMenuItem !== event.menuItem) { this.lastActivatedMenuItem.deactivate(); } this.lastActivatedMenuItem = event.menuItem; } }); const menuItemGui = menuItem.getGui(); menuItem.addManagedElementListeners(menuItemGui, { keydown: (e) => { const { key } = e; switch (key) { case KeyCode.UP: case KeyCode.RIGHT: case KeyCode.DOWN: case KeyCode.LEFT: e.preventDefault(); if (key === KeyCode.RIGHT) { menuItem.openSubMenu(true); } break; } }, focusin: () => menuItem.activate(), focusout: () => { if (!menuItem.isSubMenuOpen() && !menuItem.isSubMenuOpening()) { menuItem.deactivate(); } } }); return menuItem; }); } insertFilterGroup(filter, comp, title) { const group = this.createBean(new AgGroupComponent({ title, cssIdentifier: "multi-filter" })); this.guiDestroyFuncs.push(() => this.destroyBean(group)); group.addItem(comp.getGui()); group.toggleGroupExpand(false); if (filter.afterGuiAttached) { group.addManagedListeners(group, { expanded: () => filter.afterGuiAttached({ container: this.lastOpenedInContainer, suppressFocus: true, hidePopup: this.hidePopup }) }); } return group; } afterGuiAttached(params) { let refreshPromise; if (params) { this.hidePopup = params.hidePopup; refreshPromise = this.refreshGui(params.container); } else { this.hidePopup = undefined; refreshPromise = AgPromise.resolve(); } const suppressFocus = params?.suppressFocus; refreshPromise.then(() => { const { filterDefs, filterGuis, beans } = this; const wrappers = this.getFilterWrappers(); let hasFocused = !!suppressFocus; if (filterDefs) { forEachReverse(filterDefs, (filterDef, index) => { const isFirst = index === 0; const notInlineDisplayType = filterDef.display && filterDef.display !== "inline"; const suppressFocusForFilter = suppressFocus || !isFirst || notInlineDisplayType; const afterGuiAttachedParams = { ...params ?? {}, suppressFocus: suppressFocusForFilter }; const wrapper = wrappers[index]; const filter = wrapper ? this.getFilterFromWrapper(wrapper) : undefined; if (wrapper) { const comp = this.getCompFromWrapper(wrapper); if (comp !== filter) { comp.afterGuiAttached(afterGuiAttachedParams); } } if (filter) { this.executeFunctionIfExistsOnFilter(filter, "afterGuiAttached", afterGuiAttachedParams); if (isFirst && !suppressFocusForFilter) { hasFocused = true; } } if (!suppressFocus && isFirst && notInlineDisplayType) { const filterGui = filterGuis[index]; if (filterGui) { if (!_focusInto(filterGui)) { filterGui.focus({ preventScroll: true }); } hasFocused = true; } } }); } const activeEl = _getActiveDomElement(beans); if (!hasFocused && (_isNothingFocused(beans) || this.getGui().contains(activeEl))) { this.forceFocusOutOfContainer(true); } }); } afterGuiDetached() { this.executeFunctionIfExists("afterGuiDetached"); } onAnyFilterChanged() { this.executeFunctionIfExists("onAnyFilterChanged", (wrapper) => this.executeOnWrapper(wrapper, "onAnyFilterChanged")); } onNewRowsLoaded() { this.executeFunctionIfExists("onNewRowsLoaded", (wrapper) => this.executeOnWrapper(wrapper, "onNewRowsLoaded")); } destroy() { this.destroyChildren(); this.hidePopup = undefined; super.destroy(); } executeOnWrapper(_wrapper, _name) {} executeFunctionIfExists(name, executeOnHandler) { forEachReverse(this.getFilterWrappers(), (wrapper) => { if (wrapper) { executeOnHandler?.(wrapper); this.executeFunctionIfExistsOnFilter(this.getFilterFromWrapper(wrapper), name); } }); } executeFunctionIfExistsOnFilter(filter, name, ...params) { const func = filter[name]; if (typeof func === "function") { func.apply(filter, params); } } onFocusIn(e) { const lastActivatedMenuItem = this.lastActivatedMenuItem; if (lastActivatedMenuItem != null && !lastActivatedMenuItem.getGui().contains(e.target)) { lastActivatedMenuItem.deactivate(); this.lastActivatedMenuItem = null; } } }; var MultiFilter = class extends BaseMultiFilter { constructor() { super(...arguments); this.filterType = "multi"; this.wrappers = []; this.activeFilterIndices = []; this.afterFiltersReadyFuncs = []; } init(params) { this.params = params; this.filterDefs = getMultiFilterDefs(params); const initialModel = _getFilterModel(this.beans.colFilter.model, params.column.getColId()); const { filterChangedCallback } = params; this.filterChangedCallback = filterChangedCallback; const filterPromises = this.filterDefs.map((filterDef, index) => this.createFilter(filterDef, index, initialModel)); return new AgPromise((resolve) => { AgPromise.all(filterPromises).then((wrappers) => { this.wrappers = wrappers; this.refreshGui("columnMenu").then(() => { resolve(); }); }); }).then(() => { for (const f of this.afterFiltersReadyFuncs) { f(); } this.afterFiltersReadyFuncs.length = 0; }); } refresh(params) { this.params = params; return true; } isFilterActive() { return this.wrappers.some((wrapper) => { if (!wrapper) { return false; } const { filter, handler, model } = wrapper; if (handler) { return model != null; } return filter.isFilterActive(); }); } getLastActiveFilterIndex() { const activeFilterIndices = this.activeFilterIndices; return activeFilterIndices.length > 0 ? activeFilterIndices[activeFilterIndices.length - 1] : null; } doesFilterPass(params, indexToSkip) { return this.wrappers.every((wrapper, index) => { if (!wrapper || indexToSkip != null && index === indexToSkip) { return true; } const { handler, filter, model } = wrapper; if (handler) { return model == null || handler.doesFilterPass({ ...params, model, handlerParams: wrapper.handlerParams }); } return !filter.isFilterActive() || filter.doesFilterPass(params); }); } getModelFromUi() { const model = { filterType: this.filterType, filterModels: this.wrappers.map((wrapper) => { if (!wrapper) { return null; } const providedFilter = wrapper.filter; if (typeof providedFilter.getModelFromUi === "function") { return providedFilter.getModelFromUi(); } return null; }) }; return model; } getModel() { if (!this.isFilterActive()) { return null; } const model = { filterType: this.filterType, filterModels: this.wrappers.map((wrapper) => { if (!wrapper) { return null; } const { filter, handler, model: model2 } = wrapper; if (handler) { return model2; } return filter.isFilterActive() ? filter.getModel() : null; }) }; return model; } setModel(model) { const setFilterModel2 = (filter, filterModel) => { return new AgPromise((resolve) => { const promise = filter.setModel(filterModel); if (promise) { promise.then(resolve); } else { resolve(); } }); }; const promises = []; this.wrappers.forEach((wrapper, index) => { if (!wrapper) { return; } const modelForFilter = getFilterModelForIndex(model, index); const { filter, filterParams, handler, handlerParams, state } = wrapper; if (handler) { const newState = { model: modelForFilter, state: state?.state }; wrapper.state = newState; wrapper.model = modelForFilter; promises.push(_refreshHandlerAndUi(() => AgPromise.resolve({ filter, filterParams }), handler, handlerParams, modelForFilter, newState, "api").then(() => { this.updateActiveListForHandler(index, wrapper.model); })); } else { promises.push(setFilterModel2(filter, modelForFilter).then(() => { this.updateActiveListForFilter(index, filter); })); } }); return AgPromise.all(promises).then(() => {}); } applyModel(source = "api") { let result = false; for (const wrapper of this.wrappers) { if (wrapper) { const filter = wrapper.filter; if (filter instanceof ProvidedFilter) { result = filter.applyModel(source) || result; } } } return result; } getChildFilterInstance(index) { return this.wrappers[index]?.filter; } getNumChildFilters() { return this.wrappers.length; } destroy() { for (const wrapper of this.wrappers) { this.destroyBean(wrapper?.filter); this.destroyBean(wrapper?.handler); } this.wrappers.length = 0; super.destroy(); } getFilterWrappers() { return this.wrappers; } getFilterFromWrapper(wrapper) { return wrapper.filter; } getCompFromWrapper(wrapper) { return wrapper.comp; } executeOnWrapper(wrapper, name) { wrapper.handler?.[name]?.(); } createFilter(filterDef, index, initialModel) { const column = this.params.column; let initialModelForFilter = null; let createWrapperComp; const beans = this.beans; const onModelChange = (model, additionalEventAttributes) => { const wrapper = this.wrappers[index]; if (!wrapper) { return; } const newState = { model, state: wrapper.state?.state }; wrapper.state = newState; wrapper.model = model; _refreshHandlerAndUi(() => AgPromise.resolve({ filter: wrapper.filter, filterParams: wrapper.filterParams }), wrapper.handler, wrapper.handlerParams, model, newState, "ui").then(() => { this.onHandlerModelChanged(index, wrapper.model, additionalEventAttributes); }); }; const { compDetails, handler, handlerParams: originalHandlerParams, createFilterUi } = beans.colFilter.createFilterInstance(column, filterDef, "agTextColumnFilter", (defaultParams, isHandler) => { const updatedParams = { ...defaultParams, filterChangedCallback: isHandler ? () => {} : (additionalEventAttributes) => { this.executeWhenAllFiltersReady(() => this.onFilterModelChanged(index, additionalEventAttributes)); }, doesRowPassOtherFilter: (node) => defaultParams.doesRowPassOtherFilter(node) && this.doesFilterPass({ node, data: node.data }, index), getValue: updateGetValue(beans, column, filterDef, defaultParams.getValue) }; if (isHandler) { initialModelForFilter = getFilterModelForIndex(initialModel, index); createWrapperComp = this.updateDisplayParams(updatedParams, index, initialModelForFilter, () => compDetails, () => handler, onModelChange); } return updatedParams; }); if (!createFilterUi) { return AgPromise.resolve(null); } let handlerParams; if (handler) { const { doesRowPassOtherFilter, getValue } = originalHandlerParams; handlerParams = { ...originalHandlerParams, onModelChange, doesRowPassOtherFilter: (node) => doesRowPassOtherFilter(node) && this.doesFilterPass({ node, data: node.data }, index), getValue: updateGetValue(beans, column, filterDef, getValue) }; handler.init?.({ ...handlerParams, model: initialModelForFilter, source: "init" }); } return createFilterUi().then((filter) => { if (!handler) { return { filter, comp: filter }; } const filterParams = compDetails?.params; const comp = createWrapperComp(filter); return { filter, comp, filterParams, handler, handlerParams, model: initialModelForFilter }; }); } updateDisplayParams(displayParams, index, initialModelForFilter, getCompDetails, getHandler, onModelChange) { const column = this.params.column; const eventSvc = new LocalEventService; displayParams.model = initialModelForFilter; displayParams.state = { model: initialModelForFilter }; displayParams.onModelChange = onModelChange; displayParams.getHandler = getHandler; const updateState = (wrapper, state) => { wrapper.state = state; eventSvc.dispatchEvent({ type: "filterStateChanged", column, state }); }; displayParams.onStateChange = (state) => { const wrapper = this.wrappers[index]; if (!wrapper) { return; } updateState(wrapper, state); _refreshFilterUi(wrapper.filter, wrapper.filterParams, wrapper.model ?? null, state, "ui"); }; const updateModel = (_column, action, additionalEventAttributes) => { const wrapper = this.wrappers[index]; if (!wrapper) { return; } const getModel = () => wrapper?.model ?? null; _updateFilterModel({ action, filterParams: wrapper.filterParams, getFilterUi: () => { const promise = AgPromise.resolve(wrapper.filter); return { created: true, filterParams: wrapper.filterParams, compDetails: getCompDetails(), create: () => promise, promise }; }, getModel, getState: () => wrapper?.state ?? { model: getModel() }, updateState: (state) => updateState(wrapper, state), updateModel: (newModel) => wrapper.filterParams?.onModelChange(newModel, additionalEventAttributes), processModelToApply: wrapper.handler?.processModelToApply?.bind(wrapper.handler) }); }; displayParams.onAction = (action, additionalEventAttributes, event) => { updateModel(column, action, additionalEventAttributes); eventSvc.dispatchEvent({ type: "filterAction", column, action, event }); }; return (filter) => { const filterParams = getCompDetails()?.params; return this.createManagedBean(new FilterWrapperComp(column, { comp: filter, params: filterParams, isHandler: true }, eventSvc, updateModel, false)); }; } executeWhenAllFiltersReady(action) { if ((this.wrappers?.length ?? 0) > 0) { action(); } else { this.afterFiltersReadyFuncs.push(action); } } updateActiveListForFilter(index, filter) { this.updateActiveList(index, () => filter?.isFilterActive()); } updateActiveListForHandler(index, model) { this.updateActiveList(index, () => model != null); } updateActiveList(index, isActive) { const activeFilterIndices = this.activeFilterIndices; _removeFromArray(this.activeFilterIndices, index); if (isActive()) { activeFilterIndices.push(index); } } onFilterModelChanged(index, additionalEventAttributes) { this.updateActiveListForFilter(index, this.wrappers[index]?.filter); this.filterChanged(index, additionalEventAttributes); } onHandlerModelChanged(index, model, additionalEventAttributes) { this.updateActiveListForHandler(index, model); this.filterChanged(index, additionalEventAttributes); } filterChanged(index, additionalEventAttributes) { this.filterChangedCallback(additionalEventAttributes); this.wrappers.forEach((wrapper, childIndex) => { if (index === childIndex || !wrapper) { return; } const { filter, handler } = wrapper; handler?.onAnyFilterChanged?.(); if (typeof filter.onAnyFilterChanged === "function") { filter.onAnyFilterChanged(); } }); } getModelAsString(model) { if (!model?.filterModels?.length) { return ""; } const lastActiveIndex = this.getLastActiveFilterIndex() ?? 0; const activeFilter = this.wrappers[lastActiveIndex]?.filter; return activeFilter?.getModelAsString?.(model.filterModels[lastActiveIndex]) ?? ""; } }; var MultiFilterHandler = class extends BeanStub { constructor() { super(...arguments); this.filterType = "multi"; this.handlerWrappers = []; this.activeFilterIndices = []; this.filterDefs = []; } init(params) { this.params = params; const filterDefs = getMultiFilterDefs(params.filterParams); this.filterDefs = filterDefs; filterDefs.forEach((def, index) => { const wrapper = this.beans.colFilter.createHandler(params.column, def, "agTextColumnFilter"); this.handlerWrappers.push(wrapper); if (!wrapper) { _warn(278, { colId: params.column.getColId() }); return; } const { handler, handlerParams } = wrapper; handler.init?.({ ...this.updateHandlerParams(handlerParams, index, true), model: getFilterModelForIndex(params.model, index), source: "init" }); }); this.resetActiveList(params.model); } refresh(params) { this.params = params; const { model, source, filterParams } = params; const filters = filterParams?.filters; this.handlerWrappers.forEach((wrapper, index) => { if (wrapper) { const updatedParams = this.updateHandlerParams(params, index, false, filters?.[index].filterParams); wrapper.handlerParams = updatedParams; wrapper.handler.refresh?.({ ...updatedParams, model: getFilterModelForIndex(model, index), source }); } }); if (params.source !== "floating" && params.source !== "ui") { this.resetActiveList(params.model); } if (params.additionalEventAttributes?.fromButtons) { this.onAnyFilterChanged(); } } updateHandlerParams(params, index, isInit, providedFilterParams) { const { onModelChange, doesRowPassOtherFilter, getValue } = params; const handlerParams = { ...params, onModelChange: (newModel, additionalEventAttributes) => onModelChange(getUpdatedMultiFilterModel(this.params.model, this.handlerWrappers.length, newModel, index), additionalEventAttributes), doesRowPassOtherFilter: (node) => doesRowPassOtherFilter(node) && this.doesFilterPass({ node, data: node.data, model: this.params.model, handlerParams }, index), getValue: updateGetValue(this.beans, params.column, this.filterDefs[index], getValue), filterParams: this.updateFilterParams(params, isInit, providedFilterParams) }; return handlerParams; } updateFilterParams(params, isInit, providedFilterParams) { const originalFilterParams = params.filterParams; if (providedFilterParams?.buttons && isInit) { _warn(292, { colId: params.column.getColId() }); } const filterParamsForFilter = providedFilterParams ? { ...originalFilterParams, ...providedFilterParams } : originalFilterParams; if (!filterParamsForFilter.buttons) { return filterParamsForFilter; } if (providedFilterParams) { delete filterParamsForFilter.buttons; return filterParamsForFilter; } const { buttons: _, ...filterParamsForFilterWithoutButtons } = filterParamsForFilter; return filterParamsForFilterWithoutButtons; } doesFilterPass(params, indexToSkip) { const filterModels = params.model?.filterModels; if (filterModels == null) { return true; } return this.handlerWrappers.every((wrapper, index) => { const model = filterModels[index]; if (model == null || indexToSkip != null && index === indexToSkip) { return true; } const handler = wrapper?.handler; return !handler || handler.doesFilterPass({ ...params, model, handlerParams: wrapper.handlerParams }); }); } resetActiveList(model) { this.activeFilterIndices = []; const filterModels = model?.filterModels; if (filterModels == null) { return; } for (let i = 0;i < this.handlerWrappers.length; i++) { const isActive = filterModels[i] != null; if (isActive) { this.activeFilterIndices.push(i); } } } updateActiveList(index, childModel) { const activeFilterIndices = this.activeFilterIndices; _removeFromArray(activeFilterIndices, index); if (childModel != null) { activeFilterIndices.push(index); } } getLastActiveFilterIndex() { const activeFilterIndices = this.activeFilterIndices; return activeFilterIndices.length > 0 ? activeFilterIndices[activeFilterIndices.length - 1] : null; } getModelAsString(model, source) { const isForToolPanel = source === "filterToolPanel"; const defaultOption = () => isForToolPanel ? this.getLocaleTextFunc()("filterSummaryInactive", "is (All)") : ""; if (!model?.filterModels?.length) { return defaultOption(); } const lastActiveIndex = this.getLastActiveFilterIndex() ?? 0; const activeWrapper = this.handlerWrappers[lastActiveIndex]; return activeWrapper?.handler.getModelAsString?.(model.filterModels[lastActiveIndex], source) ?? defaultOption(); } getHandler(index) { return this.handlerWrappers[index]?.handler; } onAnyFilterChanged() { forEachReverse(this.handlerWrappers, (wrapper) => wrapper?.handler?.onAnyFilterChanged?.()); } onNewRowsLoaded() { forEachReverse(this.handlerWrappers, (wrapper) => wrapper?.handler?.onNewRowsLoaded?.()); } destroy() { for (const wrapper of this.handlerWrappers) { this.destroyBean(wrapper?.handler); } this.handlerWrappers.length = 0; super.destroy(); } }; var MultiFilterService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "multiFilter"; } getParamsForDataType(existingFilterParams, existingFilterValueGetter, dataTypeDefinition, formatValue) { let filters = existingFilterParams?.filters; const beans = this.beans; if (!filters) { const simpleFilter = _getDefaultSimpleFilter(dataTypeDefinition.baseDataType); filters = [{ filter: simpleFilter }, { filter: "agSetColumnFilter" }]; } const translate = this.getLocaleTextFunc(); filters = filters.map((filterDef) => { const { filter, filterParams: existingChildFilterParams, filterValueGetter: existingChildFilterValueGetter } = filterDef; if (typeof filter !== "string") { return filterDef; } const { filterParams, filterValueGetter } = _getFilterParamsForDataType(filter, existingChildFilterParams, existingChildFilterValueGetter ?? existingFilterValueGetter, dataTypeDefinition, formatValue, beans, translate); return { ...filterDef, filterParams, filterValueGetter }; }); return { filterParams: { ...existingFilterParams, filters } }; } }; var MultiFilterUi = class extends BaseMultiFilter { constructor() { super(...arguments); this.filterType = "multi"; this.filters = []; this.filterParams = []; this.validity = []; } init(params) { this.params = params; const filterDefs = getMultiFilterDefs(params).map((filterDef) => { if (filterDef.filterParams?.buttons) { _warn(292, { colId: params.column.getColId() }); const newParams = { ...filterDef.filterParams }; delete newParams.buttons; return { ...filterDef, filterParams: newParams }; } return filterDef; }); this.filterDefs = filterDefs; this.allState = params.state; const filterPromises = this.filterDefs.map((filterDef, index) => this.createFilter(filterDef, index)); return new AgPromise((resolve) => { AgPromise.all(filterPromises).then((filters) => { this.filters = filters; this.refreshGui("columnMenu").then(() => { resolve(); }); }); }); } refresh(params) { const { model, state, source } = params; if (source === "colDef") { return false; } this.params = params; const filterParams = this.filterParams; if (state === this.allState) { return true; } this.allState = state; const newAllStateState = state.state; this.filters.forEach((filter, index) => { const modelForFilter = getFilterModelForIndex(model, index); const stateForFilter = { state: newAllStateState?.[index], model: getFilterModelForIndex(state.model, index) }; _refreshFilterUi(filter, filterParams[index], modelForFilter, stateForFilter, source); }); return true; } getLastActiveFilterIndex() { return this.getHandler().getLastActiveFilterIndex?.() ?? null; } getChildFilterInstance(index) { return this.filters[index] ?? undefined; } getNumChildFilters() { return this.filters.length; } destroy() { for (const filter of this.filters) { this.destroyBean(filter); } this.filters.length = 0; super.destroy(); } getFilterWrappers() { return this.filters; } getFilterFromWrapper(wrapper) { return wrapper; } getCompFromWrapper(wrapper) { return wrapper; } createFilter(filterDef, index) { const userCompFactory = this.beans.userCompFactory; const filterParams = this.updateParams(filterDef, this.params, index); const compDetails = _getFilterDetails(userCompFactory, filterDef, filterParams, "agTextColumnFilter"); if (!compDetails) { return AgPromise.resolve(null); } this.filterParams[index] = compDetails.params; return compDetails.newAgStackInstance(); } updateParams(filterDef, params, index) { const { doesRowPassOtherFilter, model, onModelChange, state, onStateChange, column, source, onAction, onUiChange, getValue } = params; const filterModel = getFilterModelForIndex(model, index); const filterState = state ? { model: getFilterModelForIndex(state.model, index), state: state.state?.[index] } : { model: filterModel }; const onAnyFilterChanged = () => { const handler = this.getHandler(); this.filters.forEach((filter, otherIndex) => { if (index !== otherIndex) { handler.getHandler(otherIndex)?.onAnyFilterChanged?.(); filter?.onAnyFilterChanged?.(); } }); }; const colFilter = this.beans.colFilter; return { ...colFilter.createBaseFilterParams(column), ...filterDef, doesRowPassOtherFilter: (node) => doesRowPassOtherFilter(node) && this.getHandler().doesFilterPass({ node, data: node.data, model: this.params.model, handlerParams: colFilter.getHandlerParams(column) }, index), model: filterModel, state: filterState, onModelChange: (childModel, additionalEventAttributes) => { const { filters, params: params2 } = this; const newModel = getUpdatedMultiFilterModel(params2.model, filters.length, childModel, index); this.updateActiveList(index, childModel); onModelChange(newModel, additionalEventAttributes); onAnyFilterChanged(); }, onStateChange: (newState) => this.onStateChange(onStateChange, index, newState), getHandler: () => this.getHandler().getHandler(index), onAction: (action, additionalEventAttributes, event) => { if (_isUseApplyButton(params)) { return; } const isChange = action === "apply" || action === "reset"; if (isChange) { this.updateActiveList(index, getFilterModelForIndex(this.params.state.model, index)); } onAction(action, additionalEventAttributes, event); if (isChange) { onAnyFilterChanged(); } }, onUiChange, source, getValue: updateGetValue(this.beans, column, filterDef, getValue) }; } updateActiveList(index, childModel) { this.getHandler().updateActiveList?.(index, childModel); } getHandler() { return this.params.getHandler(); } onStateChange(onStateChange, index, newState) { const { model, state, valid } = newState; const validity = this.validity; validity[index] = valid; const allState = this.allState; const newModel = getUpdatedMultiFilterModel(allState.model, this.filters.length, model, index); const allValid = validity.every((filterValid) => filterValid !== false); const allStateState = [...allState.state ?? []]; allStateState[index] = state; const newAllState = { state: allStateState, model: newModel, valid: allValid }; this.allState = newAllState; onStateChange(newAllState); } getModelAsString(model) { return this.getHandler().getModelAsString?.(model) ?? ""; } }; var MultiFloatingFilterElement = { tag: "div", cls: "ag-multi-floating-filter ag-floating-filter-input" }; var MultiFloatingFilterComp = class extends Component { constructor() { super(MultiFloatingFilterElement); this.floatingFilters = []; this.compDetailsList = []; } init(params) { this.params = params; const { compDetailsList } = this.getCompDetailsList(params); return this.setParams(compDetailsList); } setParams(compDetailsList) { const floatingFilterPromises = []; compDetailsList.forEach((compDetails) => { const floatingFilterPromise = compDetails?.newAgStackInstance(); if (floatingFilterPromise != null) { this.compDetailsList.push(compDetails); floatingFilterPromises.push(floatingFilterPromise); } }); return AgPromise.all(floatingFilterPromises).then((floatingFilters) => { floatingFilters.forEach((floatingFilter, index) => { this.floatingFilters.push(floatingFilter); const gui = floatingFilter.getGui(); this.appendChild(gui); if (index > 0) { _setDisplayed(gui, false); } }); }); } refresh(params) { this.params = params; const { compDetailsList: newCompDetailsList, floatingFilterParamsList } = this.getCompDetailsList(params); const allFloatingFilterCompsUnchanged = newCompDetailsList.length === this.compDetailsList.length && newCompDetailsList.every((newCompDetails, index) => !this.beans.colFilter?.areFilterCompsDifferent(this.compDetailsList[index], newCompDetails)); if (allFloatingFilterCompsUnchanged) { floatingFilterParamsList.forEach((floatingFilterParams, index) => { const floatingFilter = this.floatingFilters[index]; floatingFilter.refresh?.(floatingFilterParams); }); if (this.gos.get("enableFilterHandlers")) { const reactiveParams = params; if (reactiveParams.model == null) { this.floatingFilters.forEach((filter, i) => { _setDisplayed(filter.getGui(), i === 0); }); } else { const lastActiveFloatingFilterIndex = reactiveParams.getHandler()?.getLastActiveFilterIndex?.(); this.floatingFilters.forEach((filter, i) => { const shouldShow = lastActiveFloatingFilterIndex == null ? i === 0 : i === lastActiveFloatingFilterIndex; _setDisplayed(filter.getGui(), shouldShow); }); } } } else { _clearElement(this.getGui()); this.destroyBeans(this.floatingFilters); this.floatingFilters = []; this.compDetailsList = []; this.setParams(newCompDetailsList); } } getCompDetailsList(params) { const compDetailsList = []; const floatingFilterParamsList = []; const filterParams = params.filterParams; const currentParentModel = params.currentParentModel; const filterDefs = getMultiFilterDefs(filterParams); filterDefs.forEach((filterDef, index) => { const floatingFilterParams = { ...params, parentFilterInstance: (callback) => { this.parentMultiFilterInstance((parent) => { const child = parent.getChildFilterInstance(index); if (child == null) { return; } callback(child); }); }, currentParentModel: () => currentParentModel()?.filterModels?.[index] ?? null }; if (this.gos.get("enableFilterHandlers")) { const reactiveParams = floatingFilterParams; reactiveParams.model = reactiveParams.model?.filterModels?.[index] ?? null; const { onModelChange, getHandler } = reactiveParams; reactiveParams.onModelChange = (newModel, additionalEventAttributes) => onModelChange(getUpdatedMultiFilterModel(this.params.model, filterDefs.length, newModel, index), additionalEventAttributes); reactiveParams.getHandler = () => { const multiFilterHandler = getHandler(); return multiFilterHandler.getHandler(index); }; } _mergeDeep(floatingFilterParams.filterParams, filterDef.filterParams); const compDetails = this.getCompDetails(filterDef, floatingFilterParams); if (compDetails) { compDetailsList.push(compDetails); floatingFilterParamsList.push(floatingFilterParams); } }); return { compDetailsList, floatingFilterParamsList }; } onParentModelChanged(model, event) { if (event?.afterFloatingFilter) { return; } this.parentMultiFilterInstance((parent) => { if (model == null) { this.floatingFilters.forEach((filter, i) => { filter.onParentModelChanged(null, event); _setDisplayed(filter.getGui(), i === 0); }); } else { const lastActiveFloatingFilterIndex = parent.getLastActiveFilterIndex(); this.floatingFilters.forEach((filter, i) => { const filterModel = model.filterModels.length > i ? model.filterModels[i] : null; filter.onParentModelChanged(filterModel, event); const shouldShow = lastActiveFloatingFilterIndex == null ? i === 0 : i === lastActiveFloatingFilterIndex; _setDisplayed(filter.getGui(), shouldShow); }); } }); } destroy() { this.destroyBeans(this.floatingFilters); this.floatingFilters.length = 0; super.destroy(); } getCompDetails(filterDef, params) { const { colFilter, frameworkOverrides, userCompFactory } = this.beans; const defaultComponentName = _getDefaultFloatingFilterType(frameworkOverrides, filterDef, () => colFilter.getDefaultFloatingFilter(this.params.column)) ?? "agReadOnlyFloatingFilter"; return _getFloatingFilterCompDetails(userCompFactory, filterDef, params, defaultComponentName); } parentMultiFilterInstance(cb) { this.params.parentFilterInstance((parent) => { if (!(parent instanceof MultiFilter || parent instanceof MultiFilterUi)) { _error(120); } cb(parent); }); } }; var MultiFilterModule = { moduleName: "MultiFilter", version: VERSION2, userComponents: { agMultiColumnFilter: { getComp: (beans) => beans.gos.get("enableFilterHandlers") ? { classImp: MultiFilterUi, params: { useForm: true } } : MultiFilter }, agMultiColumnFloatingFilter: MultiFloatingFilterComp }, beans: [MultiFilterService], dynamicBeans: { agMultiColumnFilterHandler: MultiFilterHandler }, dependsOn: [EnterpriseCoreModule, ColumnFilterModule, MenuItemModule] }; var AggColumnNameService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "aggColNameSvc"; } getHeaderName(column, headerName) { if (this.gos.get("suppressAggFuncInHeader")) { return headerName; } const { valueColsSvc, colModel, rowGroupColsSvc } = this.beans; const pivotValueColumn = column.getColDef().pivotValueColumn; const pivotActiveOnThisColumn = _exists(pivotValueColumn); let aggFunc = null; let aggFuncFound; if (pivotActiveOnThisColumn) { const valueColumns = valueColsSvc?.columns ?? []; const isCollapsedHeaderEnabled = this.gos.get("removePivotHeaderRowWhenSingleValueColumn") && valueColumns.length === 1; const isTotalColumn = column.getColDef().pivotTotalColumnIds !== undefined; if (isCollapsedHeaderEnabled && !isTotalColumn) { return headerName; } aggFunc = pivotValueColumn ? pivotValueColumn.getAggFunc() : null; aggFuncFound = true; } else { const measureActive = column.isValueActive(); const isGrouping = rowGroupColsSvc?.columns.length !== 0; const aggregationPresent = colModel.isPivotMode() || isGrouping || this.gos.get("treeData"); if (measureActive && aggregationPresent) { aggFunc = column.getAggFunc(); aggFuncFound = true; } else { aggFuncFound = false; } } if (aggFuncFound) { const aggFuncString = typeof aggFunc === "string" ? aggFunc : "func"; const localeTextFunc = this.getLocaleTextFunc(); const aggFuncStringTranslated = localeTextFunc(aggFuncString, aggFuncString); return `${aggFuncStringTranslated}(${headerName})`; } return headerName; } }; var defaultAggFuncNames = { sum: "Sum", first: "First", last: "Last", min: "Min", max: "Max", count: "Count", avg: "Average" }; var AggFuncService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "aggFuncSvc"; this.aggFuncsMap = {}; this.initialised = false; } postConstruct() { this.init(); } init() { if (this.initialised) { return; } this.initialiseWithDefaultAggregations(); this.addAggFuncs(this.gos.get("aggFuncs")); } initialiseWithDefaultAggregations() { const aggMap = this.aggFuncsMap; aggMap["sum"] = aggSum; aggMap["first"] = aggFirst; aggMap["last"] = aggLast; aggMap["min"] = aggMin; aggMap["max"] = aggMax; aggMap["count"] = aggCount; aggMap["avg"] = aggAvg; this.initialised = true; } isAggFuncPossible(column, func) { const allKeys = this.getFuncNames(column); const allowed = allKeys.includes(func); const funcExists = _exists(this.aggFuncsMap[func]); return allowed && funcExists; } getDefaultFuncLabel(fctName) { return defaultAggFuncNames[fctName] ?? fctName; } getDefaultAggFunc(column) { const defaultAgg = column.getColDef().defaultAggFunc; if (_exists(defaultAgg) && this.isAggFuncPossible(column, defaultAgg)) { return defaultAgg; } if (this.isAggFuncPossible(column, "sum")) { return "sum"; } const allKeys = this.getFuncNames(column); return allKeys?.length ? allKeys[0] : null; } addAggFuncs(aggFuncs) { this.init(); if (!aggFuncs) { return; } for (const key of Object.keys(aggFuncs)) { if (aggFuncs[key]) { this.aggFuncsMap[key] = aggFuncs[key]; } } } getAggFunc(name) { this.init(); return this.aggFuncsMap[name]; } getFuncNames(column) { const userAllowedFuncs = column.getColDef().allowedAggFuncs; return userAllowedFuncs == null ? Object.keys(this.aggFuncsMap).sort() : userAllowedFuncs; } clear() { this.aggFuncsMap = {}; } }; function aggSum(params) { const { values } = params; let result = null; for (let i = 0;i < values.length; i++) { const value = values[i]; if (typeof value === "number") { if (result === null) { result = value; } else { result += typeof result === "number" ? value : BigInt(value); } } else if (typeof value === "bigint") { if (result === null) { result = value; } else { result = (typeof result === "bigint" ? result : BigInt(result)) + value; } } } return result; } function aggFirst(params) { return params.values.length > 0 ? params.values[0] : null; } function aggLast(params) { return params.values.length > 0 ? _last(params.values) : null; } function aggMin(params) { const { values } = params; let result = null; for (let i = 0;i < values.length; i++) { const value = values[i]; if ((typeof value === "number" || typeof value === "bigint") && (result === null || result > value)) { result = value; } } return result; } function aggMax(params) { const { values } = params; let result = null; for (let i = 0;i < values.length; i++) { const value = values[i]; if ((typeof value === "number" || typeof value === "bigint") && (result === null || result < value)) { result = value; } } return result; } var COUNT_PROTO = Object.freeze({ toString: function() { return this.value.toString(); }, toNumber: function() { return this.value; } }); function aggCount(params) { const { values } = params; let count = 0; for (let i = 0;i < values.length; i++) { const value = values[i]; count += value != null && typeof value.value === "number" ? value.value : 1; } const existingAggData = params.rowNode?.aggData?.[params.column.getColId()]; if (existingAggData && existingAggData.value === count) { return existingAggData; } const result = Object.create(COUNT_PROTO); result.value = count; return result; } var AVERAGE_PROTO = Object.freeze({ toString: function() { return typeof this.value === "number" || typeof this.value === "bigint" ? this.value.toString() : ""; }, toNumber: function() { return this.value; } }); function aggAvg(params) { const { values } = params; let sum = 0; let count = 0; for (let i = 0;i < values.length; i++) { const currentValue = values[i]; let valueToAdd = null; if (typeof currentValue === "number" || typeof currentValue === "bigint") { valueToAdd = currentValue; count++; } else if (currentValue != null && (typeof currentValue.value === "number" || typeof currentValue.value === "bigint") && typeof currentValue.count === "number") { valueToAdd = currentValue.value * (typeof currentValue.value === "number" ? currentValue.count : BigInt(currentValue.count)); count += currentValue.count; } if (typeof valueToAdd === "number") { sum += typeof sum === "number" ? valueToAdd : BigInt(valueToAdd); } else if (typeof valueToAdd === "bigint") { sum = (typeof sum === "bigint" ? sum : BigInt(sum)) + valueToAdd; } } let value = null; if (count > 0) { value = sum / (typeof sum === "number" ? count : BigInt(count)); } const existingAggData = params.rowNode?.aggData?.[params.column?.getColId()]; if (existingAggData && existingAggData.count === count && existingAggData.value === value) { return existingAggData; } const result = Object.create(AVERAGE_PROTO); result.count = count; result.value = value; return result; } var AggregatedChildrenSvc = class extends BeanStub { constructor() { super(...arguments); this.beanName = "aggChildrenSvc"; } getAggregatedChildren(rowNode, col, recursive) { if (!rowNode?.group) { return []; } if (rowNode.rowPinned) { rowNode = rowNode.pinnedSibling; if (!rowNode) { return []; } } const gos = this.gos; const children = getImmediateAggChildren(rowNode, col, gos); if (!recursive) { return children; } const result = []; collectLeafDescendants(children, col, gos, result); return result; } }; var getImmediateAggChildren = (rowNode, col, gos) => { const colDef = col?.colDef; const pivotKeys = colDef?.pivotKeys; if (pivotKeys) { if (rowNode.leafGroup && pivotKeys.length && !colDef.pivotTotalColumnIds) { return getNodesFromMappedSet(rowNode.childrenMapped, pivotKeys); } return rowNode.childrenAfterFilter ?? rowNode.childrenAfterGroup ?? []; } if (_getGroupAggFiltering(gos) || gos.get("suppressAggFilteredOnly")) { return rowNode.childrenAfterGroup ?? []; } return rowNode.childrenAfterFilter ?? rowNode.childrenAfterGroup ?? []; }; var collectLeafDescendants = (children, col, gos, result) => { for (let i = 0, len = children.length;i < len; ++i) { const child = children[i]; if (child.group) { collectLeafDescendants(getImmediateAggChildren(child, col, gos), col, gos, result); } else { result.push(child); } } }; function addAggFuncs(beans, aggFuncs) { if (beans.aggFuncSvc) { beans.aggFuncSvc.addAggFuncs(aggFuncs); } } function clearAggFuncs(beans) { if (beans.aggFuncSvc) { beans.aggFuncSvc.clear(); } } function setColumnAggFunc(beans, key, aggFunc) { beans.valueColsSvc?.setColumnAggFunc?.(key, aggFunc, "api"); } var AggregationStage = class extends BeanStub { constructor() { super(...arguments); this.beanName = "aggStage"; this.step = "aggregate"; this.refreshProps = [ "getGroupRowAgg", "alwaysAggregateAtRootLevel", "suppressAggFilteredOnly", "grandTotalRow" ]; this.hadAgg = false; } execute(changedPath) { const { gos, beans } = this; const userAggFunc = gos.getCallback("getGroupRowAgg"); const valueColumns = beans.valueColsSvc?.columns; if (!valueColumns?.length && !userAggFunc) { if (this.hadAgg && !changedPath) { this.hadAgg = false; const colModel2 = beans.colModel; const rowModel2 = beans.rowModel; _forEachChangedGroupDepthFirst(rowModel2.rootNode, rowModel2.hierarchical, undefined, (rowNode) => { setAggDataWithSiblings(rowNode, null, colModel2); }); } return; } this.hadAgg = true; const colModel = beans.colModel; const aggFuncSvc = beans.aggFuncSvc; const aggregateRoot = gos.get("alwaysAggregateAtRootLevel") || !!_getGrandTotalRow(gos) || colModel.isPivotMode(); const filteredOnly = !_getGroupAggFiltering(gos) && !gos.get("suppressAggFilteredOnly"); const valueSvc = beans.valueSvc; const api = beans.gridApi; const context = beans.gridOptions.context; const resolvedValueColumns = valueColumns ?? []; const colCount = resolvedValueColumns.length; const narrowedCellsPath = changedPath?.kind === "cells" ? changedPath : undefined; let cellsChangedPath; const valueCols = new Array(colCount); for (let i = 0;i < colCount; ++i) { const col = resolvedValueColumns[i]; const colSlot = narrowedCellsPath ? narrowedCellsPath.getSlot(col.colId) : -1; if (colSlot >= 0) { cellsChangedPath = narrowedCellsPath; } valueCols[i] = { column: col, colId: col.colId, colDef: col.colDef, aggFunc: resolveAggFunc(col.getAggFunc(), aggFuncSvc, col), colSlot }; } const pivotData = resolvePivotColumns(colModel, beans.pivotResultCols, aggFuncSvc); const values2d = colCount > 0 ? new Array(colCount) : null; const rowModel = beans.rowModel; _forEachChangedGroupDepthFirst(rowModel.rootNode, rowModel.hierarchical, changedPath, (rowNode) => { if (rowNode.level === -1 && !aggregateRoot) { setAggData(rowNode, null, colModel); return; } let aggResult; if (userAggFunc) { aggResult = userAggFunc({ nodes: rowNode.childrenAfterFilter }); } else if (!values2d) { aggResult = null; } else if (pivotData) { aggResult = aggregateValuesAndPivot(rowNode, pivotData, valueSvc, api, context); } else { aggResult = aggregateValuesOnly(rowNode, valueCols, colCount, values2d, cellsChangedPath, filteredOnly, valueSvc, api, context); } setAggDataWithSiblings(rowNode, aggResult, colModel); }); } }; var aggregateValuesOnly = (rowNode, valueCols, colCount, values2d, cellsChangedPath, filteredOnly, valueSvc, api, context) => { const aggregatedChildren = (filteredOnly ? rowNode.childrenAfterFilter : rowNode.childrenAfterGroup) ?? []; const childCount = aggregatedChildren.length; const data = rowNode.data; const result = /* @__PURE__ */ Object.create(null); const rowSlot = cellsChangedPath ? cellsChangedPath.getSlot(rowNode) : -1; const oldAggData = rowSlot >= 0 ? rowNode.aggData : undefined; let changedCount = 0; for (let j = 0;j < colCount; ++j) { const vc = valueCols[j]; if (rowSlot >= 0 && !cellsChangedPath.hasCellBySlot(rowSlot, vc.colSlot)) { values2d[j] = null; if (oldAggData) { result[vc.colId] = oldAggData[vc.colId]; } } else { values2d[j] = new Array(childCount); ++changedCount; } } if (changedCount === 0) { return result; } for (let c = 0;c < childCount; ++c) { const child = aggregatedChildren[c]; const childAggData = child.aggData; if (childAggData) { for (let j = 0;j < colCount; ++j) { const colValues = values2d[j]; if (colValues !== null) { const vc = valueCols[j]; const v = childAggData[vc.colId]; colValues[c] = v !== undefined ? v : valueSvc.getValue(vc.column, child, "data"); } } } else { for (let j = 0;j < colCount; ++j) { const colValues = values2d[j]; if (colValues !== null) { colValues[c] = valueSvc.getValue(valueCols[j].column, child, "data"); } } } } for (let j = 0;j < colCount; ++j) { const colValues = values2d[j]; if (colValues === null) { continue; } const rc = valueCols[j]; const aggFunc = rc.aggFunc; result[rc.colId] = aggFunc ? aggFunc({ values: colValues, column: rc.column, colDef: rc.colDef, rowNode, data, aggregatedChildren, api, context }) : null; } return result; }; var aggregateValuesAndPivot = (rowNode, pivotData, valueSvc, api, context) => { const pivotColCount = pivotData.length; const isLeafGroup = rowNode.leafGroup; const data = rowNode.data; const childrenMapped = rowNode.childrenMapped; const childrenAfterFilter = rowNode.childrenAfterFilter ?? []; const result = /* @__PURE__ */ Object.create(null); let prevPivotKeys; let prevPivotChildren; for (let i = 0;i < pivotColCount; ++i) { const rc = pivotData[i]; const column = rc.column; const colId = rc.colId; const totalColIds = rc.totalColIds; let values; let aggregatedChildren; if (totalColIds != null) { const tLen = totalColIds.length; values = new Array(tLen); for (let t = 0;t < tLen; ++t) { values[t] = result[totalColIds[t]]; } aggregatedChildren = childrenAfterFilter; } else if (isLeafGroup) { const pivotKeys = rc.pivotKeys; if (!prevPivotChildren || pivotKeys !== prevPivotKeys) { prevPivotKeys = pivotKeys; prevPivotChildren = getNodesFromMappedSet(childrenMapped, pivotKeys); } aggregatedChildren = prevPivotChildren; const nodeCount = aggregatedChildren.length; values = new Array(nodeCount); for (let n = 0;n < nodeCount; ++n) { values[n] = valueSvc.getValue(column, aggregatedChildren[n], "data"); } } else { aggregatedChildren = childrenAfterFilter; const nodeCount = aggregatedChildren.length; values = new Array(nodeCount); for (let n = 0;n < nodeCount; ++n) { const childNode = aggregatedChildren[n]; const childAggData = childNode.aggData; const v = childAggData ? childAggData[colId] : undefined; values[n] = v !== undefined ? v : valueSvc.getValue(column, childNode, "data"); } } const aggFunc = rc.aggFunc; result[colId] = aggFunc ? aggFunc({ values, column, colDef: column.colDef, pivotResultColumn: rc.pivotResultCol, rowNode, data, aggregatedChildren, api, context }) : null; } return result; }; var resolveAggFunc = (aggFuncOrString, aggFuncSvc, column) => { if (typeof aggFuncOrString === "function") { return aggFuncOrString; } if (aggFuncOrString == null) { return null; } const aggFunc = aggFuncSvc.getAggFunc(aggFuncOrString); if (typeof aggFunc !== "function") { _warn(109, { inputValue: aggFuncOrString.toString(), allSuggestions: aggFuncSvc.getFuncNames(column) }); return null; } return aggFunc; }; var resolvePivotColumns = (colModel, pivotResultCols, aggFuncSvc) => { if (!colModel.isPivotActive()) { return null; } const orderedList = pivotResultCols?.getAggregationOrderedList(); if (!orderedList || orderedList.length === 0) { return null; } const len = orderedList.length; const resolved = new Array(len); let count = 0; for (let i = 0;i < len; ++i) { const pivotResultCol = orderedList[i]; const resultColDef = pivotResultCol.colDef; const valueCol = resultColDef.pivotValueColumn; if (!valueCol) { continue; } resolved[count++] = { column: valueCol, colId: resultColDef.colId, aggFunc: resolveAggFunc(valueCol.getAggFunc(), aggFuncSvc, valueCol), pivotResultCol, pivotKeys: resultColDef.pivotKeys, totalColIds: resultColDef.pivotTotalColumnIds }; } if (count === 0) { return null; } resolved.length = count; return resolved; }; var FilterAggregatesStage = class extends BeanStub { constructor() { super(...arguments); this.beanName = "filterAggStage"; this.step = "filter_aggregates"; this.refreshProps = []; this.setAllChildrenCountTreeData = (rowNode) => { const childrenAfterAggFilter = rowNode.childrenAfterAggFilter; let allChildrenCount = 0; if (childrenAfterAggFilter) { const length = childrenAfterAggFilter.length; allChildrenCount = length; for (let i = 0;i < length; ++i) { allChildrenCount += childrenAfterAggFilter[i].allChildrenCount ?? 0; } } const count = allChildrenCount === 0 && rowNode.level >= 0 ? null : allChildrenCount; rowNode.setAllChildrenCount(count); rowNode.pinnedSibling?.setAllChildrenCount(count); }; this.setAllChildrenCountGridGrouping = (rowNode) => { const children = rowNode.childrenAfterAggFilter; let allChildrenCount = 0; for (let i = 0, len = children.length;i < len; ++i) { const child = children[i]; if (child.group) { allChildrenCount += child.allChildrenCount; } else { allChildrenCount++; } } rowNode.setAllChildrenCount(allChildrenCount); rowNode.pinnedSibling?.setAllChildrenCount(allChildrenCount); }; } wireBeans(beans) { this.filterManager = beans.filterManager; } execute(changedPath) { const { rowModel, colModel, groupStage } = this.beans; const { filterManager } = this; const isPivotMode2 = colModel.isPivotMode(); const isAggFilterActive = filterManager?.isAggregateFilterPresent() || filterManager?.isAggregateQuickFilterPresent(); const isTreeData = !!groupStage?.treeData; const defaultPrimaryColumnPredicate = (params) => !params.node.group; const defaultSecondaryColumnPredicate = (params) => params.node.leafGroup; const applyFilterToNode = _getGroupAggFiltering(this.gos) || (isPivotMode2 ? defaultSecondaryColumnPredicate : defaultPrimaryColumnPredicate); const setAllChildrenCount = isTreeData ? this.setAllChildrenCountTreeData : this.setAllChildrenCountGridGrouping; const preserveChildren = (node, recursive = false) => { if (node.childrenAfterFilter) { node.childrenAfterAggFilter = node.childrenAfterFilter; if (recursive) { const children = node.childrenAfterAggFilter; for (let i = 0, len = children.length;i < len; ++i) { preserveChildren(children[i], recursive); } } if (node.hasChildren()) { setAllChildrenCount(node); } else { node.setAllChildrenCount(null); node.pinnedSibling?.setAllChildrenCount(null); } } if (node.sibling) { node.sibling.childrenAfterAggFilter = node.childrenAfterAggFilter; } }; const filterChildren = (node) => { node.childrenAfterAggFilter = node.childrenAfterFilter?.filter((child) => { const shouldFilterRow = applyFilterToNode({ node: child }); if (shouldFilterRow) { const doesNodePassFilter = filterManager.doesRowPassAggregateFilters({ rowNode: child }); if (doesNodePassFilter) { preserveChildren(child, true); return true; } } const hasChildPassed = child.childrenAfterAggFilter?.length; return hasChildPassed; }) || null; if (node.hasChildren()) { setAllChildrenCount(node); } else { node.setAllChildrenCount(null); node.pinnedSibling?.setAllChildrenCount(null); } if (node.sibling) { node.sibling.childrenAfterAggFilter = node.childrenAfterAggFilter; } }; _forEachChangedGroupDepthFirst(rowModel.rootNode, rowModel.hierarchical, changedPath, isAggFilterActive ? filterChildren : preserveChildren); } }; function _createRowNodeFooter(rowNode, beans) { if (rowNode.sibling) { return; } const footerNode = _createRowNodeSibling(rowNode, beans); footerNode.footer = true; footerNode.setRowTop(null); footerNode.setRowIndex(null); footerNode.oldRowTop = null; footerNode.id = "rowGroupFooter_" + rowNode.id; footerNode.sibling = rowNode; rowNode.sibling = footerNode; } function _destroyRowNodeFooter(rowNode) { const sibling = rowNode.sibling; if (!sibling) { return; } sibling._destroy(false); rowNode.sibling = undefined; sibling.sibling = undefined; } var FooterService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "footerSvc"; } addTotalRows(startIndex, node, callback, includeFooterNodes, isRootNode, position) { let index = startIndex; if (isRootNode) { const grandTotal = includeFooterNodes && _getGrandTotalRow(this.gos); if (_positionMatchesGrandTotalRow(position, grandTotal)) { _createRowNodeFooter(node, this.beans); callback(node.sibling, index++); } return index; } const isGroupIncludeFooter = _getGroupTotalRowCallback(this.gos); const groupTotal = includeFooterNodes && isGroupIncludeFooter({ node }); if (groupTotal === position) { _createRowNodeFooter(node, this.beans); callback(node.sibling, index++); } return index; } getTopDisplayIndex(rowsToDisplay, topLevelIndex, childrenAfterSort, getDefaultIndex) { let adjustedIndex = topLevelIndex; if (rowsToDisplay[0].footer) { if (topLevelIndex === 0) { return 0; } adjustedIndex -= 1; } const lastRow = rowsToDisplay[rowsToDisplay.length - 1]; const indexOutsideGroupBounds = adjustedIndex >= childrenAfterSort.length; if (lastRow.footer && indexOutsideGroupBounds) { return lastRow.rowIndex; } return getDefaultIndex(adjustedIndex); } doesCellShowTotalPrefix(node, col) { if (!node.footer || !col?.getColDef().showRowGroup) { return false; } if (this.gos.get("treeData")) { return true; } if (node.level === -1) { return this.beans.showRowGroupCols?.columns[0] === col; } return !!node.rowGroupColumn && col?.isRowGroupDisplayed(node.rowGroupColumn.getId()); } applyTotalPrefix(value, formattedValue, node, column) { const totalValueGetter = column.getColDef().cellRendererParams?.totalValueGetter; if (totalValueGetter) { const valueGetterParams = _addGridCommonParams(this.gos, { column, node, value, formattedValue }); const getterType = typeof totalValueGetter; if (getterType === "function") { return totalValueGetter(valueGetterParams); } if (typeof totalValueGetter === "string") { return this.beans.expressionSvc?.evaluate(totalValueGetter, valueGetterParams); } _warn(179); } if (node.level === -1) { return this.getLocaleTextFunc()("footerTotal", "Total") + " "; } return this.getTotalValue(formattedValue ?? value) ?? ""; } getTotalValue(value) { return this.getLocaleTextFunc()("footerTotal", "Total") + " " + (value ?? ""); } }; function _positionMatchesGrandTotalRow(position, grandTotaRow) { switch (grandTotaRow) { case "top": case "pinnedTop": return position === "top"; case "bottom": case "pinnedBottom": return position === "bottom"; default: return false; } } var ValueColsSvc = class extends BaseColsService { constructor() { super(...arguments); this.beanName = "valueColsSvc"; this.eventName = "columnValueChanged"; this.columnProcessors = { set: (column, added, source) => this.setValueActive(added, column, source), add: (column, added, source) => this.setValueActive(true, column, source), remove: (column, added, source) => this.setValueActive(false, column, source) }; this.columnExtractors = { setFlagFunc: (col, flag, source) => this.setColValueActive(col, flag, source), getIndexFunc: () => { return; }, getInitialIndexFunc: () => { return; }, getValueFunc: (colDef) => { const aggFunc = colDef.aggFunc; if (aggFunc === null || aggFunc === "") { return null; } if (aggFunc === undefined) { return; } return !!aggFunc; }, getInitialValueFunc: (colDef) => { return colDef.initialAggFunc != null && colDef.initialAggFunc != ""; } }; this.modifyColumnsNoEventsCallbacks = { addCol: (column) => this.columns.push(column), removeCol: (column) => _removeFromArray(this.columns, column) }; } extractCols(source, oldProvidedCols) { this.columns = super.extractCols(source, oldProvidedCols); for (const col of this.columns) { const colDef = col.getColDef(); if (colDef.aggFunc != null && colDef.aggFunc != "") { this.setColAggFunc(col, colDef.aggFunc); } else if (!col.getAggFunc()) { this.setColAggFunc(col, colDef.initialAggFunc); } } return this.columns; } setColumnAggFunc(key, aggFunc, source) { if (!key) { return; } const column = this.colModel.getColDefCol(key); if (!column) { return; } this.setColAggFunc(column, aggFunc); this.dispatchColumnChangedEvent(this.eventSvc, this.eventName, [column], source); } syncColumnWithState(column, source, getValue) { const aggFunc = getValue("aggFunc").value1; if (aggFunc !== undefined) { if (typeof aggFunc === "string") { this.setColAggFunc(column, aggFunc); if (!column.isValueActive()) { this.setColValueActive(column, true, source); this.modifyColumnsNoEventsCallbacks.addCol(column); } } else { if (_exists(aggFunc)) { _warn(33); } if (column.isValueActive()) { this.setColValueActive(column, false, source); this.modifyColumnsNoEventsCallbacks.removeCol(column); } } } } setValueActive(active, column, source) { if (active === column.isValueActive()) { return; } this.setColValueActive(column, active, source); if (active && !column.getAggFunc() && this.aggFuncSvc) { const initialAggFunc = this.aggFuncSvc.getDefaultAggFunc(column); this.setColAggFunc(column, initialAggFunc); } } setColAggFunc(column, aggFunc) { column.aggFunc = aggFunc; column.dispatchStateUpdatedEvent("aggFunc"); } setColValueActive(column, value, source) { if (column.aggregationActive !== value) { column.aggregationActive = value; column.dispatchColEvent("columnValueChanged", source); } } }; var SharedAggregationModule = { moduleName: "SharedAggregation", version: VERSION2, beans: [AggFuncService, AggColumnNameService, FooterService, ValueColsSvc], apiFunctions: { addAggFuncs, clearAggFuncs, setColumnAggFunc }, dependsOn: [EnterpriseCoreModule] }; var AggregationModule = { moduleName: "Aggregation", version: VERSION2, beans: [AggregationStage, FilterAggregatesStage, AggregatedChildrenSvc], rowModels: ["clientSide"], dependsOn: [SharedAggregationModule] }; var PivotColsSvc = class extends BaseColsService { constructor() { super(...arguments); this.beanName = "pivotColsSvc"; this.eventName = "columnPivotChanged"; this.columnProcessors = { set: (column, added, source) => this.setColPivotActive(column, added, source), add: (column, added, source) => this.setColPivotActive(column, true, source), remove: (column, added, source) => this.setColPivotActive(column, false, source) }; this.columnOrdering = { enableProp: "pivot", initialEnableProp: "initialPivot", indexProp: "pivotIndex", initialIndexProp: "initialPivotIndex" }; this.columnExtractors = { setFlagFunc: (col, flag, source) => this.setColPivotActive(col, flag, source), getIndexFunc: (colDef) => colDef.pivotIndex, getInitialIndexFunc: (colDef) => colDef.initialPivotIndex, getValueFunc: (colDef) => colDef.pivot, getInitialValueFunc: (colDef) => colDef.initialPivot }; this.modifyColumnsNoEventsCallbacks = { addCol: (column) => { if (!this.columns.includes(column)) { this.columns.push(column); } }, removeCol: (column) => _removeFromArray(this.columns, column) }; } syncColumnWithState(column, source, getValue, rowIndex) { const { value1: pivot, value2: pivotIndex } = getValue("pivot", "pivotIndex"); if (pivot !== undefined || pivotIndex !== undefined) { if (typeof pivotIndex === "number" || pivot) { if (!column.isPivotActive()) { this.setColPivotActive(column, true, source); this.modifyColumnsNoEventsCallbacks.addCol(column); } if (rowIndex && typeof pivotIndex === "number") { rowIndex[column.getId()] = pivotIndex; } } else if (column.isPivotActive()) { this.setColPivotActive(column, false, source); this.modifyColumnsNoEventsCallbacks.removeCol(column); } } } setColPivotActive(column, pivot, source) { if (column.pivotActive !== pivot) { column.pivotActive = pivot; if (pivot) { const addedCols = this.beans.groupHierarchyColSvc?.insertVirtualColumnsForCol(this.columns, column); addedCols?.forEach((c) => this.setColPivotActive(c, pivot, source)); } column.dispatchColEvent("columnPivotChanged", source); } column.dispatchStateUpdatedEvent("pivot"); } }; var RowGroupColsSvc = class extends BaseColsService { constructor() { super(...arguments); this.beanName = "rowGroupColsSvc"; this.eventName = "columnRowGroupChanged"; this.columnProcessors = { set: (column, added, source) => this.setActive(added, column, source), add: (column, added, source) => this.setActive(true, column, source), remove: (column, added, source) => this.setActive(false, column, source) }; this.columnOrdering = { enableProp: "rowGroup", initialEnableProp: "initialRowGroup", indexProp: "rowGroupIndex", initialIndexProp: "initialRowGroupIndex" }; this.columnExtractors = { setFlagFunc: (col, flag, source) => this.setColRowGroupActive(col, flag, source), getIndexFunc: (colDef) => colDef.rowGroupIndex, getInitialIndexFunc: (colDef) => colDef.initialRowGroupIndex, getValueFunc: (colDef) => colDef.rowGroup, getInitialValueFunc: (colDef) => colDef.initialRowGroup }; this.modifyColumnsNoEventsCallbacks = { addCol: (column) => { if (!this.columns.includes(column)) { this.columns.push(column); } }, removeCol: (column) => _removeFromArray(this.columns, column) }; } moveColumn(fromIndex, toIndex, source) { if (this.columns.length === 0) { return; } const column = this.columns[fromIndex]; const impactedColumns = this.columns.slice(fromIndex, toIndex); this.columns.splice(fromIndex, 1); this.columns.splice(toIndex, 0, column); this.updateIndexMap(); this.eventSvc.dispatchEvent({ type: this.eventName, columns: impactedColumns, column: impactedColumns.length === 1 ? impactedColumns[0] : null, source }); } syncColumnWithState(column, source, getValue, rowIndex) { const { value1: rowGroup, value2: rowGroupIndex } = getValue("rowGroup", "rowGroupIndex"); if (rowGroup !== undefined || rowGroupIndex !== undefined) { if (typeof rowGroupIndex === "number" || rowGroup) { if (!column.isRowGroupActive()) { this.setColRowGroupActive(column, true, source); this.modifyColumnsNoEventsCallbacks.addCol(column); } if (rowIndex && typeof rowGroupIndex === "number") { rowIndex[column.getId()] = rowGroupIndex; } } else if (column.isRowGroupActive()) { this.setColRowGroupActive(column, false, source); this.modifyColumnsNoEventsCallbacks.removeCol(column); } } } setActive(active, column, source) { if (active === column.isRowGroupActive()) { return; } this.setColRowGroupActive(column, active, source); const isGroupHierarchyCol = this.beans.groupHierarchyColSvc?.getColumn(column); if (_shouldUpdateColVisibilityAfterGroup(this.gos, active) && !isGroupHierarchyCol) { this.colModel.setColsVisible([column], !active, source); } } setColRowGroupActive(column, rowGroup, source) { if (column.rowGroupActive !== rowGroup) { column.rowGroupActive = rowGroup; if (rowGroup) { const addedCols = this.beans.groupHierarchyColSvc?.insertVirtualColumnsForCol(this.columns, column); addedCols?.forEach((c) => this.setColRowGroupActive(c, rowGroup, source)); } column.dispatchColEvent("columnRowGroupChanged", source); } column.dispatchStateUpdatedEvent("rowGroup"); } }; var AutoColService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "autoColSvc"; } postConstruct() { this.addManagedPropertyListener("autoGroupColumnDef", this.updateColumns.bind(this)); this.setupGroupHideColumnsUntilExpanded(); } setupGroupHideColumnsUntilExpanded() { const updateGroupColumnVisibility = () => this.updateGroupColumnVisibility(); this.addManagedEventListeners({ modelUpdated: updateGroupColumnVisibility }); this.addManagedPropertyListeners(["groupHideColumnsUntilExpanded", "groupDisplayType", "groupHideOpenParents"], updateGroupColumnVisibility); } addColumns(cols) { const { columns } = this; if (columns == null) { return; } cols.list = columns.list.concat(cols.list); cols.tree = columns.tree.concat(cols.tree); _updateColsMap(cols); } createColumns(cols, updateOrders, source) { const beans = this.beans; const { colModel, gos, rowGroupColsSvc, colGroupSvc } = beans; const isPivotMode2 = colModel.isPivotMode(); const groupFullWidthRow = _isGroupUseEntireRow(gos, isPivotMode2); const suppressAutoColumn = isPivotMode2 ? gos.get("pivotSuppressAutoColumn") : this.isSuppressAutoCol(); const rowGroupCols = rowGroupColsSvc?.columns; const groupingActive = rowGroupCols && rowGroupCols.length > 0 || gos.get("treeData"); const noAutoCols = !groupingActive || suppressAutoColumn || groupFullWidthRow; const destroyPrevious = () => { if (this.columns) { _destroyColumnTree(beans, this.columns.tree); this.columns = null; } }; if (noAutoCols) { destroyPrevious(); return; } const list = this.generateAutoCols(rowGroupCols); const autoColsSame = _areColIdsEqual(list, this.columns?.list || null); const newTreeDepth = cols.treeDepth; const oldTreeDepth = this.columns ? this.columns.treeDepth : -1; const treeDepthSame = oldTreeDepth == newTreeDepth; if (autoColsSame && treeDepthSame) { const colsMap = new Map(list.map((col) => [col.getId(), col])); for (const col of this.columns?.list ?? []) { const newDef = colsMap.get(col.getId()); if (newDef) { col.setColDef(newDef.getColDef(), null, source); } } return; } destroyPrevious(); const treeDepth = colGroupSvc?.findDepth(cols.tree) ?? 0; const tree = colGroupSvc?.balanceTreeForAutoCols(list, treeDepth) ?? []; this.columns = { list, tree, treeDepth, map: {} }; const putAutoColsFirstInList = (cols2) => { if (!cols2) { return null; } const colsFiltered = cols2.filter((col) => !isColumnGroupAutoCol(col)); return [...list, ...colsFiltered]; }; updateOrders(putAutoColsFirstInList); } updateColumns(event) { const source = _convertColumnEventSourceType(event.source); this.columns?.list.forEach((col, index) => this.updateOneAutoCol(col, index, source)); } getColumn(key) { return this.columns?.list.find((groupCol) => _columnsMatch(groupCol, key)) ?? null; } getColumns() { return this.columns?.list ?? null; } generateAutoCols(rowGroupCols = []) { const autoCols = []; const { gos } = this; const doingTreeData = gos.get("treeData"); let doingMultiAutoColumn = _isGroupMultiAutoColumn(gos); if (doingTreeData && doingMultiAutoColumn) { _warn(182); doingMultiAutoColumn = false; } if (doingMultiAutoColumn) { rowGroupCols.forEach((rowGroupCol, index) => { autoCols.push(this.createOneAutoCol(rowGroupCol, index)); }); } else { autoCols.push(this.createOneAutoCol()); } return autoCols; } isSuppressAutoCol() { const gos = this.gos; const groupDisplayType = gos.get("groupDisplayType"); const isCustomRowGroups = groupDisplayType === "custom"; if (isCustomRowGroups) { return true; } const treeDataDisplayType = gos.get("treeDataDisplayType"); return treeDataDisplayType === "custom"; } createOneAutoCol(rowGroupCol, index) { let colId; if (rowGroupCol) { colId = `${GROUP_AUTO_COLUMN_ID}-${rowGroupCol.getId()}`; } else { colId = GROUP_AUTO_COLUMN_ID; } const colDef = this.createAutoColDef(colId, rowGroupCol, index); colDef.colId = colId; const newCol = new AgColumn(colDef, null, colId, true); this.createBean(newCol); return newCol; } updateOneAutoCol(colToUpdate, index, source) { const oldColDef = colToUpdate.getColDef(); const underlyingColId = typeof oldColDef.showRowGroup == "string" ? oldColDef.showRowGroup : undefined; const beans = this.beans; const underlyingColumn = underlyingColId != null ? beans.colModel.getColDefCol(underlyingColId) : undefined; const colId = colToUpdate.getId(); const colDef = this.createAutoColDef(colId, underlyingColumn ?? undefined, index); colToUpdate.setColDef(colDef, null, source); _applyColumnState(beans, { state: [_getColumnStateFromColDef(colDef, colId)] }, source); } createAutoColDef(colId, underlyingColumn, index) { let res = this.createBaseColDef(underlyingColumn); const autoGroupColumnDef = this.gos.get("autoGroupColumnDef"); _mergeDeep(res, autoGroupColumnDef); res = _addColumnDefaultAndTypes(this.beans, res, colId, true); if (autoGroupColumnDef?.groupRowEditable == null) { res.groupRowEditable = undefined; } if (autoGroupColumnDef?.groupRowValueSetter == null) { res.groupRowValueSetter = undefined; } if (!this.gos.get("treeData")) { const noFieldOrValueGetter = _missing(res.field) && _missing(res.valueGetter) && _missing(res.filterValueGetter) && res.filter !== "agGroupColumnFilter"; if (noFieldOrValueGetter) { res.filter = false; } } if (index && index > 0) { res.headerCheckboxSelection = false; } const isSortingCoupled = _isColumnsSortingCoupledToGroup(this.gos); const hasOwnData = res.valueGetter || res.field != null; if (isSortingCoupled && !hasOwnData) { res.sortIndex = undefined; res.initialSort = undefined; } return res; } createBaseColDef(rowGroupCol) { const userDef = this.gos.get("autoGroupColumnDef"); const localeTextFunc = this.getLocaleTextFunc(); const res = { headerName: localeTextFunc("group", "Group"), showRowGroup: rowGroupCol?.getColId() ?? true }; const userHasProvidedGroupCellRenderer = userDef && (userDef.cellRenderer || userDef.cellRendererSelector); if (!userHasProvidedGroupCellRenderer) { res.cellRenderer = "agGroupCellRenderer"; } if (rowGroupCol) { res.headerName = this.beans.colNames.getDisplayNameForColumn(rowGroupCol, "header") ?? undefined; res.headerValueGetter = rowGroupCol.colDef.headerValueGetter; } return res; } getDeepestExpandedLevel(nodes, maxLevel) { let deepest = -1; if (!nodes) { return deepest; } for (const node of nodes) { if (!node.group || !node.expanded) { continue; } if (node.level > deepest) { deepest = node.level; } if (deepest >= maxLevel) { return deepest; } const childDeepest = this.getDeepestExpandedLevel(node.childrenAfterGroup, maxLevel); if (childDeepest > deepest) { deepest = childDeepest; } if (deepest >= maxLevel) { return deepest; } } return deepest; } updateGroupColumnVisibility() { const columns = this.columns?.list; if (!columns || columns.length === 0) { return; } const { gos, visibleCols, rowModel } = this.beans; const isFeatureEnabled = _isGroupHideColumnsUntilExpanded(gos); let changed = false; const setColVisible = (col, visible) => { if (visible !== col.isVisible()) { col.setVisible(visible, "api"); changed = true; } }; const setAllColumnsVisible = () => { for (const col of columns) { setColVisible(col, true); } }; if (!isFeatureEnabled) { setAllColumnsVisible(); } else if (columns.length > 1) { const maxLevel = columns.length - 2; const rootChildren = rowModel?.rootNode?.childrenAfterGroup; const deepestExpandedLevel = this.getDeepestExpandedLevel(rootChildren, maxLevel); if (deepestExpandedLevel >= maxLevel) { setAllColumnsVisible(); } else { for (let level = 0;level < columns.length - 1; level++) { setColVisible(columns[level + 1], deepestExpandedLevel >= level); } } } if (changed) { visibleCols.refresh("api"); } } destroy() { _destroyColumnTree(this.beans, this.columns?.tree); super.destroy(); } }; var _sortBuckets = null; var sortBucketsAlloc = (minBucket) => { const old = _sortBuckets; const newBuckets = new Uint32Array(1 << 32 - Math.clz32(minBucket | 63)); if (old) { newBuckets.set(old); } _sortBuckets = newBuckets; return newBuckets; }; var sortTwoLevels = (nodes, nodeCount, deepest, deepCount) => { const shallowCount = nodeCount - deepCount; const deepLevel = deepest - 1; if (shallowCount === 1) { let si2 = 0; while (nodes[si2].level === deepLevel) { ++si2; } if (si2 < nodeCount - 1) { const shallow2 = nodes[si2]; nodes.copyWithin(si2, si2 + 1); nodes[nodeCount - 1] = shallow2; } return nodes; } if (deepCount === 1) { let di2 = 0; while (nodes[di2].level !== deepLevel) { ++di2; } if (di2 > 0) { const deep = nodes[di2]; nodes.copyWithin(1, 0, di2); nodes[0] = deep; } return nodes; } const shallow = new Array(shallowCount); let di = 0; let si = 0; for (let i = 0;i < nodeCount; ++i) { const node = nodes[i]; if (node.level === deepLevel) { nodes[di++] = node; } else { shallow[si++] = node; } } for (let i = 0;i < shallowCount; ++i) { nodes[deepCount + i] = shallow[i]; } return nodes; }; var countingSort = (nodes, nodesLen) => { let deepest = nodes[0].level + 1; let shallowest = deepest; let unsorted = 0; let prevB = deepest; let buckets = _sortBuckets; if (!buckets || deepest >= buckets.length) { buckets = sortBucketsAlloc(deepest); } ++buckets[deepest]; for (let i = 1;i < nodesLen; ++i) { const b = nodes[i].level + 1; if (b > deepest) { deepest = b; if (deepest >= buckets.length) { buckets = sortBucketsAlloc(deepest); } } else if (b < shallowest) { shallowest = b; } ++buckets[b]; unsorted |= prevB - b; prevB = b; } if (unsorted >= 0) { buckets.fill(0, shallowest, deepest + 1); return nodes; } const sCount = buckets[shallowest]; const dCount = buckets[deepest]; if (sCount + dCount === nodesLen) { buckets[shallowest] = 0; buckets[deepest] = 0; return sortTwoLevels(nodes, nodesLen, deepest, dCount); } let pos = 0; for (let b = deepest;b >= shallowest; --b) { const count = buckets[b]; buckets[b] = pos; pos += count; } const output = new Array(nodesLen); for (let i = 0;i < nodesLen; ++i) { const node = nodes[i]; output[buckets[node.level + 1]++] = node; } buckets.fill(0, shallowest, deepest + 1); return output; }; var _sortNodesByDepthFirst = (nodes, nodesLen = nodes.length) => { if (nodesLen === 2) { if (nodes[0].level < nodes[1].level) { const tmp = nodes[0]; nodes[0] = nodes[1]; nodes[1] = tmp; } return nodes; } if (nodesLen > 16) { return countingSort(nodes, nodesLen); } for (let i = 1;i < nodesLen; i++) { const value = nodes[i]; const valueLevel = value.level; let j = i - 1; if (nodes[j].level < valueLevel) { let k = i; do { nodes[k] = nodes[j]; k = j--; } while (j >= 0 && nodes[j].level < valueLevel); nodes[k] = value; } } return nodes; }; var ChangedCellsPathImpl = class { constructor() { this.kind = "cells"; this.rows = []; this.unsorted = false; this.slots = /* @__PURE__ */ new Map; this.bits = []; this.extraBits = null; this.colCount = 0; } addRow(rowNode) { let node = rowNode; if (node == null) { return; } const slots = this.slots; if (slots.get(node) !== undefined) { while (node != null && slots.get(node) >= 0) { slots.set(node, -1); node = node.parent; } return; } const rows = this.rows; do { slots.set(node, -1); rows.push(node); node = node.parent; } while (node != null && !slots.has(node)); this.unsorted = true; } addCell(rowNode, colId) { if (colId == null) { this.addRow(rowNode); return; } if (rowNode == null) { return; } const slots = this.slots; const bits = this.bits; const colSlot = slots.get(colId) ?? this.ensureCol(colId); let rowSlot = slots.get(rowNode); if (rowSlot === undefined) { rowSlot = this.ensureRow(rowNode); } else if (rowSlot < 0) { return; } const word = colSlot < 32 ? bits : this.extraBits[(colSlot >>> 5) - 1]; const bit = 1 << (colSlot & 31); const rowBits = word[rowSlot]; if ((rowBits & bit) !== 0) { return; } word[rowSlot] = rowBits | bit; let parent = rowNode.parent; while (parent != null) { const pSlot = slots.get(parent); if (pSlot < 0) { break; } const pBits = word[pSlot]; if ((pBits & bit) !== 0) { break; } word[pSlot] = pBits | bit; parent = parent.parent; } } hasRow(rowNode) { return this.slots.has(rowNode); } getSortedRows() { if (!this.unsorted) { return this.rows; } this.unsorted = false; const rows = _sortNodesByDepthFirst(this.rows); this.rows = rows; return rows; } getSlot(key) { return this.slots.get(key) ?? -1; } hasCellBySlot(rowSlot, colSlot) { if (rowSlot < 0) { return true; } if (colSlot < 32) { return colSlot >= 0 && (this.bits[rowSlot] & 1 << colSlot) !== 0; } return (this.extraBits[(colSlot >>> 5) - 1][rowSlot] & 1 << (colSlot & 31)) !== 0; } ensureRow(rowNode) { const slots = this.slots; const rows = this.rows; const bits = this.bits; const extraBits = this.extraBits; let nextSlot = bits.push(0); const originSlot = nextSlot - 1; if (extraBits !== null) { for (let w = 0, len = extraBits.length;w < len; ++w) { extraBits[w].push(0); } } slots.set(rowNode, originSlot); rows.push(rowNode); this.unsorted = true; let p = rowNode.parent; while (p != null && !slots.has(p)) { slots.set(p, nextSlot); rows.push(p); nextSlot = bits.push(0); if (extraBits !== null) { for (let w = 0, len = extraBits.length;w < len; ++w) { extraBits[w].push(0); } } p = p.parent; } return originSlot; } ensureCol(colId) { const colSlot = this.colCount++; this.slots.set(colId, colSlot); if (colSlot >= 32) { const extraBitsIndex = (colSlot >>> 5) - 1; let extraBits = this.extraBits; if (extraBits === null) { extraBits = []; this.extraBits = extraBits; } if (extraBitsIndex >= extraBits.length) { extraBits.push(new Array(this.bits.length).fill(0)); } } return colSlot; } }; var ChangedRowsPathImpl = class { constructor() { this.kind = "rows"; this.rows = []; this.unsorted = false; this.rowSet = /* @__PURE__ */ new Set; } addRow(rowNode) { let node = rowNode; if (node == null) { return; } const rowSet = this.rowSet; if (rowSet.has(node)) { return; } const rows = this.rows; do { rowSet.add(node); rows.push(node); node = node.parent; } while (node != null && !rowSet.has(node)); this.unsorted = true; } addCell(rowNode, _colId) { this.addRow(rowNode); } hasRow(rowNode) { return this.rowSet.has(rowNode); } getSortedRows() { if (!this.unsorted) { return this.rows; } this.unsorted = false; const rows = _sortNodesByDepthFirst(this.rows); this.rows = rows; return rows; } }; var ChangedPathFactory = class extends BeanStub { constructor() { super(...arguments); this.beanName = "changedPathFactory"; } newPath(trackCells) { return trackCells ? new ChangedCellsPathImpl : new ChangedRowsPathImpl; } ensureRowsPath(params) { let changedPath = params.changedPath; if (!changedPath && params.changedRowNodes && !params.newData) { const rowModel = this.beans.rowModel; if (rowModel.hierarchical) { changedPath = new ChangedRowsPathImpl; params.changedPath = changedPath; changedPath.addRow(rowModel.rootNode); } } return changedPath; } }; var BaseExpansionService = class extends BeanStub { addExpandedCss(classes, rowNode) { if (rowNode.isExpandable()) { classes.push("ag-row-group"); classes.push(rowNode.expanded ? "ag-row-group-expanded" : "ag-row-group-contracted"); } } getRowExpandedListeners(rowCtrl) { const { rowNode } = rowCtrl; const updateExpandedCss = this.updateExpandedCss.bind(this, rowCtrl, rowNode); return { expandedChanged: updateExpandedCss, hasChildrenChanged: updateExpandedCss }; } setExpanded(rowNode, expanded, e, forceSync) { if (rowNode.expanded === expanded) { return; } rowNode._expanded = expanded; rowNode.dispatchRowEvent("expandedChanged"); const event = { ..._createGlobalRowEvent(rowNode, this.gos, "rowGroupOpened"), expanded, event: e || null }; this.dispatchExpandedEvent(event, forceSync); } defaultExpanded(rowNode) { const beans = this.beans; const gos = beans.gos; const level = rowNode.level ?? 0; const isGroupOpenByDefault = rowNode.group && gos.get("isGroupOpenByDefault"); if (!isGroupOpenByDefault) { const groupDefaultExpanded = gos.get("groupDefaultExpanded"); return groupDefaultExpanded === -1 || level < groupDefaultExpanded; } const params = _addGridCommonParams(gos, { rowNode, field: rowNode.field, key: rowNode.key, level, rowGroupColumn: rowNode.rowGroupColumn }); return !!isGroupOpenByDefault(params); } isExpandable(rowNode) { if (rowNode.footer) { return false; } if (this.beans.colModel.isPivotMode()) { return rowNode.hasChildren() && !rowNode.leafGroup; } return rowNode.hasChildren() || rowNode.master; } updateExpandedCss(rowCtrl, rowNode) { const expandable = rowNode.isExpandable(); const expanded = rowNode.expanded == true; rowCtrl.forEachGui(undefined, (gui) => { const rowComp = gui.rowComp; rowComp.toggleCss("ag-row-group", expandable); rowComp.toggleCss("ag-row-group-expanded", expandable && expanded); rowComp.toggleCss("ag-row-group-contracted", expandable && !expanded); _setAriaExpanded(gui.element, expandable && expanded); }); } dispatchStateUpdatedEvent() { this.eventSvc.dispatchEvent({ type: "rowExpansionStateChanged" }); } }; var ClientSideExpansionService = class extends BaseExpansionService { constructor() { super(...arguments); this.beanName = "expansionSvc"; this.events = null; this.dispatchExpandedDebounced = null; } destroy() { super.destroy(); this.events = null; this.dispatchExpandedDebounced = null; } setExpansionState(state) { const rowIdsToExpandSet = new Set(state.expandedRowGroupIds); this.beans.rowModel.forEachNode((node) => { const id = node.id; if (!id) { return; } node._expanded = rowIdsToExpandSet.has(id); }); this.onGroupExpandedOrCollapsed(); } getInternalExpansionState(allowCollapsed = false) { const expandedRowGroupIds = []; const collapsedRowGroupIds = []; this.beans.rowModel.forEachNode((node) => { const id = node.id; if (!id) { return; } if (node.expanded) { expandedRowGroupIds.push(id); } else if (allowCollapsed && node.isExpandable()) { collapsedRowGroupIds.push(id); } }); return { expandedRowGroupIds, collapsedRowGroupIds }; } getExpansionState() { return this.getInternalExpansionState(); } isExpanded(rowNode) { if (rowNode.footer) { return !!rowNode._expanded; } if (!(rowNode.group || rowNode.master) || rowNode.leafGroup && this.beans.colModel.isPivotMode()) { return false; } let value = rowNode._expanded; if (value === null) { value = this.defaultExpanded(rowNode) ?? false; rowNode._expanded = value; } return !!value; } resetExpansion() { const { rowModel } = this.beans; rowModel.forEachNode((node) => { if (!node.group && !node.master) { return; } node._expanded = null; }); this.onGroupExpandedOrCollapsed(); } expandAll(expand) { const { gos, rowModel, colModel, eventSvc } = this.beans; const usingTreeData = gos.get("treeData"); const usingPivotMode = colModel.isPivotActive(); const recursiveExpandOrCollapse = (rowNodes) => { if (!rowNodes) { return; } for (const rowNode of rowNodes) { const actionRow = () => { rowNode._expanded = expand; recursiveExpandOrCollapse(rowNode.childrenAfterGroup); }; if (rowNode.master) { actionRow(); continue; } if (usingTreeData) { const hasChildren = _exists(rowNode.childrenAfterGroup); if (hasChildren) { actionRow(); } continue; } if (usingPivotMode) { const notLeafGroup = !rowNode.leafGroup; if (notLeafGroup) { actionRow(); } continue; } const isRowGroup = rowNode.group; if (isRowGroup) { actionRow(); } } }; const rootNode = rowModel.rootNode; if (rootNode) { recursiveExpandOrCollapse(rootNode.childrenAfterGroup); } this.onGroupExpandedOrCollapsed(); eventSvc.dispatchEvent({ type: "expandOrCollapseAll", source: expand ? "expandAll" : "collapseAll" }); } onGroupExpandedOrCollapsed() { this.dispatchStateUpdatedEvent(); this.beans.rowModel.reMapRows(); } setDetailsExpansionState(detailGridApi) { const expansionState = this.getInternalExpansionState(true); const allExpanded = expansionState.collapsedRowGroupIds.length === 0; const allCollapsed = expansionState.expandedRowGroupIds.length === 0; if (allCollapsed === allExpanded) { return; } return allExpanded ? detailGridApi.expandAll() : detailGridApi.collapseAll(); } dispatchExpandedEvent(event, forceSync) { (this.events ?? (this.events = [])).push(event); if (forceSync) { this.dispatchExpandedEvents(); return; } let dispatch = this.dispatchExpandedDebounced; if (!dispatch) { if (!this.isAlive()) { return; } dispatch = this.debounce(() => this.dispatchExpandedEvents()); this.dispatchExpandedDebounced = dispatch; } dispatch(); } dispatchExpandedEvents() { const { eventSvc, rowRenderer } = this.beans; const eventsToDispatch = this.events; const eventsLen = eventsToDispatch?.length; if (!eventsLen) { return; } this.events = null; const rowNodes = new Array(eventsLen); for (let i = 0;i < eventsLen; ++i) { rowNodes[i] = eventsToDispatch[i].node; eventSvc.dispatchEvent(eventsToDispatch[i]); } this.dispatchStateUpdatedEvent(); rowRenderer.refreshCells({ rowNodes }); } debounce(func) { const animationFrameSvc = this.beans.animationFrameSvc; if (!animationFrameSvc) { return () => window.setTimeout(func, 0); } let pending = false; return () => { if (!animationFrameSvc.active) { window.setTimeout(func, 0); return; } if (pending) { return; } pending = true; animationFrameSvc.addDestroyTask(() => { pending = false; func(); }); }; } }; function _getFlattenDetails(gos) { let groupHideParentOfSingleChild = gos.get("groupHideParentOfSingleChild"); if (!groupHideParentOfSingleChild) { groupHideParentOfSingleChild = gos.get("groupRemoveSingleChildren"); if (!groupHideParentOfSingleChild && gos.get("groupRemoveLowestSingleChildren")) { groupHideParentOfSingleChild = "leafGroupsOnly"; } } return { groupHideParentOfSingleChild, isGroupMultiAutoColumn: _isGroupMultiAutoColumn(gos), hideOpenParents: gos.get("groupHideOpenParents"), grandTotalRow: _getGrandTotalRow(gos), groupTotalRow: _getGroupTotalRowCallback(gos) }; } function _isRemovedSingleChildrenGroup(details, rowNode, isParent) { return details.groupHideParentOfSingleChild === true && isParent && rowNode.childrenAfterGroup.length === 1; } function _isRemovedLowestSingleChildrenGroup(details, rowNode, isParent) { return details.groupHideParentOfSingleChild === "leafGroupsOnly" && isParent && rowNode.leafGroup && rowNode.childrenAfterGroup.length === 1; } function _shouldRowBeRendered(details, rowNode, isParent, skipLeafNodes, isRemovedSingleChildrenGroup, isRemovedLowestSingleChildrenGroup) { if (skipLeafNodes && !isParent) { return false; } if (isRemovedSingleChildrenGroup || isRemovedLowestSingleChildrenGroup) { return false; } if (!details.hideOpenParents) { return true; } if (rowNode.master || rowNode.level === -1) { return true; } const neverAllowToExpand = skipLeafNodes && rowNode.leafGroup; if (!neverAllowToExpand && rowNode.expanded) { return false; } return true; } var FlattenStage = class extends BeanStub { constructor() { super(...arguments); this.beanName = "flattenStage"; this.step = "map"; this.refreshProps = [ "groupHideParentOfSingleChild", "groupRemoveSingleChildren", "groupRemoveLowestSingleChildren", "groupTotalRow", "masterDetail" ]; } execute() { const { beans, gos } = this; const result = []; const rootNode = beans.rowModel.rootNode; if (!rootNode) { return result; } const skipLeafNodes = beans.colModel.isPivotMode(); const showRootNode = skipLeafNodes && rootNode.leafGroup && rootNode.aggData; const topList = showRootNode ? [rootNode] : rootNode.childrenAfterSort; const details = _getFlattenDetails(gos); this.recursivelyAddToRowsToDisplay(details, topList, result, skipLeafNodes, 0); const atLeastOneRowPresent = result.length > 0; const grandTotalRow = details.grandTotalRow; const includeGrandTotalRow = !showRootNode && atLeastOneRowPresent && grandTotalRow; if (includeGrandTotalRow) { _createRowNodeFooter(rootNode, beans); if (grandTotalRow === "pinnedBottom" || grandTotalRow === "pinnedTop") { this.beans.pinnedRowModel?.setGrandTotalPinned(grandTotalRow === "pinnedBottom" ? "bottom" : "top"); } else { const addToTop = grandTotalRow === "top"; this.addRowNodeToRowsToDisplay(details, rootNode.sibling, result, 0, addToTop); } } return result; } recursivelyAddToRowsToDisplay(details, rowsToFlatten, result, skipLeafNodes, uiLevel) { if (!rowsToFlatten?.length) { return; } const masterDetailSvc = this.beans.masterDetailSvc; for (let i = 0;i < rowsToFlatten.length; i++) { const rowNode = rowsToFlatten[i]; const isParent = rowNode.hasChildren(); const isRemovedSingleChildrenGroup = _isRemovedSingleChildrenGroup(details, rowNode, isParent); const isRemovedLowestSingleChildrenGroup = _isRemovedLowestSingleChildrenGroup(details, rowNode, isParent); const thisRowShouldBeRendered = _shouldRowBeRendered(details, rowNode, isParent, skipLeafNodes, isRemovedSingleChildrenGroup, isRemovedLowestSingleChildrenGroup); if (thisRowShouldBeRendered) { this.addRowNodeToRowsToDisplay(details, rowNode, result, uiLevel); } if (skipLeafNodes && rowNode.leafGroup) { continue; } if (isParent) { const excludedParent = isRemovedSingleChildrenGroup || isRemovedLowestSingleChildrenGroup; if (rowNode.expanded || excludedParent) { const doesRowShowFooter = details.groupTotalRow({ node: rowNode }); if (!doesRowShowFooter) { _destroyRowNodeFooter(rowNode); } const uiLevelForChildren = excludedParent ? uiLevel : uiLevel + 1; if (doesRowShowFooter === "top") { _createRowNodeFooter(rowNode, this.beans); this.addRowNodeToRowsToDisplay(details, rowNode.sibling, result, uiLevelForChildren); } const detailNode = masterDetailSvc?.getDetail(rowNode); if (detailNode) { this.addRowNodeToRowsToDisplay(details, detailNode, result, uiLevel); } this.recursivelyAddToRowsToDisplay(details, rowNode.childrenAfterSort, result, skipLeafNodes, uiLevelForChildren); if (doesRowShowFooter === "bottom") { _createRowNodeFooter(rowNode, this.beans); this.addRowNodeToRowsToDisplay(details, rowNode.sibling, result, uiLevelForChildren); } } } else { const detailNode = masterDetailSvc?.getDetail(rowNode); if (detailNode) { this.addRowNodeToRowsToDisplay(details, detailNode, result, uiLevel); } } } } addRowNodeToRowsToDisplay(details, rowNode, result, uiLevel, addToTop) { if (addToTop) { result.unshift(rowNode); } else { result.push(rowNode); } rowNode.setUiLevel(details.isGroupMultiAutoColumn ? 0 : uiLevel); } }; var GroupEditService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "groupEditSvc"; this.pendingEditRefresh = null; this.dropGroupTarget = null; this.dropGroupTimer = null; this.dropGroupThrottled = false; this.draggingGroups = null; } postConstruct() { if (_isClientSideRowModel(this.gos)) { this.addManagedListeners(this.eventSvc, { cellValueChanged: (event) => this.onCsrmCellChange(event), batchEditingStopped: () => this.flushGroupEdits() }); } } destroy() { this.stopDragging(true); super.destroy(); } isGroupingDrop(rowsDrop) { if (!rowsDrop.rowDragManaged || !rowsDrop.sameGrid) { return false; } if (!this.gos.get("refreshAfterGroupEdit")) { return false; } return !!this.beans.rowGroupColsSvc?.columns?.length && !this.beans.colModel.isPivotMode(); } initDraggingGroups(rowsDrop) { const structure = /* @__PURE__ */ new Map; const recurse = (row) => { const childrenAfterGroup = row.childrenAfterGroup; if (childrenAfterGroup) { if (structure.has(row)) { return; } const children = childrenAfterGroup.slice(); structure.set(row, children); for (const child of children) { recurse(child); } } }; for (const row of rowsDrop.rows) { if (row.group) { recurse(row); } } this.draggingGroups = structure; } canSetParent(rowsDrop) { if (!rowsDrop.sameGrid) { return false; } if (this.beans.groupStage?.treeData) { return true; } if (rowsDrop.rowDragManaged && !this.gos.get("refreshAfterGroupEdit")) { return false; } return !!this.beans.rowGroupColsSvc?.columns?.length; } canDropRow(rowNode, rowsDrop) { if (this.beans.groupStage?.treeData) { return !wouldCycle(rowNode, rowsDrop.newParent); } const { position, target, newParent, rootNode } = rowsDrop; const currentParent = rowNode.parent; if (rowNode.group && (isAncestorOrSelf(rowNode, target) || isAncestorOrSelf(rowNode, newParent))) { return false; } if (position === "inside") { return true; } if (newParent && newParent !== currentParent) { return newParent !== rootNode || currentParent === rootNode; } const comparisonParent = newParent ?? target?.parent ?? rootNode; if (comparisonParent !== currentParent) { return false; } const sourceLevel = rowNode.group ? rowNode.level : currentParent.level ?? -1; let targetLevel = -1; if (target) { targetLevel = target.group ? target.level : target.parent?.level ?? -1; } else if (comparisonParent) { targetLevel = comparisonParent.level; } if (sourceLevel >= 0 && targetLevel >= 0 && targetLevel !== sourceLevel) { return false; } return true; } fixRowsDrop(rowsDrop, canSetParent, fromNudge, yDelta) { const treeData = !!this.beans.groupStage?.treeData; rowsDrop.treeData = treeData; const isRowGrouping = !!this.beans.rowGroupColsSvc?.columns?.length || this.gos.get("pivotMode"); if (!isRowGrouping && !treeData) { return; } if (!this.draggingGroups && this.isGroupingDrop(rowsDrop) && !rowsDrop.suppressMoveWhenRowDragging) { this.initDraggingGroups(rowsDrop); } let target = rowsDrop.target; let newParent = null; let inside = false; const rootNode = rowsDrop.rootNode; const rowModel = this.beans.rowModel; const canStartGroup = this.canStartGroup(target, treeData); this.updateDropTarget(rowsDrop, fromNudge, canStartGroup); const lastRowIndex = this.beans.pageBounds?.getLastRow?.() ?? rowModel.getRowCount() - 1; if (canSetParent) { if (!target || yDelta >= 0.5 && target.rowIndex === lastRowIndex) { newParent = rootNode; } else if (rowsDrop.moved && target && this.dropGroupThrottled && this.shouldDropTargetBeParent(rowsDrop)) { newParent = target; } if (!newParent) { newParent = target?.parent ?? rootNode; } } if (!fromNudge && target && canStartGroup && !(target.group && target.expanded)) { this.startDropGroupDelay(target); } if (newParent) { if (target && newParent === target && newParent !== rootNode) { const firstRow = newParent.expanded ? _prevOrNextDisplayedRow(rowModel, 1, target) : null; if (firstRow?.parent === newParent) { target = firstRow; yDelta = -0.5; } else { inside = true; } } if (target && !inside) { let current = target; while (current && current !== rootNode && current !== newParent) { target = current; current = current.parent; } } } rowsDrop.target = target; rowsDrop.newParent = newParent; rowsDrop.yDelta = yDelta; rowsDrop.inside = inside; } clearNewSameParent(rowsDrop, canSetParent) { const newParent = rowsDrop.newParent; if (newParent && (!canSetParent || rowsHaveSameParent(rowsDrop.rows, newParent))) { rowsDrop.newParent = null; } } updateDropTarget(rowsDrop, fromNudge, canStartGroup) { const target = canStartGroup ? rowsDrop.target : null; if (this.dropGroupTarget && this.dropGroupTarget !== target) { this.resetDragGroup(); } if (!target?.childrenAfterSort?.length) { return; } if (fromNudge && this.dropGroupThrottled && !target.expanded && target.isExpandable?.()) { target.setExpanded(true, undefined, true); } if (this.canDropInTarget(target, rowsDrop)) { this.dropGroupThrottled = true; this.dropGroupTarget = target; } } canDropInTarget(target, rowsDrop) { if (target.expanded) { return true; } if (!target.group) { return false; } if (rowsDrop.pointerPos === "inside") { return true; } if (rowsDrop.treeData) { return false; } const rows = rowsDrop.rows; const targetLevel = target.level; for (let i = 0, len = rows.length;i < len; ++i) { const row = rows[i]; if (row !== target && row.group && row.level !== targetLevel) { return false; } } return true; } startDropGroupDelay(target) { if (this.dropGroupTarget && this.dropGroupTarget !== target) { this.resetDragGroup(); } this.dropGroupTarget = target; if (this.dropGroupTimer !== null) { return; } const delay = this.gos.get("rowDragInsertDelay"); this.dropGroupTimer = window.setTimeout(() => { this.dropGroupTimer = null; this.dropGroupThrottled = true; this.beans.dragAndDrop?.nudge(); }, delay); } resetDragGroup() { if (this.dropGroupTimer !== null) { window.clearTimeout(this.dropGroupTimer); this.dropGroupTimer = null; } this.dropGroupTarget = null; this.dropGroupThrottled = false; } stopDragging(final) { if (final) { this.draggingGroups = null; } this.resetDragGroup(); } shouldDropTargetBeParent({ target, rows, pointerPos, treeData }) { if (!target || pointerPos === "none") { return false; } if (pointerPos === "inside") { return true; } if (!treeData && target.group && !target.expanded) { return true; } if (pointerPos === "above") { return false; } const rowModel = this.beans.rowModel; const targetRowIndex = target.rowIndex; let nextRowIndex = targetRowIndex + 1; let nextRow; do { nextRow = rowModel.getRow(nextRowIndex++); } while (nextRow?.footer); const childrenAfterGroup = this.draggingGroups?.get(target) ?? target.childrenAfterGroup; if (nextRow && nextRow.parent === target && childrenAfterGroup?.length) { const rowsSet = new Set(rows); for (let i = 0, len = childrenAfterGroup.length;i < len; ++i) { const child = childrenAfterGroup[i]; if (child.rowIndex !== null && !rowsSet.has(child)) { return true; } } } return false; } dropGroupEdit(rowsDrop) { const { beans } = this; const position = rowsDrop.position; const target = rowsDrop.target ?? null; const rootNode = rowsDrop.rootNode; const parentForValues = rowsDrop.newParent ?? target?.parent ?? rootNode; const focusSvc = beans.focusSvc; const cellPosition = focusSvc.getFocusedCell(); const cellCtrl = cellPosition && _getCellByPosition(beans, cellPosition); const leafs = /* @__PURE__ */ new Set; const changedRowNodes = new ChangedRowNodes; const updates = changedRowNodes.updates; let newGroupValues; const processLeaf = (leafRow) => { if (leafs.has(leafRow)) { return; } leafs.add(leafRow); newGroupValues ?? (newGroupValues = this.newGroupValues(parentForValues)); if (this.setRowGroup(leafRow, newGroupValues)) { updates.add(leafRow); } }; const visitGroupedChildren = (groupNode) => { const children = this.draggingGroups?.get(groupNode) ?? groupNode.childrenAfterGroup; const childrenLen = children?.length; if (childrenLen) { for (let i = 0;i < childrenLen; ++i) { const child = children[i]; if (child.sourceRowIndex >= 0) { processLeaf(child); } else { visitGroupedChildren(child); } } } }; for (const row of rowsDrop.rows) { if (row.group) { visitGroupedChildren(row); } else { const firstLeaf = row.sourceRowIndex >= 0 && !row.destroyed ? row : this.csrmFirstLeaf(row); if (firstLeaf) { processLeaf(firstLeaf); } } } const reorderPosition = position === "inside" ? "above" : position; const reorderTarget = position === "inside" ? this.findFirstLeafForParent(parentForValues, leafs) ?? target : target; let orderChanged = false; if (leafs.size && reorderPosition !== "none") { orderChanged = _csrmReorderAllLeafs(rootNode._leafs, leafs, reorderTarget, reorderPosition === "above"); } if (!updates.size && !orderChanged) { return false; } changedRowNodes.reordered = orderChanged; for (const leaf of leafs) { changedRowNodes.updates.add(leaf); } this.csrmRefresh(changedRowNodes); if (cellCtrl) { cellCtrl.focusCell(); } else { focusSvc.clearFocusedCell(); } return true; } canStartGroup(target, treeData) { if (!target || target.level < 0 || target.footer || target.detail) { return false; } if (target.group) { return true; } return treeData; } flushGroupEdits() { const pending = this.pendingEditRefresh; if (pending) { this.pendingEditRefresh = null; this.csrmRefresh(pending); } } csrmRefresh(changedRowNodes) { const clientSideRowModel = this.beans.rowModel; const rootNode = clientSideRowModel.rootNode; if (!rootNode) { return; } clientSideRowModel.refreshModel({ step: "group", keepRenderedRows: true, animate: !this.gos.get("suppressAnimationFrame"), changedRowNodes }); } newGroupValues(parent) { const columns = this.beans.rowGroupColsSvc?.columns ?? []; const values = new Array(columns.length); let maxLevel = -1; let current = parent; while (current && current.level >= 0) { const column = columns[current.level]; if (column) { const colId = column.getColId(); const level = current.level; values[level] = current.groupData?.[colId] ?? current.key ?? undefined; if (level > maxLevel) { maxLevel = level; } } current = current.parent; } return { values, columns, maxLevel }; } setRowGroup(row, { values, columns, maxLevel }) { if (maxLevel < 0) { return false; } const { valueSvc, changeDetectionSvc } = this.beans; let changed = false; changeDetectionSvc?.beginDeferred(); try { for (let level = 0;level < columns.length; ++level) { const column = columns[level]; if (!column || level > maxLevel) { continue; } const newValue = values[level]; const currentValue = valueSvc.getValue(column, row, "data"); if (currentValue === newValue || currentValue == null && newValue == null) { continue; } let valueToSet = newValue; const parsedValue = valueSvc.parseValue(column, row, newValue, currentValue); if (parsedValue !== undefined) { valueToSet = parsedValue; } const updated = row.setDataValue(column, valueToSet, "rowDrag"); if (updated) { changed = true; } } } finally { changeDetectionSvc?.endDeferred(); } return changed; } onCsrmCellChange(event) { const { column, node, source } = event; if (!this.gos.get("refreshAfterGroupEdit")) { return; } if (source === "rowDrag") { return; } if (!column?.isRowGroupActive()) { return; } if (node.group || !node.data) { return; } const editSvc = this.beans.editSvc; if (editSvc?.isBatchEditing()) { let pending = this.pendingEditRefresh; if (!pending) { pending = newEditChangedRowNodes(); this.pendingEditRefresh = pending; } pending.updates.add(node); } else { const changedRowNodes = newEditChangedRowNodes(); changedRowNodes.updates.add(node); this.csrmRefresh(changedRowNodes); } } csrmFirstLeaf(parent) { if (!parent) { return null; } const draggingGroups = this.draggingGroups; let children = draggingGroups?.get(parent) ?? parent.childrenAfterGroup; while (children?.length) { const child = children[0]; if (child.sourceRowIndex >= 0) { if (!child.destroyed) { return child; } return this.firstAliveChildLeaf(child); } children = draggingGroups?.get(child) ?? child.childrenAfterGroup; } return _csrmFirstLeaf(parent); } firstAliveChildLeaf(parent) { const children = this.draggingGroups?.get(parent) ?? parent.childrenAfterGroup; if (children) { for (const grandChild of children) { if (grandChild.sourceRowIndex >= 0 && !grandChild.destroyed) { return grandChild; } } } return null; } findFirstLeafForParent(parent, exclude) { if (!parent) { return null; } const children = this.draggingGroups?.get(parent) ?? parent?.childrenAfterGroup; if (!children) { return null; } for (let i = 0, len = children.length;i < len; ++i) { const child = children[i]; if (child.sourceRowIndex >= 0 && !exclude.has(child)) { return child; } const found = this.findFirstLeafForParent(child, exclude); if (found !== null) { return found; } } return null; } }; var newEditChangedRowNodes = () => { const result = new ChangedRowNodes; result.reordered = true; return result; }; var isAncestorOrSelf = (candidate, node) => { if (!candidate || !node) { return false; } let current = node; while (current) { if (current === candidate) { return true; } current = current.parent; } return false; }; var wouldCycle = (row, newParent) => { if (!newParent || row.parent === newParent) { return false; } let current = newParent; const rowId = row.id; while (current) { if (current === row) { return true; } if (rowId != null && current.id === rowId) { return true; } current = current.parent; } return false; }; var rowsHaveSameParent = (rows, newParent) => { for (let i = 0, len = rows.length;i < len; ++i) { if (rows[i].parent !== newParent) { return false; } } return true; }; var GroupStage = class extends BeanStub { constructor() { super(...arguments); this.beanName = "groupStage"; this.step = "group"; this.refreshProps = [ "groupAllowUnbalanced", "groupDefaultExpanded", "groupDisplayType", "groupHideOpenParents", "initialGroupOrderComparator", "treeData", "treeDataChildrenField", "treeDataParentIdField" ]; this.treeData = false; this.grouping = false; this.gosTreeData = false; this.pivotMode = false; this.hasTreeData = false; this.hasRowGrouping = false; this.needReset = false; this.nested = false; this.strategy = undefined; this.strategyType = undefined; this.columnsInvalidated = false; } postConstruct() { const gos = this.gos; this.hasRowGrouping = gos.isModuleRegistered("RowGrouping"); if (gos.isModuleRegistered("TreeData")) { this.hasTreeData = true; this.gosTreeData = gos.get("treeData"); } this.addManagedEventListeners({ showRowGroupColsSetChanged: () => this.strategy?.onShowRowGroupColsSetChanged() }); } invalidateGroupCols() { this.columnsInvalidated = true; this.strategy?.invalidateGroupCols?.(); } destroy() { this.strategy = this.destroyBean(this.strategy); super.destroy(); } getNonLeaf(id) { return this.strategy?.nonLeafsById?.get(id); } getNestedDataGetter() { return this.getStrategy()?.nestedDataGetter; } onPropChange(changedProps) { const gos = this.gos; const oldNestedDataGetter = this.strategy?.nestedDataGetter; if (changedProps.has("treeData")) { this.gosTreeData = gos.get("treeData") && this.hasTreeData; this.columnsInvalidated = true; } this.strategy?.onPropChange?.(changedProps); return this.getNestedDataGetter() !== oldNestedDataGetter; } extractData() { const rootNode = this.beans.rowModel.rootNode; const nodes = this.nested ? rootNode?.childrenAfterGroup : rootNode?._leafs; if (!nodes) { return this.gos.get("rowData") ?? []; } const len = nodes.length; const result = new Array(len); let writeIdx = 0; for (let i = 0;i < len; ++i) { const data = nodes[i].data; if (data != null) { result[writeIdx++] = data; } } result.length = writeIdx; return result; } execute(params) { const beans = this.beans; const rowModel = beans.rowModel; const rootNode = rowModel.rootNode; if (!rootNode) { return false; } const strategy = this.getStrategy(); const nested = !!strategy?.nestedDataGetter; const needReset = this.needReset; this.nested = nested; if (needReset) { this.needReset = false; beans.rowDragSvc?.cancelRowDrag(); params.animate = false; resetGrouping(rootNode, !nested, beans); } if (!strategy) { rowModel.hierarchical = false; return; } rowModel.hierarchical = true; beans.changedPathFactory?.ensureRowsPath(params, rootNode); const executeResult = strategy.execute(rootNode, params); return executeResult || needReset; } loadLeafs(node) { return node.footer ? loadFooterLeafs(node) : loadRealLeafs(node); } loadGroupData(node) { const strategy = this.getStrategy(); if (strategy) { return strategy.loadGroupData(node); } node._groupData = null; return null; } clearNonLeafs() { this.strategy?.clearNonLeafs(); } getWantedStrategyType() { if (this.isAlive()) { if (this.gosTreeData) { return "tree"; } if (this.hasRowGrouping && (this.beans.rowGroupColsSvc?.columns?.length || this.pivotMode)) { return "group"; } } return "none"; } getStrategy() { let strategy = this.strategy; const pivotMode = this.beans.colModel.isPivotMode(); if (pivotMode !== this.pivotMode) { this.pivotMode = pivotMode; this.columnsInvalidated = true; } if (strategy !== undefined && !this.columnsInvalidated && this.isAlive()) { return strategy; } this.columnsInvalidated = false; const wantedType = this.getWantedStrategyType(); if (wantedType === this.strategyType) { if (strategy !== undefined) { return strategy; } this.strategy = null; return null; } if (strategy) { this.strategy = this.destroyBean(strategy); this.needReset = true; } this.strategyType = wantedType; this.treeData = wantedType === "tree"; this.grouping = wantedType === "group"; if (wantedType === "none") { this.strategy = null; return null; } const beanName = wantedType === "tree" ? "treeGroupStrategy" : "groupStrategy"; strategy = this.beans.registry.createDynamicBean(beanName, false) ?? null; this.strategy = strategy && this.createBean(strategy); return strategy; } }; var loadFooterLeafs = (node) => { const sibling = node.sibling; if (!sibling) { return null; } const siblingLeafs = sibling._leafs; if (siblingLeafs !== undefined) { return siblingLeafs; } return loadRealLeafs(sibling); }; var loadRealLeafs = (node) => { const childrenAfterGroup = node.childrenAfterGroup; const childrenAfterGroupLen = childrenAfterGroup?.length; node._leafs = null; if (!childrenAfterGroupLen) { return null; } let leafs; const onlyChild = childrenAfterGroupLen === 1 ? childrenAfterGroup[0] : null; if (onlyChild?.group && onlyChild.sourceRowIndex < 0) { leafs = onlyChild._leafs; if (leafs === undefined) { leafs = loadRealLeafs(onlyChild); } } else if (node.leafGroup) { leafs = childrenAfterGroup; } else { leafs = []; for (let i = 0;i < childrenAfterGroupLen; ++i) { const child = childrenAfterGroup[i]; if (child.sourceRowIndex >= 0) { leafs.push(child); } if (!child.group) { continue; } let childLeafs = child._leafs; if (childLeafs === undefined) { childLeafs = loadRealLeafs(child); } if (childLeafs) { for (let j = 0, len = childLeafs.length;j < len; ++j) { leafs.push(childLeafs[j]); } } } } node._leafs = leafs; return leafs; }; var resetGrouping = (rootNode, canResetTreeNode, beans) => { const allLeafs = rootNode._leafs; const rootSibling = rootNode.sibling; rootNode.treeNodeFlags = 0; rootNode.childrenAfterGroup = allLeafs; rootNode.childrenMapped = null; rootNode._groupData = undefined; rootNode.aggData = null; if (rootSibling) { rootSibling.childrenAfterGroup = rootNode.childrenAfterGroup; rootSibling.childrenAfterAggFilter = rootNode.childrenAfterAggFilter; rootSibling.childrenAfterFilter = rootNode.childrenAfterFilter; rootSibling.childrenAfterSort = rootNode.childrenAfterSort; rootSibling.childrenMapped = null; rootSibling._groupData = undefined; rootSibling.aggData = null; } for (let i = 0, allLeafsLen = allLeafs.length ?? 0;i < allLeafsLen; ++i) { const row = allLeafs[i]; const sibling = row.sibling; row._leafs = undefined; resetChildRowGrouping(row); if (sibling) { resetChildRowGrouping(sibling); } row.parent = rootNode; if (canResetTreeNode) { row.treeParent = null; } setRowNodeGroup(row, beans, false); } rootNode.updateHasChildren(); }; var resetChildRowGrouping = (row) => { row.key = null; row.treeNodeFlags = 0; row.allChildrenCount = null; row.childrenAfterGroup = null; row.childrenAfterAggFilter = null; row.childrenAfterFilter = null; row.childrenAfterSort = null; row.childrenMapped = null; row.level = 0; row._groupData = undefined; }; function _isHiddenParent(node, ancestor, gos) { let currentNode = node; const levelDiff = currentNode.level - ancestor.level; if (levelDiff <= 0) { return false; } const isHideOpenParents = gos.get("groupHideOpenParents"); if (!isHideOpenParents) { return false; } for (let i = 0;i < levelDiff; i++) { const isFirstChild = currentNode.parent?.getFirstChild() === currentNode; if (!isFirstChild) { return false; } currentNode = currentNode.parent; } return currentNode === ancestor; } var GroupCellRendererCtrl = class extends BeanStub { constructor() { super(...arguments); this.indentClass = null; } init(comp, eGui, eCheckbox, eExpanded, eContracted, compClass, params) { this.params = params; this.eGui = eGui; this.eCheckbox = eCheckbox; this.eExpanded = eExpanded; this.eContracted = eContracted; this.comp = comp; this.compClass = compClass; const { node, column } = params; this.node = node; this.displayedNode = node; const embeddedRowMismatch = this.isEmbeddedRowMismatch(); if (embeddedRowMismatch) { return; } if (node.footer) { this.initFooterCell(); return; } if (!column) { this.initFullWidthCell(); return; } this.displayedNode = this.beans.showRowGroupColValueSvc?.getDisplayedNode(node, column) ?? this.node; this.setupExpand(); this.setupCheckbox(); this.addGroupValue(); this.setupIndent(); } initFooterCell() { const { node } = this.params; this.addGroupValue(); this.setupIndent(); const isGrandTotal = node.level === -1; if (!isGrandTotal) { this.comp.toggleCss("ag-row-group-leaf-indent", true); } } initFullWidthCell() { const setupDragger = () => { const { rowDragSvc } = this.beans; if (!this.params.rowDrag || !rowDragSvc) { return; } const rowDragComp = rowDragSvc.createRowDragComp(() => this.params.value, this.params.node); this.createManagedBean(rowDragComp); this.eGui.insertAdjacentElement("afterbegin", rowDragComp.getGui()); }; this.setupExpand(); setupDragger(); this.setupCheckbox(); this.addGroupValue(); this.setupIndent(); } getCellAriaRole() { const colDefAriaRole = this.params.colDef?.cellAriaRole; const columnColDefAriaRole = this.params.column?.getColDef().cellAriaRole; return colDefAriaRole || columnColDefAriaRole || "gridcell"; } isEmbeddedRowMismatch() { if (!this.params.fullWidth || !this.gos.get("embedFullWidthRows")) { return false; } const { visibleCols } = this.beans; const pinnedLeftCell = this.params.pinned === "left"; const pinnedRightCell = this.params.pinned === "right"; const bodyCell = !pinnedLeftCell && !pinnedRightCell; if (this.gos.get("enableRtl")) { if (visibleCols.isPinningLeft()) { return !pinnedRightCell; } return !bodyCell; } if (visibleCols.isPinningLeft()) { return !pinnedLeftCell; } return !bodyCell; } addGroupValue() { const { params: { value, valueFormatted } } = this; const innerCompDetails = this.getInnerCompDetails(); this.comp.setInnerRenderer(innerCompDetails, valueFormatted ?? value ?? null); } setupExpand() { const { colModel } = this.beans; const { eGridCell, suppressDoubleClickExpand } = this.params; const addIconToDom = (iconName, element) => { const icon = _createIconNoSpan(iconName, this.beans, null); if (icon) { element.appendChild(icon); this.addDestroyFunc(() => icon.remove()); } }; addIconToDom("groupExpanded", this.eExpanded); addIconToDom("groupContracted", this.eContracted); const comp = this.comp; const onExpandedChanged = () => { const expandable = this.isExpandable(); if (!expandable) { return; } const expanded = !!this.displayedNode.expanded; comp.setExpandedDisplayed(expanded); comp.setContractedDisplayed(!expanded); _setAriaExpanded(eGridCell, expanded); }; const onExpandableChanged = () => { const expandable = this.isExpandable(); comp.toggleCss("ag-cell-expandable", expandable); comp.toggleCss("ag-row-group", expandable); const pivotModeAndLeaf = !expandable && colModel.isPivotMode(); comp.toggleCss("ag-pivot-leaf-group", pivotModeAndLeaf); const normalModeNotTotalFooter = !colModel.isPivotMode() && (!this.displayedNode.footer || this.displayedNode.level !== -1); comp.toggleCss("ag-row-group-leaf-indent", !expandable && normalModeNotTotalFooter); const count = this.getChildCount(); const countString = count > 0 ? `(${count})` : ``; comp.setChildCount(countString); if (!expandable) { comp.setExpandedDisplayed(false); comp.setContractedDisplayed(false); _removeAriaExpanded(eGridCell); } else { onExpandedChanged(); } }; const setupListeners = () => { if (!suppressDoubleClickExpand && !this.isGroupCellEditable(this.displayedNode)) { this.addManagedListeners(eGridCell, { dblclick: this.onCellDblClicked.bind(this) }); } this.addManagedListeners(this.eExpanded, { click: this.onExpandClicked.bind(this) }); this.addManagedListeners(this.eContracted, { click: this.onExpandClicked.bind(this) }); this.addManagedListeners(eGridCell, { keydown: this.onKeyDown.bind(this) }); this.addManagedListeners(this.displayedNode, { allChildrenCountChanged: onExpandableChanged, masterChanged: onExpandableChanged, groupChanged: onExpandableChanged, hasChildrenChanged: onExpandableChanged, expandedChanged: onExpandedChanged }); }; setupListeners(); onExpandableChanged(); } getInnerCompDetails() { const { userCompFactory, findSvc } = this.beans; const params = this.params; if (params.fullWidth) { const groupRowRendererParams = this.gos.get("groupRowRendererParams"); const groupRowInnerCompDetails = _getInnerCellRendererDetails(userCompFactory, groupRowRendererParams, params); if (groupRowInnerCompDetails) { return groupRowInnerCompDetails; } if (findSvc?.isMatch(params.node, null)) { return _getInnerCellRendererDetails(userCompFactory, { ...groupRowRendererParams, innerRenderer: "agFindCellRenderer" }, params); } return; } const isGroupRowRenderer = (details) => details && details.componentClass == this.compClass; const innerCompDetails = _getInnerCellRendererDetails(userCompFactory, params, params); if (innerCompDetails && !isGroupRowRenderer(innerCompDetails)) { return innerCompDetails; } const { displayedNode: { rowGroupColumn } } = this; const relatedColDef = rowGroupColumn?.colDef; const isShowingThisCol = rowGroupColumn && params.column?.isRowGroupDisplayed(rowGroupColumn.getId()); if (relatedColDef && isShowingThisCol) { const relatedCompDetails = _getCellRendererDetails(userCompFactory, relatedColDef, params); if (relatedCompDetails) { if (isGroupRowRenderer(relatedCompDetails)) { if (relatedColDef?.cellRendererParams?.innerRenderer) { return _getInnerCellRendererDetails(userCompFactory, relatedColDef.cellRendererParams, params); } } else { return relatedCompDetails; } } } if (findSvc?.isMatch(params.node, params.column)) { return _getCellRendererDetails(userCompFactory, { ...relatedColDef ?? params.colDef, cellRenderer: "agFindCellRenderer" }, params); } } getChildCount() { const { column, suppressCount } = this.params; if (suppressCount) { return 0; } const { allChildrenCount, rowGroupColumn } = this.displayedNode; const isDisplayingRowGroupCell = (allChildrenCount ?? 0) > 0 && (!rowGroupColumn || !column || column?.isRowGroupDisplayed(rowGroupColumn.getId())); if (!isDisplayingRowGroupCell) { return 0; } const isRepresentingOtherNode = this.gos.get("showOpenedGroup") && this.displayedNode !== this.node; if (isRepresentingOtherNode && !_isHiddenParent(this.node, this.displayedNode, this.gos)) { return 0; } return allChildrenCount ?? 0; } isExpandable() { const { node, column, colDef } = this.params; if (!this.displayedNode.isExpandable()) { return false; } if (node.rowPinned) { return false; } const isFullWidth = !column; if (isFullWidth) { return true; } const hasChildren = node.hasChildren(); if (hasChildren && colDef) { const { showRowGroup } = colDef; if (!showRowGroup) { return false; } if (showRowGroup === true) { return true; } } if (node === this.displayedNode) { if (node.rowGroupColumn) { const showingThisRowGroup = column?.isRowGroupDisplayed(node.rowGroupColumn.getId()); if (showingThisRowGroup) { return true; } } if (node.master) { return colDef?.showRowGroup === true || colDef?.showRowGroup == null; } return false; } return _isHiddenParent(this.node, this.displayedNode, this.gos); } setupIndent() { const { suppressPadding, node, colDef } = this.params; if (suppressPadding) { return; } const setIndent = () => { let level = node.uiLevel; if (colDef && colDef.showRowGroup !== true) { level = 0; } const newIndentClass = "ag-row-group-indent-" + level; if (newIndentClass === this.indentClass) { return; } if (this.indentClass) { this.comp.toggleCss(this.indentClass, false); } this.indentClass = newIndentClass; this.comp.toggleCss(newIndentClass, true); this.eGui.style.setProperty("--ag-indentation-level", String(level)); }; this.addManagedListeners(node, { uiLevelChanged: setIndent.bind(this) }); setIndent(); } setupCheckbox() { const { node } = this.params; const isRowSelectable = !node.footer && !node.rowPinned && !node.detail; if (!isRowSelectable) { return; } this.addManagedPropertyListener("rowSelection", ({ currentValue, previousValue }) => { const curr = typeof currentValue === "object" ? currentValue : undefined; const prev = typeof previousValue === "object" ? previousValue : undefined; if (curr?.checkboxLocation !== prev?.checkboxLocation) { this.destroyCheckbox(); this.addCheckbox(); } }); this.addCheckbox(); } addCheckbox() { const { selectionSvc } = this.beans; if (!selectionSvc || !_isRowSelection(this.gos)) { return; } const { node, column } = this.params; const rowSelection = this.gos.get("rowSelection"); const checkboxLocation = _getCheckboxLocation(rowSelection); if (checkboxLocation === "selectionColumn") { return; } if (checkboxLocation === "autoGroupColumn") { const isGroupColumn = column?.getColDef().showRowGroup != null; const isFullWidthGroupRow = !column && node.group; const isApplicableCell = isGroupColumn || isFullWidthGroupRow; if (!isApplicableCell) { return; } } const checkboxes = typeof rowSelection === "object" ? _getCheckboxes(rowSelection) : this.params.checkbox; const userWantsCheckboxes = typeof checkboxes === "function" || checkboxes === true; if (!userWantsCheckboxes) { return; } const isMultiAutoCol = typeof column?.getColDef().showRowGroup === "string"; if (isMultiAutoCol && !this.isExpandable()) { this.comp.setCheckboxSpacing(true); return; } const cbSelectionComponent = selectionSvc.createCheckboxSelectionComponent(); this.cbComp = cbSelectionComponent; this.createBean(cbSelectionComponent); cbSelectionComponent.init({ rowNode: node, column, overrides: { isVisible: checkboxes, callbackParams: this.params, removeHidden: true } }); this.eCheckbox.appendChild(cbSelectionComponent.getGui()); this.comp.setCheckboxVisible(true); } destroyCheckbox() { this.comp.setCheckboxSpacing(false); this.comp.setCheckboxVisible(false); this.cbComp?.getGui().remove(); this.cbComp = this.destroyBean(this.cbComp); } isGroupCellEditable(node) { const column = this.params.column; return !!column && (!!column.getColDef().groupRowEditable || this.gos.get("enableGroupEdit")) && column.isCellEditable(node); } onExpandClicked(mouseEvent) { if (_isStopPropagationForAgGrid(mouseEvent)) { return; } _stopPropagationForAgGrid(mouseEvent); this.onExpandOrContract(mouseEvent); } onKeyDown(event) { const isEnterKey = event.key === KeyCode.ENTER; if (!isEnterKey || this.params.suppressEnterExpand) { return; } if (this.isGroupCellEditable(this.params.node)) { return; } this.onExpandOrContract(event); } onCellDblClicked(mouseEvent) { if (_isStopPropagationForAgGrid(mouseEvent)) { return; } const targetIsExpandIcon = _isElementInEventPath(this.eExpanded, mouseEvent) || _isElementInEventPath(this.eContracted, mouseEvent); if (!targetIsExpandIcon) { this.onExpandOrContract(mouseEvent); } } onExpandOrContract(e) { if (!this.isExpandable()) { return; } const rowNode = this.displayedNode; const nextExpandState = !rowNode.expanded; if (!nextExpandState && rowNode.sticky) { this.beans.ctrlsSvc.getScrollFeature().setVerticalScrollPosition(rowNode.rowTop - rowNode.stickyRowTop); } rowNode.setExpanded(nextExpandState, e); } destroy() { super.destroy(); this.destroyCheckbox(); } }; var GroupCellRendererElement = { tag: "span", cls: "ag-cell-wrapper", children: [ { tag: "span", ref: "eExpanded", cls: "ag-group-expanded ag-hidden" }, { tag: "span", ref: "eContracted", cls: "ag-group-contracted ag-hidden" }, { tag: "span", ref: "eCheckbox", cls: "ag-group-checkbox ag-invisible" }, { tag: "span", ref: "eValue", cls: "ag-group-value" }, { tag: "span", ref: "eChildCount", cls: "ag-group-child-count" } ] }; var GroupCellRenderer = class extends Component { constructor() { super(GroupCellRendererElement); this.eExpanded = RefPlaceholder; this.eContracted = RefPlaceholder; this.eCheckbox = RefPlaceholder; this.eValue = RefPlaceholder; this.eChildCount = RefPlaceholder; } init(params) { const compProxy = { setInnerRenderer: (compDetails, valueToDisplay) => this.setRenderDetails(compDetails, valueToDisplay), setChildCount: (count) => this.eChildCount.textContent = count, toggleCss: (cssClass, value) => this.toggleCss(cssClass, value), setContractedDisplayed: (expanded) => _setDisplayed(this.eContracted, expanded), setExpandedDisplayed: (expanded) => _setDisplayed(this.eExpanded, expanded), setCheckboxVisible: (visible) => this.eCheckbox.classList.toggle("ag-invisible", !visible), setCheckboxSpacing: (add) => this.eCheckbox.classList.toggle("ag-group-checkbox-spacing", add) }; const ctrl = this.createManagedBean(new GroupCellRendererCtrl); const fullWidth = !params.colDef; const eGui = this.getGui(); ctrl.init(compProxy, eGui, this.eCheckbox, this.eExpanded, this.eContracted, this.constructor, params); if (fullWidth) { _setAriaRole(eGui, ctrl.getCellAriaRole()); } } setRenderDetails(compDetails, valueToDisplay) { if (compDetails) { compDetails.newAgStackInstance().then((comp) => { if (!comp) { return; } const destroyComp = () => this.destroyBean(comp); if (this.isAlive()) { this.eValue.appendChild(comp.getGui()); this.addDestroyFunc(destroyComp); } else { destroyComp(); } }); } else { this.eValue.innerText = valueToDisplay; } } destroy() { this.destroyBean(this.innerCellRenderer); super.destroy(); } refresh() { return false; } }; var groupCellStyles_default = ".ag-group-checkbox-spacing{width:var(--ag-icon-size)}:where(.ag-ltr) .ag-group-checkbox-spacing{margin-right:var(--ag-cell-widget-spacing)}:where(.ag-rtl) .ag-group-checkbox-spacing{margin-left:var(--ag-cell-widget-spacing)}"; var ShowRowGroupColValueService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "showRowGroupColValueSvc"; } getGroupValue(node, column, ignoreAggData) { if (!column) { if (!node.group) { return null; } return { displayedNode: node, value: node.groupValue }; } const valueSvc = this.beans.valueSvc; const rowGroupColId = column.colDef.showRowGroup; if (!rowGroupColId) { return null; } if (node.level === -1 && node.footer) { return { displayedNode: node, value: null }; } if (typeof rowGroupColId === "string") { const colRowGroupIndex = this.beans.rowGroupColsSvc?.getColumnIndex(rowGroupColId) ?? -1; if (colRowGroupIndex > node.level) { return null; } const hideOpenParentsNode = this.getDisplayedNode(node, column, true); if (hideOpenParentsNode) { return { displayedNode: hideOpenParentsNode, value: valueSvc.getValue(column, hideOpenParentsNode, "data", ignoreAggData) }; } } const value = valueSvc.getValue(column, node, "data", ignoreAggData); if (value == null) { const displayedNode = this.getDisplayedNode(node, column); if (displayedNode) { return { displayedNode, value: valueSvc.getValue(column, displayedNode, "data", ignoreAggData) }; } } return { displayedNode: node, value }; } formatAndPrefixGroupColValue(groupValue, column, exporting = false) { const formattedValue = this.formatGroupColValue(groupValue, column, exporting); const { value, displayedNode } = groupValue; const footerSvc = this.beans.footerSvc; if (footerSvc?.doesCellShowTotalPrefix(displayedNode, column)) { const footerValue = footerSvc.applyTotalPrefix(value, formattedValue, displayedNode, column); return footerValue; } if (displayedNode.footer && displayedNode.level === -1) { return null; } return formattedValue; } formatGroupColValue(groupValue, column, exporting = false) { const valueSvc = this.beans.valueSvc; const { displayedNode, value } = groupValue; const groupedCol = displayedNode.rowGroupColumn; const isFullWidthGroup = displayedNode.group && !column; const isShowingGroupCell = groupedCol && (isFullWidthGroup || column?.isRowGroupDisplayed(groupedCol.colId)); if (isShowingGroupCell) { if (exporting && groupedCol.colDef.useValueFormatterForExport === false) { return null; } const formattedValue = valueSvc.formatValue(groupedCol, displayedNode, value); if (formattedValue == null && displayedNode.key === "") { const localeTextFunc = this.getLocaleTextFunc(); return localeTextFunc("blanks", "(Blanks)"); } return formattedValue; } if (!column || displayedNode.group) { return null; } if (exporting && column.colDef.useValueFormatterForExport === false) { return null; } return valueSvc.formatValue(column, displayedNode, value); } getDisplayedNode(node, column, onlyHideOpenParents = false) { const gos = this.gos; const isGroupHideOpenParents = gos.get("groupHideOpenParents"); const isShowOpenedGroupValue = gos.get("showOpenedGroup") && !onlyHideOpenParents; if (!isGroupHideOpenParents && !isShowOpenedGroupValue) { return; } const showRowGroup = column.colDef.showRowGroup; if (showRowGroup === true) { if (node.group) { return; } return node.parent ?? undefined; } let pointer = node; while (pointer && pointer.rowGroupColumn?.getId() != showRowGroup) { const isFirstChild = pointer === pointer.parent?.getFirstChild(); if (!isShowOpenedGroupValue && !isFirstChild) { return; } pointer = pointer.parent; } if (pointer === node) { return; } return pointer ?? undefined; } }; var ShowRowGroupColsService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "showRowGroupCols"; this.columns = []; this.colsSet = /* @__PURE__ */ new Set; this.colsMap = /* @__PURE__ */ new Map; } destroy() { super.destroy(); this.columns.length = 0; this.colsSet.clear(); this.colsMap.clear(); } refresh() { const { colModel, rowGroupColsSvc } = this.beans; const showRowGroupCols = this.columns; const showRowGroupColsSet = this.colsSet; const showRowGroupColsMap = this.colsMap; showRowGroupColsMap.clear(); const oldShowRowGroupColsLLen = showRowGroupCols.length; let showRowGroupColsCount = 0; let showRowGroupColsSetChanged = false; const cols = colModel.getCols(); for (let colIdx = 0, colsLen = cols.length;colIdx < colsLen; ++colIdx) { const col = cols[colIdx]; const colDef = col.getColDef(); const showRowGroup = colDef.showRowGroup; if (typeof showRowGroup === "string") { showRowGroupColsMap.set(showRowGroup, col); } else if (showRowGroup === true) { const groupColumns = rowGroupColsSvc?.columns; if (groupColumns) { for (let grpColIdx = 0, grpColsLen = groupColumns.length;grpColIdx < grpColsLen; ++grpColIdx) { showRowGroupColsMap.set(groupColumns[grpColIdx].getId(), col); } } } else { continue; } showRowGroupColsSetChanged || (showRowGroupColsSetChanged = showRowGroupColsCount >= oldShowRowGroupColsLLen || !showRowGroupColsSet.has(col)); showRowGroupCols[showRowGroupColsCount++] = col; } showRowGroupColsSetChanged || (showRowGroupColsSetChanged = showRowGroupColsCount !== oldShowRowGroupColsLLen); if (showRowGroupColsSetChanged) { showRowGroupCols.length = showRowGroupColsCount; showRowGroupColsSet.clear(); for (let j = 0;j < showRowGroupColsCount; ++j) { showRowGroupColsSet.add(showRowGroupCols[j]); } this.eventSvc.dispatchEvent({ type: "showRowGroupColsSetChanged" }); } } getShowRowGroupCol(id) { return this.colsMap.get(id); } getSourceColumnsForGroupColumn(groupCol) { const sourceColumnId = groupCol.getColDef().showRowGroup; if (!sourceColumnId) { return null; } const { rowGroupColsSvc, colModel } = this.beans; if (sourceColumnId === true && rowGroupColsSvc) { return rowGroupColsSvc.columns; } const column = colModel.getColDefCol(sourceColumnId); return column ? [column] : null; } isRowGroupDisplayed(column, colId) { const showRowGroup = column.getColDef()?.showRowGroup; return showRowGroup === true || showRowGroup != null && showRowGroup === colId; } }; var StickyRowFeature = class extends BeanStub { constructor(createRowCon, destroyRowCtrls) { super(); this.createRowCon = createRowCon; this.destroyRowCtrls = destroyRowCtrls; this.stickyTopRowCtrls = []; this.stickyBottomRowCtrls = []; this.extraTopHeight = 0; this.extraBottomHeight = 0; } postConstruct() { this.isClientSide = _isClientSideRowModel(this.gos); this.beans.ctrlsSvc.whenReady(this, (params) => { this.gridBodyCtrl = params.gridBodyCtrl; }); this.resetStickyContainers(); } setOffsetTop(offset) { if (this.extraTopHeight === offset) { return; } this.extraTopHeight = offset; this.eventSvc.dispatchEvent({ type: "stickyTopOffsetChanged", offset }); } setOffsetBottom(offset) { if (this.extraBottomHeight === offset) { return; } this.extraBottomHeight = offset; } resetOffsets() { this.setOffsetBottom(0); this.setOffsetTop(0); } getLastPixelOfGroup(row) { return this.isClientSide ? getClientSideLastPixelOfGroup(row) : getServerSideLastPixelOfGroup(row); } getFirstPixelOfGroup(row) { if (row.footer) { return row.sibling.rowTop + row.sibling.rowHeight - 1; } if (row.hasChildren()) { return row.rowTop - 1; } return 0; } updateStickyRows(container) { const isTop = container === "top"; let newStickyContainerHeight = 0; if (!this.canRowsBeSticky()) { return this.refreshNodesAndContainerHeight(container, /* @__PURE__ */ new Set, newStickyContainerHeight); } const newStickyRows = /* @__PURE__ */ new Set; const { rowModel, rowRenderer, pinnedRowModel, pageBounds, rowContainerHeight } = this.beans; const { pageFirstPixel, pageLastPixel } = pageBounds.getCurrentPagePixelRange(); const pixelAtContainerBoundary = isTop ? rowRenderer.firstVisibleVPixel - this.extraTopHeight : rowRenderer.lastVisibleVPixel - this.extraTopHeight; const divStretchOffset = rowContainerHeight.divStretchOffset ?? 0; const pageFirstPixelWithOffset = pageFirstPixel + divStretchOffset; const pageLastPixelWithOffset = pageLastPixel + divStretchOffset; const addStickyRow = (stickyRow) => { newStickyRows.add(stickyRow); if (isTop) { const lastChildBottom = this.getLastPixelOfGroup(stickyRow); const stickRowBottom = pixelAtContainerBoundary + newStickyContainerHeight + stickyRow.rowHeight; if (lastChildBottom < stickRowBottom) { stickyRow.stickyRowTop = newStickyContainerHeight + (lastChildBottom - stickRowBottom); } else { stickyRow.stickyRowTop = newStickyContainerHeight; } } else { const lastChildBottom = this.getFirstPixelOfGroup(stickyRow); const stickRowTop = pixelAtContainerBoundary - (newStickyContainerHeight + stickyRow.rowHeight); if (lastChildBottom > stickRowTop) { stickyRow.stickyRowTop = newStickyContainerHeight - (lastChildBottom - stickRowTop); } else { stickyRow.stickyRowTop = newStickyContainerHeight; } } newStickyContainerHeight = 0; newStickyRows.forEach((rowNode) => { const thisRowLastPx = rowNode.stickyRowTop + rowNode.rowHeight; if (newStickyContainerHeight < thisRowLastPx) { newStickyContainerHeight = thisRowLastPx; } }); }; const suppressFootersSticky = this.areFooterRowsStickySuppressed(); const suppressGroupsSticky = this.gos.get("suppressGroupRowsSticky"); const isRowSticky = (row) => { if (!row.displayed) { return false; } if (row.footer) { if (suppressFootersSticky === true) { return false; } if (suppressFootersSticky === "grand" && row.level === -1) { return false; } if (suppressFootersSticky === "group" && row.level > -1) { return false; } const isFooterFirstRowInGroup = row.sibling.rowIndex ? row.sibling.rowIndex + 1 === row.rowIndex : false; if (container === "bottom" && isFooterFirstRowInGroup) { return false; } if (row.level === -1 && pinnedRowModel?.getGrandTotalPinned()) { return false; } const alreadySticking = newStickyRows.has(row); return !alreadySticking; } if (row.isExpandable()) { if (suppressGroupsSticky === true) { return false; } if (container === "bottom") { return false; } const alreadySticking = newStickyRows.has(row); return !alreadySticking && !!row.expanded; } return false; }; for (let i = 0;i < 100; i++) { let firstPixelAfterStickyRows = pixelAtContainerBoundary + newStickyContainerHeight; if (!isTop) { firstPixelAfterStickyRows = pixelAtContainerBoundary - newStickyContainerHeight; } if (isTop && firstPixelAfterStickyRows < pageFirstPixelWithOffset) { firstPixelAfterStickyRows = pageFirstPixelWithOffset; } else if (!isTop && firstPixelAfterStickyRows > pageLastPixelWithOffset) { firstPixelAfterStickyRows = pageLastPixelWithOffset; } const firstIndex = rowModel.getRowIndexAtPixel(firstPixelAfterStickyRows); const firstRow = rowModel.getRow(firstIndex); if (firstRow == null) { break; } const ancestors = this.getStickyAncestors(firstRow); const firstMissingParent = ancestors.find((parent) => (isTop ? parent.rowIndex < firstIndex : parent.rowIndex > firstIndex) && isRowSticky(parent)); if (firstMissingParent) { addStickyRow(firstMissingParent); continue; } const isFirstRowOutsideViewport = isTop ? firstRow.rowTop < firstPixelAfterStickyRows : firstRow.rowTop + firstRow.rowHeight > firstPixelAfterStickyRows; if (isFirstRowOutsideViewport && isRowSticky(firstRow)) { addStickyRow(firstRow); continue; } break; } if (!isTop) { newStickyRows.forEach((rowNode) => { rowNode.stickyRowTop = newStickyContainerHeight - (rowNode.stickyRowTop + rowNode.rowHeight); }); } return this.refreshNodesAndContainerHeight(container, newStickyRows, newStickyContainerHeight); } areFooterRowsStickySuppressed() { const suppressFootersSticky = this.gos.get("suppressStickyTotalRow"); if (suppressFootersSticky === true) { return true; } const suppressGroupRows = suppressFootersSticky === "group"; const suppressGrandRows = suppressFootersSticky === "grand"; if (suppressGroupRows && suppressGrandRows) { return true; } if (suppressGrandRows) { return "grand"; } if (suppressGroupRows) { return "group"; } return false; } canRowsBeSticky() { const isStickyEnabled = _isGroupRowsSticky(this.gos); const suppressFootersSticky = this.areFooterRowsStickySuppressed(); const suppressGroupsSticky = this.gos.get("suppressGroupRowsSticky"); return isStickyEnabled && (!suppressFootersSticky || !suppressGroupsSticky); } getStickyAncestors(rowNode) { const ancestors = []; let p = rowNode.footer ? rowNode.sibling : rowNode.parent; while (p) { if (p.sibling) { ancestors.push(p.sibling); } ancestors.push(p); p = p.parent; } return ancestors.reverse(); } checkStickyRows() { const hasTopUpdated = this.updateStickyRows("top"); const hasBottomUpdated = this.updateStickyRows("bottom"); return hasTopUpdated || hasBottomUpdated; } destroyStickyCtrls() { this.resetStickyContainers(); } resetStickyContainers() { this.refreshNodesAndContainerHeight("top", /* @__PURE__ */ new Set, 0); this.refreshNodesAndContainerHeight("bottom", /* @__PURE__ */ new Set, 0); } refreshStickyNode(stickRowNode) { const allStickyNodes = /* @__PURE__ */ new Set; if (this.stickyTopRowCtrls.some((ctrl) => ctrl.rowNode === stickRowNode)) { for (let i = 0;i < this.stickyTopRowCtrls.length; i++) { const currentNode = this.stickyTopRowCtrls[i].rowNode; if (currentNode !== stickRowNode) { allStickyNodes.add(currentNode); } } if (this.refreshNodesAndContainerHeight("top", allStickyNodes, this.topContainerHeight)) { this.checkStickyRows(); } return; } for (let i = 0;i < this.stickyBottomRowCtrls.length; i++) { const currentNode = this.stickyBottomRowCtrls[i].rowNode; if (currentNode !== stickRowNode) { allStickyNodes.add(currentNode); } } if (this.refreshNodesAndContainerHeight("bottom", allStickyNodes, this.bottomContainerHeight)) { this.checkStickyRows(); } } refreshNodesAndContainerHeight(container, newStickyNodes, height) { const isTop = container === "top"; const previousCtrls = isTop ? this.stickyTopRowCtrls : this.stickyBottomRowCtrls; const removedCtrlsMap = {}; const remainingCtrls = []; for (let i = 0;i < previousCtrls.length; i++) { const node = previousCtrls[i].rowNode; const hasBeenRemoved = !newStickyNodes.has(node); if (hasBeenRemoved) { removedCtrlsMap[node.id] = previousCtrls[i]; node.sticky = false; continue; } remainingCtrls.push(previousCtrls[i]); } const existingNodes = /* @__PURE__ */ new Set; for (let i = 0;i < remainingCtrls.length; i++) { existingNodes.add(remainingCtrls[i].rowNode); } const newCtrls = []; newStickyNodes.forEach((node) => { if (existingNodes.has(node)) { return; } node.sticky = true; newCtrls.push(this.createRowCon(node, false, false)); }); let hasSomethingChanged = !!newCtrls.length || remainingCtrls.length !== previousCtrls.length; if (isTop) { if (this.topContainerHeight !== height) { this.topContainerHeight = height; this.gridBodyCtrl.setStickyTopHeight(height); hasSomethingChanged = true; } } else if (this.bottomContainerHeight !== height) { this.bottomContainerHeight = height; this.gridBodyCtrl.setStickyBottomHeight(height); hasSomethingChanged = true; } this.destroyRowCtrls(removedCtrlsMap, false); const newCtrlsList = [...remainingCtrls, ...newCtrls]; newCtrlsList.sort((a, b) => b.rowNode.rowIndex - a.rowNode.rowIndex); if (!isTop) { newCtrlsList.reverse(); } for (const ctrl of newCtrlsList) { ctrl.setRowTop(ctrl.rowNode.stickyRowTop); } const pageBounds = this.beans.pageBounds; let extraHeight = 0; if (isTop) { for (const node of newStickyNodes) { if (node.rowIndex < pageBounds.getFirstRow()) { extraHeight += node.rowHeight; } } if (extraHeight > this.topContainerHeight) { extraHeight = this.topContainerHeight; } this.setOffsetTop(extraHeight); } else { for (const node of newStickyNodes) { if (node.rowIndex > pageBounds.getLastRow()) { extraHeight += node.rowHeight; } } if (extraHeight > this.bottomContainerHeight) { extraHeight = this.bottomContainerHeight; } this.setOffsetBottom(extraHeight); } if (!hasSomethingChanged) { return false; } if (isTop) { this.stickyTopRowCtrls = newCtrlsList; } else { this.stickyBottomRowCtrls = newCtrlsList; } return true; } ensureRowHeightsValid() { let anyChange = false; const updateRowHeight = (ctrl) => { const rowNode = ctrl.rowNode; if (rowNode.rowHeightEstimated) { const rowHeight = _getRowHeightForNode(this.beans, rowNode); rowNode.setRowHeight(rowHeight.height); anyChange = true; } }; this.stickyTopRowCtrls.forEach(updateRowHeight); this.stickyBottomRowCtrls.forEach(updateRowHeight); return anyChange; } }; function getServerSideLastPixelOfGroup(row) { if (row.isExpandable() || row.footer) { if (row.master && row.detailNode) { return row.detailNode.rowTop + row.detailNode.rowHeight; } const noOrContiguousSiblings = !row.sibling || Math.abs(row.sibling.rowIndex - row.rowIndex) === 1; if (noOrContiguousSiblings) { let storeBounds = row.childStore?.getStoreBounds(); if (row.footer) { storeBounds = row.sibling.childStore?.getStoreBounds(); } return (storeBounds?.heightPx ?? 0) + (storeBounds?.topPx ?? 0); } if (row.footer) { return row.rowTop + row.rowHeight; } return row.sibling.rowTop + row.sibling.rowHeight; } return Number.MAX_SAFE_INTEGER; } function getClientSideLastPixelOfGroup(row) { if (row.isExpandable() || row.footer) { const grandTotalAtTop = row.footer && row.rowIndex === 0; if (grandTotalAtTop) { return Number.MAX_SAFE_INTEGER; } const noOrContiguousSiblings = !row.sibling || Math.abs(row.sibling.rowIndex - row.rowIndex) === 1; if (noOrContiguousSiblings) { let lastAncestor = row.footer ? row.sibling : row; while (lastAncestor.isExpandable() && lastAncestor.expanded) { if (lastAncestor.master && lastAncestor.detailNode) { lastAncestor = lastAncestor.detailNode; } else if (lastAncestor.childrenAfterSort) { if (lastAncestor.childrenAfterSort.length === 0) { break; } lastAncestor = _last(lastAncestor.childrenAfterSort); } } return lastAncestor.rowTop + lastAncestor.rowHeight; } if (row.footer) { return row.rowTop + row.rowHeight; } return row.sibling.rowTop + row.sibling.rowHeight; } return Number.MAX_SAFE_INTEGER; } var StickyRowService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "stickyRowSvc"; } createStickyRowFeature(ctrl, createRowCon, destroyRowCtrls) { const gos = this.gos; if (_isGroupRowsSticky(gos) && _isClientSideRowModel(gos) || _isServerSideRowModel(gos)) { return ctrl.createManagedBean(new StickyRowFeature(createRowCon, destroyRowCtrls)); } return; } }; var GroupCellRendererModule = { moduleName: "GroupCellRenderer", version: VERSION2, userComponents: { agGroupRowRenderer: GroupCellRenderer, agGroupCellRenderer: GroupCellRenderer }, dynamicBeans: { groupCellRendererCtrl: GroupCellRendererCtrl }, icons: { groupContracted: "tree-closed", groupExpanded: "tree-open" }, css: [groupCellStyles_default], dependsOn: [EnterpriseCoreModule] }; var GroupColumnModule = { moduleName: "GroupColumn", version: VERSION2, beans: [ AutoColService, ShowRowGroupColsService, ShowRowGroupColValueService, RowGroupColsSvc, PivotColsSvc, ValueColsSvc ], dependsOn: [EnterpriseCoreModule, GroupCellRendererModule] }; var ChangedPathModule = { moduleName: "ChangedPath", version: VERSION2, beans: [ChangedPathFactory], dependsOn: [EnterpriseCoreModule] }; var ClientSideRowModelHierarchyModule = { moduleName: "ClientSideRowModelHierarchy", version: VERSION2, rowModels: ["clientSide"], beans: [GroupStage, FlattenStage, ClientSideExpansionService], dependsOn: [EnterpriseCoreModule, ChangedPathModule] }; var StickyRowModule = { moduleName: "StickyRow", version: VERSION2, beans: [StickyRowService] }; var GroupEditModule = { moduleName: "GroupEdit", version: VERSION2, beans: [GroupEditService], dependsOn: [EnterpriseCoreModule, ClientSideRowModelHierarchyModule] }; var getDate = ({ valueSvc, dataTypeSvc }, sourceCol, node) => { const innerValue = valueSvc.getValue(sourceCol, node, "data"); let date = null; if (innerValue instanceof Date) { date = innerValue; } else if (typeof innerValue === "string") { const parseDate = dataTypeSvc?.getDateParserFunction(sourceCol) ?? _parseDateTimeFromString; date = parseDate(innerValue) ?? null; } return date; }; var getDatePartValueGetter = (beans, col, index, map) => (params) => { const date = getDate(beans, col, params.node); const parts = _getDateParts(date); if (!parts) { return null; } return map?.(parts[index]) ?? parts[index]; }; var getHeaderValueGetter = ({ colNames }, col, part) => (params) => { const sourceName = colNames.getDisplayNameForColumn(col, params.location); if (sourceName) { return `${sourceName} (${part})`; } return ""; }; var MONTH_TO_LOCALE_KEY = Object.fromEntries(MONTHS.map((m) => [m, m.toLowerCase()])); var numericalMonthToNamedMonth = (monthStr) => { const month = MONTHS[Number.parseInt(monthStr, 10) - 1] ?? monthStr; const localeKey = MONTH_TO_LOCALE_KEY[month] ?? monthStr; return { month, localeKey }; }; function _getGroupHierarchy(colDef) { return colDef.groupHierarchy ?? colDef.rowGroupingHierarchy; } var GroupHierarchyColService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "groupHierarchyColSvc"; this.columns = null; this.sourceColumnMap = /* @__PURE__ */ new WeakMap; this.inverseColumnMap = /* @__PURE__ */ new WeakMap; } addColumns(cols) { const groupHierarchyCols = this.columns; if (groupHierarchyCols == null) { return; } cols.list = groupHierarchyCols.list.filter((col) => !cols.list.some((c) => c.getColId() === col.getColId())).concat(cols.list); cols.tree = groupHierarchyCols.tree.filter((col) => !cols.tree.some((c) => c.getId() === col.getId())).concat(cols.tree); _updateColsMap(cols); } createColumns(cols) { const newSourceColumnMap = /* @__PURE__ */ new WeakMap; const newInverseColumnMap = /* @__PURE__ */ new WeakMap; const list = this.createGroupHierarchyColumns(cols, newSourceColumnMap, newInverseColumnMap); const areSame = _areColIdsEqual(list, this.columns?.list ?? []); if (areSame) { return; } _destroyColumnTree(this.beans, this.columns?.tree); this.columns = null; const { colGroupSvc } = this.beans; const treeDepth = colGroupSvc?.findDepth(cols.tree) ?? 0; const tree = colGroupSvc?.balanceTreeForAutoCols(list, treeDepth) ?? []; this.columns = { list, tree, treeDepth, map: {} }; this.sourceColumnMap = newSourceColumnMap; this.inverseColumnMap = newInverseColumnMap; } updateColumns(_event) {} getColumn(key) { return this.columns?.list.find((col) => _columnsMatch(col, key)) ?? null; } getColumns() { return this.columns?.list ?? null; } expandColumnInto(target, col) { const expanded = this.getVirtualColumnsForColumn(col).concat(col); for (const expandedCol of expanded) { if (!target.some((_c) => _columnsMatch(_c, expandedCol) || _c.getColId() === expandedCol.getColId())) { target.push(expandedCol); } } } compareVirtualColumns(colA, colB) { const sourceA = this.inverseColumnMap.get(colA); const sourceB = this.inverseColumnMap.get(colB); if (sourceA && sourceA === sourceB) { const hierarchyCols = this.sourceColumnMap.get(sourceA) ?? []; return hierarchyCols?.indexOf(colA) - hierarchyCols?.indexOf(colB); } if (this.sourceColumnMap.get(colA)?.includes(colB)) { return 1; } if (this.sourceColumnMap.get(colB)?.includes(colA)) { return -1; } return null; } insertVirtualColumnsForCol(columns, col) { const hierarchyCols = this.getVirtualColumnsForColumn(col); if (!hierarchyCols) { return []; } let idxCol = columns.indexOf(col); if (idxCol < 0) { idxCol = columns.length - 1; } _removeAllFromArray(columns, hierarchyCols); columns.splice(idxCol, 0, ...hierarchyCols); return hierarchyCols; } getVirtualColumnsForColumn(col) { if (this.isGroupHierarchyColsEnabledForCol(col)) { return this.sourceColumnMap.get(col) ?? []; } return []; } isGroupHierarchyColsEnabled(cols) { return cols.list.some((col) => this.isGroupHierarchyColsEnabledForCol(col)); } isGroupHierarchyColsEnabledForCol(col) { const def = col.getColDef(); const groupHierarchy = _getGroupHierarchy(def); return !!(groupHierarchy && (def.rowGroup || def.enableRowGroup || def.rowGroupIndex != null || def.pivot || def.enablePivot || def.pivotIndex != null)); } createGroupHierarchyColDefs(sourceCol) { const colDefs = []; const sourceColDef = sourceCol.getColDef(); const groupHierarchy = _getGroupHierarchy(sourceColDef); if (!groupHierarchy) { return colDefs; } if (!this.isGroupHierarchyColsEnabledForCol(sourceCol)) { return colDefs; } for (const part of groupHierarchy) { let colDef = null; if (typeof part === "string") { colDef = this.createColDefForPart(part, sourceCol, sourceColDef); } else { colDef = part; } if (colDef) { colDefs.push(colDef); } } return colDefs; } createGroupHierarchyColumns(cols, sourceColMap, inverseColMap) { if (!this.isGroupHierarchyColsEnabled(cols)) { return []; } const newCols = []; for (const col of cols.list) { for (const colDef of this.createGroupHierarchyColDefs(col)) { const colId = colDef.colId; this.gos.validateColDef(colDef, colId, true); const newCol = new AgColumn(colDef, null, colId, true); this.createBean(newCol); newCols.push(newCol); updateMap(sourceColMap, col, newCol); inverseColMap.set(newCol, col); } } return newCols; } createColDefForPart(part, sourceCol, sourceColDef) { const { beans, gos } = this; const colId = `${GROUP_HIERARCHY_COLUMN_ID_PREFIX}-${sourceCol.getColId()}-${part}`; const defaults = { enableRowGroup: sourceColDef.enableRowGroup, rowGroup: sourceColDef.rowGroup, enablePivot: sourceColDef.enablePivot, hide: true, editable: false }; const groupHierarchyConfig = gos.get("groupHierarchyConfig") ?? {}; if (part in groupHierarchyConfig) { const colDef = { ...defaults, ...groupHierarchyConfig[part] }; colDef.colId ?? (colDef.colId = colId); return _addColumnDefaultAndTypes(beans, colDef, colDef.colId, true); } const base = _addColumnDefaultAndTypes(beans, { colId, ...defaults }, colId, true); const translate = this.getLocaleTextFunc(); const translatePart = (part2, fallback) => translate?.(part2, fallback) ?? fallback; switch (part) { case "year": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart(part, "Year")), valueGetter: getDatePartValueGetter(beans, sourceCol, 0) }; case "quarter": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart(part, "Quarter")), valueGetter: getDatePartValueGetter(beans, sourceCol, 1, (month) => (Math.floor(Number(month) / 4) + 1).toString()) }; case "month": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart(part, "Month")), valueGetter: getDatePartValueGetter(beans, sourceCol, 1) }; case "formattedMonth": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart("month", "Month")), valueGetter: getDatePartValueGetter(beans, sourceCol, 1, (month) => { const nm = numericalMonthToNamedMonth(month); return translatePart(nm.localeKey, nm.month); }) }; case "day": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart(part, "Day")), valueGetter: getDatePartValueGetter(beans, sourceCol, 2) }; case "hour": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart(part, "Hour")), valueGetter: getDatePartValueGetter(beans, sourceCol, 3) }; case "minute": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart(part, "Minute")), valueGetter: getDatePartValueGetter(beans, sourceCol, 4) }; case "second": return { ...base, headerValueGetter: getHeaderValueGetter(beans, sourceCol, translatePart(part, "Second")), valueGetter: getDatePartValueGetter(beans, sourceCol, 5) }; default: return null; } } }; function updateMap(wm, key, value) { const existing = wm.get(key); wm.set(key, (existing ?? []).concat(value)); } var GroupHierarchyModule = { moduleName: "GroupHierarchy", version: VERSION2, beans: [GroupHierarchyColService], dependsOn: [ChangedPathModule] }; var makeGroupColumns = (columns, result) => { if (!columns) { result.length = 0; return; } const len = columns.length; result.length = len; for (let i = 0;i < len; i++) { const col = columns[i]; const colDef = col.getColDef(); result[i] = { col, field: colDef.field, type: colDef.type, keyCreator: colDef.keyCreator, valueGetter: colDef.valueGetter }; } }; var groupColumnsChanged = (groupColumns, columns) => { const len = groupColumns.length; if (len !== columns?.length) { return true; } for (let i = 0;i < len; i++) { const a = groupColumns[i]; const b = columns[i]; if (a.col !== b) { return true; } const bColDef = b.getColDef(); if (a.field !== bColDef.field || a.type !== bColDef.type || a.valueGetter !== bColDef.valueGetter || a.keyCreator !== bColDef.keyCreator) { return true; } } return false; }; function sortGroupChildren(rowNodes) { if (!rowNodes) { return false; } const length = rowNodes.length; if (length < 2) { return false; } let atLeastOneOutOfOrder = false; for (let i = 1;i < length; i++) { if (compareGroupChildren(rowNodes[i - 1], rowNodes[i]) > 0) { atLeastOneOutOfOrder = true; break; } } if (!atLeastOneOutOfOrder) { return false; } rowNodes.sort(compareGroupChildren); return true; } function compareGroupChildren(nodeA, nodeB) { const positionA = nodeA.sourceRowIndex; const positionB = nodeB.sourceRowIndex; const aHasIndex = positionA >= 0; const bHasIndex = positionB >= 0; const bothNodesAreUserNodes = aHasIndex && bHasIndex; const bothNodesAreFillerNodes = !aHasIndex && !bHasIndex; if (bothNodesAreUserNodes) { return positionA - positionB; } if (bothNodesAreFillerNodes) { return nodeA.__objectId - nodeB.__objectId; } if (aHasIndex) { return 1; } return -1; } var GroupStrategy = class extends BeanStub { constructor() { super(...arguments); this.groupCols = []; this.nonLeafsById = /* @__PURE__ */ new Map; this.checkGroupCols = true; this.pivotMode = false; this.groupEmpty = false; } invalidateGroupCols() { this.checkGroupCols = true; } destroy() { super.destroy(); this.groupCols.length = 0; this.nonLeafsById.clear(); } clearNonLeafs() { const nonLeafsById = this.nonLeafsById; for (const node of nonLeafsById.values()) { node._destroy(false); } nonLeafsById.clear(); } loadGroupData(node) { if (!node.group) { node._groupData = null; return null; } const rowGroupCol = node.rowGroupColumn; const { valueSvc, showRowGroupCols } = this.beans; const groupData = {}; node._groupData = groupData; if (!rowGroupCol) { return groupData; } const leafNode = _csrmFirstLeaf(node); const rowGroupColId = rowGroupCol.getId(); if (!showRowGroupCols) { return groupData; } const groupDisplayCols = showRowGroupCols.columns; for (let i = 0, len = groupDisplayCols.length;i < len; ++i) { const col = groupDisplayCols[i]; if (col.isRowGroupDisplayed(rowGroupColId)) { groupData[col.getColId()] = valueSvc.getValue(rowGroupCol, leafNode, "data"); } } return groupData; } execute(rootNode, params) { const changedPath = params.changedPath; const refreshResult = this.initRefresh(params); if (refreshResult !== "skip") { const changedRowNodes = params.changedRowNodes; if (changedRowNodes) { this.handleDeltaUpdate(rootNode, changedPath, changedRowNodes, !!params.animate); } else { this.shotgunResetEverything(rootNode); } } this.positionLeafsAndGroups(rootNode, changedPath); this.orderGroups(rootNode); this.beans.selectionSvc?.updateSelectableAfterGrouping(changedPath); } positionLeafsAndGroups(rootNode, changedPath) { _forEachChangedGroupDepthFirst(rootNode, true, changedPath, (group) => { const children = group.childrenAfterGroup; const childrenLen = children?.length; if (!childrenLen) { return; } const newChildren = new Array(childrenLen); let writeIdx = 0; let changed = false; let unbalancedNode; for (let readIdx = 0;readIdx < childrenLen; ++readIdx) { const node = children[readIdx]; if (!node.childrenAfterGroup?.length) { changed || (changed = writeIdx !== readIdx); newChildren[writeIdx++] = node; } else if (!unbalancedNode && node.key === "") { unbalancedNode = node; const last = childrenLen - 1; changed || (changed = readIdx !== last); newChildren[last] = node; } } if (changed) { for (let readIdx = 0;readIdx < childrenLen; ++readIdx) { const node = children[readIdx]; if (node.childrenAfterGroup?.length && node !== unbalancedNode) { newChildren[writeIdx++] = node; } } group.childrenAfterGroup = newChildren; const sibling = group.sibling; if (sibling) { sibling.childrenAfterGroup = newChildren; } } }); } initRefresh(params) { const { rowGroupColsSvc, colModel, gos } = this.beans; this.pivotMode = colModel.isPivotMode(); this.groupEmpty = this.pivotMode || !gos.get("groupAllowUnbalanced"); const cols = rowGroupColsSvc?.columns; const groupCols = this.groupCols; const afterColumnsChanged = params.afterColumnsChanged; if (afterColumnsChanged || !groupCols || this.checkGroupCols) { this.checkGroupCols = false; if (groupCols && !groupColumnsChanged(groupCols, cols)) { if (afterColumnsChanged) { return "skip"; } } else { params.animate = false; const topLevelChanged = groupCols[0]?.col.getId() !== cols?.[0]?.getId(); makeGroupColumns(cols, groupCols); return topLevelChanged ? "refresh" : "groupColsChanged"; } } return "refresh"; } handleDeltaUpdate(rootNode, changedPath, { removals, updates, adds, reordered }, animate) { const parentsWithRemovals = /* @__PURE__ */ new Set; for (let i = 0, len = removals.length;i < len; ++i) { const rowNode = removals[i]; const oldParent = this.removeFromParent(rowNode); if (!parentsWithRemovals.has(oldParent)) { parentsWithRemovals.add(oldParent); changedPath?.addRow(oldParent); } } for (const rowNode of updates) { const oldParent = rowNode.parent; changedPath?.addRow(oldParent); if (this.moveNodeInWrongPath(rootNode, rowNode)) { parentsWithRemovals.add(oldParent); const newParent = rowNode.parent; changedPath?.addRow(newParent); reordered || (reordered = (newParent?.childrenAfterGroup?.length ?? 0) > 1); } } if (adds.size) { for (const rowNode of adds) { this.insertOneNode(rootNode, rowNode); const newParent = rowNode.parent; changedPath?.addRow(newParent); reordered || (reordered = (newParent?.childrenAfterGroup?.length ?? 0) > 1); } } if (parentsWithRemovals.size) { batchedRemove(parentsWithRemovals); this.removeEmptyGroups(parentsWithRemovals, animate); } if (reordered) { this.sortChildren(rootNode, changedPath); } } sortChildren(rootNode, changedPath) { _forEachChangedGroupDepthFirst(rootNode, true, undefined, (node) => { const didSort = sortGroupChildren(node.childrenAfterGroup); if (didSort) { changedPath?.addRow(node); } }); } orderGroups(rootNode) { const initialGroupOrderComparator = this.gos.getCallback("initialGroupOrderComparator"); if (!initialGroupOrderComparator) { return; } const beans = this.beans; const api = beans.gridApi; const context = beans.gridOptions.context; const comparer = (nodeA, nodeB) => initialGroupOrderComparator({ api, context, nodeA, nodeB }); const recursiveSort = (rowNode) => { const childrenAfterGroup = rowNode.childrenAfterGroup; const childrenAfterGroupLen = childrenAfterGroup?.length; if (!childrenAfterGroupLen || rowNode.leafGroup) { return; } if (childrenAfterGroupLen > 1) { childrenAfterGroup.sort(comparer); } for (let i = 0, len = childrenAfterGroupLen;i < len; ++i) { recursiveSort(childrenAfterGroup[i]); } }; recursiveSort(rootNode); } moveNodeInWrongPath(rootNode, childNode) { const { valueSvc } = this.beans; const createGroupForEmpty = this.groupEmpty; let ancestor = childNode.parent; let changed = false; const groupCols = this.groupCols; if (!groupCols) { return false; } for (let idx = groupCols.length - 1;idx >= 0; --idx) { const { col } = groupCols[idx]; let key = valueSvc.getKeyForNode(col, childNode); if (key == null || key === "") { if (!createGroupForEmpty) { continue; } key = ""; } if (!ancestor?.parent || ancestor.key !== key) { changed = true; break; } ancestor = ancestor.parent; } changed || (changed = !!ancestor?.parent); if (!changed) { return false; } this.removeFromParent(childNode); this.insertOneNode(rootNode, childNode); childNode.setData(childNode.data); return true; } groupShouldBeRemoved(rowNode) { const mapKey = this.getChildrenMappedKey(rowNode.key, rowNode.rowGroupColumn); const parentChildrenMapped = rowNode.parent?.childrenMapped; const groupAlreadyRemoved = parentChildrenMapped ? !parentChildrenMapped[mapKey] : true; if (groupAlreadyRemoved) { return false; } return !!rowNode.group && (rowNode.childrenAfterGroup?.length ?? 0) === 0; } removeEmptyGroups(parents, animate) { const selectionSvc = this.beans.selectionSvc; let nodesToUnselect; const possibleEmptyGroups = Array.from(parents); const groupsById = this.nonLeafsById; do { parents.clear(); for (let idx = 0;idx < possibleEmptyGroups.length; ++idx) { let pointer = possibleEmptyGroups[idx]; while (pointer) { const parent = pointer.parent; if (pointer.destroyed) { possibleEmptyGroups[idx] = parent; pointer = parent; continue; } if (!parent) { break; } if (!this.groupShouldBeRemoved(pointer)) { pointer = parent; continue; } parents.add(parent); this.removeFromParent(pointer); if (selectionSvc && pointer.isSelected()) { nodesToUnselect ?? (nodesToUnselect = []); nodesToUnselect.push(pointer); } possibleEmptyGroups[idx] = parent; groupsById.delete(pointer.id); pointer._destroy(animate); pointer = parent; } } batchedRemove(parents); } while (parents.size); if (nodesToUnselect) { selectionSvc.setNodesSelected({ nodes: nodesToUnselect, newValue: false, source: "rowGroupChanged" }); } } removeFromParent(child) { const oldParent = child.parent; if (oldParent) { const mapKey = this.getChildrenMappedKey(child.key, child.rowGroupColumn); const childParentChildrenMapped = oldParent.childrenMapped; if (childParentChildrenMapped) { delete childParentChildrenMapped[mapKey]; } } child.setRowTop(null); child.setRowIndex(null); return oldParent; } addToParent(child, parent) { const childrenMapped = parent.childrenMapped ?? (parent.childrenMapped = {}); const mapKey = this.getChildrenMappedKey(child.key, child.rowGroupColumn); if (childrenMapped[mapKey] !== child) { childrenMapped[mapKey] = child; let childrenAfterGroup = parent.childrenAfterGroup; if (!childrenAfterGroup) { parent.childrenAfterGroup = childrenAfterGroup = []; const sibling = parent.sibling; if (sibling) { sibling.childrenAfterGroup = parent.childrenAfterGroup; } } childrenAfterGroup.push(child); setRowNodeGroup(parent, this.beans, true); invalidateAllLeafChildren(parent); } } shotgunResetEverything(rootNode) { const groupsById = this.nonLeafsById; for (const node of groupsById.values()) { node.childrenAfterGroup = null; node.childrenMapped = null; } rootNode.leafGroup = !this.groupCols?.length; rootNode.childrenAfterGroup = []; rootNode.childrenMapped = {}; rootNode.updateHasChildren(); const sibling = rootNode.sibling; if (sibling) { sibling.childrenAfterGroup = rootNode.childrenAfterGroup; sibling.childrenMapped = rootNode.childrenMapped; } const allLeafs = rootNode._leafs; for (let i = 0, len = allLeafs.length;i < len; ++i) { this.insertOneNode(rootNode, allLeafs[i]); } this.destroyStaleGroups(groupsById); } destroyStaleGroups(groupsById) { const selectionSvc = this.beans.selectionSvc; let nodesToDeselect; for (const [id, node] of groupsById) { if (node.childrenAfterGroup !== null) { continue; } if (selectionSvc && node.isSelected()) { (nodesToDeselect ?? (nodesToDeselect = [])).push(node); } groupsById.delete(id); node._destroy(false); } if (nodesToDeselect) { selectionSvc.setNodesSelected({ nodes: nodesToDeselect, newValue: false, source: "rowGroupChanged" }); } } insertOneNode(rootNode, childNode) { let parentGroup = rootNode; const { beans, groupCols, groupEmpty } = this; const valueSvc = beans.valueSvc; if (!groupCols) { return; } const len = groupCols.length; for (let i = 0;i < len; ++i) { const groupCol = groupCols[i]; const col = groupCol.col; let key = valueSvc.getKeyForNode(col, childNode); if (key == null || key === "") { if (!groupEmpty) { continue; } key = ""; } const existingGroup = parentGroup.childrenMapped?.[this.getChildrenMappedKey(key, col)]; if (existingGroup) { parentGroup = existingGroup; continue; } const nextLevel = parentGroup.level + 1; const isLeafLevel = nextLevel >= len - 1; const newGroup = this.createGroup(parentGroup, groupCol, key, nextLevel, isLeafLevel, childNode); this.addToParent(newGroup, parentGroup); parentGroup = newGroup; } if (!parentGroup.group) { _warn(184, { parentGroupData: parentGroup.data, childNodeData: childNode.data }); } childNode.parent = parentGroup; childNode.level = parentGroup.level + 1; parentGroup.childrenAfterGroup.push(childNode); parentGroup.updateHasChildren(); invalidateAllLeafChildren(parentGroup); } createGroup(parent, groupCol, key, level, isLeafLevel, leafNode) { const col = groupCol.col; const id = (parent.level >= 0 ? parent.id + "-" : "row-group-") + (col.getColId() + "-" + key); const groupsById = this.nonLeafsById; let node = groupsById.get(id); let singleUse = true; if (node) { if (node.childrenAfterGroup !== null) { node._expanded ?? (node._expanded = null); return node; } singleUse = false; invalidateAllLeafChildren(node); } else { node = new RowNode(this.beans); node.group = true; node.key = key; node.id = id; node.aggData = null; groupsById.set(id, node); } const applyValuesToNode = (n) => { n.childrenAfterGroup = children; n.childrenMapped = mapped; n.parent = parent; n.level = level; n.rowGroupIndex = level; n.leafGroup = isLeafLevel; }; const children = []; const mapped = {}; applyValuesToNode(node); node.field = groupCol.field ?? null; node.rowGroupColumn = col; node.groupValue = this.beans.valueSvc.getValue(col, leafNode, "data"); node._expanded ?? (node._expanded = null); if (singleUse) { node.setAllChildrenCount(0); node.updateHasChildren(); return node; } const sibling = node.sibling; if (sibling) { applyValuesToNode(sibling); } node.dispatchRowEvent("hasChildrenChanged"); return node; } getChildrenMappedKey(key, rowGroupColumn) { return rowGroupColumn ? rowGroupColumn.getId() + "-" + key : key; } onShowRowGroupColsSetChanged() { const { rowModel, valueSvc } = this.beans; for (const groupNode of this.nonLeafsById.values()) { groupNode._groupData = undefined; const rowGroupColumn = groupNode.rowGroupColumn; const leafNode = rowGroupColumn && _csrmFirstLeaf(groupNode); groupNode.groupValue = leafNode && valueSvc.getValue(rowGroupColumn, leafNode, "data"); } const allLeafs = rowModel.rootNode?._leafs; if (allLeafs) { for (let i = 0, len = allLeafs.length;i < len; ++i) { const leafNode = allLeafs[i]; leafNode.parent._groupData = undefined; } } } }; var batchedRemove = (parents) => { for (const parent of parents) { const childrenAfterGroup = parent?.childrenAfterGroup; if (!childrenAfterGroup) { continue; } const childrenAfterGroupLen = childrenAfterGroup.length; let writeIdx = 0; for (let readIdx = 0;readIdx < childrenAfterGroupLen; ++readIdx) { const item = childrenAfterGroup[readIdx]; if (item.parent === parent && !item.destroyed) { if (writeIdx !== readIdx) { childrenAfterGroup[writeIdx] = item; } ++writeIdx; } } if (childrenAfterGroupLen !== writeIdx) { childrenAfterGroup.length = writeIdx; parent.updateHasChildren(); invalidateAllLeafChildren(parent); } } }; var invalidateAllLeafChildren = (node) => { while (node._leafs !== undefined) { const parent = node.parent; if (!parent) { break; } node._leafs = undefined; node = parent; } }; function setRowGroupColumns(beans, colKeys) { beans.rowGroupColsSvc?.setColumns(colKeys, "api"); } function removeRowGroupColumns(beans, colKeys) { beans.rowGroupColsSvc?.removeColumns(colKeys, "api"); } function addRowGroupColumns(beans, colKeys) { beans.rowGroupColsSvc?.addColumns(colKeys, "api"); } function moveRowGroupColumn(beans, fromIndex, toIndex) { beans.rowGroupColsSvc?.moveColumn?.(fromIndex, toIndex, "api"); } function getRowGroupColumns(beans) { return beans.rowGroupColsSvc?.columns ?? []; } var SharedRowGroupingModule = { moduleName: "SharedRowGrouping", version: VERSION2, apiFunctions: { setRowGroupColumns, removeRowGroupColumns, addRowGroupColumns, getRowGroupColumns, moveRowGroupColumn }, dependsOn: [ EnterpriseCoreModule, SharedAggregationModule, GroupColumnModule, StickyRowModule, GroupHierarchyModule ] }; var RowGroupingModule = { moduleName: "RowGrouping", version: VERSION2, dynamicBeans: { groupStrategy: GroupStrategy }, rowModels: ["clientSide"], dependsOn: [SharedRowGroupingModule, AggregationModule, ClientSideRowModelHierarchyModule, GroupEditModule] }; function copyToClipboard(beans, params) { beans.clipboardSvc?.copyToClipboard(params); } function cutToClipboard(beans, params) { beans.clipboardSvc?.cutToClipboard(params); } function copySelectedRowsToClipboard(beans, params) { beans.clipboardSvc?.copySelectedRowsToClipboard(params); } function copySelectedRangeToClipboard(beans, params) { beans.clipboardSvc?.copySelectedRangeToClipboard(params); } function copySelectedRangeDown(beans) { beans.clipboardSvc?.copyRangeDown(); } function pasteFromClipboard(beans) { beans.clipboardSvc?.pasteFromClipboard(); } var SOURCE_PASTE2 = "paste"; var EXPORT_TYPE_DRAG_COPY = "dragCopy"; var EXPORT_TYPE_CLIPBOARD = "clipboard"; function stringToArray(strData, delimiter = ",") { const data = []; const isNewline = (char) => char === "\r" || char === ` `; let insideQuotedField = false; if (strData === "") { return [[""]]; } for (let row = 0, column = 0, position = 0;position < strData.length; position++) { const previousChar = strData[position - 1]; const currentChar = strData[position]; const nextChar = strData[position + 1]; const ensureDataExists = () => { if (!data[row]) { data[row] = []; } if (!data[row][column]) { data[row][column] = ""; } }; ensureDataExists(); if (currentChar === '"') { if (insideQuotedField) { if (nextChar === '"') { data[row][column] += '"'; position++; } else { insideQuotedField = false; } } else if (previousChar === undefined || previousChar === delimiter || isNewline(previousChar)) { insideQuotedField = true; } } if (!insideQuotedField && currentChar !== '"') { if (currentChar === delimiter) { column++; ensureDataExists(); continue; } else if (isNewline(currentChar)) { column = 0; row++; ensureDataExists(); if (currentChar === "\r" && nextChar === ` `) { position++; } continue; } } data[row][column] += currentChar; } return data; } var ClipboardService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "clipboardSvc"; this.clientSideRowModel = null; this.gridCtrl = null; this.lastPasteOperationTime = 0; this.navigatorApiFailed = false; } postConstruct() { const { gos, rowModel, ctrlsSvc } = this.beans; if (_isClientSideRowModel(gos, rowModel)) { this.clientSideRowModel = rowModel; } ctrlsSvc.whenReady(this, (p) => { this.gridCtrl = p.gridCtrl; }); } destroy() { super.destroy(); this.clientSideRowModel = null; this.gridCtrl = null; } pasteFromClipboard() { const allowNavigator = !this.gos.get("suppressClipboardApi"); if (allowNavigator && !this.navigatorApiFailed && navigator.clipboard?.readText) { navigator.clipboard.readText().then(this.processClipboardData.bind(this)).catch((e) => { _warn(40, { e, method: "readText" }); this.navigatorApiFailed = true; this.pasteFromClipboardLegacy(); }); } else { this.pasteFromClipboardLegacy(); } } pasteFromClipboardLegacy() { let defaultPrevented = false; const handlePasteEvent = (e) => { const currentPastOperationTime = Date.now(); if (currentPastOperationTime - this.lastPasteOperationTime < 50) { defaultPrevented = true; e.preventDefault(); } this.lastPasteOperationTime = currentPastOperationTime; }; this.executeOnTempElement((textArea) => { textArea.addEventListener("paste", handlePasteEvent); textArea.focus({ preventScroll: true }); }, (element) => { const data = element.value; if (!defaultPrevented) { this.processClipboardData(data); } else { this.refocusLastFocusedCell(); } element.removeEventListener("paste", handlePasteEvent); }); } refocusLastFocusedCell() { const { focusSvc } = this.beans; const focusedCell = focusSvc.getFocusedCell(); if (focusedCell) { focusSvc.setFocusedCell({ rowIndex: focusedCell.rowIndex, column: focusedCell.column, rowPinned: focusedCell.rowPinned, forceBrowserFocus: true }); } } getClipboardDelimiter() { const delimiter = this.gos.get("clipboardDelimiter"); return _exists(delimiter) ? delimiter : "\t"; } processClipboardData(data) { if (data == null) { return; } let parsedData = stringToArray(data, this.getClipboardDelimiter()); const userFunc = this.gos.getCallback("processDataFromClipboard"); if (userFunc) { parsedData = userFunc({ data: parsedData }); } if (parsedData == null) { return; } if (this.gos.get("suppressLastEmptyLineOnPaste")) { this.removeLastLineIfBlank(parsedData); } const { rangeSvc, editSvc } = this.beans; const pasteOperation = (cellsToFlash, updatedRowNodes, focusedCell, changedPath) => { const rangeActive = rangeSvc?.isMoreThanOneCell(); const pasteIntoRange = rangeActive && !this.hasOnlyOneValueToPaste(parsedData); if (pasteIntoRange) { this.pasteIntoActiveRange(parsedData, cellsToFlash, updatedRowNodes, changedPath); } else { this.pasteStartingFromFocusedCell(parsedData, cellsToFlash, updatedRowNodes, focusedCell, changedPath); } editSvc?.stopEditing(undefined, { source: SOURCE_PASTE2 }); }; this.doPasteOperation(pasteOperation); } doPasteOperation(pasteOperationFunc) { const source = "clipboard"; const { eventSvc, focusSvc, rowRenderer, gos } = this.beans; eventSvc.dispatchEvent({ type: "pasteStart", source }); const { clientSideRowModel } = this; const rootNode = clientSideRowModel?.rootNode; const changedPath = rootNode && this.beans.changedPathFactory?.newPath(gos.get("aggregateOnlyChangedColumns")); const cellsToFlash = {}; const updatedRowNodes = []; const focusedCell = focusSvc.getFocusedCell(); pasteOperationFunc(cellsToFlash, updatedRowNodes, focusedCell, changedPath); const nodesToRefresh = updatedRowNodes.slice(); if (changedPath) { clientSideRowModel.doAggregate(changedPath); _forEachChangedGroupDepthFirst(rootNode, clientSideRowModel.hierarchical, changedPath, (rowNode) => { nodesToRefresh.push(rowNode); }); } rowRenderer.refreshCells({ rowNodes: nodesToRefresh }); this.dispatchFlashCells(cellsToFlash); this.fireRowChanged(updatedRowNodes); this.refocusLastFocusedCell(); eventSvc.dispatchEvent({ type: "pasteEnd", source }); } getPreProcessRangeCallback(clipboardData) { return (cellRange) => { const { rangeSvc } = this.beans; if (!rangeSvc) { return; } const { rowDiff, colDiff } = this.getAdjustedRangeDimensionForPaste(cellRange, clipboardData); if (rowDiff !== 0) { rangeSvc.extendRangeRowCountBy(cellRange, rowDiff); } if (colDiff !== 0) { rangeSvc.extendRangeColumnCountBy(cellRange, colDiff); } }; } getAdjustedRangeDimensionForPaste(cellRange, clipboardData) { const rangeSvc = this.beans.rangeSvc; const clipboardRowCount = clipboardData.length; const rangeRowCount = rangeSvc.getRangeRowCount(cellRange); const isRowMultiple = rangeRowCount >= clipboardRowCount && rangeRowCount % clipboardRowCount === 0; const clipboardColCount = clipboardData[0].length; const rangeColCount = cellRange.columns.length; const isColMultiple = rangeColCount >= clipboardColCount && rangeColCount % clipboardColCount === 0; return { rowDiff: isRowMultiple ? 0 : clipboardRowCount - rangeRowCount, colDiff: isColMultiple ? 0 : clipboardColCount - rangeColCount }; } pasteIntoActiveRange(clipboardData, cellsToFlash, updatedRowNodes, changedPath) { let indexOffset = 0; let dataRowIndex = 0; const rowCallback = (currentRow, rowNode, range, rangeIndex) => { const atEndOfClipboardData = rangeIndex - indexOffset >= clipboardData.length; if (atEndOfClipboardData) { if (rangeIndex % clipboardData.length !== 0) { return; } indexOffset += dataRowIndex; dataRowIndex = 0; } const currentRowData = clipboardData[rangeIndex - indexOffset]; updatedRowNodes.push(rowNode); const processCellFromClipboardFunc = this.gos.getCallback("processCellFromClipboard"); const columns = range.columns; const selectionColIdx = columns.findIndex(isColumnSelectionCol); if (selectionColIdx !== -1) { columns.splice(selectionColIdx, 1); } for (let idx = 0;idx < columns.length; idx++) { const column = columns[idx]; if (!column.isCellEditable(rowNode) || column.isSuppressPaste(rowNode)) { continue; } let calculatedIdx = idx; if (idx >= currentRowData.length) { calculatedIdx = idx % currentRowData.length; } const newValue = this.processCell(rowNode, column, currentRowData[calculatedIdx], EXPORT_TYPE_DRAG_COPY, processCellFromClipboardFunc, true); rowNode.setDataValue(column, newValue, SOURCE_PASTE2); changedPath?.addCell(rowNode.parent, column.getId()); const { rowIndex, rowPinned } = currentRow; const cellId = _createCellId({ rowIndex, column, rowPinned }); cellsToFlash[cellId] = true; } dataRowIndex++; }; this.iterateActiveRanges(rowCallback, false, this.getPreProcessRangeCallback(clipboardData)); } getDisplayedColumnsStartingAt(column) { let currentColumn = column; const columns = []; const { visibleCols } = this.beans; while (currentColumn && isSpecialCol(currentColumn)) { currentColumn = visibleCols.getColAfter(currentColumn); } while (currentColumn != null) { columns.push(currentColumn); currentColumn = visibleCols.getColAfter(currentColumn); } return columns; } pasteStartingFromFocusedCell(parsedData, cellsToFlash, updatedRowNodes, focusedCell, changedPath) { if (!focusedCell) { return; } const currentRow = { rowIndex: focusedCell.rowIndex, rowPinned: focusedCell.rowPinned }; const columnsToPasteInto = this.getDisplayedColumnsStartingAt(focusedCell.column); if (this.isPasteSingleValueIntoRange(parsedData)) { this.pasteSingleValueIntoRange(parsedData, updatedRowNodes, cellsToFlash, changedPath); } else { this.pasteMultipleValues(parsedData, currentRow, updatedRowNodes, columnsToPasteInto, cellsToFlash, EXPORT_TYPE_CLIPBOARD, changedPath); } } isPasteSingleValueIntoRange(parsedData) { const rangeSvc = this.beans.rangeSvc; return this.hasOnlyOneValueToPaste(parsedData) && !!rangeSvc && !rangeSvc.isEmpty(); } pasteSingleValueIntoRange(parsedData, updatedRowNodes, cellsToFlash, changedPath) { const value = parsedData[0][0]; const rowCallback = (currentRow, rowNode, range) => { updatedRowNodes.push(rowNode); range.columns.forEach((column) => this.updateCellValue(rowNode, column, value, cellsToFlash, EXPORT_TYPE_CLIPBOARD, changedPath)); }; this.iterateActiveRanges(rowCallback); } hasOnlyOneValueToPaste(parsedData) { return parsedData.length === 1 && parsedData[0].length === 1; } copyRangeDown() { const { rangeSvc, gos, formula, valueSvc } = this.beans; if (!rangeSvc || rangeSvc.isEmpty()) { return; } const firstRowValues = []; const pasteOperation = (cellsToFlash, updatedRowNodes, focusedCell, changedPath) => { const processCellForClipboardFunc = gos.getCallback("processCellForClipboard"); const processCellFromClipboardFunc = gos.getCallback("processCellFromClipboard"); const rowCallback = (currentRow, rowNode, range) => { const { columns } = range; if (!firstRowValues.length) { columns.forEach((column) => { const value = this.processCell(rowNode, column, valueSvc.getValue(column, rowNode, "batch"), EXPORT_TYPE_DRAG_COPY, processCellForClipboardFunc, false, true); firstRowValues.push(value); }); } else { updatedRowNodes.push(rowNode); columns.forEach((column, index) => { if (!column.isCellEditable(rowNode) || column.isSuppressPaste(rowNode)) { return; } const isFormula = column.isAllowFormula() && formula?.isFormula(firstRowValues[index]); if (isFormula) { firstRowValues[index] = formula?.updateFormulaByOffset({ value: firstRowValues[index], rowDelta: 1 }); } const firstRowValue = this.processCell(rowNode, column, firstRowValues[index], EXPORT_TYPE_DRAG_COPY, processCellFromClipboardFunc, true); rowNode.setDataValue(column, firstRowValue, SOURCE_PASTE2); changedPath?.addCell(rowNode.parent, column.getId()); const { rowIndex, rowPinned } = currentRow; const cellId = _createCellId({ rowIndex, column, rowPinned }); cellsToFlash[cellId] = true; }); } }; this.iterateActiveRanges(rowCallback, true); }; this.doPasteOperation(pasteOperation); } removeLastLineIfBlank(parsedData) { const lastLine = _last(parsedData); const lastLineIsBlank = lastLine && lastLine.length === 1 && lastLine[0] === ""; if (lastLineIsBlank) { if (parsedData.length === 1) { return; } _removeFromArray(parsedData, lastLine); } } fireRowChanged(rowNodes) { if (this.gos.get("editType") !== "fullRow") { return; } for (const rowNode of rowNodes) { this.eventSvc.dispatchEvent({ type: "rowValueChanged", node: rowNode, data: rowNode.data, rowIndex: rowNode.rowIndex, rowPinned: rowNode.rowPinned }); } } shouldSkipPasteRow(row, columns, skipGroupRows) { if (row.detail || row.footer) { return true; } if (skipGroupRows && row.group) { for (const col of columns) { if (col.isCellEditable(row)) { return false; } } return true; } return false; } pasteMultipleValues(clipboardGridData, currentRow, updatedRowNodes, columnsToPasteInto, cellsToFlash, type, changedPath) { let rowPointer = currentRow; const beans = this.beans; const { gos } = beans; const skipGroupRows = this.clientSideRowModel != null && !gos.get("enableGroupEdit") && !gos.get("treeData"); const getNextGoodRowNode = () => { while (rowPointer) { const res = _getRowNode(beans, rowPointer); rowPointer = _getRowBelow(beans, { rowPinned: rowPointer.rowPinned, rowIndex: rowPointer.rowIndex }); if (res != null && !this.shouldSkipPasteRow(res, columnsToPasteInto, skipGroupRows)) { return res; } } return null; }; for (const clipboardRowData of clipboardGridData) { const rowNode = getNextGoodRowNode(); if (!rowNode) { continue; } clipboardRowData.forEach((value, index) => this.updateCellValue(rowNode, columnsToPasteInto[index], value, cellsToFlash, type, changedPath)); updatedRowNodes.push(rowNode); } } updateCellValue(rowNode, column, value, cellsToFlash, type, changedPath) { if (!rowNode || !column?.isCellEditable(rowNode) || column?.isSuppressPaste(rowNode)) { return; } const processedValue = this.processCell(rowNode, column, value, type, this.gos.getCallback("processCellFromClipboard"), true); rowNode.setDataValue(column, processedValue, SOURCE_PASTE2); const { rowIndex, rowPinned } = rowNode; const cellId = _createCellId({ rowIndex, column, rowPinned }); cellsToFlash[cellId] = true; changedPath?.addCell(rowNode.parent, column.getId()); } copyToClipboard(params = {}) { this.copyOrCutToClipboard(params); } cutToClipboard(params = {}, source = "api") { if (this.gos.get("suppressCutToClipboard")) { return; } this.eventSvc.dispatchEvent({ type: "cutStart", source }); this.copyOrCutToClipboard(params, true); this.eventSvc.dispatchEvent({ type: "cutEnd", source }); } copyOrCutToClipboard(params, cut) { let { includeHeaders, includeGroupHeaders } = params; const { gos, focusSvc } = this.beans; if (includeHeaders == null) { includeHeaders = gos.get("copyHeadersToClipboard"); } if (includeGroupHeaders == null) { includeGroupHeaders = gos.get("copyGroupHeadersToClipboard"); } const copyParams = { includeHeaders, includeGroupHeaders }; const rowSelection = gos.get("rowSelection"); const cellSelection = gos.get("cellSelection"); let cellClearType = null; if (this.shouldCopyCells(cellSelection, rowSelection)) { this.copySelectedRangeToClipboard(copyParams); cellClearType = 0; } else if (this.shouldCopyRows(rowSelection)) { this.copySelectedRowsToClipboard(copyParams); cellClearType = 1; } else if (focusSvc.isAnyCellFocused()) { this.copyFocusedCellToClipboard(copyParams); cellClearType = 2; } if (cut && cellClearType !== null) { this.clearCellsAfterCopy(cellClearType); } } shouldCopyCells(cellSelection, rowSelection) { const { rangeSvc, selectionSvc, gos } = this.beans; if (!rangeSvc || rangeSvc.isEmpty()) { return false; } if (cellSelection) { const shouldCopyRowsInstead = typeof rowSelection === "object" && rowSelection.copySelectedRows && !selectionSvc?.isEmpty(); return !shouldCopyRowsInstead; } else { const suppressCopySingleCellRanges = gos.get("suppressCopySingleCellRanges"); const shouldSkip = !rangeSvc.isMoreThanOneCell() && suppressCopySingleCellRanges; return !shouldSkip; } } shouldCopyRows(rowSelection) { const { selectionSvc, gos } = this.beans; if (selectionSvc?.isEmpty() ?? true) { return false; } if (rowSelection && typeof rowSelection !== "string") { return rowSelection.copySelectedRows ?? false; } else { return !gos.get("suppressCopyRowsToClipboard"); } } clearCellsAfterCopy(type) { const beans = this.beans; const { rangeSvc, focusSvc, eventSvc } = beans; eventSvc.dispatchEvent({ type: "keyShortcutChangedCellStart" }); if (type === 0) { rangeSvc.clearCellRangeCellValues({ cellEventSource: "clipboardSvc" }); } else if (type === 1) { this.clearSelectedRows(); } else { const focusedCell = focusSvc.getFocusedCell(); if (focusedCell == null) { return; } const rowNode = _getRowNode(beans, focusedCell); if (rowNode) { this.clearCellValue(rowNode, focusedCell.column); } } eventSvc.dispatchEvent({ type: "keyShortcutChangedCellEnd" }); } clearSelectedRows() { const { selectionSvc, visibleCols } = this.beans; const selected = selectionSvc?.getSelectedNodes() ?? []; const columns = visibleCols.allCols; for (const row of selected) { for (const col of columns) { this.clearCellValue(row, col); } } } clearCellValue(rowNode, column) { if (!column.isCellEditable(rowNode)) { return; } const deleteValue = this.beans.valueSvc.getDeleteValue(column, rowNode); rowNode.setDataValue(column, deleteValue, "clipboardSvc"); } iterateActiveRanges(rowCallback, onlyFirst, preProcessRange) { const rangeSvc = this.beans.rangeSvc; if (!rangeSvc || rangeSvc.isEmpty()) { return; } const currentCellRanges = rangeSvc.getCellRanges(); const cellRanges = onlyFirst ? [currentCellRanges[0]] : currentCellRanges; for (const cellRange of cellRanges) { this.iterateActiveRange({ cellRange, rowCallback, preProcessRange }); } } iterateActiveRange(params) { const { cellRange, preProcessRange, rowCallback } = params; const { beans } = this; const { rangeSvc } = beans; if (!rangeSvc) { return; } if (preProcessRange) { preProcessRange(cellRange); } let currentRow = rangeSvc.getRangeStartRow(cellRange); const lastRow = rangeSvc.getRangeEndRow(cellRange); let rangeIndex = 0; let isLastRow = false; while (!isLastRow && currentRow != null) { const rowNode = _getRowNode(beans, currentRow); isLastRow = _isSameRow(currentRow, lastRow); rowCallback(currentRow, rowNode, cellRange, rangeIndex++); currentRow = _getRowBelow(beans, currentRow); } } copySelectedRangeToClipboard(params = {}) { const rangeSvc = this.beans.rangeSvc; if (!rangeSvc || rangeSvc.isEmpty()) { return; } const allRangesMerge = rangeSvc.areAllRangesAbleToMerge(); const { data, cellsToFlash } = allRangesMerge ? this.buildDataFromMergedRanges(rangeSvc, params) : this.buildDataFromRanges(rangeSvc, params); this.copyDataToClipboard(data); this.dispatchFlashCells(cellsToFlash); } buildDataFromMergedRanges(rangeSvc, params) { const columnsSet = /* @__PURE__ */ new Set; const ranges = rangeSvc.getCellRanges(); const rowPositionsMap = /* @__PURE__ */ new Map; const allRowPositions = []; const allCellsToFlash = {}; const isClientSideRowModel = _isClientSideRowModel(this.gos, this.beans.rowModel); const flatCache = /* @__PURE__ */ new Set; if (!isClientSideRowModel) { this.beans.rowModel.forEachNode((node) => { flatCache.add(node.rowIndex); }); } for (const range of ranges) { range.columns.forEach((col) => columnsSet.add(col)); const { rowPositions, cellsToFlash } = this.getRangeRowPositionsAndCellsToFlash(rangeSvc, range); for (const rowPosition of rowPositions) { const isInCache = flatCache.has(rowPosition.rowIndex); if (!isClientSideRowModel && !isInCache) { continue; } const rowPositionAsString = `${rowPosition.rowIndex}-${rowPosition.rowPinned || "null"}`; if (!rowPositionsMap.get(rowPositionAsString)) { rowPositionsMap.set(rowPositionAsString, true); allRowPositions.push(rowPosition); } } Object.assign(allCellsToFlash, cellsToFlash); } const allColumns = this.beans.visibleCols.allCols; const exportedColumns = Array.from(columnsSet); exportedColumns.sort((a, b) => { const posA = allColumns.indexOf(a); const posB = allColumns.indexOf(b); return posA - posB; }); const data = this.buildExportParams({ columns: exportedColumns, rowPositions: allRowPositions, includeHeaders: params.includeHeaders, includeGroupHeaders: params.includeGroupHeaders }); return { data, cellsToFlash: allCellsToFlash }; } buildDataFromRanges(rangeSvc, params) { const ranges = rangeSvc.getCellRanges(); const data = []; const allCellsToFlash = {}; for (const range of ranges) { const { rowPositions, cellsToFlash } = this.getRangeRowPositionsAndCellsToFlash(rangeSvc, range); Object.assign(allCellsToFlash, cellsToFlash); data.push(this.buildExportParams({ columns: range.columns, rowPositions, includeHeaders: params.includeHeaders, includeGroupHeaders: params.includeGroupHeaders })); } return { data: data.join(` `), cellsToFlash: allCellsToFlash }; } getRangeRowPositionsAndCellsToFlash(rangeSvc, range) { const rowPositions = []; const cellsToFlash = {}; const startRow = rangeSvc.getRangeStartRow(range); const lastRow = rangeSvc.getRangeEndRow(range); let node = startRow; while (node) { rowPositions.push(node); for (const column of range.columns) { const { rowIndex, rowPinned } = node; const cellId = _createCellId({ rowIndex, column, rowPinned }); cellsToFlash[cellId] = true; } if (_isSameRow(node, lastRow)) { break; } node = _getRowBelow(this.beans, node); } return { rowPositions, cellsToFlash }; } getCellsToFlashFromRowNodes(rowNodes) { const allDisplayedColumns = this.beans.visibleCols.allCols; const cellsToFlash = {}; for (let i = 0;i < rowNodes.length; i++) { const { level, rowIndex: index, rowPinned, sibling } = rowNodes[i]; const rowIndex = level === -1 ? sibling.rowIndex : index; if (rowIndex == null) { continue; } for (let j = 0;j < allDisplayedColumns.length; j++) { const column = allDisplayedColumns[j]; const cellId = _createCellId({ rowIndex, column, rowPinned }); cellsToFlash[cellId] = true; } } return cellsToFlash; } copyFocusedCellToClipboard(params = {}) { let focusedCell = this.beans.focusSvc.getFocusedCell(); if (focusedCell == null) { return; } focusedCell = this.beans.rowSpanSvc?.getCellStart(focusedCell) ?? focusedCell; const cellId = _createCellId(focusedCell); const currentRow = { rowPinned: focusedCell.rowPinned, rowIndex: focusedCell.rowIndex }; const column = focusedCell.column; const data = this.buildExportParams({ columns: [column], rowPositions: [currentRow], includeHeaders: params.includeHeaders, includeGroupHeaders: params.includeGroupHeaders }); this.copyDataToClipboard(data); this.dispatchFlashCells({ [cellId]: true }); } copySelectedRowsToClipboard(params = {}) { const { columnKeys, includeHeaders, includeGroupHeaders } = params; const data = this.buildExportParams({ columns: columnKeys, includeHeaders, includeGroupHeaders }); this.copyDataToClipboard(data); const rowNodes = this.beans.selectionSvc?.getSelectedNodes() || []; this.dispatchFlashCells(this.getCellsToFlashFromRowNodes(rowNodes)); } buildExportParams(params) { const { columns, rowPositions, includeHeaders = false, includeGroupHeaders = false } = params; const { gos, csvCreator } = this.beans; const processRowGroupCallback = ({ node, column }) => { const { value, valueFormatted } = this.beans.valueSvc.getValueForDisplay({ column, node, includeValueFormatted: true, from: "batch" }); const val = valueFormatted ?? value ?? ""; const cb = gos.getCallback("processCellForClipboard"); if (!cb) { return val; } return cb({ column, node, value: val, type: EXPORT_TYPE_CLIPBOARD, formatValue: (valueToFormat) => this.beans.valueSvc.formatValue(column, node, valueToFormat) ?? valueToFormat, parseValue: (valueToParse) => this.beans.valueSvc.parseValue(column, node, valueToParse, value) ?? valueToParse }); }; const exportParams = { columnKeys: columns, rowPositions, skipColumnHeaders: !includeHeaders, skipColumnGroupHeaders: !includeGroupHeaders, suppressQuotes: true, columnSeparator: this.getClipboardDelimiter(), onlySelected: !rowPositions, valueFrom: "batch", processCellCallback: gos.getCallback("processCellForClipboard"), processRowGroupCallback, processHeaderCallback: gos.getCallback("processHeaderForClipboard"), processGroupHeaderCallback: gos.getCallback("processGroupHeaderForClipboard") }; return csvCreator.getDataAsCsv(exportParams, true); } dispatchFlashCells(cellsToFlash) { window.setTimeout(() => { this.eventSvc.dispatchEvent({ type: "flashCells", cells: cellsToFlash }); }, 0); } processCell(rowNode, column, value, type, func, canParse, canFormat) { const { valueSvc, formula } = this.beans; if (func) { const params = { column, node: rowNode, value, type, formatValue: (valueToFormat) => valueSvc.formatValue(column, rowNode ?? null, valueToFormat) ?? valueToFormat, parseValue: (valueToParse) => valueSvc.parseValue(column, rowNode ?? null, valueToParse, valueSvc.getValue(column, rowNode, "edit")) }; return func(params); } if (canParse && column.getColDef().useValueParserForImport !== false) { return valueSvc.parseValue(column, rowNode ?? null, value, valueSvc.getValue(column, rowNode, "edit")); } if (canFormat && column.getColDef().useValueFormatterForExport !== false) { if (formula?.isFormula(value)) { return value; } return valueSvc.formatValue(column, rowNode ?? null, value) ?? value; } return value; } copyDataToClipboard(data) { const userProvidedFunc = this.gos.getCallback("sendToClipboard"); if (userProvidedFunc) { userProvidedFunc({ data }); return; } const allowNavigator = !this.gos.get("suppressClipboardApi"); if (allowNavigator && navigator.clipboard) { navigator.clipboard.writeText(data).catch((e) => { _warn(40, { e, method: "writeText" }); this.copyDataToClipboardLegacy(data); }); return; } this.copyDataToClipboardLegacy(data); } copyDataToClipboardLegacy(data) { this.executeOnTempElement((element) => { const eDocument = _getDocument(this.beans); const focusedElementBefore = _getActiveDomElement(this.beans); element.value = data || " "; element.select(); element.focus({ preventScroll: true }); const result = eDocument.execCommand("copy"); if (!result) { _warn(41); } if (focusedElementBefore?.focus != null) { focusedElementBefore.focus({ preventScroll: true }); } }); } executeOnTempElement(callbackNow, callbackAfter) { if (!this.gridCtrl) { return; } const eDoc = _getDocument(this.beans); const eTempInput = eDoc.createElement("textarea"); const style = eTempInput.style; style.width = "1px"; style.height = "1px"; const documentElement = eDoc.documentElement; style.top = documentElement.scrollTop + "px"; style.left = documentElement.scrollLeft + "px"; style.position = "absolute"; style.opacity = "0"; const guiRoot = this.gridCtrl.getGui(); guiRoot.appendChild(eTempInput); try { callbackNow(eTempInput); } catch (err) { _warn(42); } if (callbackAfter) { window.setTimeout(() => { callbackAfter(eTempInput); eTempInput.remove(); }, 100); } else { eTempInput.remove(); } } }; var ClipboardModule = { moduleName: "Clipboard", version: VERSION2, beans: [ClipboardService], apiFunctions: { copyToClipboard, cutToClipboard, copySelectedRowsToClipboard, copySelectedRangeToClipboard, copySelectedRangeDown, pasteFromClipboard }, dependsOn: [EnterpriseCoreModule, CsvExportModule, KeyboardNavigationModule, HighlightChangesModule] }; var DetailCellRendererCtrl = class extends BeanStub { constructor() { super(...arguments); this.loadRowDataVersion = 0; } wireBeans(beans) { this.environment = beans.environment; } init(comp, params) { this.params = params; this.comp = comp; const doNothingBecauseInsidePinnedSection = params.pinned != null; if (doNothingBecauseInsidePinnedSection) { return; } this.setAutoHeightClasses(); this.setupRefreshStrategy(); this.createDetailGrid(); this.loadRowData(); this.addManagedEventListeners({ fullWidthRowFocused: this.onFullWidthRowFocused.bind(this) }); } onFullWidthRowFocused(e) { const params = this.params; const row = { rowIndex: params.node.rowIndex, rowPinned: params.node.rowPinned }; const eventRow = { rowIndex: e.rowIndex, rowPinned: e.rowPinned }; const isSameRow = _isSameRow(row, eventRow); if (!isSameRow) { return; } _focusInto(this.comp.getGui(), e.fromBelow); } setAutoHeightClasses() { const autoHeight = this.gos.get("detailRowAutoHeight"); const parentClass = autoHeight ? "ag-details-row-auto-height" : "ag-details-row-fixed-height"; const detailClass = autoHeight ? "ag-details-grid-auto-height" : "ag-details-grid-fixed-height"; const comp = this.comp; comp.toggleCss(parentClass, true); comp.toggleDetailGridCss(detailClass, true); } setupRefreshStrategy() { const providedStrategy = this.params.refreshStrategy; const validSelection = providedStrategy == "everything" || providedStrategy == "nothing" || providedStrategy == "rows"; if (validSelection) { this.refreshStrategy = providedStrategy; return; } if (providedStrategy != null) { _warn(170, { providedStrategy }); } this.refreshStrategy = "rows"; } createDetailGrid() { const { params, gos } = this; if (_missing(params.detailGridOptions)) { _warn(171); return; } const masterTheme = gos.get("theme"); const detailTheme = params.detailGridOptions.theme; if (detailTheme && detailTheme !== masterTheme) { _warn(267); } const gridOptions = { themeStyleContainer: this.environment.eStyleContainer, ...params.detailGridOptions, theme: masterTheme }; const autoHeight = gos.get("detailRowAutoHeight"); if (autoHeight) { gridOptions.domLayout = "autoHeight"; } this.comp.setDetailGrid(gridOptions); } registerDetailWithMaster(api) { const { params, beans: { selectionSvc, findSvc, expansionSvc } } = this; const rowId = params.node.id; const masterGridApi = params.api; const gridInfo = { id: rowId, api }; const rowNode = params.node; if (masterGridApi.isDestroyed()) { return; } masterGridApi.addDetailGridInfo(rowId, gridInfo); rowNode.detailGridInfo = gridInfo; const masterNode = rowNode.parent; findSvc?.registerDetailGrid(rowNode, api); function onDetailSelectionChanged() { if (masterNode) { selectionSvc?.refreshMasterNodeState(masterNode); } } function adjustDetailsOnExpandOrCollapseAll({ source }) { if (source === "expandAll") { return api.expandAll(); } if (source === "collapseAll") { return api.collapseAll(); } } function onMasterRowSelected({ node, source }) { if (node !== masterNode || source === "masterDetail" || api.isDestroyed()) { return; } selectionSvc?.setDetailSelectionState(masterNode, params.detailGridOptions, api); } api.addEventListener("firstDataRendered", () => { if (api.isDestroyed() || masterGridApi.isDestroyed()) { return; } selectionSvc?.setDetailSelectionState(masterNode, params.detailGridOptions, api); api.addEventListener("selectionChanged", onDetailSelectionChanged); masterGridApi.addEventListener("rowSelected", onMasterRowSelected); const sharedApiModuleName = "CsrmSsrmSharedApi"; const asAgModuleName = `${sharedApiModuleName}Module`; if (api.isModuleRegistered(asAgModuleName)) { masterGridApi.addEventListener("expandOrCollapseAll", adjustDetailsOnExpandOrCollapseAll); expansionSvc?.setDetailsExpansionState(api); } }); this.addManagedListeners(masterNode, { masterChanged: (event) => { if (!event.node.master) { this.onDestroy(gridInfo); } } }); this.addDestroyFunc(() => this.onDestroy(gridInfo)); } onDestroy(gridInfo) { const { params } = this; const rowNode = params.node; const masterGridApi = params.api; if (rowNode.detailGridInfo !== gridInfo) { return; } if (!masterGridApi.isDestroyed()) { masterGridApi.removeDetailGridInfo(rowNode.id); } rowNode.detailGridInfo = null; } loadRowData() { this.loadRowDataVersion++; const versionThisCall = this.loadRowDataVersion; const params = this.params; if (params.detailGridOptions?.rowModelType === "serverSide") { const node = params.node; node.detailGridInfo?.api?.refreshServerSide({ purge: true }); return; } const userFunc = params.getDetailRowData; if (!userFunc) { _warn(172); return; } const successCallback = (rowData) => { const mostRecentCall = this.loadRowDataVersion === versionThisCall; if (mostRecentCall) { this.comp.setRowData(rowData); } }; const funcParams = { node: params.node, data: params.node.data, successCallback, context: _addGridCommonParams(this.gos, {}).context }; userFunc(funcParams); } refresh() { const GET_GRID_TO_REFRESH = false; const GET_GRID_TO_DO_NOTHING = true; switch (this.refreshStrategy) { case "nothing": return GET_GRID_TO_DO_NOTHING; case "everything": return GET_GRID_TO_REFRESH; } this.loadRowData(); return GET_GRID_TO_DO_NOTHING; } }; var DetailFrameworkComponentWrapper = class { constructor(parentWrapper) { this.parentWrapper = parentWrapper; } wrap(frameworkComponent, mandatoryMethods, optionalMethods, componentType) { return this.parentWrapper.wrap(frameworkComponent, mandatoryMethods, optionalMethods, componentType); } }; var PinnedDetailCellRendererElement = { tag: "div", cls: "ag-details-row" }; var DetailCellRendererElement = { tag: "div", cls: "ag-details-row", role: "gridcell", children: [{ tag: "div", ref: "eDetailGrid", cls: "ag-details-grid", role: "presentation" }] }; var DetailCellRenderer = class extends Component { constructor() { super(...arguments); this.eDetailGrid = RefPlaceholder; } wireBeans(beans) { this.context = beans.context; } init(params) { this.params = params; this.selectAndSetTemplate(); const compProxy = { toggleCss: (cssClassName, on) => this.toggleCss(cssClassName, on), toggleDetailGridCss: (cssClassName, on) => this.eDetailGrid.classList.toggle(cssClassName, on), setDetailGrid: (gridOptions) => this.setDetailGrid(gridOptions), setRowData: (rowData) => this.setRowData(rowData), getGui: () => this.eDetailGrid }; this.ctrl = this.createManagedBean(new DetailCellRendererCtrl); this.ctrl.init(compProxy, params); } refresh() { return this.ctrl?.refresh() ?? false; } selectAndSetTemplate() { const params = this.params; if (params.pinned) { this.setTemplate(PinnedDetailCellRendererElement); return; } const setDefaultTemplate = () => { this.setTemplate(DetailCellRendererElement); }; if (_missing(params.template)) { setDefaultTemplate(); } else if (typeof params.template === "string") { this.setTemplate(params.template, []); } else if (typeof params.template === "function") { const templateFunc = params.template; const template = templateFunc(params); this.setTemplate(template, []); } else { _warn(168); setDefaultTemplate(); } if (this.eDetailGrid == null) { _warn(169); } } setDetailGrid(gridOptions) { if (!this.eDetailGrid) { return; } const parentFrameworkComponentWrapper = this.context.getBean("frameworkCompWrapper"); const frameworkCompWrapper = new DetailFrameworkComponentWrapper(parentFrameworkComponentWrapper); const { frameworkOverrides } = this.beans; const api = createGrid(this.eDetailGrid, gridOptions, { frameworkOverrides, providedBeanInstances: { frameworkCompWrapper }, modules: _getGridRegisteredModules(this.params.api.getGridId(), gridOptions.rowModelType ?? "clientSide") }); this.detailApi = api; this.ctrl?.registerDetailWithMaster(api); this.addDestroyFunc(() => { api.destroy(); }); } setRowData(rowData) { this.detailApi?.setGridOption("rowData", rowData); } }; function operateOnStore(beans, callback) { const store = beans.masterDetailSvc?.store; return store ? callback(store) : undefined; } function addDetailGridInfo(beans, id, gridInfo) { operateOnStore(beans, (store) => { store[id] = gridInfo; }); } function removeDetailGridInfo(beans, id) { operateOnStore(beans, (store) => { delete store[id]; }); } function getDetailGridInfo(beans, id) { return operateOnStore(beans, (store) => store[id]); } function forEachDetailGridInfo(beans, callback) { operateOnStore(beans, (store) => { let index = 0; Object.values(store).forEach((gridInfo) => { if (gridInfo) { callback(gridInfo, index++); } }); }); } var masterDetailModule_default = ".ag-details-row{width:100%}.ag-details-row-fixed-height{height:100%}.ag-details-grid{width:100%}.ag-details-grid-fixed-height{height:100%}"; var MasterDetailService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "masterDetailSvc"; this.store = {}; } isEnabled() { return this.gos.get("masterDetail"); } postConstruct() { const gos = this.gos; if (_isClientSideRowModel(gos)) { this.enabled = this.isEnabled(); } if (_isServerSideRowModel(gos)) { this.addEventListeners(); } } addEventListeners() { const rowNodeDataChanged = (event) => { this.setMaster(event.node, false, true); }; let removeListeners; const addOrRemoveListeners = () => { if (removeListeners) { for (const removeListener of removeListeners) { removeListener(); } removeListeners = undefined; } if (this.isEnabled()) { removeListeners = this.addManagedListeners(this.beans.eventSvc, { rowNodeDataChanged }); } }; addOrRemoveListeners(); this.gos.addPropertyEventListener("masterDetail", addOrRemoveListeners); } refreshModel(params) { if (params.changedProps) { const enabled = this.isEnabled(); if (this.enabled !== enabled) { this.setMasters(null); return; } } if (params.rowDataUpdated) { this.setMasters(params.changedRowNodes); } } setMaster(row, created, updated) { const oldMaster = row.master; const enabled = this.isEnabled(); let newMaster = enabled; const gos = this.gos; const isRowMaster = gos.get("isRowMaster"); const treeData = gos.get("treeData"); if (enabled) { if (created || updated) { if (isRowMaster) { const data = row.data; newMaster = !!data && !!isRowMaster(data); } } else { newMaster = oldMaster; } } if (!treeData) { if (newMaster && created || !newMaster && oldMaster) { row._expanded ?? (row._expanded = null); } } if (newMaster !== oldMaster) { row.master = newMaster; row.dispatchRowEvent("masterChanged"); } } setMasters(changedRowNodes) { this.enabled = this.isEnabled(); if (changedRowNodes) { for (const node of changedRowNodes.updates) { this.setMaster(node, false, true); } for (const node of changedRowNodes.adds) { this.setMaster(node, true, false); } } else { const allLeafChildren = _getClientSideRowModel(this.beans)?.rootNode?._leafs; if (allLeafChildren) { for (let i = 0, len = allLeafChildren.length;i < len; ++i) { this.setMaster(allLeafChildren[i], true, false); } } } } getDetail(masterNode) { if (!masterNode.master || !masterNode.expanded) { return null; } let detailNode = masterNode.detailNode; if (detailNode) { return detailNode; } detailNode = new RowNode(this.beans); detailNode.detail = true; detailNode.selectable = false; detailNode.parent = masterNode; if (_exists(masterNode.id)) { detailNode.id = "detail_" + masterNode.id; } detailNode.data = masterNode.data; detailNode.level = masterNode.level + 1; masterNode.detailNode = detailNode; return detailNode; } setupDetailRowAutoHeight(rowCtrl, eDetailGui) { const { gos, beans } = this; if (!gos.get("detailRowAutoHeight")) { return; } const checkRowSizeFunc = () => { const clientHeight = eDetailGui.clientHeight; if (clientHeight != null && clientHeight > 0) { const updateRowHeightFunc = () => { const { rowModel } = this.beans; const { rowNode } = rowCtrl; rowNode.setRowHeight(clientHeight); if (_isClientSideRowModel(gos, rowModel) || _isServerSideRowModel(gos, rowModel)) { rowModel.onRowHeightChanged(); } }; window.setTimeout(updateRowHeightFunc, 0); } }; const resizeObserverDestroyFunc = _observeResize(beans, eDetailGui, checkRowSizeFunc); rowCtrl.addDestroyFunc(resizeObserverDestroyFunc); checkRowSizeFunc(); } destroy() { this.store = {}; super.destroy(); } }; var SharedMasterDetailModule = { moduleName: "SharedMasterDetail", version: VERSION2, beans: [MasterDetailService], userComponents: { agDetailCellRenderer: DetailCellRenderer }, dynamicBeans: { detailCellRendererCtrl: DetailCellRendererCtrl }, apiFunctions: { addDetailGridInfo, removeDetailGridInfo, getDetailGridInfo, forEachDetailGridInfo }, dependsOn: [EnterpriseCoreModule, GroupCellRendererModule, StickyRowModule], css: [masterDetailModule_default] }; var MasterDetailModule = { moduleName: "MasterDetail", version: VERSION2, dependsOn: [SharedMasterDetailModule, ClientSideRowModelHierarchyModule, EventApiModule] }; var AbstractSelectionHandle = class extends Component { constructor() { super(...arguments); this.changedCalculatedValues = false; this.dragging = false; this.shouldDestroyOnEndDragging = false; } postConstruct() { this.beans.dragSvc.addDragSource({ dragStartPixels: 0, eElement: this.getGui(), onDragging: (e) => { let startingMove = false; if (!this.dragging) { startingMove = true; this.dragging = true; const pageBody = _getPageBody(this.beans); pageBody.classList?.add(this.getDraggingCssClass()); } this.updateValuesOnMove(e); if (startingMove) { this.changedCalculatedValues = false; return; } this.beans.rangeSvc.autoScrollService.check(e); if (this.changedCalculatedValues) { this.onDrag(e); this.changedCalculatedValues = false; } }, onDragStop: (e) => { this.dragging = false; this.onDragEnd(e); this.clearDragProperties(); }, onDragCancel: () => { this.dragging = false; this.onDragCancel(); this.clearDragProperties(); } }); this.addManagedEventListeners({ cellSelectionChanged: this.updateLocalRangeIfNeeded.bind(this) }); this.addManagedElementListeners(this.getGui(), { pointerdown: stopEventPropagation, mousedown: stopEventPropagation }); } getLastCellHovered() { return this.lastCellHovered; } getDraggingCssClass() { return `ag-dragging-${this.type === 0 ? "fill" : "range"}-handle`; } updateValuesOnMove(e) { const cell = _getCellPositionForEvent(this.gos, e); if (!cell || this.shouldSkipCell(cell) || this.lastCellHovered && _areCellsEqual(cell, this.lastCellHovered)) { return; } this.lastCellHovered = cell; this.changedCalculatedValues = true; } clearDragProperties() { this.clearValues(); this.beans.rangeSvc.autoScrollService.ensureCleared(); const pageBody = _getPageBody(this.beans); pageBody.classList?.remove(this.getDraggingCssClass()); if (this.shouldDestroyOnEndDragging) { this.destroy(); } } getType() { return this.type; } refresh(cellCtrl, cellRange) { const oldCellComp = this.cellCtrl; const eGui = this.getGui(); const cellRangeToUse = cellRange ?? _last(this.beans.rangeSvc.getCellRanges()); const start = cellRangeToUse.startRow; const end = cellRangeToUse.endRow; if (start && end) { const isBefore = _isRowBefore(end, start); if (isBefore) { this.rangeStartRow = end; this.rangeEndRow = start; } else { this.rangeStartRow = start; this.rangeEndRow = end; } } if (oldCellComp !== cellCtrl || !_isVisible(eGui)) { this.cellCtrl = cellCtrl; const eParentOfValue = cellCtrl.comp.getParentOfValue(); if (eParentOfValue) { eParentOfValue.appendChild(eGui); } } this.cellRange = cellRangeToUse; } clearValues() { this.lastCellHovered = undefined; } destroy() { if (!this.shouldDestroyOnEndDragging && this.dragging) { _setDisplayed(this.getGui(), false); this.shouldDestroyOnEndDragging = true; return; } this.shouldDestroyOnEndDragging = false; super.destroy(); this.getGui()?.remove(); } updateLocalRangeIfNeeded(event) { if (!this.cellRange) { return; } const { id, type } = this.cellRange; if (!id || id !== event.id) { return; } const newRange = this.beans.rangeSvc?.getCellRanges().find((range) => range.id === id && range.type === type); if (newRange && newRange !== this.cellRange) { this.cellRange = newRange; } } }; var stopEventPropagation = (e) => { e.stopPropagation(); }; function findLineByLeastSquares(values) { const len = values.length; let maxDecimals = 0; if (len <= 1) { return values; } for (let i = 0;i < values.length; i++) { const value = values[i]; const splitExponent = value.toString().split("e-"); if (splitExponent.length > 1) { maxDecimals = Math.max(maxDecimals, parseInt(splitExponent[1], 10)); continue; } if (Math.floor(value) === value) { continue; } maxDecimals = Math.max(maxDecimals, value.toString().split(".")[1].length); } let sum_x = 0; let sum_y = 0; let sum_xy = 0; let sum_xx = 0; let y = 0; for (let x = 0;x < len; x++) { y = values[x]; sum_x += x; sum_y += y; sum_xx += x * x; sum_xy += x * y; } const m = (len * sum_xy - sum_x * sum_y) / (len * sum_xx - sum_x * sum_x); const b = sum_y / len - m * sum_x / len; const result = []; for (let x = 0;x <= len; x++) { result.push(parseFloat((x * m + b).toFixed(maxDecimals))); } return result; } var FillHandleElement = { tag: "div", cls: "ag-fill-handle" }; var AgFillHandle = class extends AbstractSelectionHandle { constructor() { super(FillHandleElement); this.markedCells = []; this.cellValues = []; this.isUp = false; this.isLeft = false; this.isReduce = false; this.type = 0; } postConstruct() { super.postConstruct(); this.addManagedElementListeners(this.getGui(), { dblclick: this.onDblClick.bind(this) }); } onDblClick(e) { _stopPropagationForAgGrid(e); const { cellRange: initialRange, rangeStartRow, beans } = this; const { rangeSvc, visibleCols } = beans; const lastRow = _getLastRow(beans); if (!lastRow) { return; } const fillHandleDirection = this.getFillHandleDirection(); this.dragAxis = fillHandleDirection === "xy" ? "y" : fillHandleDirection; const finalRange = rangeSvc?.createCellRangeFromCellRangeParams({ rowStartIndex: rangeStartRow.rowIndex, rowStartPinned: rangeStartRow.rowPinned, columnStart: initialRange.columns[0], rowEndIndex: this.dragAxis === "x" ? initialRange.endRow?.rowIndex ?? null : lastRow.rowIndex, rowEndPinned: this.dragAxis === "x" ? initialRange.endRow?.rowPinned : lastRow.rowPinned, columnEnd: this.dragAxis === "x" ? _last(visibleCols.allCols) : _last(initialRange.columns) }); this.isUp = false; this.isLeft = false; if (finalRange) { this.performFill({ event: e, initialRange, finalRange }); } this.dragAxis = undefined; } updateValuesOnMove(e) { super.updateValuesOnMove(e); if (!this.initialXY) { this.initialXY = _getNormalisedMousePosition(this.beans, e); } const { x, y } = this.initialXY; const { x: newX, y: newY } = _getNormalisedMousePosition(this.beans, e); const diffX = Math.abs(x - newX); const diffY = Math.abs(y - newY); const allowedDirection = this.getFillHandleDirection(); let direction; if (allowedDirection === "xy") { direction = diffX > diffY ? "x" : "y"; } else { direction = allowedDirection; } if (direction !== this.dragAxis) { this.dragAxis = direction; this.changedCalculatedValues = true; } } shouldSkipCell(cell) { return isRowNumberCol(cell.column); } onDrag(_) { if (!this.initialPosition) { const cellCtrl = this.cellCtrl; if (!cellCtrl) { return; } this.initialPosition = cellCtrl.cellPosition; } const lastCellHovered = this.getLastCellHovered(); if (lastCellHovered) { this.markPathFrom(this.initialPosition, lastCellHovered); } } onDragEnd(e) { this.initialXY = null; if (!this.markedCells.length) { return; } const isX = this.dragAxis === "x"; const { cellRange: initialRange, rangeStartRow, rangeEndRow, beans: { rangeSvc } } = this; const colLen = initialRange.columns.length; let finalRange; if (!this.isUp && !this.isLeft) { finalRange = rangeSvc.createCellRangeFromCellRangeParams({ rowStartIndex: rangeStartRow.rowIndex, rowStartPinned: rangeStartRow.rowPinned, columnStart: initialRange.columns[0], rowEndIndex: isX ? rangeEndRow.rowIndex : this.lastCellMarked.rowIndex, rowEndPinned: isX ? rangeEndRow.rowPinned : this.lastCellMarked.rowPinned, columnEnd: isX ? this.lastCellMarked.column : initialRange.columns[colLen - 1] }); } else { const startRow = isX ? rangeStartRow : this.lastCellMarked; finalRange = rangeSvc.createCellRangeFromCellRangeParams({ rowStartIndex: startRow.rowIndex, rowStartPinned: startRow.rowPinned, columnStart: isX ? this.lastCellMarked.column : initialRange.columns[0], rowEndIndex: rangeEndRow.rowIndex, rowEndPinned: rangeEndRow.rowPinned, columnEnd: initialRange.columns[colLen - 1] }); } if (finalRange) { this.performFill({ event: e, initialRange, finalRange, shouldUpdateRange: true }); } } onDragCancel() { this.initialXY = null; if (!this.markedCells.length) { return; } this.clearMarkedPath(); } performFill({ event, initialRange, finalRange, shouldUpdateRange }) { const { eventSvc, rangeSvc } = this.beans; eventSvc.dispatchEvent({ type: "fillStart" }); this.handleValueChanged(initialRange, finalRange, event); if (shouldUpdateRange) { rangeSvc.setCellRanges([finalRange]); } eventSvc.dispatchEvent({ type: "fillEnd", initialRange, finalRange }); } getFillHandleDirection() { const direction = _getFillHandle(this.gos)?.direction; if (!direction) { return "xy"; } if (direction !== "x" && direction !== "y" && direction !== "xy") { _warn(177); return "xy"; } return direction; } handleValueChanged(initialRange, finalRange, e) { const { beans } = this; const { rangeSvc, gos, valueSvc } = beans; const initialRangeEndRow = rangeSvc.getRangeEndRow(initialRange); const initialRangeStartRow = rangeSvc.getRangeStartRow(initialRange); const finalRangeEndRow = rangeSvc.getRangeEndRow(finalRange); const finalRangeStartRow = rangeSvc.getRangeStartRow(finalRange); const isVertical = this.dragAxis === "y"; if (this.isReduce && !_getFillHandle(gos)?.suppressClearOnFillReduction) { const columns = isVertical ? initialRange.columns : initialRange.columns.filter((col) => finalRange.columns.indexOf(col) < 0); const startRow = isVertical ? _getRowBelow(beans, finalRangeEndRow) : finalRangeStartRow; if (startRow) { this.clearCellsInRange(startRow, initialRangeEndRow, columns); } return; } const values = []; const initialValues = []; const initialNonAggregatedValues = []; const initialFormattedValues = []; let withinInitialRange = true; let idx = 0; const resetValues = () => { values.length = 0; initialValues.length = 0; initialNonAggregatedValues.length = 0; initialFormattedValues.length = 0; idx = 0; }; const iterateAcrossCells = (column, columns) => { let currentRow = this.isUp ? initialRangeEndRow : initialRangeStartRow; let finished = false; if (isVertical) { withinInitialRange = true; resetValues(); } while (!finished && currentRow) { const rowNode = _getRowNode(beans, currentRow); if (!rowNode) { break; } if (isVertical && column) { fillValues(values, column, rowNode, () => !_isSameRow(currentRow, this.isUp ? initialRangeStartRow : initialRangeEndRow)); } else if (columns) { withinInitialRange = true; resetValues(); for (const col of columns) { fillValues(values, col, rowNode, () => col !== (this.isLeft ? initialRange.columns[0] : _last(initialRange.columns))); } } finished = _isSameRow(currentRow, this.isUp ? finalRangeStartRow : finalRangeEndRow); currentRow = this.isUp ? _getRowAbove(this.beans, currentRow) : _getRowBelow(beans, currentRow); } }; const fillValues = (currentValues, col, rowNode, updateInitialSet) => { let currentValue; let skipValue = false; if (withinInitialRange) { currentValue = valueSvc.getValue(col, rowNode, "edit"); initialValues.push(currentValue); initialNonAggregatedValues.push(valueSvc.getValue(col, rowNode, "edit", true)); initialFormattedValues.push(valueSvc.getValueForDisplay({ column: col, node: rowNode, from: "edit" }).valueFormatted); withinInitialRange = updateInitialSet(); } else { const { value, fromUserFunction, sourceCol, sourceRowNode } = this.processValues({ event: e, values: currentValues, initialValues, initialNonAggregatedValues, initialFormattedValues, col, rowNode, idx: idx++ }); currentValue = value; if (col.isCellEditable(rowNode)) { const cellValue = valueSvc.getValue(col, rowNode, "edit"); if (!fromUserFunction) { if (sourceCol) { const sourceColDef = sourceCol.getColDef(); if (sourceColDef.useValueFormatterForExport !== false && sourceColDef.valueFormatter) { const formattedValue = valueSvc.getValueForDisplay({ column: sourceCol, node: sourceRowNode, includeValueFormatted: true, from: "edit" }).valueFormatted; if (formattedValue != null) { currentValue = formattedValue; } } } if (col.getColDef().useValueParserForImport !== false) { currentValue = valueSvc.parseValue(col, rowNode, sourceCol ? currentValue : _toStringOrNull(currentValue), cellValue); } } if (!fromUserFunction || cellValue !== currentValue) { rowNode.setDataValue(col, currentValue, "rangeSvc"); } else { skipValue = true; } } } if (!skipValue) { currentValues.push({ value: currentValue, column: col, rowNode }); } }; const { changeDetectionSvc } = this.beans; changeDetectionSvc?.beginDeferred(); try { if (isVertical) { initialRange.columns.forEach((col) => { iterateAcrossCells(col); }); } else { const columns = this.isLeft ? [...finalRange.columns].reverse() : finalRange.columns; iterateAcrossCells(undefined, columns); } this.beans.editSvc?.stopEditing(undefined, { source: "fillHandle" }); } finally { changeDetectionSvc?.endDeferred(); } } clearCellsInRange(startRow, endRow, columns) { const cellRange = { startRow, endRow, columns, startColumn: columns[0] }; this.beans.rangeSvc.clearCellRangeCellValues({ cellRanges: [cellRange], restoreSourceInBatch: true }); } processValues(params) { const { formula, valueSvc } = this.beans; const { event, values, initialValues, initialNonAggregatedValues, initialFormattedValues, col, rowNode, idx } = params; const userFillOperation = _getFillHandle(this.gos)?.setFillValue; const isVertical = this.dragAxis === "y"; let direction; if (isVertical) { direction = this.isUp ? "up" : "down"; } else { direction = this.isLeft ? "left" : "right"; } if (userFillOperation) { const params2 = _addGridCommonParams(this.gos, { event, values: values.map(({ value }) => value), initialValues, initialNonAggregatedValues, initialFormattedValues, currentIndex: idx, currentCellValue: valueSvc.getValue(col, rowNode, "edit"), direction, column: col, rowNode }); const userResult = userFillOperation(params2); if (userResult !== false) { return { value: userResult, fromUserFunction: true }; } } const isNumeric2 = (v) => typeof v === "number" && Number.isFinite(v) || typeof v === "string" && /^[+-]?\d+(?:\.\d+)?$/.test(v.trim()); const allNumbers = values.every(({ value }) => isNumeric2(value)); if (event.altKey || !allNumbers) { const valueForFunctions = String(_last(values)?.value ?? ""); if (allNumbers && initialValues.length === 1) { const multiplier = this.isUp || this.isLeft ? -1 : 1; return { value: parseFloat(valueForFunctions) + 1 * multiplier, fromUserFunction: false }; } const { value: cyclicValue, column: sourceCol, rowNode: sourceRowNode } = values[idx % values.length]; let processedValue; const fromFormula = sourceCol.isAllowFormula() && formula?.isFormula(valueForFunctions); if (fromFormula) { const rowDelta = direction === "up" ? -1 : direction === "down" ? 1 : 0; const columnDelta = direction === "left" ? -1 : direction === "right" ? 1 : 0; processedValue = formula.updateFormulaByOffset({ value: valueForFunctions, rowDelta, columnDelta }); } else { processedValue = cyclicValue; } return { value: processedValue, fromUserFunction: false, sourceCol: fromFormula ? undefined : sourceCol, sourceRowNode }; } return { value: _last(findLineByLeastSquares(values.map(({ value }) => Number(value)))), fromUserFunction: false }; } clearValues() { this.clearMarkedPath(); this.clearCellValues(); this.lastCellMarked = undefined; super.clearValues(); } clearMarkedPath() { for (const cell of this.markedCells) { if (!cell.isAlive()) { continue; } const { comp } = cell; comp.toggleCss("ag-selection-fill-top", false); comp.toggleCss("ag-selection-fill-right", false); comp.toggleCss("ag-selection-fill-bottom", false); comp.toggleCss("ag-selection-fill-left", false); } this.markedCells.length = 0; this.isUp = false; this.isLeft = false; this.isReduce = false; } clearCellValues() { this.cellValues.length = 0; } markPathFrom(initialPosition, currentPosition) { this.clearMarkedPath(); this.clearCellValues(); if (this.dragAxis === "y") { if (_isSameRow(currentPosition, initialPosition)) { return; } const isBefore = _isRowBefore(currentPosition, initialPosition); const { rangeStartRow, rangeEndRow } = this; if (isBefore && (currentPosition.rowPinned == rangeStartRow.rowPinned && currentPosition.rowIndex >= rangeStartRow.rowIndex || rangeStartRow.rowPinned != rangeEndRow.rowPinned && currentPosition.rowPinned == rangeEndRow.rowPinned && currentPosition.rowIndex <= rangeEndRow.rowIndex)) { this.reduceVertical(initialPosition, currentPosition); this.isReduce = true; } else { this.extendVertical(initialPosition, currentPosition, isBefore); this.isReduce = false; } } else { const initialColumn = initialPosition.column; const currentColumn = currentPosition.column; if (initialColumn === currentColumn) { return; } const displayedColumns = this.beans.visibleCols.allCols; const initialIndex = displayedColumns.indexOf(initialColumn); const currentIndex = displayedColumns.indexOf(currentColumn); if (currentIndex <= initialIndex && currentIndex >= displayedColumns.indexOf(this.cellRange.columns[0])) { this.reduceHorizontal(initialPosition, currentPosition); this.isReduce = true; } else { this.extendHorizontal(initialPosition, currentPosition, currentIndex < initialIndex); this.isReduce = false; } } this.lastCellMarked = currentPosition; } extendVertical(initialPosition, endPosition, isMovingUp) { const beans = this.beans; const { rangeSvc } = beans; let row = initialPosition; do { const cellRange = this.cellRange; const colLen = cellRange.columns.length; for (let i = 0;i < colLen; i++) { const column = cellRange.columns[i]; const rowPos = { rowIndex: row.rowIndex, rowPinned: row.rowPinned }; const cellPos = { ...rowPos, column }; const cellInRange = rangeSvc.isCellInSpecificRange(cellPos, cellRange); const isInitialRow = _isSameRow(row, initialPosition); if (isMovingUp) { this.isUp = true; } if (!isInitialRow) { const cell = _getCellByPosition(beans, cellPos); if (cell) { this.markedCells.push(cell); const cellComp = cell.comp; if (!cellInRange) { cellComp.toggleCss("ag-selection-fill-left", i === 0); cellComp.toggleCss("ag-selection-fill-right", i === colLen - 1); } cellComp.toggleCss(isMovingUp ? "ag-selection-fill-top" : "ag-selection-fill-bottom", _isSameRow(row, endPosition)); } } } if (_isSameRow(row, endPosition)) { break; } } while (row = isMovingUp ? _getRowAbove(this.beans, row) : _getRowBelow(beans, row)); } reduceVertical(initialPosition, endPosition) { let row = initialPosition; const beans = this.beans; do { const cellRange = this.cellRange; const colLen = cellRange.columns.length; const isLastRow = _isSameRow(row, endPosition); for (let i = 0;i < colLen; i++) { const rowPos = { rowIndex: row.rowIndex, rowPinned: row.rowPinned }; const celPos = { ...rowPos, column: cellRange.columns[i] }; const cell = _getCellByPosition(beans, celPos); if (cell) { this.markedCells.push(cell); cell.comp.toggleCss("ag-selection-fill-bottom", _isSameRow(row, endPosition)); } } if (isLastRow) { break; } } while (row = _getRowAbove(beans, row)); } extendHorizontal(initialPosition, endPosition, isMovingLeft) { const beans = this.beans; const { visibleCols } = beans; const allCols = visibleCols.allCols; const startCol = allCols.indexOf(isMovingLeft ? endPosition.column : initialPosition.column); const endCol = allCols.indexOf(isMovingLeft ? this.cellRange.columns[0] : endPosition.column); const offset = isMovingLeft ? 0 : 1; const colsToMark = allCols.slice(startCol + offset, endCol + offset); const { rangeStartRow, rangeEndRow } = this; for (const column of colsToMark) { let row = rangeStartRow; let isLastRow = false; do { isLastRow = _isSameRow(row, rangeEndRow); const cell = _getCellByPosition(beans, { rowIndex: row.rowIndex, rowPinned: row.rowPinned, column }); if (cell) { this.markedCells.push(cell); const cellComp = cell.comp; cellComp.toggleCss("ag-selection-fill-top", _isSameRow(row, rangeStartRow)); cellComp.toggleCss("ag-selection-fill-bottom", _isSameRow(row, rangeEndRow)); if (isMovingLeft) { this.isLeft = true; cellComp.toggleCss("ag-selection-fill-left", column === colsToMark[0]); } else { cellComp.toggleCss("ag-selection-fill-right", column === _last(colsToMark)); } } row = _getRowBelow(beans, row); } while (!isLastRow); } } reduceHorizontal(initialPosition, endPosition) { const beans = this.beans; const { visibleCols } = beans; const allCols = visibleCols.allCols; const startCol = allCols.indexOf(endPosition.column); const endCol = allCols.indexOf(initialPosition.column); const colsToMark = allCols.slice(startCol, endCol); const { rangeStartRow, rangeEndRow } = this; for (const column of colsToMark) { let row = rangeStartRow; let isLastRow = false; do { isLastRow = _isSameRow(row, rangeEndRow); const cell = _getCellByPosition(this.beans, { rowIndex: row.rowIndex, rowPinned: row.rowPinned, column }); if (cell) { this.markedCells.push(cell); cell.comp.toggleCss("ag-selection-fill-right", column === colsToMark[0]); } row = _getRowBelow(beans, row); } while (!isLastRow); } } refresh(cellCtrl, cellRange) { const cellRangeToUse = cellRange ?? this.beans.rangeSvc.getCellRanges()[0]; const isColumnRange = !cellRangeToUse.startRow || !cellRangeToUse.endRow; if (isColumnRange) { this.destroy(); return; } super.refresh(cellCtrl, cellRangeToUse); } }; var AgRangeHandle = class extends AbstractSelectionHandle { constructor() { super({ tag: "div", cls: "ag-range-handle" }); this.type = 1; this.rangeFixed = false; } onDrag(_) { const lastCellHovered = this.getLastCellHovered(); if (!lastCellHovered) { return; } const rangeSvc = this.beans.rangeSvc; const targetRange = this.cellRange ?? _last(rangeSvc.getCellRanges()); if (!targetRange) { return; } if (!this.rangeFixed) { this.fixRangeStartEnd(targetRange); this.rangeFixed = true; } this.endPosition = { rowIndex: lastCellHovered.rowIndex, rowPinned: lastCellHovered.rowPinned, column: lastCellHovered.column }; if (rangeSvc.getCellRanges().length === 2 && rangeSvc.getCellRanges()[0].type === CellRangeType.DIMENSION && targetRange.type === CellRangeType.VALUE) { const rowChanged = !_isSameRow(this.endPosition, rangeSvc.getRangeEndRow(targetRange)); if (rowChanged) { rangeSvc.updateRangeRowBoundary({ cellRange: rangeSvc.getCellRanges()[0], boundary: "end", cellPosition: { ...this.endPosition, column: rangeSvc.getCellRanges()[0].columns[0] }, silent: true }); } } rangeSvc.extendRangeToCell(targetRange, this.endPosition); } shouldSkipCell(_) { return false; } onDragEnd(_) { const cellRange = this.cellRange ?? _last(this.beans.rangeSvc.getCellRanges()); if (!cellRange) { return; } this.fixRangeStartEnd(cellRange); this.rangeFixed = false; } onDragCancel() { this.rangeFixed = false; } fixRangeStartEnd(cellRange) { const rangeSvc = this.beans.rangeSvc; const startRow = rangeSvc.getRangeStartRow(cellRange); const endRow = rangeSvc.getRangeEndRow(cellRange); const column = cellRange.columns[0]; cellRange.startRow = startRow; cellRange.endRow = endRow; cellRange.startColumn = column; } }; var rangeSelection_default = ".ag-body-viewport:not(.ag-has-focus) .ag-cell-range-single-cell:not(.ag-cell-inline-editing),.ag-cell-range-selected.ag-cell-range-chart,.ag-cell-range-selected:not(.ag-cell-focus){background-color:var(--ag-range-selection-background-color);&.ag-cell-range-chart{background-color:var(--ag-range-selection-chart-background-color)!important;&.ag-cell-range-chart-category{background-color:var(--ag-range-selection-chart-category-background-color)!important}}}.ag-cell-range-selected-1.ag-cell-range-chart,.ag-cell-range-selected-1.ag-formula-range,.ag-cell-range-selected-1:not(.ag-cell-focus),.ag-root:not(.ag-context-menu-open) .ag-body-viewport:not(.ag-has-focus) .ag-cell-range-selected-1:not(.ag-cell-inline-editing){background-color:var(--ag-range-selection-background-color)}.ag-cell-range-selected-2.ag-cell-range-chart,.ag-cell-range-selected-2.ag-formula-range,.ag-cell-range-selected-2:not(.ag-cell-focus){background-image:linear-gradient(var(--ag-range-selection-background-color),var(--ag-range-selection-background-color))}.ag-cell-range-selected-3.ag-cell-range-chart,.ag-cell-range-selected-3.ag-formula-range,.ag-cell-range-selected-3:not(.ag-cell-focus){background-image:linear-gradient(var(--ag-range-selection-background-color),var(--ag-range-selection-background-color)),linear-gradient(var(--ag-range-selection-background-color),var(--ag-range-selection-background-color))}.ag-cell-range-selected-4.ag-cell-range-chart,.ag-cell-range-selected-4.ag-formula-range,.ag-cell-range-selected-4:not(.ag-cell-focus){background-image:linear-gradient(var(--ag-range-selection-background-color),var(--ag-range-selection-background-color)),linear-gradient(var(--ag-range-selection-background-color),var(--ag-range-selection-background-color)),linear-gradient(var(--ag-range-selection-background-color),var(--ag-range-selection-background-color))}.ag-cell.ag-cell-range-selected:not(.ag-cell-range-single-cell){&.ag-cell-range-top{border-top-color:var(--ag-range-selection-border-color);border-top-style:var(--ag-range-selection-border-style)}&.ag-cell-range-right{border-right-color:var(--ag-range-selection-border-color);border-right-style:var(--ag-range-selection-border-style)}&.ag-cell-range-bottom{border-bottom-color:var(--ag-range-selection-border-color);border-bottom-style:var(--ag-range-selection-border-style)}&.ag-cell-range-left{border-left-color:var(--ag-range-selection-border-color);border-left-style:var(--ag-range-selection-border-style)}}.ag-cell.ag-selection-fill-top,.ag-cell.ag-selection-fill-top.ag-cell-range-selected{border-top:1px dashed;border-top-color:var(--ag-range-selection-border-color)}:where(.ag-ltr) .ag-cell.ag-selection-fill-right,:where(.ag-ltr) .ag-cell.ag-selection-fill-right.ag-cell-range-selected{border-right:1px dashed var(--ag-range-selection-border-color)!important}:where(.ag-rtl) .ag-cell.ag-selection-fill-right,:where(.ag-rtl) .ag-cell.ag-selection-fill-right.ag-cell-range-selected{border-left:1px dashed var(--ag-range-selection-border-color)!important}.ag-cell.ag-selection-fill-bottom,.ag-cell.ag-selection-fill-bottom.ag-cell-range-selected{border-bottom:1px dashed;border-bottom-color:var(--ag-range-selection-border-color)}:where(.ag-ltr) .ag-cell.ag-selection-fill-left,:where(.ag-ltr) .ag-cell.ag-selection-fill-left.ag-cell-range-selected{border-left:1px dashed var(--ag-range-selection-border-color)!important}:where(.ag-rtl) .ag-cell.ag-selection-fill-left,:where(.ag-rtl) .ag-cell.ag-selection-fill-left.ag-cell-range-selected{border-right:1px dashed var(--ag-range-selection-border-color)!important}.ag-fill-handle,.ag-range-handle{background-color:var(--ag-range-selection-border-color);bottom:-1px;height:6px;position:absolute;width:6px}:where(.ag-ltr) .ag-fill-handle,:where(.ag-ltr) .ag-range-handle{right:-1px}:where(.ag-rtl) .ag-fill-handle,:where(.ag-rtl) .ag-range-handle{left:-1px}.ag-fill-handle{cursor:crosshair}:where(.ag-ltr) .ag-range-handle{cursor:nwse-resize}:where(.ag-rtl) .ag-range-handle{cursor:nesw-resize}"; function getCellRanges(beans) { return beans.rangeSvc?.getCellRanges() ?? null; } function addCellRange(beans, params) { beans.rangeSvc?.addCellRange(params); } function clearRangeSelection(beans) { beans.rangeSvc?.removeAllCellRanges(); } var CSS_CELL_RANGE_SELECTED = "ag-cell-range-selected"; var CSS_CELL_RANGE_CHART = "ag-cell-range-chart"; var CSS_CELL_RANGE_SINGLE_CELL = "ag-cell-range-single-cell"; var CSS_CELL_RANGE_CHART_CATEGORY = "ag-cell-range-chart-category"; var CSS_CELL_RANGE_HANDLE = "ag-cell-range-handle"; var CSS_CELL_RANGE_TOP = "ag-cell-range-top"; var CSS_CELL_RANGE_RIGHT = "ag-cell-range-right"; var CSS_CELL_RANGE_BOTTOM = "ag-cell-range-bottom"; var CSS_CELL_RANGE_LEFT = "ag-cell-range-left"; function _isRangeHandleEnabled(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== undefined; if (!useNewAPI) { return gos.get("enableRangeHandle"); } return typeof selection !== "boolean" ? selection.handle?.mode === "range" : false; } function _isFillHandleEnabled(gos) { const selection = gos.get("cellSelection"); const useNewAPI = selection !== undefined; if (!useNewAPI) { return gos.get("enableFillHandle"); } return typeof selection !== "boolean" ? selection.handle?.mode === "fill" : false; } var CellRangeFeature = class { constructor(beans, cellCtrl) { this.beans = beans; this.cellCtrl = cellCtrl; this.rangeColorClass = null; this.handleColorClass = null; this.rangeSvc = beans.rangeSvc; } setComp(cellComp) { this.cellComp = cellComp; this.eGui = this.cellCtrl.eGui; this.onCellSelectionChanged(); } unsetComp() { this.beans.context.destroyBean(this.selectionHandle); } onCellSelectionChanged() { const cellComp = this.cellComp; if (!cellComp) { return; } const { rangeSvc, cellCtrl, eGui } = this; const rangeCount = rangeSvc.getCellRangeCount(cellCtrl.cellPosition); this.rangeCount = rangeCount; const hasChartRange = this.getHasChartRange(); this.hasChartRange = hasChartRange; cellComp.toggleCss(CSS_CELL_RANGE_SELECTED, rangeCount !== 0); cellComp.toggleCss(`${CSS_CELL_RANGE_SELECTED}-1`, rangeCount === 1); cellComp.toggleCss(`${CSS_CELL_RANGE_SELECTED}-2`, rangeCount === 2); cellComp.toggleCss(`${CSS_CELL_RANGE_SELECTED}-3`, rangeCount === 3); cellComp.toggleCss(`${CSS_CELL_RANGE_SELECTED}-4`, rangeCount >= 4); cellComp.toggleCss(CSS_CELL_RANGE_CHART, hasChartRange); _setAriaSelected(eGui, rangeCount > 0 ? true : undefined); cellComp.toggleCss(CSS_CELL_RANGE_SINGLE_CELL, this.isSingleCell()); this.updateRangeBorders(); this.refreshRangeStyleAndHandle(); } updateRangeBorders() { const rangeBorders = this.getRangeBorders(); const isSingleCell = this.isSingleCell(); const isTop = !isSingleCell && rangeBorders.top; const isRight = !isSingleCell && rangeBorders.right; const isBottom = !isSingleCell && rangeBorders.bottom; const isLeft = !isSingleCell && rangeBorders.left; const cellComp = this.cellComp; cellComp.toggleCss(CSS_CELL_RANGE_TOP, isTop); cellComp.toggleCss(CSS_CELL_RANGE_RIGHT, isRight); cellComp.toggleCss(CSS_CELL_RANGE_BOTTOM, isBottom); cellComp.toggleCss(CSS_CELL_RANGE_LEFT, isLeft); } isSingleCell() { const { rangeSvc } = this; return this.rangeCount === 1 && !!rangeSvc && !rangeSvc.isMoreThanOneCell(); } getHasChartRange() { const { rangeSvc } = this; if (!this.rangeCount || !rangeSvc) { return false; } const cellRanges = rangeSvc.getCellRanges(); return cellRanges.length > 0 && cellRanges.every((range) => [CellRangeType.DIMENSION, CellRangeType.VALUE].includes(range.type)); } updateRangeBordersIfRangeCount() { if (this.rangeCount > 0) { this.updateRangeBorders(); this.refreshRangeStyleAndHandle(); } } getRangeBorders() { const isRtl = this.beans.gos.get("enableRtl"); let top = false; let right = false; let bottom = false; let left = false; const { rangeSvc, beans: { visibleCols }, cellCtrl: { cellPosition } } = this; const thisCol = cellPosition.column; const ranges = rangeSvc.getCellRanges().filter((range) => rangeSvc.isCellInSpecificRange(cellPosition, range)); if (!ranges.length) { return { top, right, bottom, left }; } let leftCol; let rightCol; if (isRtl) { leftCol = visibleCols.getColAfter(thisCol); rightCol = visibleCols.getColBefore(thisCol); } else { leftCol = visibleCols.getColBefore(thisCol); rightCol = visibleCols.getColAfter(thisCol); } if (!leftCol) { left = true; } if (!rightCol) { right = true; } for (let i = 0;i < ranges.length; i++) { if (top && right && bottom && left) { break; } const range = ranges[i]; const startRow = rangeSvc.getRangeStartRow(range); const endRow = rangeSvc.getRangeEndRow(range); if (!top && _isSameRow(startRow, cellPosition)) { top = true; } if (!bottom && _isSameRow(endRow, cellPosition)) { bottom = true; } if (!left && leftCol && range.columns.indexOf(leftCol) < 0) { left = true; } if (!right && rightCol && range.columns.indexOf(rightCol) < 0) { right = true; } } return { top, right, bottom, left }; } refreshRangeStyleAndHandle() { const { context } = this.beans; if (context.isDestroyed()) { return; } this.styleCellForRangeType(); const rangeForHandle = this.getRangeForHandle(); if (this.selectionHandle && !rangeForHandle) { this.selectionHandle = context.destroyBean(this.selectionHandle); } if (rangeForHandle) { this.addSelectionHandle(rangeForHandle); } this.refreshHandleColor(rangeForHandle); this.cellComp.toggleCss(CSS_CELL_RANGE_HANDLE, !!this.selectionHandle); } styleCellForRangeType() { if (this.hasChartRange) { const { rangeSvc } = this; const dimensionRange = rangeSvc.getCellRanges()[0]; const hasCategoryRange = dimensionRange.type === CellRangeType.DIMENSION; const isCategoryCell = hasCategoryRange && rangeSvc.isCellInSpecificRange(this.cellCtrl.cellPosition, dimensionRange); this.cellComp.toggleCss(CSS_CELL_RANGE_CHART_CATEGORY, isCategoryCell); } else { this.cellComp.toggleCss(CSS_CELL_RANGE_CHART_CATEGORY, false); this.applyRangeColor(this.getRangeColorClass()); } } applyRangeColor(nextClass) { if (this.rangeColorClass && this.rangeColorClass !== nextClass) { this.cellComp.toggleCss(this.rangeColorClass, false); this.cellComp.toggleCss("ag-formula-range", false); } if (nextClass) { this.cellComp.toggleCss(nextClass, true); this.cellComp.toggleCss("ag-formula-range", nextClass.startsWith("ag-formula-range")); } this.rangeColorClass = nextClass ?? null; } getRangeColorClass() { const { rangeSvc, rangeCount } = this; if (!rangeSvc || !rangeCount) { return null; } const ranges = rangeSvc.getCellRanges(); for (let i = ranges.length - 1;i >= 0; i--) { const range = ranges[i]; const colorClass = range.colorClass; if (!colorClass) { continue; } if (rangeSvc.isCellInSpecificRange(this.cellCtrl.cellPosition, range)) { return colorClass; } } return null; } refreshHandleColor(rangeForHandle) { const handleGui = this.selectionHandle?.getGui?.(); const nextClass = rangeForHandle?.colorClass ?? null; if (!handleGui) { this.handleColorClass = null; return; } if (this.handleColorClass && this.handleColorClass !== nextClass) { handleGui.classList.remove(this.handleColorClass); } if (nextClass) { handleGui.classList.add(nextClass); } else if (this.handleColorClass) { handleGui.classList.remove(this.handleColorClass); } this.handleColorClass = nextClass ?? null; } getRangeForHandle() { const { gos, editSvc } = this.beans; const rangeSvc = this.rangeSvc; const allRanges = rangeSvc.getCellRanges(); const rangesLen = allRanges.length; if (this.rangeCount < 1 || rangesLen < 1) { return null; } const isRangeSelectionEnabledWhileEditing = editSvc?.isRangeSelectionEnabledWhileEditing(); const rangesToRefreshHandle = isRangeSelectionEnabledWhileEditing ? allRanges : [_last(allRanges)]; for (const cellRange of rangesToRefreshHandle) { const { cellPosition, column } = this.cellCtrl; const isFillHandleAvailable = _isFillHandleEnabled(gos) && !column.isSuppressFillHandle(); const isRangeHandleAvailable = _isRangeHandleEnabled(gos); const isCellEditing = editSvc?.isEditing(this.cellCtrl, { withOpenEditor: true }); let handleIsAvailable = !isCellEditing && (isRangeSelectionEnabledWhileEditing || rangesLen === 1 && (isFillHandleAvailable || isRangeHandleAvailable)); if (this.hasChartRange) { handleIsAvailable = cellRange.type === CellRangeType.VALUE; } if (handleIsAvailable && cellRange.endRow != null && rangeSvc.isContiguousRange(cellRange) && rangeSvc.isBottomRightCell(cellRange, cellPosition)) { return cellRange; } } return null; } addSelectionHandle(cellRange) { const { beans } = this; const isRangeSelectionEnabledWhileEditing = beans.editSvc?.isRangeSelectionEnabledWhileEditing(); const cellRangeType = cellRange.type; const selectionHandleFill = !isRangeSelectionEnabledWhileEditing && _isFillHandleEnabled(beans.gos) && _missing(cellRangeType); const type = selectionHandleFill ? 0 : 1; if (this.selectionHandle && this.selectionHandle.getType() !== type) { this.selectionHandle = beans.context.destroyBean(this.selectionHandle); } if (!this.selectionHandle) { const selectionHandle = beans.registry.createDynamicBean(type === 0 ? "fillHandle" : "rangeHandle", false); if (selectionHandle) { this.selectionHandle = beans.context.createBean(selectionHandle); } } this.selectionHandle?.refresh(this.cellCtrl, cellRange); } destroy() { this.unsetComp(); } }; var DragListenerFeature = class extends BeanStub { constructor(eContainer) { super(); this.eContainer = eContainer; } postConstruct() { const { beans, gos, eContainer } = this; const rangeSvc = beans.rangeSvc; const params = { eElement: eContainer, onDragStart: rangeSvc.onDragStart.bind(rangeSvc), onDragStop: rangeSvc.onDragStop.bind(rangeSvc), onDragging: rangeSvc.onDragging.bind(rangeSvc) }; const dragSvc = beans.dragSvc; const enableFeature = dragSvc.addDragSource.bind(dragSvc, params); const disableFeature = dragSvc.removeDragSource.bind(dragSvc, params); this.addManagedPropertyListeners(["enableRangeSelection", "cellSelection"], () => { if (_isCellSelectionEnabled(gos)) { enableFeature(); } else { disableFeature(); } }); this.addDestroyFunc(disableFeature); if (_isCellSelectionEnabled(gos)) { enableFeature(); } } }; var HeaderGroupCellMouseListenerFeature = class extends BeanStub { constructor(column, eGui) { super(); this.column = column; this.eGui = eGui; } postConstruct() { this.addManagedElementListeners(this.eGui, { click: (e) => e && this.onClick(e) }); } onClick(event) { this.beans.rangeSvc?.handleColumnSelection(this.column, event); } }; var RangeHeaderHighlightFeature = class extends BeanStub { constructor(column, comp) { super(); this.column = column; this.comp = comp; this.columnMap = /* @__PURE__ */ new Map; this.isActive = false; this.resetColumnMap(); } postConstruct() { this.addManagedPropertyListener("cellSelection", () => { this.refreshActive(); }); this.refreshActive(); this.setupRangeHeaderHighlight(); } resetColumnMap() { this.columnMap.clear(); let columns; if (this.column.isColumn) { columns = [this.column]; } else { columns = this.column.getDisplayedLeafColumns(); } for (const column of columns) { this.columnMap.set(column, false); } } refreshActive() { const { gos, rangeSvc } = this.beans; const selection = gos.get("cellSelection"); this.isActive = !!(selection && rangeSvc && typeof selection === "object" && selection.enableHeaderHighlight); } setupRangeHeaderHighlight() { const listener = this.onRangeSelectionChanged.bind(this); this.addManagedEventListeners({ rangeSelectionChanged: listener, columnPinned: listener, columnMoved: listener, columnGroupOpened: listener }); listener(); } onRangeSelectionChanged() { if (!this.isActive) { return; } this.resetColumnMap(); const ranges = this.beans.rangeSvc.getCellRanges(); let hasRange = false; let isAllColumnRange = true; for (const range of ranges) { if (hasRange) { break; } for (const column of range.columns) { if (this.columnMap.has(column)) { this.columnMap.set(column, true); hasRange || (hasRange = true); } } } for (const value of Array.from(this.columnMap.values())) { if (value === false) { isAllColumnRange = false; break; } } this.comp.toggleCss("ag-header-range-highlight", hasRange && isAllColumnRange); } destroy() { super.destroy(); this.comp = null; this.column = null; } }; var RangeService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "rangeSvc"; this.rangeSelectionExtensions = []; this.cellRanges = []; this.bodyScrollListener = this.onBodyScroll.bind(this); this.dragging = false; this.intersectionRange = false; this.columnRangeSelectionCtx = {}; } wireBeans(beans) { this.rowModel = beans.rowModel; this.dragSvc = beans.dragSvc; this.colModel = beans.colModel; this.visibleCols = beans.visibleCols; this.cellNavigation = beans.cellNavigation; this.ctrlsSvc = beans.ctrlsSvc; } postConstruct() { const onColumnsChanged = this.onColumnsChanged.bind(this); const removeAllCellRanges = () => this.removeAllCellRanges(); const refreshLastRangeStart = this.refreshLastRangeStart.bind(this); this.addManagedEventListeners({ newColumnsLoaded: onColumnsChanged, columnVisible: onColumnsChanged, columnValueChanged: onColumnsChanged, columnPivotModeChanged: removeAllCellRanges, columnRowGroupChanged: removeAllCellRanges, columnPivotChanged: removeAllCellRanges, columnGroupOpened: refreshLastRangeStart, columnMoved: refreshLastRangeStart, columnPinned: refreshLastRangeStart }); this.ctrlsSvc.whenReady(this, (p) => { const gridBodyCtrl = p.gridBodyCtrl; this.autoScrollService = new AutoScrollService({ scrollContainer: gridBodyCtrl.eBodyViewport, scrollAxis: "xy", getVerticalPosition: () => gridBodyCtrl.scrollFeature.getVScrollPosition().top, setVerticalPosition: (position) => gridBodyCtrl.scrollFeature.setVerticalScrollPosition(position), getHorizontalPosition: () => gridBodyCtrl.scrollFeature.getHScrollPosition().left, setHorizontalPosition: (position) => gridBodyCtrl.scrollFeature.setHorizontalScrollPosition(position), shouldSkipVerticalScroll: () => !_isDomLayout(this.gos, "normal"), shouldSkipHorizontalScroll: () => !gridBodyCtrl.scrollFeature.isHorizontalScrollShowing() }); }); } registerRangeSelectionExtension(extension) { if (this.rangeSelectionExtensions.includes(extension)) { return; } this.rangeSelectionExtensions.push(extension); } unregisterRangeSelectionExtension(extension) { _removeFromArray(this.rangeSelectionExtensions, extension); } shouldSuppressRangeSelection(eventTarget) { return this.rangeSelectionExtensions.some((extension) => extension.shouldSuppressRangeSelection?.(eventTarget)); } shouldSkipColumn(column) { return this.rangeSelectionExtensions.some((extension) => extension.shouldSkipColumn?.(column)); } isAllColumnsSelectionCell(cellPosition) { return this.rangeSelectionExtensions.some((extension) => extension.isAllColumnsSelectionCell?.(cellPosition)); } isAllColumnsRange(range, allColumns) { return this.rangeSelectionExtensions.some((extension) => extension.isAllColumnsRange?.(range, allColumns)); } updateSelectionModeForCell(cellPosition) { this.setSelectionMode(this.isAllColumnsSelectionCell(cellPosition)); } onDragStart(mouseEvent) { const gos = this.gos; const target = mouseEvent.target; if (!_isCellSelectionEnabled(gos) || _getRowCtrlForEventTarget(gos, target)?.isSuppressMouseEvent(mouseEvent)) { return; } if (this.shouldSuppressRangeSelection(target)) { return; } const { shiftKey } = mouseEvent; const isMultiRange = this.isMultiRange(mouseEvent); const extendRange = shiftKey && !!this.cellRanges?.length; if (!isMultiRange && (!extendRange || _exists(_last(this.cellRanges).type))) { this.removeAllCellRanges(true); } const startTarget = this.dragSvc.startTarget; if (startTarget) { this.updateValuesOnMove(startTarget); } if (!this.lastCellHovered) { return; } this.dragging = true; this.lastMouseEvent = mouseEvent; this.intersectionRange = isMultiRange && this.getCellRangeCount(this.lastCellHovered) > 1; if (!extendRange) { this.setNewestRangeStartCell(this.lastCellHovered); } if (this.cellRanges.length > 0) { this.draggingRange = _last(this.cellRanges); } else { const mouseRowPosition = { rowIndex: this.lastCellHovered.rowIndex, rowPinned: this.lastCellHovered.rowPinned }; const columns = this.getColumnsFromModel([this.lastCellHovered.column]); if (!columns?.length) { return; } this.draggingRange = { startRow: mouseRowPosition, endRow: mouseRowPosition, columns, startColumn: this.newestRangeStartCell.column }; this.cellRanges.push(this.draggingRange); } this.ctrlsSvc.getGridBodyCtrl().eBodyViewport.addEventListener("scroll", this.bodyScrollListener, { passive: true }); this.dispatchChangedEvent(true, false, this.draggingRange.id); } onDragging(mouseEvent) { const { dragging, lastCellHovered, newestRangeStartCell, autoScrollService, cellHasChanged } = this; if (!dragging || !mouseEvent) { return; } this.updateValuesOnMove(mouseEvent.target); this.lastMouseEvent = mouseEvent; const isMouseAndStartInPinned = (position) => lastCellHovered && lastCellHovered.rowPinned === position && newestRangeStartCell.rowPinned === position; const skipVerticalScroll = isMouseAndStartInPinned("top") || isMouseAndStartInPinned("bottom"); autoScrollService.check(mouseEvent, skipVerticalScroll); if (!cellHasChanged || !lastCellHovered) { return; } const startColumn = newestRangeStartCell?.column; const currentColumn = lastCellHovered?.column; const columns = this.calculateColumnsBetween(startColumn, currentColumn); if (!columns) { return; } const { rowIndex, rowPinned } = lastCellHovered; this.draggingRange.endRow = { rowIndex, rowPinned }; this.draggingRange.columns = columns; this.dispatchChangedEvent(false, false, this.draggingRange.id); } onDragStop() { if (!this.dragging) { return; } const { id } = this.draggingRange; this.autoScrollService.ensureCleared(); this.ctrlsSvc.getGridBodyCtrl().eBodyViewport.removeEventListener("scroll", this.bodyScrollListener); this.lastMouseEvent = null; this.dragging = false; this.draggingRange = undefined; this.lastCellHovered = undefined; if (this.intersectionRange) { this.intersectionRange = false; this.intersectLastRange(); } this.dispatchChangedEvent(false, true, id); } onColumnsChanged() { this.refreshLastRangeStart(); const allColumns = this.visibleCols.allCols; for (const cellRange of this.cellRanges) { const beforeCols = cellRange.columns; cellRange.columns = cellRange.columns.filter((col) => col.isVisible() && allColumns.indexOf(col) !== -1); const colsInRangeChanged = !_areEqual(beforeCols, cellRange.columns); if (colsInRangeChanged) { this.dispatchChangedEvent(false, true, cellRange.id); } } const countBefore = this.cellRanges.length; this.cellRanges = this.cellRanges.filter((range) => range.columns.length > 0); if (countBefore > this.cellRanges.length) { this.dispatchChangedEvent(false, true); } } refreshLastRangeStart() { const lastRange = _last(this.cellRanges); if (!lastRange) { return; } this.refreshRangeStart(lastRange); } isContiguousRange(cellRange) { const rangeColumns = cellRange.columns; if (!rangeColumns.length) { return false; } const allColumns = this.visibleCols.allCols; const allPositions = rangeColumns.map((c) => allColumns.indexOf(c)).sort((a, b) => a - b); return _last(allPositions) - allPositions[0] + 1 === rangeColumns.length; } getRangeStartRow(cellRange) { if (cellRange.startRow && cellRange.endRow) { return _isRowBefore(cellRange.startRow, cellRange.endRow) ? cellRange.startRow : cellRange.endRow; } const pinnedTopRowCount = this.beans.pinnedRowModel?.getPinnedTopRowCount() ?? 0; const rowPinned = pinnedTopRowCount > 0 ? "top" : null; return { rowIndex: 0, rowPinned }; } getRangeEndRow(cellRange) { if (cellRange.startRow && cellRange.endRow) { return _isRowBefore(cellRange.startRow, cellRange.endRow) ? cellRange.endRow : cellRange.startRow; } const pinnedBottomRowCount = this.beans.pinnedRowModel?.getPinnedBottomRowCount() ?? 0; const pinnedBottom = pinnedBottomRowCount > 0; if (pinnedBottom) { return { rowIndex: pinnedBottomRowCount - 1, rowPinned: "bottom" }; } return { rowIndex: this.rowModel.getRowCount() - 1, rowPinned: null }; } getRangeRowCount(cellRange) { const beans = this.beans; const start = this.getRangeStartRow(cellRange); const end = this.getRangeEndRow(cellRange); const startIndex = _getAbsoluteRowIndex(beans, start); const endIndex = _getAbsoluteRowIndex(beans, end); return endIndex - startIndex + 1; } handleCellMouseDown(event, cell) { const isMultiKey = event.ctrlKey || event.metaKey; this.handleCellSelectionInput(cell, { target: event.target, shiftKey: event.shiftKey, isRightClick: _interpretAsRightClick(this.beans, event), isMultiRange: this.isMultiRange(event), isMultiKey, preventDefault: () => event.preventDefault() }); } handleCellKeyboardSelect(event, cell) { const isMultiKey = event.ctrlKey || event.metaKey; this.handleCellSelectionInput(cell, { target: event.target, shiftKey: event.shiftKey, isRightClick: false, isMultiRange: this.isMultiRangeForKeyState(isMultiKey), isMultiKey, preventDefault: () => event.preventDefault() }); } handleCellSelectionInput(cell, params) { const { target, shiftKey, isRightClick, isMultiRange, isMultiKey, preventDefault } = params; if (this.shouldSuppressRangeSelection(target)) { return; } const isAllColumnsCell = this.isAllColumnsSelectionCell(cell); if (isAllColumnsCell) { preventDefault(); } if (shiftKey) { return this.extendLatestRangeToCell(cell); } if (isAllColumnsCell && isRightClick) { return; } this.updateSelectionModeForCell(cell); const columns = this.calculateColumnsBetween(cell.column, cell.column); if (!columns) { return; } const containingRange = isAllColumnsCell ? this.findContainingRange({ columns, startRow: cell, endRow: cell }) : undefined; const isMultiRangeRemoval = isAllColumnsCell && !!containingRange && isMultiRange && isMultiKey; if (isMultiRangeRemoval && containingRange) { this.removeRowFromAllColumnsRange(cell, containingRange); } else { this.setRangeToCell(cell, isMultiRange); } } isMultiRange(event) { return this.isMultiRangeForKeyState(event.ctrlKey || event.metaKey); } isMultiRangeForKeyState(isMultiKey) { const { editingWithRanges, allowMulti } = this.getMultiRangeContext(); return editingWithRanges || (allowMulti ? isMultiKey : false); } getMultiRangeContext() { const { gos, editSvc } = this.beans; const editingWithRanges = !!editSvc?.isEditing() && !!editSvc?.isRangeSelectionEnabledWhileEditing(); const suppressMultiRanges = _getSuppressMultiRanges(gos) && !editingWithRanges; return { editingWithRanges, suppressMultiRanges, allowMulti: !suppressMultiRanges }; } removeRowFromAllColumnsRange(cell, containingRange) { const { beans, cellRanges } = this; const firstRow = _getFirstRow(beans); const lastRow = _getLastRow(beans); const startRow = this.getRangeStartRow(containingRange); const endRow = this.getRangeEndRow(containingRange); if (!startRow && _isSameRow(firstRow, cell)) { replaceEdgeRow(containingRange, _getRowBelow(beans, firstRow), "top"); } else if (!endRow && _isSameRow(lastRow, cell)) { replaceEdgeRow(containingRange, _getRowAbove(beans, lastRow), "bottom"); } else if (_isSameRow(startRow, endRow)) { _removeFromArray(cellRanges, containingRange); } else if (_isSameRow(startRow, cell)) { replaceEdgeRow(containingRange, _getRowBelow(beans, cell), "top"); } else if (_isSameRow(endRow, cell)) { replaceEdgeRow(containingRange, _getRowAbove(beans, cell), "bottom"); } else { const rowAbove = _getRowAbove(beans, cell); const rowBelow = _getRowBelow(beans, cell); containingRange.startRow = startRow; containingRange.endRow = rowAbove ?? undefined; cellRanges.push({ ...containingRange, startRow: rowBelow ?? undefined, endRow }); } this.dispatchChangedEvent(true, true); } setRangeToCell(cell, appendRange = false) { const { gos } = this; if (!_isCellSelectionEnabled(gos)) { return; } this.updateSelectionModeForCell(cell); const columns = this.calculateColumnsBetween(cell.column, cell.column); if (!columns) { return; } const { suppressMultiRanges } = this.getMultiRangeContext(); if (suppressMultiRanges || !appendRange || _missing(this.cellRanges)) { this.removeAllCellRanges(true); } const rowForCell = { rowIndex: cell.rowIndex, rowPinned: cell.rowPinned }; const cellRange = { startRow: rowForCell, endRow: rowForCell, columns, startColumn: cell.column }; const startColumn = this.ensureRangeStartColumn(cellRange); if (!startColumn) { return; } this.cellRanges.push(cellRange); this.setNewestRangeStartCell({ ...cell, column: startColumn }); this.onDragStop(); this.dispatchChangedEvent(true, true); } getRangeLastColumn(cellRange) { const firstCol = cellRange.columns[0]; const lastCol = _last(cellRange.columns); return this.newestRangeStartCell?.column === firstCol ? lastCol : firstCol; } extendRangeRowCountBy(cellRange, targetCount) { const { beans } = this; const { startRow, endRow } = cellRange; if (!startRow || !endRow) { return; } let stepsMoved = 0; let currentRow; const isBottomUp = _isRowBefore(endRow, startRow); if (isBottomUp) { currentRow = startRow; } else { currentRow = endRow; } const stepFn = targetCount > 0 ? _getRowBelow : _getRowAbove; const stepCount = Math.abs(targetCount); while (stepsMoved < stepCount) { const nextRow = stepFn(beans, currentRow); if (!nextRow) { break; } currentRow = nextRow; stepsMoved++; } if (stepsMoved !== stepCount) { return; } const cellPosition = { ...currentRow, column: this.getRangeLastColumn(cellRange) }; this.updateRangeRowBoundary({ cellRange, boundary: isBottomUp ? "start" : "end", cellPosition }); } extendRangeColumnCountBy(cellRange, delta) { const { columns } = cellRange; if (delta === 0) { return; } const allColumns = this.getColumnsFromModel(); if (!allColumns) { return; } const rangeStartColumn = this.ensureRangeStartColumn(cellRange); if (!rangeStartColumn) { return; } const lastColumn = _last(columns); const endColumn = rangeStartColumn === columns[0] ? lastColumn : columns[0]; if (!lastColumn || !endColumn) { return; } let startIdx = allColumns.indexOf(rangeStartColumn); const endIdx = allColumns.indexOf(endColumn); const isRtlRange = endIdx < startIdx; if (isRtlRange) { startIdx = endIdx; } const currentLength = columns.length; const targetLength = currentLength + delta; if (targetLength <= 0) { return; } const newColumns = []; for (let i = startIdx;i < startIdx + targetLength; i++) { const col = allColumns[i]; if (!col) { break; } newColumns.push(col); } if (newColumns.length === targetLength) { if (isRtlRange) { const newColumnToFocus = _last(newColumns); cellRange.startColumn = newColumnToFocus; this.focusCellOnNewColumn(cellRange, newColumnToFocus); } cellRange.columns = newColumns; this.dispatchChangedEvent(true, true, cellRange.id); } } extendLatestRangeToCell(cellPosition) { if (this.isEmpty() || !this.newestRangeStartCell) { return; } const cellRange = _last(this.cellRanges); this.updateSelectionModeForCell(cellPosition); this.updateRangeRowBoundary({ cellRange, boundary: "end", cellPosition }); } extendRangeToCell(cellRange, cellPosition) { if (!cellRange) { return; } this.updateSelectionModeForCell(cellPosition); this.updateRangeRowBoundary({ cellRange, boundary: "end", cellPosition }); } updateRangeRowBoundary(params) { const { cellRange, boundary, cellPosition, silent = false } = params; const endColumn = cellPosition.column; const startColumn = this.ensureRangeStartColumn(cellRange); if (!startColumn) { return; } const colsToAdd = this.calculateColumnsBetween(startColumn, endColumn); if (!colsToAdd || isLastCellOfRange(cellRange, cellPosition)) { return; } if (boundary === "start") { this.focusCellOnNewRow(cellRange, cellPosition); } cellRange.columns = colsToAdd; cellRange[boundary === "start" ? "startRow" : "endRow"] = { rowIndex: cellPosition.rowIndex, rowPinned: cellPosition.rowPinned }; if (!silent) { this.dispatchChangedEvent(true, true, cellRange.id); } } getRangeEdgeColumns(cellRange) { const allColumns = this.visibleCols.allCols; const allIndices = cellRange.columns.map((c) => allColumns.indexOf(c)).filter((i) => i > -1).sort((a, b) => a - b); return { left: allColumns[allIndices[0]], right: allColumns[_last(allIndices)] }; } extendLatestRangeInDirection(event) { if (this.isEmpty() || !this.newestRangeStartCell) { return; } const key = event.key; const ctrlKey = event.ctrlKey || event.metaKey; const lastRange = _last(this.cellRanges); const startCell = this.newestRangeStartCell; const endCellIndex = lastRange.endRow.rowIndex; const endCellFloating = lastRange.endRow.rowPinned; const endCellColumn = this.getRangeLastColumn(lastRange); const endCell = { column: endCellColumn, rowIndex: endCellIndex, rowPinned: endCellFloating }; const newEndCell = this.cellNavigation.getNextCellToFocus(key, endCell, ctrlKey); if (!newEndCell) { return; } if (this.shouldSkipColumn(newEndCell.column)) { return; } this.setCellRange({ rowStartIndex: startCell.rowIndex, rowStartPinned: startCell.rowPinned, rowEndIndex: newEndCell.rowIndex, rowEndPinned: newEndCell.rowPinned, columnStart: startCell.column, columnEnd: newEndCell.column }); return newEndCell; } setCellRange(params) { if (!_isCellSelectionEnabled(this.gos)) { return; } this.removeAllCellRanges(true); this.addCellRange(params); } setCellRanges(cellRanges) { if (_areEqual(this.cellRanges, cellRanges)) { return; } if (!this.verifyCellRanges(this.gos)) { return; } this.setSelectionMode(false); this.removeAllCellRanges(true); const allDataColumns = this.getColumnsFromModel(this.visibleCols.allCols) ?? []; let hasAllColumnsRange = false; for (const cellRange of cellRanges) { if (cellRange.columns && cellRange.startRow) { const columns = this.getColumnsFromModel(cellRange.columns); if (!columns || columns.length === 0) { continue; } cellRange.columns = columns; const { startRow } = cellRange; this.setNewestRangeStartCell({ rowIndex: startRow.rowIndex, rowPinned: startRow.rowPinned, column: cellRange.columns[0] }); } if (!hasAllColumnsRange && allDataColumns.length > 0 && this.isAllColumnsRange(cellRange, allDataColumns)) { hasAllColumnsRange = true; } this.cellRanges.push(cellRange); } this.setSelectionMode(hasAllColumnsRange); this.dispatchChangedEvent(false, true); } clearCellRangeCellValues(params) { const { beans, eventSvc } = this; const { cellEventSource = "rangeSvc", dispatchWrapperEvents, wrapperEventSource = "deleteKey", restoreSourceInBatch } = params; let { cellRanges } = params; if (dispatchWrapperEvents) { eventSvc.dispatchEvent({ type: "cellSelectionDeleteStart", source: wrapperEventSource }); eventSvc.dispatchEvent({ type: "rangeDeleteStart", source: wrapperEventSource }); } if (!cellRanges) { cellRanges = this.cellRanges; } const { valueSvc, editSvc } = beans; const batch = !!editSvc?.isBatchEditing(); const { changeDetectionSvc } = beans; changeDetectionSvc?.beginDeferred(); try { this.forEachEditableCellInRanges(cellRanges, (rowNode, column) => { if (restoreSourceInBatch && batch) { editSvc?.batchResetToSourceValue({ rowNode, column }); return; } const deleteValue = valueSvc.getDeleteValue(column, rowNode); rowNode.setDataValue(column, deleteValue, cellEventSource); }); } finally { changeDetectionSvc?.endDeferred(); } if (dispatchWrapperEvents) { eventSvc.dispatchEvent({ type: "cellSelectionDeleteEnd", source: wrapperEventSource }); eventSvc.dispatchEvent({ type: "rangeDeleteEnd", source: wrapperEventSource }); } } createCellRangeFromCellRangeParams(params) { return this.createPartialCellRangeFromRangeParams(params, false); } createPartialCellRangeFromRangeParams(params, allowEmptyColumns) { const { columns: paramColumns, columnStart, columnEnd, rowStartIndex, rowStartPinned, rowEndIndex, rowEndPinned } = params; const columnInfo = this.getColumnsFromParams(paramColumns, columnStart, columnEnd); if (!columnInfo || !allowEmptyColumns && columnInfo.columns.length === 0) { return; } const { columns, startsOnTheRight } = columnInfo; const startRow = createRowPosition(rowStartIndex, rowStartPinned); const endRow = createRowPosition(rowEndIndex, rowEndPinned); return { startRow, endRow, columns, startColumn: this.getColumnFromModel(columnStart) ?? (startsOnTheRight ? _last(columns) : columns[0]) }; } addCellRange(params) { const gos = this.gos; if (!_isCellSelectionEnabled(gos) || !this.verifyCellRanges(gos)) { return; } this.setSelectionMode(false); const newRange = this.createCellRangeFromCellRangeParams(params); if (newRange) { if (newRange.startRow) { this.setNewestRangeStartCell({ rowIndex: newRange.startRow.rowIndex, rowPinned: newRange.startRow.rowPinned, column: newRange.startColumn }); } this.cellRanges.push(newRange); this.dispatchChangedEvent(false, true, newRange.id); return newRange; } } getCellRanges() { return this.cellRanges; } isEmpty() { return this.cellRanges.length === 0; } isMoreThanOneCell() { const len = this.cellRanges.length; if (len === 0) { return false; } if (len > 1) { return true; } const range = this.cellRanges[0]; const startRow = this.getRangeStartRow(range); const endRow = this.getRangeEndRow(range); return startRow.rowPinned !== endRow.rowPinned || startRow.rowIndex !== endRow.rowIndex || range.columns.length !== 1; } areAllRangesAbleToMerge() { const rowToColumnMap = /* @__PURE__ */ new Map; const len = this.cellRanges.length; if (len <= 1) { return true; } for (const range of this.cellRanges) { this.forEachRowInRange(range, (row) => { const rowName = `${row.rowPinned || "normal"}_${row.rowIndex}`; const columns = rowToColumnMap.get(rowName); const currentRangeColIds = range.columns.map((col) => col.getId()); if (columns) { const filteredColumns = currentRangeColIds.filter((col) => columns.indexOf(col) === -1); columns.push(...filteredColumns); } else { rowToColumnMap.set(rowName, currentRangeColIds); } }); } let columnsString; for (const val of rowToColumnMap.values()) { const currentValString = val.sort().join(); if (columnsString === undefined) { columnsString = currentValString; continue; } if (columnsString !== currentValString) { return false; } } return true; } removeAllCellRanges(silent) { if (this.isEmpty()) { return; } this.onDragStop(); this.cellRanges.length = 0; if (!silent) { this.dispatchChangedEvent(false, true); } } isCellInAnyRange(cell) { return this.getCellRangeCount(cell) > 0; } isCellInSpecificRange(cell, range) { const columnInRange = range.columns?.includes(cell.column); const rowInRange = this.isRowInRange(cell, range); return columnInRange && rowInRange; } isColumnInAnyRange(column) { const { beans } = this; const firstRow = _getFirstRow(beans); const lastRow = _getLastRow(beans); if (!firstRow || !lastRow) { return false; } const columns = column.isColumn ? [column] : column.getDisplayedLeafColumns(); return this.findContainingRange({ columns, startRow: firstRow, endRow: lastRow }, true) != null; } findContainingRange({ columns, startRow, endRow }, matchOnly = false) { const ranges = this.cellRanges; for (let i = ranges.length - 1;i >= 0; i--) { const range = ranges[i]; const hasCols = columns.every((c) => range.columns.includes(c)); let condition = false; if (matchOnly) { condition = _isSameRow(range.startRow, startRow) && _isSameRow(range.endRow, endRow); } else { const isStartBeforeOrEqual = startRow && this.isRowInRange(startRow, range); const isEndAfterOrEqual = endRow && this.isRowInRange(endRow, range); condition = !!isStartBeforeOrEqual && !!isEndAfterOrEqual; } if (hasCols && condition) { return range; } } } isBottomRightCell(cellRange, cell) { const allColumns = this.visibleCols.allCols; const allPositions = cellRange.columns.map((c) => allColumns.indexOf(c)).sort((a, b) => a - b); const { startRow, endRow } = cellRange; const lastRow = _isRowBefore(startRow, endRow) ? endRow : startRow; const isRightColumn = allColumns.indexOf(cell.column) === _last(allPositions); const isLastRow = cell.rowIndex === lastRow.rowIndex && _makeNull(cell.rowPinned) === _makeNull(lastRow.rowPinned); return isRightColumn && isLastRow; } getCellRangeCount(cell) { return this.cellRanges.filter((cellRange) => this.isCellInSpecificRange(cell, cellRange)).length; } isRowInRange(thisRow, cellRange) { const firstRow = this.getRangeStartRow(cellRange); const lastRow = this.getRangeEndRow(cellRange); const equalsFirstRow = _isSameRow(thisRow, firstRow); const equalsLastRow = _isSameRow(thisRow, lastRow); if (equalsFirstRow || equalsLastRow) { return true; } const afterFirstRow = !_isRowBefore(thisRow, firstRow); const beforeLastRow = _isRowBefore(thisRow, lastRow); return afterFirstRow && beforeLastRow; } intersectLastRange(fromMouseClick) { const { editingWithRanges, suppressMultiRanges } = this.getMultiRangeContext(); if (editingWithRanges || suppressMultiRanges || fromMouseClick && this.dragging || this.isEmpty()) { return; } const lastRange = _last(this.cellRanges); const intersectionStartRow = this.getRangeStartRow(lastRange); const intersectionEndRow = this.getRangeEndRow(lastRange); const newRanges = []; for (const range of this.cellRanges.slice(0, -1)) { const startRow = this.getRangeStartRow(range); const endRow = this.getRangeEndRow(range); const cols = range.columns; const intersectCols = cols.filter((col) => lastRange.columns.indexOf(col) === -1); if (intersectCols.length === cols.length) { newRanges.push(range); continue; } if (_isRowBefore(intersectionEndRow, startRow) || _isRowBefore(endRow, intersectionStartRow)) { newRanges.push(range); continue; } const rangeCountBefore = newRanges.length; if (_isRowBefore(startRow, intersectionStartRow)) { const top = { columns: [...cols], startColumn: lastRange.startColumn, startRow: { ...startRow }, endRow: _getRowAbove(this.beans, intersectionStartRow) }; newRanges.push(top); } if (intersectCols.length > 0) { const middle = { columns: intersectCols, startColumn: intersectCols.includes(lastRange.startColumn) ? lastRange.startColumn : intersectCols[0], startRow: rowMax([{ ...intersectionStartRow }, { ...startRow }]), endRow: rowMin([{ ...intersectionEndRow }, { ...endRow }]) }; newRanges.push(middle); } if (_isRowBefore(intersectionEndRow, endRow)) { newRanges.push({ columns: [...cols], startColumn: lastRange.startColumn, startRow: _getRowBelow(this.beans, intersectionEndRow), endRow: { ...endRow } }); } if (newRanges.length - rangeCountBefore === 1) { newRanges[newRanges.length - 1].id = range.id; } } this.cellRanges = newRanges; if (fromMouseClick) { this.dispatchChangedEvent(false, true); } } createRangeHighlightFeature(compBean, column, headerComp) { compBean.createManagedBean(new RangeHeaderHighlightFeature(column, headerComp)); } setSelectionMode(allColumns) { this.selectionMode = allColumns ? 1 : 0; } refreshRangeStart(cellRange) { const { columns } = cellRange; const startColumn = this.ensureRangeStartColumn(cellRange); if (!startColumn) { return; } const moveColInCellRange = (colToMove, moveToFront) => { const otherCols = cellRange.columns.filter((col) => col !== colToMove); if (colToMove) { cellRange.startColumn = colToMove; cellRange.columns = moveToFront ? [colToMove, ...otherCols] : [...otherCols, colToMove]; } else { cellRange.columns = otherCols; } }; const { left, right } = this.getRangeEdgeColumns(cellRange); const shouldMoveLeftCol = startColumn === columns[0] && startColumn !== left; if (shouldMoveLeftCol) { moveColInCellRange(left, true); return; } const shouldMoveRightCol = startColumn === _last(columns) && startColumn === right; if (shouldMoveRightCol) { moveColInCellRange(right, false); } } setNewestRangeStartCell(position) { this.newestRangeStartCell = position; } getColumnsFromParams(columns, columnA, columnB) { const noColsInfo = !columns && !columnA && !columnB; let processedColumns; let startsOnTheRight = false; if (noColsInfo || columns) { processedColumns = this.getColumnsFromModel(noColsInfo ? undefined : columns); } else if (columnA && columnB) { processedColumns = this.calculateColumnsBetween(columnA, columnB); if (processedColumns?.length) { startsOnTheRight = processedColumns[0] !== this.getColumnFromModel(columnA); } } return processedColumns ? { columns: processedColumns, startsOnTheRight } : undefined; } verifyCellRanges(gos) { const { suppressMultiRanges } = this.getMultiRangeContext(); const invalid = _isUsingNewCellSelectionAPI(gos) && suppressMultiRanges && this.cellRanges.length > 1; if (invalid) { _warn(93); } return !invalid; } forEachRowInRange(cellRange, callback) { const topRow = this.getRangeStartRow(cellRange); const bottomRow = this.getRangeEndRow(cellRange); let currentRow = topRow; while (currentRow) { callback(currentRow); if (_isSameRow(currentRow, bottomRow)) { break; } currentRow = _getRowBelow(this.beans, currentRow); } } forEachEditableCellInRanges(cellRanges, callback) { const { beans } = this; for (const cellRange of cellRanges) { this.forEachRowInRange(cellRange, (rowPosition) => { const rowNode = _getRowNode(beans, rowPosition); if (!rowNode) { return; } for (let i = 0;i < cellRange.columns.length; i++) { const column = this.getColumnFromModel(cellRange.columns[i]); if (!column?.isCellEditable(rowNode)) { continue; } callback(rowNode, column); } }); } } onBodyScroll() { if (this.dragging && this.lastMouseEvent) { this.onDragging(this.lastMouseEvent); } } updateValuesOnMove(eventTarget) { const cellCtrl = _getCellCtrlForEventTarget(this.gos, eventTarget); const cell = cellCtrl?.cellPosition; this.cellHasChanged = false; if (!cell || this.lastCellHovered && _areCellsEqual(cell, this.lastCellHovered)) { return; } const editSvc = this.beans.editSvc; const editing = editSvc?.isEditing(cellCtrl, { withOpenEditor: true }); if (editing && !editSvc?.isRangeSelectionEnabledWhileEditing()) { this.dragSvc.cancelDrag(eventTarget); return; } if (this.lastCellHovered) { this.cellHasChanged = true; } this.lastCellHovered = cell; } dispatchChangedEvent(started, finished, id) { this.eventSvc.dispatchEvent({ type: "cellSelectionChanged", started, finished, id }); this.eventSvc.dispatchEvent({ type: "rangeSelectionChanged", started, finished, id }); } getColumnFromModel(col) { return typeof col === "string" ? this.colModel.getCol(col) : col; } getColumnsFromModel(cols) { const { visibleCols, selectionMode } = this; if (!cols || selectionMode === 1) { cols = visibleCols.allCols; } const columns = []; for (const col of cols) { const column = this.getColumnFromModel(col); if (!column || this.shouldSkipColumn(column)) { continue; } columns.push(column); } return columns.length ? columns : undefined; } ensureRangeStartColumn(cellRange) { const startColumn = this.getRangeStartColumn(cellRange.columns, cellRange.startColumn); if (!startColumn) { return; } cellRange.startColumn = startColumn; return startColumn; } getRangeStartColumn(columns, preferredStartColumn) { const firstColumn = columns[0]; const lastColumn = _last(columns); if (!firstColumn || !lastColumn) { return; } if (!preferredStartColumn || columns.includes(preferredStartColumn)) { return preferredStartColumn ?? firstColumn; } const allColumns = this.visibleCols.allCols; const preferredStartIndex = allColumns.indexOf(preferredStartColumn); const firstIndex = allColumns.indexOf(firstColumn); const lastIndex = allColumns.indexOf(lastColumn); if (preferredStartIndex < 0 || firstIndex < 0 || lastIndex < 0) { return firstColumn; } return preferredStartIndex - firstIndex <= lastIndex - preferredStartIndex ? firstColumn : lastColumn; } calculateColumnsBetween(columnA, columnB) { const allColumns = this.visibleCols.allCols; const fromColumn = this.getColumnFromModel(columnA); const toColumn = this.getColumnFromModel(columnB); const isSameColumn = fromColumn === toColumn; const fromIndex = allColumns.indexOf(fromColumn); if (fromIndex < 0) { _warn(178, { colId: fromColumn.getId() }); return; } const toIndex = isSameColumn ? fromIndex : allColumns.indexOf(toColumn); if (toIndex < 0) { _warn(178, { colId: toColumn.getId() }); return; } if (isSameColumn || this.selectionMode === 1) { return this.getColumnsFromModel([fromColumn]); } const firstIndex = Math.min(fromIndex, toIndex); const lastIndex = firstIndex === fromIndex ? toIndex : fromIndex; return this.getColumnsFromModel(allColumns.slice(firstIndex, lastIndex + 1)); } focusCellOnNewColumn(currentRange, column) { const { focusSvc } = this.beans; const focusedCell = focusSvc.getFocusedCell(); if (!focusedCell) { return; } if (this.isCellInSpecificRange(focusedCell, currentRange)) { focusSvc.setFocusedCell({ ...focusedCell, column, forceBrowserFocus: true, preventScrollOnBrowserFocus: true }); } } focusCellOnNewRow(currentRange, row) { const { focusSvc } = this.beans; const focusedCell = focusSvc.getFocusedCell(); if (!focusedCell) { return; } if (this.isCellInSpecificRange(focusedCell, currentRange)) { focusSvc.setFocusedCell({ ...row, column: focusedCell.column, forceBrowserFocus: true, preventScrollOnBrowserFocus: true }); } } createDragListenerFeature(eContainer) { return new DragListenerFeature(eContainer); } createCellRangeFeature(ctrl) { return new CellRangeFeature(this.beans, ctrl); } createHeaderGroupCellMouseListenerFeature(column, eGui) { return new HeaderGroupCellMouseListenerFeature(column, eGui); } handleColumnSelection(clickedColumn, event) { const { gos, beans, columnRangeSelectionCtx: ctx, cellRanges } = this; if (!_getEnableColumnSelection(gos)) { return; } const { suppressMultiRanges, editingWithRanges } = this.getMultiRangeContext(); const hasRanges = cellRanges.length > 0; const isMeta = event.ctrlKey || event.metaKey; const allowToggle = !editingWithRanges || isMeta; const firstRow = _getFirstRow(beans); const lastRow = _getLastRow(beans); if (!firstRow || !lastRow) { return; } if (event.key === KeyCode.ENTER) { event.preventDefault(); } if (event.shiftKey) { const root = ctx.root; if (!root) { return; } const column = clickedColumn.isColumn ? clickedColumn : _last(clickedColumn.getLeafColumns()); const range = this.findContainingRange({ columns: [root], startRow: firstRow, endRow: lastRow }, true); if (!range) { _removeFromArray(cellRanges, ctx.lastCellRange); this.selectColumns(this.calculateColumnsBetween(root, column), firstRow, lastRow); return; } this.updateRangeRowBoundary({ cellRange: range, boundary: "end", cellPosition: { column, ...lastRow } }); return; } if (hasRanges && (suppressMultiRanges || !isMeta && !editingWithRanges)) { this.removeAllCellRanges(true); } const toggleColumns = (columns, root) => { const foundRange = this.findContainingRange({ columns, startRow: firstRow, endRow: lastRow }, true); if (foundRange && allowToggle) { this.deselectColumnsFromRange(foundRange, columns); } else { const addedRange = this.selectColumns(columns, firstRow, lastRow); if (addedRange) { ctx.lastCellRange = addedRange; } } ctx.root = root; }; if (clickedColumn.isColumn) { toggleColumns([clickedColumn], clickedColumn); } else { const leafCols = clickedColumn.getDisplayedLeafColumns(); toggleColumns(leafCols, leafCols[0]); } } deselectColumnsFromRange(range, columns) { _removeAllFromArray(range.columns, columns); if (columns.includes(range.startColumn)) { range.startColumn = range.columns[0]; } if (range.columns.length === 0) { _removeFromArray(this.cellRanges, range); } this.dispatchChangedEvent(true, true); } selectColumns(columns, startRow, endRow) { return this.addCellRange({ columns, columnStart: columns[0], columnEnd: _last(columns), rowStartIndex: startRow.rowIndex, rowStartPinned: startRow.rowPinned, rowEndIndex: endRow.rowIndex, rowEndPinned: endRow.rowPinned }); } }; function createRowPosition(rowIndex, rowPinned) { return rowIndex != null ? { rowIndex, rowPinned } : undefined; } function rowMax(rows) { let max; for (const row of rows) { if (max === undefined || _isRowBefore(max, row)) { max = row; } } return max; } function rowMin(rows) { let min; for (const row of rows) { if (min === undefined || _isRowBefore(row, min)) { min = row; } } return min; } function isLastCellOfRange(cellRange, cell) { const { startRow, endRow } = cellRange; const lastRow = _isRowBefore(startRow, endRow) ? endRow : startRow; const isLastRow = cell.rowIndex === lastRow.rowIndex && cell.rowPinned === lastRow.rowPinned; const rangeFirstIndexColumn = cellRange.columns[0]; const rangeLastIndexColumn = _last(cellRange.columns); const lastRangeColumn = cellRange.startColumn === rangeFirstIndexColumn ? rangeLastIndexColumn : rangeFirstIndexColumn; const isLastColumn = cell.column === lastRangeColumn; return isLastColumn && isLastRow; } function replaceEdgeRow(range, row, topOrBottom) { let key; if (topOrBottom === "top") { key = !range.startRow || !range.endRow || _isRowBefore(range.startRow, range.endRow) ? "startRow" : "endRow"; } else { key = !range.startRow || !range.endRow || _isRowBefore(range.startRow, range.endRow) ? "endRow" : "startRow"; } range[key] = row ?? undefined; } var CellSelectionModule = { moduleName: "CellSelection", version: VERSION2, beans: [RangeService], dynamicBeans: { fillHandle: AgFillHandle, rangeHandle: AgRangeHandle }, apiFunctions: { getCellRanges, addCellRange, clearRangeSelection, clearCellSelection: clearRangeSelection }, dependsOn: [EnterpriseCoreModule, KeyboardNavigationModule, DragModule], css: [rangeSelection_default] }; function isPivotMode(beans) { return beans.colModel.isPivotMode(); } function getPivotResultColumn(beans, pivotKeys, valueColKey) { return beans.pivotResultCols?.lookupPivotResultCol(pivotKeys, valueColKey) ?? null; } function setValueColumns(beans, colKeys) { beans.valueColsSvc?.setColumns(colKeys, "api"); } function getValueColumns(beans) { return beans.valueColsSvc?.columns ?? []; } function removeValueColumns(beans, colKeys) { beans.valueColsSvc?.removeColumns(colKeys, "api"); } function addValueColumns(beans, colKeys) { beans.valueColsSvc?.addColumns(colKeys, "api"); } function setPivotColumns(beans, colKeys) { beans.pivotColsSvc?.setColumns(colKeys, "api"); } function removePivotColumns(beans, colKeys) { beans.pivotColsSvc?.removeColumns(colKeys, "api"); } function addPivotColumns(beans, colKeys) { beans.pivotColsSvc?.addColumns(colKeys, "api"); } function getPivotColumns(beans) { return beans.pivotColsSvc?.columns ?? []; } function setPivotResultColumns(beans, colDefs) { beans.pivotResultCols?.setPivotResultCols(colDefs, "api"); } function getPivotResultColumns(beans) { const pivotResultCols = beans.pivotResultCols?.getPivotResultCols(); return pivotResultCols ? pivotResultCols.list : null; } var PIVOT_ROW_TOTAL_PREFIX = "PivotRowTotal_"; var headerNameComparator = ({ headerName: a }, { headerName: b }) => { if (a && !b) { return 1; } else if (!a && b) { return -1; } else if (!a && !b) { return 0; } if (a < b) { return -1; } else if (a > b) { return 1; } else { return 0; } }; var convertToHeaderNameComparator = (comparator) => (a, b) => comparator(a.headerName, b.headerName); var PivotColDefService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "pivotColDefSvc"; } wireBeans(beans) { this.colModel = beans.colModel; this.pivotColsSvc = beans.pivotColsSvc; this.valueColsSvc = beans.valueColsSvc; this.colNames = beans.colNames; } postConstruct() { const getFieldSeparator = () => this.gos.get("serverSidePivotResultFieldSeparator") ?? "_"; this.fieldSeparator = getFieldSeparator(); this.addManagedPropertyListener("serverSidePivotResultFieldSeparator", () => { this.fieldSeparator = getFieldSeparator(); }); const getPivotDefaultExpanded = () => this.gos.get("pivotDefaultExpanded"); this.pivotDefaultExpanded = getPivotDefaultExpanded(); this.addManagedPropertyListener("pivotDefaultExpanded", () => { this.pivotDefaultExpanded = getPivotDefaultExpanded(); }); } createPivotColumnDefs(uniqueValues) { const pivotColumnGroupDefs = this.createPivotColumnsFromUniqueValues(uniqueValues); function extractColDefs(input, arr = []) { input.forEach((def) => { if (def.children !== undefined) { extractColDefs(def.children, arr); } else { arr.push(def); } }); return arr; } const pivotColumnDefs = extractColDefs(pivotColumnGroupDefs); this.addRowGroupTotals(pivotColumnGroupDefs, pivotColumnDefs); this.addExpandablePivotGroups(pivotColumnGroupDefs, pivotColumnDefs); this.addPivotTotalsToGroups(pivotColumnGroupDefs, pivotColumnDefs); return pivotColumnGroupDefs; } createPivotColumnsFromUniqueValues(uniqueValues) { const pivotColumns = this.pivotColsSvc?.columns ?? []; const maxDepth = pivotColumns.length; const pivotColumnGroupDefs = this.recursivelyBuildGroup(0, uniqueValues, [], maxDepth, pivotColumns); return pivotColumnGroupDefs; } recursivelyBuildGroup(index, uniqueValue, pivotKeys, maxDepth, primaryPivotColumns) { if (index >= maxDepth) { return this.buildMeasureCols(pivotKeys); } const { pivotComparator } = primaryPivotColumns[index].getColDef(); const comparator = pivotComparator ? convertToHeaderNameComparator(pivotComparator) : headerNameComparator; const measureColumns = this.valueColsSvc?.columns; if (measureColumns?.length === 1 && this.gos.get("removePivotHeaderRowWhenSingleValueColumn") && index === maxDepth - 1) { const leafCols = []; for (const key of uniqueValue.keys()) { const newPivotKeys = [...pivotKeys, key]; const colDef = this.createColDef(measureColumns[0], key, newPivotKeys); colDef.columnGroupShow = "open"; leafCols.push(colDef); } leafCols.sort(comparator); return leafCols; } const groups = []; for (const key of uniqueValue.keys()) { const openByDefault = this.pivotDefaultExpanded === -1 || index < this.pivotDefaultExpanded; const newPivotKeys = [...pivotKeys, key]; groups.push({ children: this.recursivelyBuildGroup(index + 1, uniqueValue.get(key), newPivotKeys, maxDepth, primaryPivotColumns), headerName: key, pivotKeys: newPivotKeys, columnGroupShow: "open", openByDefault, groupId: this.generateColumnGroupId(newPivotKeys) }); } groups.sort(comparator); return groups; } buildMeasureCols(pivotKeys) { const measureColumns = this.valueColsSvc?.columns ?? []; if (measureColumns.length === 0) { return [this.createColDef(null, "-", pivotKeys)]; } return measureColumns.map((measureCol) => { const columnName = this.colNames.getDisplayNameForColumn(measureCol, "header"); const colDef = this.createColDef(measureCol, columnName, pivotKeys); colDef.columnGroupShow = "open"; return colDef; }); } addExpandablePivotGroups(pivotColumnGroupDefs, pivotColumnDefs) { const isSuppressExpand = this.gos.get("suppressExpandablePivotGroups"); if (isSuppressExpand || this.gos.get("pivotColumnGroupTotals")) { return; } const recursivelyAddSubTotals = (def, currentPivotColumnDefs, acc) => { if ("children" in def) { const { valueColsSvc } = this; const { columns: valueCols = [] } = valueColsSvc ?? {}; const childAcc = /* @__PURE__ */ new Map; def.children.forEach((grp) => { recursivelyAddSubTotals(grp, currentPivotColumnDefs, childAcc); }); const leafGroup = !def.children.some((child) => child.children); const hasCollapsedLeafGroup = leafGroup && valueCols.length === 1 && this.gos.get("removePivotHeaderRowWhenSingleValueColumn"); for (const valueColumn of valueCols) { const columnName = this.colNames.getDisplayNameForColumn(valueColumn, "header"); const totalColDef = this.createColDef(valueColumn, columnName, def.pivotKeys); totalColDef.pivotTotalColumnIds = childAcc.get(valueColumn.getColId()); totalColDef.columnGroupShow = !isSuppressExpand ? "closed" : "open"; totalColDef.aggFunc = valueColumn.getAggFunc(); if (!leafGroup || hasCollapsedLeafGroup) { const children = def.children; children.push(totalColDef); currentPivotColumnDefs.push(totalColDef); } } this.merge(acc, childAcc); return; } if (!def.pivotValueColumn) { return; } const pivotValueColId = def.pivotValueColumn.getColId(); const exists = acc.has(pivotValueColId); if (exists) { const arr = acc.get(pivotValueColId); arr.push(def.colId); } else { acc.set(pivotValueColId, [def.colId]); } }; pivotColumnGroupDefs.forEach((groupDef) => { recursivelyAddSubTotals(groupDef, pivotColumnDefs, /* @__PURE__ */ new Map); }); } addPivotTotalsToGroups(pivotColumnGroupDefs, pivotColumnDefs) { if (!this.gos.get("pivotColumnGroupTotals")) { return; } const insertAfter = this.gos.get("pivotColumnGroupTotals") === "after"; const valueCols = this.valueColsSvc?.columns; const aggFuncs = valueCols?.map((valueCol) => valueCol.getAggFunc()); if (!aggFuncs || aggFuncs.length < 1 || !this.sameAggFuncs(aggFuncs)) { return; } if (valueCols) { const valueColumn = valueCols[0]; pivotColumnGroupDefs.forEach((groupDef) => { this.recursivelyAddPivotTotal(groupDef, pivotColumnDefs, valueColumn, insertAfter); }); } } recursivelyAddPivotTotal(groupDef, pivotColumnDefs, valueColumn, insertAfter) { const group = groupDef; if (!group.children) { const def = groupDef; return def.colId ? [def.colId] : null; } let colIds = []; group.children.forEach((grp) => { const childColIds = this.recursivelyAddPivotTotal(grp, pivotColumnDefs, valueColumn, insertAfter); if (childColIds) { colIds = colIds.concat(childColIds); } }); if (group.children.length > 1) { const localeTextFunc = this.getLocaleTextFunc(); const headerName = localeTextFunc("pivotColumnGroupTotals", "Total"); const totalColDef = this.createColDef(valueColumn, headerName, groupDef.pivotKeys, true); totalColDef.pivotTotalColumnIds = colIds; totalColDef.aggFunc = valueColumn.getAggFunc(); totalColDef.columnGroupShow = this.gos.get("suppressExpandablePivotGroups") ? "open" : undefined; const children = groupDef.children; if (insertAfter) { children.push(totalColDef); } else { children.unshift(totalColDef); } pivotColumnDefs.push(totalColDef); } return colIds; } addRowGroupTotals(pivotColumnGroupDefs, pivotColumnDefs) { if (!this.gos.get("pivotRowTotals")) { return; } const insertAtEnd = this.gos.get("pivotRowTotals") === "after"; const valueColumns = this.valueColsSvc?.columns ?? []; const valueCols = valueColumns.slice(); if (!insertAtEnd) { valueCols.reverse(); } const isCreateTotalGroups = valueCols.length > 1 || !this.gos.get("removePivotHeaderRowWhenSingleValueColumn"); for (let i = 0;i < valueCols.length; i++) { const valueCol = valueCols[i]; const columnName = this.colNames.getDisplayNameForColumn(valueCol, "header"); const colDef = this.createColDef(valueCol, columnName, []); const colIds = []; for (let i2 = 0;i2 < pivotColumnDefs.length; i2++) { const colDef2 = pivotColumnDefs[i2]; if (colDef2.pivotValueColumn === valueCol) { colIds.push(colDef2.colId); } } colDef.pivotTotalColumnIds = colIds; colDef.colId = PIVOT_ROW_TOTAL_PREFIX + colDef.colId; const valueGroup = isCreateTotalGroups ? { children: [colDef], pivotKeys: [], groupId: `${PIVOT_ROW_TOTAL_PREFIX}_pivotGroup_${valueCol.getColId()}` } : colDef; pivotColumnDefs.push(colDef); if (insertAtEnd) { pivotColumnGroupDefs.push(valueGroup); } else { pivotColumnGroupDefs.unshift(valueGroup); } } } recreateColDef(colDef) { const { pivotValueColumn, headerName, pivotKeys, pivotTotalColumnIds, columnGroupShow, colId, valueGetter, aggFunc } = colDef; if (!pivotValueColumn) { return colDef; } const newColDef = this.createColDef(pivotValueColumn, headerName, pivotKeys, !!pivotTotalColumnIds); newColDef.columnGroupShow = columnGroupShow; newColDef.colId = colId; newColDef.valueGetter = valueGetter; newColDef.aggFunc = aggFunc; newColDef.pivotTotalColumnIds = pivotTotalColumnIds; this.gos.get("processPivotResultColDef")?.(newColDef); return newColDef; } createColDef(valueColumn, headerName, pivotKeys, totalColumn = false) { const colDef = {}; if (valueColumn) { const colDefToCopy = valueColumn.getColDef(); Object.assign(colDef, colDefToCopy); colDef.hide = false; } colDef.headerName = headerName; colDef.colId = this.generateColumnId(pivotKeys || [], valueColumn && !totalColumn ? valueColumn.getColId() : ""); colDef.field = colDef.colId; colDef.valueGetter = (params) => params.data?.[params.colDef.field]; colDef.pivotKeys = pivotKeys; colDef.pivotValueColumn = valueColumn; if (colDef.filter === true) { colDef.filter = "agNumberColumnFilter"; } return colDef; } sameAggFuncs(aggFuncs) { if (aggFuncs.length == 1) { return true; } for (let i = 1;i < aggFuncs.length; i++) { if (aggFuncs[i] !== aggFuncs[0]) { return false; } } return true; } merge(m1, m2) { m2.forEach((value, key) => { const existingList = m1.has(key) ? m1.get(key) : []; const updatedList = [...existingList, ...value]; m1.set(key, updatedList); }); } generateColumnGroupId(pivotKeys) { const pivotCols = (this.pivotColsSvc?.columns ?? []).map((col) => col.getColId()); return `pivotGroup_${pivotCols.join("-")}_${pivotKeys.join("-")}`; } generateColumnId(pivotKeys, measureColumnId) { const pivotCols = (this.pivotColsSvc?.columns ?? []).map((col) => col.getColId()); return `pivot_${pivotCols.join("-")}_${pivotKeys.join("-")}_${measureColumnId}`; } createColDefsFromFields(fields) { const uniqueValues = /* @__PURE__ */ new Map; for (let i = 0;i < fields.length; i++) { const field = fields[i]; const parts = field.split(this.fieldSeparator); let level = uniqueValues; for (let p = 0;p < parts.length; p++) { const part = parts[p]; let map = level.get(part); if (!map) { map = /* @__PURE__ */ new Map; level.set(part, map); } level = map; } } const uniqueValuesToGroups = (id, key, uniqueValues2, depth) => { const children = []; for (const [key2, item] of uniqueValues2) { const child = uniqueValuesToGroups(`${id}${this.fieldSeparator}${key2}`, key2, item, depth + 1); children.push(child); } if (children.length === 0) { const potentialAggCol = this.colModel.getColDefCol(key); if (potentialAggCol) { const headerName = this.colNames.getDisplayNameForColumn(potentialAggCol, "header") ?? key; const colDef = this.createColDef(potentialAggCol, headerName, undefined, false); colDef.colId = id; colDef.aggFunc = potentialAggCol.getAggFunc(); colDef.valueGetter = (params) => params.data?.[id]; return colDef; } const col = { colId: id, headerName: key, valueGetter: (params) => params.data?.[id] }; return col; } const collapseSingleChildren = this.gos.get("removePivotHeaderRowWhenSingleValueColumn"); if (collapseSingleChildren && children.length === 1 && "colId" in children[0]) { children[0].headerName = key; return children[0]; } const group = { openByDefault: this.pivotDefaultExpanded === -1 || depth < this.pivotDefaultExpanded, groupId: id, headerName: key, children }; return group; }; const res = []; for (const [key, item] of uniqueValues) { const col = uniqueValuesToGroups(key, key, item, 0); res.push(col); } return res; } }; var PivotResultColsService = class extends BeanStub { constructor() { super(...arguments); this.beanName = "pivotResultCols"; } wireBeans(beans) { this.colModel = beans.colModel; this.visibleCols = beans.visibleCols; } destroy() { _destroyColumnTree(this.beans, this.pivotResultCols?.tree); super.destroy(); } isPivotResultColsPresent() { return this.pivotResultCols != null; } lookupPivotResultCol(pivotKeys, valueColKey) { if (this.pivotResultCols == null) { return null; } const valueColumnToFind = this.colModel.getColDefCol(valueColKey); let foundColumn = null; for (const column of this.pivotResultCols.list) { const thisPivotKeys = column.getColDef().pivotKeys; const pivotValueColumn = column.getColDef().pivotValueColumn; const pivotKeyMatches = _areEqual(thisPivotKeys, pivotKeys); const pivotValueMatches = pivotValueColumn === valueColumnToFind; if (pivotKeyMatches && pivotValueMatches) { foundColumn = column; } } return foundColumn; } getPivotResultCols() { return this.pivotResultCols; } getPivotResultCol(key) { if (!this.pivotResultCols) { return null; } return this.colModel.getColFromCollection(key, this.pivotResultCols); } getAggregationOrderedList() { let result = this.aggOrderedList; if (result !== undefined) { return result; } const list = this.pivotResultCols?.list; if (!list || list.length === 0) { this.aggOrderedList = null; return null; } let hasAnyTotals = false; for (let i = 0;i < list.length; ++i) { if (list[i].getColDef().pivotTotalColumnIds != null) { hasAnyTotals = true; break; } } if (!hasAnyTotals) { result = list; } else { const regular = []; const totals = []; for (let i = 0;i < list.length; ++i) { const col = list[i]; if (col.getColDef().pivotTotalColumnIds != null) { totals.push(col); } else { regular.push(col); } } result = regular.concat(totals); } this.aggOrderedList = result; return result; } setPivotResultCols(colDefs, source) { this.aggOrderedList = undefined; if (!this.colModel.ready) { return; } if (colDefs == null && this.pivotResultCols == null) { return; } if (colDefs) { this.processPivotResultColDef(colDefs); const createColTreeFunc = source === "api" ? _createColumnTree : _createColumnTreeWithIds; const balancedTreeResult = createColTreeFunc(this.beans, colDefs, false, this.pivotResultCols?.tree || this.previousPivotResultCols || undefined, source); _destroyColumnTree(this.beans, this.pivotResultCols?.tree, balancedTreeResult.columnTree); const tree = balancedTreeResult.columnTree; const treeDepth = balancedTreeResult.treeDepth; const list = _getColumnsFromTree(tree); const map = {}; this.pivotResultCols = { tree, treeDepth, list, map }; for (const col of this.pivotResultCols.list) { this.pivotResultCols.map[col.getId()] = col; } const hasPreviousCols = !!this.previousPivotResultCols; this.previousPivotResultCols = null; this.colModel.refreshCols(!hasPreviousCols, source); } else { this.previousPivotResultCols = this.pivotResultCols ? this.pivotResultCols.tree : null; this.pivotResultCols = null; this.colModel.refreshCols(false, source); } this.visibleCols.refresh(source); } processPivotResultColDef(colDefs) { const columnCallback = this.gos.get("processPivotResultColDef"); const groupCallback = this.gos.get("processPivotResultColGroupDef"); if (!columnCallback && !groupCallback) { return; } const searchForColDefs = (colDefs2) => { colDefs2.forEach((abstractColDef) => { const isGroup = _exists(abstractColDef.children); if (isGroup) { const colGroupDef = abstractColDef; if (groupCallback) { groupCallback(colGroupDef); } searchForColDefs(colGroupDef.children); } else { const colDef = abstractColDef; if (columnCallback) { columnCallback(colDef); } } }); }; if (colDefs) { searchForColDefs(colDefs); } } }; var EXCEEDED_MAX_UNIQUE_VALUES = "Exceeded maximum allowed pivot column count."; var mapToObject = (map) => { const obj = {}; map.forEach((value, key) => obj[key] = value instanceof Map ? mapToObject(value) : value); return obj; }; var PivotStage = class extends BeanStub { constructor() { super(...arguments); this.beanName = "pivotStage"; this.step = "pivot"; this.refreshProps = [ "removePivotHeaderRowWhenSingleValueColumn", "pivotRowTotals", "pivotColumnGroupTotals", "suppressExpandablePivotGroups" ]; this.uniqueValues = /* @__PURE__ */ new Map; this.lastTimeFailed = false; this.maxUniqueValues = -1; this.currentUniqueCount = 0; } wireBeans(beans) { this.valueSvc = beans.valueSvc; this.colModel = beans.colModel; this.pivotResultCols = beans.pivotResultCols; this.rowGroupColsSvc = beans.rowGroupColsSvc; this.valueColsSvc = beans.valueColsSvc; this.pivotColsSvc = beans.pivotColsSvc; this.pivotColDefSvc = beans.pivotColDefSvc; } execute(changedPath) { if (this.colModel.isPivotActive()) { return this.executePivotOn(changedPath); } else { return this.executePivotOff(); } } executePivotOff() { this.aggregationColumnsHashLastTime = null; this.uniqueValues = /* @__PURE__ */ new Map; if (this.pivotResultCols.isPivotResultColsPresent()) { this.pivotResultCols.setPivotResultCols(null, "rowModelUpdated"); return true; } return false; } executePivotOn(changedPath) { const numberOfAggregationColumns = this.valueColsSvc?.columns.length ?? 1; const configuredMaxCols = this.gos.get("pivotMaxGeneratedColumns"); this.maxUniqueValues = configuredMaxCols === -1 ? -1 : configuredMaxCols / numberOfAggregationColumns; let uniqueValues; try { uniqueValues = this.bucketUpRowNodes(changedPath); } catch (e) { if (e.message === EXCEEDED_MAX_UNIQUE_VALUES) { this.pivotResultCols.setPivotResultCols([], "rowModelUpdated"); this.eventSvc.dispatchEvent({ type: "pivotMaxColumnsExceeded", message: e.message }); this.lastTimeFailed = true; return false; } throw e; } const uniqueValuesChanged = this.setUniqueValues(uniqueValues); const aggregationColumns = this.valueColsSvc?.columns ?? []; const aggregationColumnsHash = aggregationColumns.map((column) => `${column.getId()}-${column.getColDef().headerName}`).join("#"); const aggregationFuncsHash = aggregationColumns.map((column) => column.getAggFunc().toString()).join("#"); const aggregationColumnsChanged = this.aggregationColumnsHashLastTime !== aggregationColumnsHash; const aggregationFuncsChanged = this.aggregationFuncsHashLastTime !== aggregationFuncsHash; this.aggregationColumnsHashLastTime = aggregationColumnsHash; this.aggregationFuncsHashLastTime = aggregationFuncsHash; const groupColumnsHash = (this.rowGroupColsSvc?.columns ?? []).map((column) => column.getId()).join("#"); const groupColumnsChanged2 = groupColumnsHash !== this.groupColumnsHashLastTime; this.groupColumnsHashLastTime = groupColumnsHash; const pivotRowTotals = this.gos.get("pivotRowTotals"); const pivotColumnGroupTotals = this.gos.get("pivotColumnGroupTotals"); const suppressExpandablePivotGroups = this.gos.get("suppressExpandablePivotGroups"); const removePivotHeaderRowWhenSingleValueColumn = this.gos.get("removePivotHeaderRowWhenSingleValueColumn"); const anyGridOptionsChanged = pivotRowTotals !== this.pivotRowTotalsLastTime || pivotColumnGroupTotals !== this.pivotColumnGroupTotalsLastTime || suppressExpandablePivotGroups !== this.suppressExpandablePivotGroupsLastTime || removePivotHeaderRowWhenSingleValueColumn !== this.removePivotHeaderRowWhenSingleValueColumnLastTime; this.pivotRowTotalsLastTime = pivotRowTotals; this.pivotColumnGroupTotalsLastTime = pivotColumnGroupTotals; this.suppressExpandablePivotGroupsLastTime = suppressExpandablePivotGroups; this.removePivotHeaderRowWhenSingleValueColumnLastTime = removePivotHeaderRowWhenSingleValueColumn; if (this.lastTimeFailed || uniqueValuesChanged || aggregationColumnsChanged || groupColumnsChanged2 || aggregationFuncsChanged || anyGridOptionsChanged) { const pivotColumnGroupDefs = this.pivotColDefSvc.createPivotColumnDefs(this.uniqueValues); this.pivotResultCols.setPivotResultCols(pivotColumnGroupDefs, "rowModelUpdated"); this.lastTimeFailed = false; return true; } this.lastTimeFailed = false; return false; } setUniqueValues(newValues) { const uniqueValuesChanged = !_jsonEquals(mapToObject(this.uniqueValues), mapToObject(newValues)); if (uniqueValuesChanged) { this.uniqueValues = newValues; return true; } return false; } bucketUpRowNodes(changedPath) { this.currentUniqueCount = 0; const uniqueValues = /* @__PURE__ */ new Map; _forEachChangedGroupDepthFirst(this.beans.rowModel.rootNode, this.beans.rowModel.hierarchical, changedPath, (node) => { if (node.leafGroup) { node.childrenMapped = null; } }); const recursivelyBucketFilteredChildren = (node) => { if (node.leafGroup) { this.bucketRowNode(node, uniqueValues); } else { const children = node.childrenAfterFilter; if (children) { for (let i = 0, len = children.length;i < len; ++i) { recursivelyBucketFilteredChildren(children[i]); } } } }; recursivelyBucketFilteredChildren(this.beans.rowModel.rootNode); return uniqueValues; } bucketRowNode(rowNode, uniqueValues) { const pivotColumns = this.pivotColsSvc?.columns; if (pivotColumns?.length === 0) { rowNode.childrenMapped = null; } else { rowNode.childrenMapped = mapToObject(this.bucketChildren(rowNode.childrenAfterFilter, pivotColumns, 0, uniqueValues)); } if (rowNode.sibling) { rowNode.sibling.childrenMapped = rowNode.childrenMapped; } } bucketChildren(children, pivotColumns = [], pivotIndex, uniqueValues) { const mappedChildren = /* @__PURE__ */ new Map; const pivotColumn = pivotColumns[pivotIndex]; const doesGeneratedColMaxExist = this.maxUniqueValues !== -1; for (let i = 0, len = children.length;i < len; ++i) { const child = children[i]; let key = this.valueSvc.getKeyForNode(pivotColumn, child); if (_missing(key)) { key = ""; } if (!uniqueValues.get(key)) { this.currentUniqueCount += 1; uniqueValues.set(key, /* @__PURE__ */ new Map); const hasExceededColMax = this.currentUniqueCount > this.maxUniqueValues; if (doesGeneratedColMaxExist && hasExceededColMax) { throw new Error(EXCEEDED_MAX_UNIQUE_VALUES); } } if (!mappedChildren.has(key)) { mappedChildren.set(key, []); } mappedChildren.get(key).push(child); } if (pivotIndex === pivotColumns.length - 1) { return mappedChildren; } const result = /* @__PURE__ */ new Map; for (const key of mappedChildren.keys()) { result.set(key, this.bucketChildren(mappedChildren.get(key), pivotColumns, pivotIndex + 1, uniqueValues.get(key))); } return result; } }; var SharedPivotModule = { moduleName: "SharedPivot", version: VERSION2, beans: [PivotResultColsService, PivotColDefService, PivotColsSvc], apiFunctions: { isPivotMode, getPivotResultColumn, setValueColumns, getValueColumns, removeValueColumns, addValueColumns, setPivotColumns, removePivotColumns, addPivotColumns, getPivotColumns, setPivotResultColumns, getPivotResultColumns }, dependsOn: [SharedRowGroupingModule, ColumnGroupModule] }; var PivotModule = { moduleName: "Pivot", version: VERSION2, rowModels: ["clientSide"], beans: [PivotStage], dependsOn: [SharedPivotModule, RowGroupingModule, ClientSideRowModelHierarchyModule] }; var PATH_KEY_SEPARATOR = String.fromCodePoint(31, 41150, 8291); var OP_DEFS = [ { symbol: "%", fixity: "postfix", precedence: 100 }, { symbol: "-", fixity: "prefix", precedence: 90 }, { symbol: "+", fixity: "prefix", precedence: 90 }, { symbol: "^", fixity: "infix", precedence: 80, associativity: "right" }, { symbol: "*", fixity: "infix", precedence: 70, associativity: "left", isAssociative: true }, { symbol: "/", fixity: "infix", precedence: 70, associativity: "left" }, { symbol: "+", fixity: "infix", precedence: 60, associativity: "left", isAssociative: true }, { symbol: "-", fixity: "infix", precedence: 60, associativity: "left" }, { symbol: "&", fixity: "infix", precedence: 55, associativity: "left", isAssociative: true }, { symbol: "=", fixity: "infix", precedence: 50, associativity: "left" }, { symbol: "<>", fixity: "infix", precedence: 50, associativity: "left" }, { symbol: ">=", fixity: "infix", precedence: 50, associativity: "left" }, { symbol: "<=", fixity: "infix", precedence: 50, associativity: "left" }, { symbol: ">", fixity: "infix", precedence: 50, associativity: "left" }, { symbol: "<", fixity: "infix", precedence: 50, associativity: "left" } ]; var symbolOperatorMap = /* @__PURE__ */ new Map; for (const d of OP_DEFS) { const s2 = symbolOperatorMap.get(d.symbol) ?? []; s2.push(d); symbolOperatorMap.set(d.symbol, s2); } var OP_SYMBOLS_DESC = [...new Set(OP_DEFS.map((d) => d.symbol))].sort((a, b) => b.length - a.length); var MS_PER_DAY = 24 * 60 * 60 * 1000; var WrappedFunctionMarker = Symbol("WrappedFunctionMarker"); var CHART_TYPE_TO_SERIES_TYPE = { column: "bar", groupedColumn: "bar", stackedColumn: "bar", normalizedColumn: "bar", bar: "bar", groupedBar: "bar", stackedBar: "bar", normalizedBar: "bar", line: "line", stackedLine: "line", normalizedLine: "line", scatter: "scatter", bubble: "bubble", pie: "pie", donut: "donut", doughnut: "donut", area: "area", stackedArea: "area", normalizedArea: "area", histogram: "histogram", radarLine: "radar-line", radarArea: "radar-area", nightingale: "nightingale", radialColumn: "radial-column", radialBar: "radial-bar", sunburst: "sunburst", rangeBar: "range-bar", rangeArea: "range-area", boxPlot: "box-plot", treemap: "treemap", heatmap: "heatmap", waterfall: "waterfall", funnel: "funnel", coneFunnel: "cone-funnel", pyramid: "pyramid" }; var COMBO_CHART_TYPES = /* @__PURE__ */ new Set(["columnLineCombo", "areaColumnCombo", "customCombo"]); function isComboChart(chartType) { return COMBO_CHART_TYPES.has(chartType); } function getCanonicalChartType(chartType) { return chartType === "doughnut" ? "donut" : chartType; } function getSeriesTypeIfExists(chartType) { return CHART_TYPE_TO_SERIES_TYPE[chartType]; } var ALL_AXIS_TYPES = ["number", "category", "grouped-category", "log", "time"]; var STATIC_INBUILT_STOCK_THEME_AXES_OVERRIDES = ALL_AXIS_TYPES.reduce((r, n) => ({ ...r, [n]: { title: { _enabledFromTheme: true } } }), {}); var validateIfDefined = (validationFn) => { return (value) => { if (value == undefined) { return true; } return validationFn(value); }; }; var legacyChartTypes = ["doughnut"]; function isValidChartType(value) { return !!getSeriesTypeIfExists(value) || isComboChart(value); } function isLegacyChartType(value) { return legacyChartTypes.includes(value); } var validateChartType = validateIfDefined((chartType) => { if (isValidChartType(chartType)) { return true; } if (isLegacyChartType(chartType)) { const renamedChartType = getCanonicalChartType(chartType); _warnOnce(`The chart type '${chartType}' has been deprecated. Please use '${renamedChartType}' instead.`); return renamedChartType; } return false; }); var validateAgChartThemeOverrides = validateIfDefined((themeOverrides) => { return typeof themeOverrides === "object"; }); var validateChartParamsCellRange = validateIfDefined((cellRange) => { return typeof cellRange === "object"; }); var validateAggFunc = validateIfDefined((aggFunc) => { return typeof aggFunc === "string" || typeof aggFunc === "function"; }); function stackData(data) { return data.map((stack, sindex, array) => stack.map((_y, i) => array.slice(0, sindex + 1).reduce((p, c) => p + c[i], 0))); } function normalizeStackData(data) { const colSum = data.map((_, index) => data.reduce((acc, cur) => Math.max(acc, cur[index]), 0)); return data.map((stack) => stack.map((y, index) => y / colSum[index] * 19)); } var miniLineData = [ [1, 3, 5], [2, 6, 4], [5, 3, 1] ]; var miniStackedLineData = stackData(miniLineData); var miniNormalizedLineData = normalizeStackData(miniStackedLineData); var miniAreaData = miniLineData; var miniStackedAreaData = stackData(miniAreaData); var miniNormalizedAreaData = normalizeStackData(miniStackedAreaData); var CARTESIAN_AXIS_TYPES = ["number", "category", "time", "grouped-category"]; var POLAR_AXIS_TYPES = ["angle-category", "angle-number", "radius-category", "radius-number"]; var VALID_AXIS_TYPES = [...CARTESIAN_AXIS_TYPES, ...POLAR_AXIS_TYPES]; // src/sigpro-grid.js ModuleRegistry.registerModules([ ValidationModule, ColumnAutoSizeModule, CellStyleModule, QuickFilterModule, RowSelectionModule, TextEditorModule, ClientSideRowModelModule, MultiFilterModule, CellSelectionModule, PivotModule, MasterDetailModule, SideBarModule, ColumnsToolPanelModule, ColumnMenuModule, StatusBarModule, ExcelExportModule, ClipboardModule, NumberFilterModule, TextFilterModule, SetFilterModule, DateFilterModule, ContextMenuModule ]); var Grid = (props) => { const { data, options, api, on, class: className, style = "height: 100%; width: 100%", dark } = props; let gridApi = null; let cleanupFn = null; const getDark = () => dark !== undefined ? typeof dark === "function" ? dark() : dark : document.documentElement.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches; const getTheme = () => { const isDark = getDark(); if (isDark) { return themeQuartz.withParams({ headerFontSize: 14, headerVerticalPaddingScale: 0.4, rowVerticalPaddingScale: 0.4, backgroundColor: "#1d1d1d", foregroundColor: "#ffffff", headerBackgroundColor: "#2a2a2a", headerForegroundColor: "#ffffff", oddRowBackgroundColor: "#262626", borderColor: "#404040", browserColorScheme: "dark" }); } return themeQuartz.withParams({ browserColorScheme: "light", headerFontSize: 14, headerVerticalPaddingScale: 0.4, rowVerticalPaddingScale: 0.4 }); }; const initGrid = (container) => { if (cleanupFn) { cleanupFn(); cleanupFn = null; } if (gridApi && !gridApi.isDestroyed()) { gridApi.destroy(); if (api) api.current = null; gridApi = null; } if (!container) return; const initialData = typeof data === "function" ? data() : data; const initialOptions = typeof options === "function" ? options() : options; const commonEvents = [ "onFilterChanged", "onModelUpdated", "onGridSizeChanged", "onFirstDataRendered", "onRowValueChanged", "onSelectionChanged", "onCellClicked", "onCellDoubleClicked", "onCellValueChanged", "onRowClicked", "onSortChanged", "onContextMenu", "onColumnResized", "onColumnMoved", "onRowDataUpdated", "onCellEditingStarted", "onCellEditingStopped", "onPaginationChanged", "onBodyScroll" ]; const eventHandlers = {}; commonEvents.forEach((eventName) => { if (on?.[eventName]) { eventHandlers[eventName] = (params) => on[eventName](params); } }); const gridOptions = { ...initialOptions, theme: getTheme(), rowData: initialData || [], onGridReady: (params) => { gridApi = params.api; if (api) api.current = gridApi; if (on?.onGridReady) on.onGridReady(params); if (initialOptions?.autoSizeColumns) { params.api.autoSizeAllColumns(); } }, ...eventHandlers }; gridApi = createGrid(container, gridOptions); const stopData = watch(() => { if (!gridApi || gridApi.isDestroyed()) return; const newData = typeof data === "function" ? data() : data; if (Array.isArray(newData)) { const currentData = gridApi.getGridOption("rowData"); if (newData !== currentData) { gridApi.setGridOption("rowData", newData); } } }); const stopTheme = watch(() => { if (!gridApi || gridApi.isDestroyed()) return; getDark(); const newTheme = getTheme(); const currentTheme = gridApi.getGridOption("theme"); if (JSON.stringify(newTheme) !== JSON.stringify(currentTheme)) { gridApi.setGridOption("theme", newTheme); } }); const stopOptions = watch(() => { if (!gridApi || gridApi.isDestroyed() || !options) return; const newOptions = typeof options === "function" ? options() : options; if (newOptions) { Object.entries(newOptions).forEach(([key, val]) => { try { gridApi.setGridOption(key, val); } catch (e) {} }); } }); cleanupFn = () => { stopData(); stopTheme(); stopOptions(); if (gridApi && !gridApi.isDestroyed()) { gridApi.destroy(); if (api) api.current = null; gridApi = null; } }; onUnmount(() => { if (cleanupFn) { cleanupFn(); cleanupFn = null; } }); }; return h("div", { class: className, style, ref: initGrid }); }; export { Grid };