UNPKG

angular-slickgrid

Version:
1 lines 156 kB
{"version":3,"file":"angular-slickgrid.mjs","sources":["../../src/library/services/angularUtil.service.ts","../../src/library/services/container.service.ts","../../src/library/services/translater.service.ts","../../src/library/services/utilities.ts","../../src/library/global-grid-options.ts","../../src/library/slickgrid-config.ts","../../src/library/constants.ts","../../src/library/components/angular-slickgrid.component.ts","../../src/angular-slickgrid.ts"],"sourcesContent":["import { Inject, Injectable, ViewContainerRef } from '@angular/core';\nimport type { EmbeddedViewRef, EnvironmentInjector, Injector, NgModuleRef, Type } from '@angular/core';\nimport type { AngularComponentOutput } from '../models/angularComponentOutput.interface';\n\ninterface CreateComponentOption {\n index?: number;\n injector?: Injector;\n ngModuleRef?: NgModuleRef<unknown>;\n environmentInjector?: EnvironmentInjector | NgModuleRef<unknown>;\n projectableNodes?: Node[][];\n sanitizer?: (dirtyHtml: string) => string;\n}\n\n@Injectable()\nexport class AngularUtilService {\n constructor(@Inject(ViewContainerRef) private vcr: ViewContainerRef) {}\n\n createInteractiveAngularComponent<C>(\n component: Type<C>,\n targetElement: Element,\n data?: any,\n createCompOptions?: CreateComponentOption\n ): AngularComponentOutput {\n // Create a component reference from the component\n const componentRef = this.vcr.createComponent(component, createCompOptions);\n\n // user could provide data to assign to the component instance\n if (componentRef?.instance && data) {\n Object.assign(componentRef.instance as any, data);\n }\n\n // Get DOM element from component\n let domElem: HTMLElement | null = null;\n const viewRef = componentRef.hostView as EmbeddedViewRef<any>;\n\n if (viewRef && Array.isArray(viewRef.rootNodes) && viewRef.rootNodes[0]) {\n domElem = viewRef.rootNodes[0] as HTMLElement;\n\n // when user provides the DOM element target, we will move the dynamic component into that target (aka portal-ing it)\n if (targetElement && domElem) {\n targetElement.replaceChildren(componentRef.location.nativeElement);\n }\n }\n\n return { componentRef, domElement: domElem as HTMLElement };\n }\n\n /**\n * Dynamically create an Angular component, user could also provide optional arguments for target, data & createComponent options\n * @param {Component} component\n * @param {HTMLElement} [targetElement]\n * @param {*} [data]\n * @param {CreateComponentOption} [createCompOptions]\n * @returns\n */\n createAngularComponent<C>(\n component: Type<C>,\n targetElement?: Element,\n data?: any,\n createCompOptions?: CreateComponentOption\n ): AngularComponentOutput {\n // Create a component reference from the component\n const componentRef = this.vcr.createComponent(component, createCompOptions);\n\n // user could provide data to assign to the component instance\n if (componentRef?.instance && data) {\n Object.assign(componentRef.instance as any, data);\n }\n\n // Get DOM element from component\n let domElem: HTMLElement | null = null;\n const viewRef = componentRef.hostView as EmbeddedViewRef<any>;\n\n // get DOM element from the new dynamic Component, make sure this is read after any data\n if (viewRef && Array.isArray(viewRef.rootNodes) && viewRef.rootNodes[0]) {\n domElem = viewRef.rootNodes[0] as HTMLElement;\n\n // when user provides the DOM element target, we will read the new Component html and use it to replace the target html\n if (targetElement && domElem) {\n targetElement.innerHTML =\n typeof createCompOptions?.sanitizer === 'function' ? createCompOptions.sanitizer(domElem.innerHTML || '') : domElem.innerHTML;\n }\n }\n\n return { componentRef, domElement: domElem as HTMLElement };\n }\n\n /**\n * Dynamically create an Angular component and append it to the DOM unless a target element is provided,\n * user could also provide other optional arguments for data & createComponent options.\n * @param {Component} component\n * @param {HTMLElement} [targetElement]\n * @param {*} [data]\n * @param {CreateComponentOption} [createCompOptions]\n * @returns\n */\n createAngularComponentAppendToDom<C>(\n component: Type<C>,\n targetElement?: Element,\n data?: any,\n createCompOptions?: CreateComponentOption\n ): AngularComponentOutput {\n const componentOutput = this.createAngularComponent(component, targetElement, data, createCompOptions);\n\n // Append DOM element to the HTML element specified\n if (targetElement?.replaceChildren) {\n targetElement.replaceChildren(componentOutput.domElement);\n } else {\n document.body.appendChild(componentOutput.domElement); // when no target provided, we'll simply add it to the HTML Body\n }\n\n return componentOutput;\n }\n}\n","import { Injectable } from '@angular/core';\nimport type { ContainerInstance, ContainerService as UniversalContainerService } from '@slickgrid-universal/common';\n\n@Injectable({\n providedIn: 'root', // This ensures it can be injected anywhere\n})\nexport class ContainerService implements UniversalContainerService {\n dependencies: ContainerInstance[] = [];\n\n get<T = any>(key: string): T | null {\n const dependency = this.dependencies.find((dep) => dep.key === key);\n if (dependency?.instance) {\n return dependency.instance;\n }\n return null;\n }\n\n dispose() {\n this.dependencies = [];\n }\n\n registerInstance(key: string, instance: any) {\n const dependency = this.dependencies.some((dep) => dep.key === key);\n if (!dependency) {\n this.dependencies.push({ key, instance });\n }\n }\n}\n","import { Injectable, Optional } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport type { TranslaterService as UniversalTranslateService } from '@slickgrid-universal/common';\n\n/**\n * This is a Translate Service Wrapper for Slickgrid-Universal monorepo lib to work properly,\n * it must implement Slickgrid-Universal TranslaterService interface to work properly\n */\n@Injectable()\nexport class TranslaterService implements UniversalTranslateService {\n constructor(@Optional() private readonly translateService: TranslateService) {}\n\n /**\n * Method to return the current language used by the App\n * @return {string} current language\n */\n getCurrentLanguage(): string {\n return this.translateService?.getCurrentLang?.() ?? '';\n }\n\n /**\n * Method to set the language to use in the App and Translate Service\n * @param {string} language\n * @return {Promise} output\n */\n async use(newLang: string): Promise<any> {\n return this.translateService?.use?.(newLang);\n }\n\n /**\n * Method which receives a translation key and returns the translated value assigned to that key\n * @param {string} translation key\n * @return {string} translated value\n */\n translate(translationKey: string): string {\n return this.translateService?.instant?.(translationKey || ' ') as string;\n }\n}\n","/**\n * Unsubscribe all Observables Subscriptions\n * It will return an empty array if it all went well\n * @param subscriptions\n */\nexport function unsubscribeAllObservables(subscriptions: Array<{ unsubscribe: () => void }>): void {\n if (Array.isArray(subscriptions)) {\n let subscription = subscriptions.pop();\n while (subscription) {\n if (typeof subscription.unsubscribe === 'function') {\n subscription.unsubscribe();\n }\n subscription = subscriptions.pop();\n }\n }\n}\n","import { GlobalGridOptions as UniversalGridOptions } from '@slickgrid-universal/common';\nimport type { GridOption, RowDetailView } from './models/index';\n\n/** Global Grid Options Defaults */\nexport const GlobalGridOptions: Partial<GridOption> = {\n ...UniversalGridOptions,\n eventNamingStyle: 'camelCase',\n // technically speaking the Row Detail requires the process & viewComponent but we'll ignore it just to set certain options\n rowDetailView: {\n collapseAllOnSort: true,\n cssClass: 'detail-view-toggle',\n panelRows: 1,\n keyPrefix: '__',\n useRowClick: false,\n saveDetailViewOnScroll: false,\n } as RowDetailView,\n};\n","import { GlobalGridOptions } from './global-grid-options';\nimport type { GridOption } from './models/gridOption.interface';\n\nexport class SlickgridConfig {\n options: Partial<GridOption>;\n\n constructor() {\n this.options = GlobalGridOptions;\n }\n}\n","import type { Locale } from '@slickgrid-universal/common';\n\nexport class Constants {\n // English Locale texts when using only 1 Locale instead of I18N\n static readonly locales: Locale = {\n TEXT_ALL_SELECTED: 'All Selected',\n TEXT_ALL_X_RECORDS_SELECTED: 'All {{x}} records selected',\n TEXT_APPLY_MASS_UPDATE: 'Apply Mass Update',\n TEXT_APPLY_TO_SELECTION: 'Update Selection',\n TEXT_CANCEL: 'Cancel',\n TEXT_CLEAR_ALL_FILTERS: 'Clear all Filters',\n TEXT_CLEAR_ALL_GROUPING: 'Clear all Grouping',\n TEXT_CLEAR_ALL_SORTING: 'Clear all Sorting',\n TEXT_CLEAR_PINNING: 'Unfreeze Columns/Rows',\n TEXT_CLONE: 'Clone',\n TEXT_COLLAPSE_ALL_GROUPS: 'Collapse all Groups',\n TEXT_CONTAINS: 'Contains',\n TEXT_COLUMNS: 'Columns',\n TEXT_COLUMN_RESIZE_BY_CONTENT: 'Resize by Content',\n TEXT_COMMANDS: 'Commands',\n TEXT_COPY: 'Copy',\n TEXT_EQUALS: 'Equals',\n TEXT_EQUAL_TO: 'Equal to',\n TEXT_ENDS_WITH: 'Ends With',\n TEXT_ERROR_EDITABLE_GRID_REQUIRED: 'Your grid must be editable in order to use the Composite Editor Modal.',\n TEXT_ERROR_ENABLE_CELL_NAVIGATION_REQUIRED:\n 'Composite Editor requires the flag \"enableCellNavigation\" to be set to True in your Grid Options.',\n TEXT_ERROR_NO_CHANGES_DETECTED: 'Sorry we could not detect any changes.',\n TEXT_ERROR_NO_EDITOR_FOUND: 'We could not find any Editor in your Column Definition.',\n TEXT_ERROR_NO_RECORD_FOUND: 'No records selected for edit or clone operation.',\n TEXT_ERROR_ROW_NOT_EDITABLE: 'Current row is not editable.',\n TEXT_ERROR_ROW_SELECTION_REQUIRED: 'You must select some rows before trying to apply new value(s).',\n TEXT_EXPAND_ALL_GROUPS: 'Expand all Groups',\n TEXT_EXPORT_TO_CSV: 'Export in CSV format',\n TEXT_EXPORT_TO_TEXT_FORMAT: 'Export in Text format (Tab delimited)',\n TEXT_EXPORT_TO_EXCEL: 'Export to Excel',\n TEXT_EXPORT_TO_PDF: 'Export to PDF',\n TEXT_EXPORT_TO_TAB_DELIMITED: 'Export in Text format (Tab delimited)',\n TEXT_FORCE_FIT_COLUMNS: 'Force fit columns',\n TEXT_FREEZE_COLUMNS: 'Freeze Columns',\n TEXT_GREATER_THAN: 'Greater than',\n TEXT_GREATER_THAN_OR_EQUAL_TO: 'Greater than or equal to',\n TEXT_GROUP_BY: 'Group By',\n TEXT_HIDE_COLUMN: 'Hide Column',\n TEXT_ITEMS: 'items',\n TEXT_ITEMS_PER_PAGE: 'items per page',\n TEXT_ITEMS_SELECTED: 'items selected',\n TEXT_OF: 'of',\n TEXT_OK: 'OK',\n TEXT_OPTIONS: 'Options',\n TEXT_LAST_UPDATE: 'Last Update',\n TEXT_LESS_THAN: 'Less than',\n TEXT_LESS_THAN_OR_EQUAL_TO: 'Less than or equal to',\n TEXT_LOADING: 'Loading...',\n TEXT_NO_ELEMENTS_FOUND: 'Aucun élément trouvé',\n TEXT_NOT_CONTAINS: 'Not contains',\n TEXT_NOT_EQUAL_TO: 'Not equal to',\n TEXT_PAGE: 'Page',\n TEXT_REFRESH_DATASET: 'Refresh Dataset',\n TEXT_REMOVE_FILTER: 'Remove Filter',\n TEXT_REMOVE_SORT: 'Remove Sort',\n TEXT_SAVE: 'Save',\n TEXT_SELECT_ALL: 'Select All',\n TEXT_SYNCHRONOUS_RESIZE: 'Synchronous resize',\n TEXT_SORT_ASCENDING: 'Sort Ascending',\n TEXT_SORT_DESCENDING: 'Sort Descending',\n TEXT_STARTS_WITH: 'Starts With',\n TEXT_TOGGLE_DARK_MODE: 'Toggle Dark Mode',\n TEXT_TOGGLE_FILTER_ROW: 'Toggle Filter Row',\n TEXT_TOGGLE_PRE_HEADER_ROW: 'Toggle Pre-Header Row',\n TEXT_UNFREEZE_COLUMNS: 'Unfreeze Columns',\n TEXT_X_OF_Y_SELECTED: '# of % selected',\n TEXT_X_OF_Y_MASS_SELECTED: '{{x}} of {{y}} selected',\n };\n\n static readonly treeDataProperties = {\n CHILDREN_PROP: 'children',\n COLLAPSED_PROP: '__collapsed',\n HAS_CHILDREN_PROP: '__hasChildren',\n LAZY_LOADING_PROP: '__lazyLoading',\n TREE_LEVEL_PROP: '__treeLevel',\n PARENT_PROP: '__parentId',\n };\n\n // some Validation default texts\n static readonly VALIDATION_REQUIRED_FIELD = 'Field is required';\n static readonly VALIDATION_EDITOR_VALID_NUMBER = 'Please enter a valid number';\n static readonly VALIDATION_EDITOR_VALID_INTEGER = 'Please enter a valid integer number';\n static readonly VALIDATION_EDITOR_INTEGER_BETWEEN = 'Please enter a valid integer number between {{minValue}} and {{maxValue}}';\n static readonly VALIDATION_EDITOR_INTEGER_MAX = 'Please enter a valid integer number that is lower than {{maxValue}}';\n static readonly VALIDATION_EDITOR_INTEGER_MAX_INCLUSIVE =\n 'Please enter a valid integer number that is lower than or equal to {{maxValue}}';\n static readonly VALIDATION_EDITOR_INTEGER_MIN = 'Please enter a valid integer number that is greater than {{minValue}}';\n static readonly VALIDATION_EDITOR_INTEGER_MIN_INCLUSIVE =\n 'Please enter a valid integer number that is greater than or equal to {{minValue}}';\n static readonly VALIDATION_EDITOR_NUMBER_BETWEEN = 'Please enter a valid number between {{minValue}} and {{maxValue}}';\n static readonly VALIDATION_EDITOR_NUMBER_MAX = 'Please enter a valid number that is lower than {{maxValue}}';\n static readonly VALIDATION_EDITOR_NUMBER_MAX_INCLUSIVE = 'Please enter a valid number that is lower than or equal to {{maxValue}}';\n static readonly VALIDATION_EDITOR_NUMBER_MIN = 'Please enter a valid number that is greater than {{minValue}}';\n static readonly VALIDATION_EDITOR_NUMBER_MIN_INCLUSIVE = 'Please enter a valid number that is greater than or equal to {{minValue}}';\n static readonly VALIDATION_EDITOR_DECIMAL_BETWEEN = 'Please enter a valid number with a maximum of {{maxDecimal}} decimals';\n static readonly VALIDATION_EDITOR_TEXT_LENGTH_BETWEEN =\n 'Please make sure your text length is between {{minLength}} and {{maxLength}} characters';\n static readonly VALIDATION_EDITOR_TEXT_MAX_LENGTH = 'Please make sure your text is less than {{maxLength}} characters';\n static readonly VALIDATION_EDITOR_TEXT_MAX_LENGTH_INCLUSIVE =\n 'Please make sure your text is less than or equal to {{maxLength}} characters';\n static readonly VALIDATION_EDITOR_TEXT_MIN_LENGTH = 'Please make sure your text is more than {{minLength}} character(s)';\n static readonly VALIDATION_EDITOR_TEXT_MIN_LENGTH_INCLUSIVE = 'Please make sure your text is at least {{minLength}} character(s)';\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ApplicationRef,\n Component,\n ContentChild,\n ElementRef,\n EventEmitter,\n Inject,\n Input,\n Optional,\n Output,\n output,\n type AfterViewInit,\n type OnDestroy,\n type TemplateRef,\n} from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport {\n autoAddEditorFormatterToColumnsWithEditor,\n BackendUtilityService,\n CollectionService,\n emptyElement,\n ExtensionService,\n ExtensionUtility,\n ExternalResourceConstructor,\n FilterFactory,\n FilterService,\n GridEventService,\n GridService,\n GridStateService,\n HeaderGroupingService,\n isColumnDateType,\n PaginationService,\n PluginFlagMappings,\n ResizerService,\n SharedService,\n SlickDataView,\n SlickEventHandler,\n SlickGrid,\n SlickgridConfig,\n SlickGroupItemMetadataProvider,\n SortService,\n TreeDataService,\n unsubscribeAll,\n type BackendService,\n type BackendServiceApi,\n type BackendServiceOption,\n type BasePaginationComponent,\n type Column,\n type CustomDataView,\n type DataViewOption,\n type EventSubscription,\n type ExternalResource,\n type Locale,\n type Metrics,\n type Pagination,\n type PaginationMetadata,\n type RxJsFacade,\n} from '@slickgrid-universal/common';\nimport { SlickFooterComponent } from '@slickgrid-universal/custom-footer-component';\nimport { SlickEmptyWarningComponent } from '@slickgrid-universal/empty-warning-component';\nimport { EventPubSubService } from '@slickgrid-universal/event-pub-sub';\nimport { SlickPaginationComponent } from '@slickgrid-universal/pagination-component';\nimport { RxJsResource } from '@slickgrid-universal/rxjs-observable';\nimport { extend } from '@slickgrid-universal/utils';\nimport { dequal } from 'dequal/lite';\nimport { Observable } from 'rxjs';\nimport { Constants } from '../constants';\nimport { GlobalGridOptions } from '../global-grid-options';\nimport type { AngularGridInstance, ExternalTestingDependencies, GridOption } from '../models/index';\nimport { AngularUtilService } from '../services/angularUtil.service';\nimport { ContainerService } from '../services/container.service';\nimport { TranslaterService } from '../services/translater.service';\nimport type { AngularSlickgridOutputs, RegularEventOutput, SlickEventOutput } from './angular-slickgrid-outputs.interface';\n\nconst WARN_NO_PREPARSE_DATE_SIZE = 10000; // data size to warn user when pre-parse isn't enabled\n\nexport interface AngularRowDetailView {\n create(columns: Column[], gridOptions: GridOption): any;\n init(grid: SlickGrid, containerService?: ContainerService): void;\n}\n\n@Component({\n selector: 'angular-slickgrid',\n template: `\n <div id=\"slickGridContainer-{{ gridId }}\" class=\"gridPane\" [class]=\"containerClasses\">\n <ng-container *ngTemplateOutlet=\"slickgridHeader\"></ng-container>\n <div [attr.id]=\"gridId\" class=\"slickgrid-container\"></div>\n <ng-container *ngTemplateOutlet=\"slickgridFooter\"></ng-container>\n </div>\n `,\n providers: [AngularUtilService, TranslaterService], // make everything transient (non-singleton)\n imports: [NgTemplateOutlet],\n})\nexport class AngularSlickgridComponent<TData = any> implements AfterViewInit, OnDestroy {\n protected _dataset?: TData[] | null;\n protected _columns!: Column[];\n protected _currentDatasetLength = 0;\n protected _darkMode = false;\n protected _eventHandler: SlickEventHandler = new SlickEventHandler();\n protected _eventPubSubService!: EventPubSubService;\n protected _angularGridInstances: AngularGridInstance | undefined;\n protected _hideHeaderRowAfterPageLoad = false;\n protected _isAutosizeColsCalled = false;\n protected _isGridInitialized = false;\n protected _isDatasetInitialized = false;\n protected _isDatasetHierarchicalInitialized = false;\n protected _isPaginationInitialized = false;\n protected _isLocalGrid = true;\n protected _paginationOptions: Pagination | undefined;\n protected _registeredResources: Array<ExternalResource | ExternalResourceConstructor> = [];\n protected _scrollEndCalled = false;\n dataView!: SlickDataView;\n slickGrid!: SlickGrid;\n groupingDefinition: any = {};\n groupItemMetadataProvider?: SlickGroupItemMetadataProvider;\n backendServiceApi?: BackendServiceApi;\n locales!: Locale;\n metrics?: Metrics;\n showPagination = false;\n serviceList: any[] = [];\n totalItems = 0;\n paginationData?: {\n gridOptions: GridOption;\n paginationService: PaginationService;\n };\n subscriptions: EventSubscription[] = [];\n\n // components / plugins\n slickEmptyWarning?: SlickEmptyWarningComponent;\n slickFooter?: SlickFooterComponent;\n slickPagination?: BasePaginationComponent;\n paginationComponent: BasePaginationComponent | undefined;\n slickRowDetailView?: AngularRowDetailView;\n\n // services\n backendUtilityService!: BackendUtilityService;\n collectionService: CollectionService;\n extensionService: ExtensionService;\n extensionUtility: ExtensionUtility;\n filterFactory!: FilterFactory;\n filterService: FilterService;\n gridEventService: GridEventService;\n gridService: GridService;\n gridStateService: GridStateService;\n headerGroupingService: HeaderGroupingService;\n paginationService: PaginationService;\n resizerService!: ResizerService;\n rxjs?: RxJsFacade;\n sharedService: SharedService;\n sortService: SortService;\n treeDataService: TreeDataService;\n\n @Input() customDataView: CustomDataView | undefined;\n @Input() gridId = '';\n @Input() options: GridOption = {};\n @Input() containerClasses?: string[] = undefined;\n\n @Input()\n get paginationOptions(): Pagination | undefined {\n return this._paginationOptions;\n }\n set paginationOptions(newPaginationOptions: Pagination | undefined) {\n if (newPaginationOptions && this._paginationOptions) {\n this._paginationOptions = { ...this.options.pagination, ...this._paginationOptions, ...newPaginationOptions };\n } else {\n this._paginationOptions = newPaginationOptions;\n }\n this.options.pagination = this._paginationOptions ?? this.options.pagination;\n this.paginationService.updateTotalItems(this.options.pagination?.totalItems ?? 0, true);\n }\n\n @Input()\n get columns(): Column[] {\n return this._columns;\n }\n set columns(columns: Column[]) {\n this._columns = columns;\n if (this._isGridInitialized) {\n this.updateColumnDefinitionsList(columns);\n }\n if (columns.length > 0) {\n this.copyColumnWidthsReference(columns);\n }\n }\n\n // make the columnDefinitions a 2-way binding so that plugin adding cols\n // are synched on user's side as well (RowMove, RowDetail, RowSelections)\n @Output() columnsChange = new EventEmitter(true);\n\n // SlickGrid events\n onActiveCellChanged = output<SlickEventOutput<AngularSlickgridOutputs['onActiveCellChanged']>>();\n onActiveCellPositionChanged = output<SlickEventOutput<AngularSlickgridOutputs['onActiveCellPositionChanged']>>();\n onAddNewRow = output<SlickEventOutput<AngularSlickgridOutputs['onAddNewRow']>>();\n onAutosizeColumns = output<SlickEventOutput<AngularSlickgridOutputs['onAutosizeColumns']>>();\n onBeforeAppendCell = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeAppendCell']>>();\n onBeforeCellEditorDestroy = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeCellEditorDestroy']>>();\n onBeforeColumnsResize = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeColumnsResize']>>();\n onBeforeDestroy = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeDestroy']>>();\n onBeforeEditCell = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeEditCell']>>();\n onBeforeHeaderCellDestroy = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeHeaderCellDestroy']>>();\n onBeforeHeaderRowCellDestroy = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeHeaderRowCellDestroy']>>();\n onBeforeFooterRowCellDestroy = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeFooterRowCellDestroy']>>();\n onBeforeSetColumns = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeSetColumns']>>();\n onBeforeSort = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeSort']>>();\n onCellChange = output<SlickEventOutput<AngularSlickgridOutputs['onCellChange']>>();\n onCellCssStylesChanged = output<SlickEventOutput<AngularSlickgridOutputs['onCellCssStylesChanged']>>();\n onClick = output<SlickEventOutput<AngularSlickgridOutputs['onClick']>>();\n onColumnsDrag = output<SlickEventOutput<AngularSlickgridOutputs['onColumnsDrag']>>();\n onColumnsReordered = output<SlickEventOutput<AngularSlickgridOutputs['onColumnsReordered']>>();\n onColumnsResized = output<SlickEventOutput<AngularSlickgridOutputs['onColumnsResized']>>();\n onColumnsResizeDblClick = output<SlickEventOutput<AngularSlickgridOutputs['onColumnsResizeDblClick']>>();\n onCompositeEditorChange = output<SlickEventOutput<AngularSlickgridOutputs['onCompositeEditorChange']>>();\n onContextMenu = output<SlickEventOutput<AngularSlickgridOutputs['onContextMenu']>>();\n onDrag = output<SlickEventOutput<AngularSlickgridOutputs['onDrag']>>();\n onDragEnd = output<SlickEventOutput<AngularSlickgridOutputs['onDragEnd']>>();\n onDragInit = output<SlickEventOutput<AngularSlickgridOutputs['onDragInit']>>();\n onDragStart = output<SlickEventOutput<AngularSlickgridOutputs['onDragStart']>>();\n onDragReplaceCells = output<SlickEventOutput<AngularSlickgridOutputs['onDragReplaceCells']>>();\n onDblClick = output<SlickEventOutput<AngularSlickgridOutputs['onDblClick']>>();\n onFooterContextMenu = output<SlickEventOutput<AngularSlickgridOutputs['onFooterContextMenu']>>();\n onFooterRowCellRendered = output<SlickEventOutput<AngularSlickgridOutputs['onFooterRowCellRendered']>>();\n onHeaderCellRendered = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderCellRendered']>>();\n onFooterClick = output<SlickEventOutput<AngularSlickgridOutputs['onFooterClick']>>();\n onHeaderClick = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderClick']>>();\n onHeaderContextMenu = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderContextMenu']>>();\n onHeaderMouseEnter = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderMouseEnter']>>();\n onHeaderMouseLeave = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderMouseLeave']>>();\n onHeaderRowCellRendered = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderRowCellRendered']>>();\n onHeaderRowMouseEnter = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderRowMouseEnter']>>();\n onHeaderRowMouseLeave = output<SlickEventOutput<AngularSlickgridOutputs['onHeaderRowMouseLeave']>>();\n onKeyDown = output<SlickEventOutput<AngularSlickgridOutputs['onKeyDown']>>();\n onMouseEnter = output<SlickEventOutput<AngularSlickgridOutputs['onMouseEnter']>>();\n onMouseLeave = output<SlickEventOutput<AngularSlickgridOutputs['onMouseLeave']>>();\n onValidationError = output<SlickEventOutput<AngularSlickgridOutputs['onValidationError']>>();\n onViewportChanged = output<SlickEventOutput<AngularSlickgridOutputs['onViewportChanged']>>();\n onRendered = output<SlickEventOutput<AngularSlickgridOutputs['onRendered']>>();\n onSelectedRowsChanged = output<SlickEventOutput<AngularSlickgridOutputs['onSelectedRowsChanged']>>();\n onSetOptions = output<SlickEventOutput<AngularSlickgridOutputs['onSetOptions']>>();\n onScroll = output<SlickEventOutput<AngularSlickgridOutputs['onScroll']>>();\n onSort = output<SlickEventOutput<AngularSlickgridOutputs['onSort']>>();\n\n // DataView events\n onBeforePagingInfoChanged = output<SlickEventOutput<AngularSlickgridOutputs['onBeforePagingInfoChanged']>>();\n onGroupExpanded = output<SlickEventOutput<AngularSlickgridOutputs['onGroupExpanded']>>();\n onGroupCollapsed = output<SlickEventOutput<AngularSlickgridOutputs['onGroupCollapsed']>>();\n onPagingInfoChanged = output<SlickEventOutput<AngularSlickgridOutputs['onPagingInfoChanged']>>();\n onRowCountChanged = output<SlickEventOutput<AngularSlickgridOutputs['onRowCountChanged']>>();\n onRowsChanged = output<SlickEventOutput<AngularSlickgridOutputs['onRowsChanged']>>();\n onRowsOrCountChanged = output<SlickEventOutput<AngularSlickgridOutputs['onRowsOrCountChanged']>>();\n onSelectedRowIdsChanged = output<SlickEventOutput<AngularSlickgridOutputs['onSelectedRowIdsChanged']>>();\n onSetItemsCalled = output<SlickEventOutput<AngularSlickgridOutputs['onSetItemsCalled']>>();\n\n // other Slick Events\n onAfterMenuShow = output<SlickEventOutput<AngularSlickgridOutputs['onAfterMenuShow']>>();\n onBeforeMenuClose = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeMenuClose']>>();\n onBeforeMenuShow = output<SlickEventOutput<AngularSlickgridOutputs['onBeforeMenuShow']>>();\n onColumnsChanged = output<SlickEventOutput<AngularSlickgridOutputs['onColumnsChanged']>>();\n onCommand = output<SlickEventOutput<AngularSlickgridOutputs['onCommand']>>();\n onGridMenuColumnsChanged = output<SlickEventOutput<AngularSlickgridOutputs['onGridMenuColumnsChanged']>>();\n onMenuClose = output<SlickEventOutput<AngularSlickgridOutputs['onMenuClose']>>();\n onCopyCells = output<SlickEventOutput<AngularSlickgridOutputs['onCopyCells']>>();\n onCopyCancelled = output<SlickEventOutput<AngularSlickgridOutputs['onCopyCancelled']>>();\n onPasteCells = output<SlickEventOutput<AngularSlickgridOutputs['onPasteCells']>>();\n onBeforePasteCell = output<SlickEventOutput<AngularSlickgridOutputs['onBeforePasteCell']>>();\n\n // Slickgrid-Universal events\n onAfterExportToExcel = output<RegularEventOutput<AngularSlickgridOutputs['onAfterExportToExcel']>>();\n onBeforeExportToExcel = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeExportToExcel']>>();\n onBeforeFilterChange = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeFilterChange']>>();\n onBeforeFilterClear = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeFilterClear']>>();\n onBeforeSearchChange = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeSearchChange']>>();\n onBeforeSortChange = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeSortChange']>>();\n onContextMenuClearGrouping = output<RegularEventOutput<AngularSlickgridOutputs['onContextMenuClearGrouping']>>();\n onContextMenuCollapseAllGroups = output<RegularEventOutput<AngularSlickgridOutputs['onContextMenuCollapseAllGroups']>>();\n onContextMenuExpandAllGroups = output<RegularEventOutput<AngularSlickgridOutputs['onContextMenuExpandAllGroups']>>();\n onOptionSelected = output<RegularEventOutput<AngularSlickgridOutputs['onOptionSelected']>>();\n onColumnPickerColumnsChanged = output<RegularEventOutput<AngularSlickgridOutputs['onColumnPickerColumnsChanged']>>();\n onGridMenuMenuClose = output<RegularEventOutput<AngularSlickgridOutputs['onGridMenuMenuClose']>>();\n onGridMenuBeforeMenuShow = output<RegularEventOutput<AngularSlickgridOutputs['onGridMenuBeforeMenuShow']>>();\n onGridMenuAfterMenuShow = output<RegularEventOutput<AngularSlickgridOutputs['onGridMenuAfterMenuShow']>>();\n onGridMenuClearAllPinning = output<RegularEventOutput<AngularSlickgridOutputs['onGridMenuClearAllPinning']>>();\n onGridMenuClearAllFilters = output<RegularEventOutput<AngularSlickgridOutputs['onGridMenuClearAllFilters']>>();\n onGridMenuClearAllSorting = output<RegularEventOutput<AngularSlickgridOutputs['onGridMenuClearAllSorting']>>();\n onGridMenuCommand = output<RegularEventOutput<AngularSlickgridOutputs['onGridMenuCommand']>>();\n onHeaderButtonCommand = output<RegularEventOutput<AngularSlickgridOutputs['onHeaderButtonCommand']>>();\n onHeaderMenuCommand = output<RegularEventOutput<AngularSlickgridOutputs['onHeaderMenuCommand']>>();\n onHeaderMenuColumnResizeByContent = output<RegularEventOutput<AngularSlickgridOutputs['onHeaderMenuColumnResizeByContent']>>();\n onHeaderMenuBeforeMenuShow = output<RegularEventOutput<AngularSlickgridOutputs['onHeaderMenuBeforeMenuShow']>>();\n onHeaderMenuAfterMenuShow = output<RegularEventOutput<AngularSlickgridOutputs['onHeaderMenuAfterMenuShow']>>();\n onHideColumns = output<RegularEventOutput<AngularSlickgridOutputs['onHideColumns']>>();\n onItemsAdded = output<RegularEventOutput<AngularSlickgridOutputs['onItemsAdded']>>();\n onItemsDeleted = output<RegularEventOutput<AngularSlickgridOutputs['onItemsDeleted']>>();\n onItemsUpdated = output<RegularEventOutput<AngularSlickgridOutputs['onItemsUpdated']>>();\n onItemsUpserted = output<RegularEventOutput<AngularSlickgridOutputs['onItemsUpserted']>>();\n onFullResizeByContentRequested = output<RegularEventOutput<AngularSlickgridOutputs['onFullResizeByContentRequested']>>();\n onGridStateChanged = output<RegularEventOutput<AngularSlickgridOutputs['onGridStateChanged']>>();\n onBeforePaginationChange = output<RegularEventOutput<AngularSlickgridOutputs['onBeforePaginationChange']>>();\n onPaginationChanged = output<RegularEventOutput<AngularSlickgridOutputs['onPaginationChanged']>>();\n onPaginationRefreshed = output<RegularEventOutput<AngularSlickgridOutputs['onPaginationRefreshed']>>();\n onPaginationVisibilityChanged = output<RegularEventOutput<AngularSlickgridOutputs['onPaginationVisibilityChanged']>>();\n onPaginationSetCursorBased = output<RegularEventOutput<AngularSlickgridOutputs['onPaginationSetCursorBased']>>();\n onGridBeforeResize = output<RegularEventOutput<AngularSlickgridOutputs['onGridBeforeResize']>>();\n onGridAfterResize = output<RegularEventOutput<AngularSlickgridOutputs['onGridAfterResize']>>();\n onBeforeResizeByContent = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeResizeByContent']>>();\n onAfterResizeByContent = output<RegularEventOutput<AngularSlickgridOutputs['onAfterResizeByContent']>>();\n onSortCleared = output<RegularEventOutput<AngularSlickgridOutputs['onSortCleared']>>();\n onFilterChanged = output<RegularEventOutput<AngularSlickgridOutputs['onFilterChanged']>>();\n onFilterCleared = output<RegularEventOutput<AngularSlickgridOutputs['onFilterCleared']>>();\n onSortChanged = output<RegularEventOutput<AngularSlickgridOutputs['onSortChanged']>>();\n onTreeItemToggled = output<RegularEventOutput<AngularSlickgridOutputs['onTreeItemToggled']>>();\n onTreeFullToggleEnd = output<RegularEventOutput<AngularSlickgridOutputs['onTreeFullToggleEnd']>>();\n onTreeFullToggleStart = output<RegularEventOutput<AngularSlickgridOutputs['onTreeFullToggleStart']>>();\n\n // Angular-Slickgrid specific events\n onBeforeGridCreate = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeGridCreate']>>();\n onGridCreated = output<RegularEventOutput<AngularSlickgridOutputs['onGridCreated']>>();\n onDataviewCreated = output<RegularEventOutput<AngularSlickgridOutputs['onDataviewCreated']>>();\n onAngularGridCreated = output<RegularEventOutput<AngularSlickgridOutputs['onAngularGridCreated']>>();\n onBeforeGridDestroy = output<RegularEventOutput<AngularSlickgridOutputs['onBeforeGridDestroy']>>();\n onLanguageChange = output<RegularEventOutput<AngularSlickgridOutputs['onLanguageChange']>>();\n\n @Input()\n get dataset(): any[] {\n return (this.customDataView ? this.slickGrid?.getData?.() : this.dataView?.getItems()) || [];\n }\n set dataset(newDataset: any[]) {\n const prevDatasetLn = this._currentDatasetLength;\n const isDatasetEqual = dequal(newDataset, this._dataset || []);\n let data = newDataset;\n\n // when Tree Data is enabled and we don't yet have the hierarchical dataset filled, we can force a convert+sort of the array\n if (\n this.slickGrid &&\n this.options?.enableTreeData &&\n Array.isArray(newDataset) &&\n (newDataset.length > 0 || newDataset.length !== prevDatasetLn || !isDatasetEqual)\n ) {\n this._isDatasetHierarchicalInitialized = false;\n data = this.sortTreeDataset(newDataset, !isDatasetEqual); // if dataset changed, then force a refresh anyway\n }\n this._dataset = data;\n this.refreshGridData(data || []);\n this._currentDatasetLength = (newDataset || []).length;\n\n // expand/autofit columns on first page load\n // we can assume that if the prevDataset was empty then we are on first load\n if (this.slickGrid && this.options?.autoFitColumnsOnFirstLoad && prevDatasetLn === 0 && !this._isAutosizeColsCalled) {\n this.slickGrid.autosizeColumns();\n this._isAutosizeColsCalled = true;\n }\n this.suggestDateParsingWhenHelpful();\n }\n\n @Input()\n get datasetHierarchical(): any[] | undefined {\n return this.sharedService.hierarchicalDataset;\n }\n set datasetHierarchical(newHierarchicalDataset: any[] | undefined) {\n const isDatasetEqual = dequal(newHierarchicalDataset, this.sharedService?.hierarchicalDataset ?? []);\n const prevFlatDatasetLn = this._currentDatasetLength;\n this.sharedService.hierarchicalDataset = newHierarchicalDataset;\n\n if (newHierarchicalDataset && this.columns && this.filterService?.clearFilters) {\n this.filterService.clearFilters();\n }\n\n // when a hierarchical dataset is set afterward, we can reset the flat dataset and call a tree data sort that will overwrite the flat dataset\n if (newHierarchicalDataset && this.slickGrid && this.sortService?.processTreeDataInitialSort) {\n this.sortService.processTreeDataInitialSort();\n this.treeDataService.initHierarchicalTree();\n\n // we also need to reset/refresh the Tree Data filters because if we inserted new item(s) then it might not show up without doing this refresh\n // however we need to queue our process until the flat dataset is ready, so we can queue a microtask to execute the DataView refresh only after everything is ready\n queueMicrotask(() => {\n const flatDatasetLn = this.dataView.getItemCount();\n if (flatDatasetLn > 0 && (flatDatasetLn !== prevFlatDatasetLn || !isDatasetEqual)) {\n this.filterService.refreshTreeDataFilters();\n }\n });\n this._isDatasetHierarchicalInitialized = true;\n }\n }\n\n get elementRef(): ElementRef {\n return this.elm;\n }\n\n get backendService(): BackendService | undefined {\n return this.options?.backendServiceApi?.service;\n }\n\n get eventHandler(): SlickEventHandler {\n return this._eventHandler;\n }\n\n get gridContainerElement(): HTMLElement | null {\n return document.querySelector(`#${this.options.gridContainerId || ''}`);\n }\n\n /** GETTER to know if dataset was initialized or not */\n get isDatasetInitialized(): boolean {\n return this._isDatasetInitialized;\n }\n /** SETTER to change if dataset was initialized or not (stringly used for unit testing purposes) */\n set isDatasetInitialized(isInitialized: boolean) {\n this._isDatasetInitialized = isInitialized;\n }\n set isDatasetHierarchicalInitialized(isInitialized: boolean) {\n this._isDatasetHierarchicalInitialized = isInitialized;\n }\n\n get registeredResources(): Array<ExternalResource | ExternalResourceConstructor> {\n return this._registeredResources;\n }\n\n @ContentChild('slickgridHeader', { static: true }) slickgridHeader: TemplateRef<any> | null = null;\n @ContentChild('slickgridFooter', { static: true }) slickgridFooter: TemplateRef<any> | null = null;\n\n constructor(\n protected readonly angularUtilService: AngularUtilService,\n protected readonly appRef: ApplicationRef,\n protected readonly containerService: ContainerService,\n protected readonly elm: ElementRef,\n @Optional() protected readonly translate: TranslateService,\n @Optional() protected readonly translaterService: TranslaterService,\n @Optional() @Inject('defaultGridOption') protected forRootConfig?: GridOption,\n @Optional() @Inject('externalService') externalServices?: ExternalTestingDependencies\n ) {\n const slickgridConfig = new SlickgridConfig();\n\n // initialize and assign all Service Dependencies\n this._eventPubSubService = externalServices?.eventPubSubService ?? new EventPubSubService(this.elm.nativeElement);\n this._eventPubSubService.eventNamingStyle = 'camelCase';\n\n this.backendUtilityService = externalServices?.backendUtilityService ?? new BackendUtilityService();\n this.gridEventService = externalServices?.gridEventService ?? new GridEventService();\n this.sharedService = externalServices?.sharedService ?? new SharedService();\n this.collectionService = externalServices?.collectionService ?? new CollectionService(this.translaterService);\n // prettier-ignore\n this.extensionUtility = externalServices?.extensionUtility ?? new ExtensionUtility(this.sharedService, this.backendUtilityService, this.translaterService);\n this.filterFactory = new FilterFactory(slickgridConfig, this.translaterService, this.collectionService);\n // prettier-ignore\n this.filterService = externalServices?.filterService ?? new FilterService(this.filterFactory as any, this._eventPubSubService, this.sharedService, this.backendUtilityService);\n this.resizerService = externalServices?.resizerService ?? new ResizerService(this._eventPubSubService);\n // prettier-ignore\n this.sortService = externalServices?.sortService ?? new SortService(this.collectionService, this.sharedService, this._eventPubSubService, this.backendUtilityService);\n // prettier-ignore\n this.treeDataService = externalServices?.treeDataService ?? new TreeDataService(this._eventPubSubService, this.filterService, this.sharedService, this.sortService);\n // prettier-ignore\n this.paginationService = externalServices?.paginationService ?? new PaginationService(this._eventPubSubService, this.sharedService, this.backendUtilityService);\n\n this.extensionService =\n externalServices?.extensionService ??\n new ExtensionService(\n this.extensionUtility,\n this.filterService,\n this._eventPubSubService,\n this.sharedService,\n this.sortService,\n this.treeDataService,\n this.translaterService,\n () => this.gridService\n );\n\n // prettier-ignore\n /* v8 ignore next 8 */\n this.gridStateService = externalServices?.gridStateService ?? new GridStateService(\n this.extensionService,\n this.filterService,\n this._eventPubSubService,\n this.sharedService,\n this.sortService,\n this.treeDataService\n );\n\n // prettier-ignore\n /* v8 ignore next 9 */\n this.gridService = externalServices?.gridService ?? new GridService(\n this.gridStateService,\n this.filterService,\n this._eventPubSubService,\n this.paginationService,\n this.sharedService,\n this.sortService,\n this.treeDataService\n );\n this.headerGroupingService = externalServices?.headerGroupingService ?? new HeaderGroupingService(this.extensionUtility);\n\n this.serviceList = [\n this.containerService,\n this.extensionService,\n this.filterService,\n this.gridEventService,\n this.gridService,\n this.gridStateService,\n this.headerGroupingService,\n this.paginationService,\n this.resizerService,\n this.sortService,\n this.treeDataService,\n ];\n\n // register all Service instances in the container\n this.containerService.registerInstance('ExtensionUtility', this.extensionUtility);\n this.containerService.registerInstance('FilterService', this.filterService);\n this.containerService.registerInstance('CollectionService', this.collectionService);\n this.containerService.registerInstance('ExtensionService', this.extensionService);\n this.containerService.registerInstance('GridEventService', this.gridEventService);\n this.containerService.registerInstance('GridService', this.gridService);\n this.containerService.registerInstance('GridStateService', this.gridStateService);\n this.containerService.registerInstance('HeaderGroupingService', this.headerGroupingService);\n this.containerService.registerInstance('PaginationService', this.paginationService);\n this.containerService.registerInstance('ResizerService', this.resizerService);\n this.containerService.registerInstance('SharedService', this.sharedService);\n this.containerService.registerInstance('SortService', this.sortService);\n this.containerService.registerInstance('EventPubSubService', this._eventPubSubService);\n this.containerService.registerInstance('PubSubService', this._eventPubSubService);\n this.containerService.registerInstance('TranslaterService', this.translaterService);\n this.containerService.registerInstance('TreeDataService', this.treeDataService);\n }\n\n ngAfterViewInit() {\n if (!this.columns) {\n throw new Error(\n 'Using `<angular-slickgrid>` requires [columns], it seems that you might have forgot to provide the missing bindable input.'\n );\n }\n this.initialization(this._eventHandler);\n this._isGridInitialized = true;\n\n // recheck the empty warning message after grid is shown so that it works in every use case\n if (this.options?.enableEmptyDataWarningMessage && Array.isArray(this.dataset)) {\n const finalTotalCount = this.dataset.length;\n this.displayEmptyDataWarning(finalTotalCount < 1);\n }\n\n // add dark mode CSS class when enabled\n if (this.options.darkMode) {\n this.setDarkMode(true);\n }\n\n this.suggestDateParsingWhenHelpful();\n }\n\n ngOnDestroy(): void {\n this._eventPubSubService.publish('onBeforeGridDestroy', this.slickGrid);\n this.destroy();\n }\n\n destroy(shouldEmptyDomElementContainer = false) {\n // dispose of all Services\n this.serviceList.forEach((service: any) => {\n if (typeof service?.dispose === 'function') {\n service.dispose();\n }\n });\n this.serviceList.length = 0;\n this._eventPubSubService?.unsubscribeAll();\n\n // dispose backend service when defined and a dispose method exists\n this.backendService?.dispose?.();\n\n // dispose all registered external resources\n this.disposeExternalResources();\n\n // dispose the Components\n this.slickEmptyWarning?.dispose();\n this.slickFooter?.dispose();\n this.slickPagination?.dispose();\n\n if (this._eventHandler?.unsubscribeAll) {\n this._eventHandler.unsubscribeAll();\n }\n if (this.dataView) {\n this.dataView.setItems([]);\n this.dataView.destroy();\n }\n if (this.slickGrid?.destroy) {\n this.slickGrid.destroy(shouldEmptyDomElementContainer);\n }\n\n if (this.backendServiceApi) {\n for (const prop of Object.keys(this.backendServiceApi)) {\n delete this.backendServiceApi[prop as keyof BackendServiceApi];\n }\n this.backendServiceApi = undefined;\n }\n if (this.columns) {\n for (const prop of Object.keys(this.columns)) {\n (this.columns as any)[prop] = null;\n }\n }\n for (const prop of Object.keys(this.sharedService)) {\n (this.sharedService as any)[prop] = null;\n }\n\n // also unsubscribe all RxJS subscriptions\n this.subscriptions = unsubscribeAll(this.subscriptions);\n\n this._dataset = null;\n this.datasetHierarchical = undefined;\n this._columns = [];\n this._angularGridInstances = undefined;\n this.slickGrid = undefined as any;\n\n // we could optionally also empty the content of the grid container DOM element\n if (shouldEmptyDomElementContainer) {\n this.emptyGridContainerElm();\n }\n }\n\n disposeExternalResources() {\n if (Array.isArray(this._registeredResources)) {\n while (this._registeredResources.length > 0) {\n const res = this._registeredResources.pop();\n if (typeof (res as ExternalResource)?.dispose === 'function') {\n (res as ExternalResource).dispose!();\n }\n }\n }\n this._registeredResources = [];\n }\n\n emptyGridContainerElm() {\n const gridContainerId = this.options?.gridContainerId || 'grid1';\n const gridContainerElm = document.querySelector(`#${gridContainerId}`);\n emptyElement(gridContainerElm);\n }\n\n /**\n * Define our internal Post Process callback, it will execute internally after we get back result from the Process backend call\n * Currently ONLY available with the GraphQL Backend Service.\n * The behavior is to refresh the Dataset & Pagination without requiring the user to create his own PostProcess every time\n */\n createBackendApiInternalPostProcessCallback(gridOptions: GridOption) {\n const backendApi = gridOptions?.backendServiceApi;\n if (backendApi?.service) {\n const backendApiService = backendApi.service;\n\n // internalPostProcess only works (for now) with a GraphQL Service, so make sure it is of that type\n if (typeof backendApiService.getDatasetName === 'function') {\n backendApi.internalPostProcess = (processResult: any) => {\n // prettier-ignore\n const datasetName = backendApi && backendApiService && typeof backendApiService.getDatasetName === 'function' ? backendApiService.getDatasetName() : '';\n if (!Array.isArray(processResult) && processResult?.data[datasetName]) {\n const data =\n 'nodes' in processResult.data[datasetName]\n ? (processResult as any).data[datasetName].nodes\n : (processResult as any).data[datasetName];\n const totalCount =\n 'totalCount' in processResult.data[datasetName]\n ? (processResult as any).data[datasetName].totalCount\n : (processResult as any).data[datasetName].length;\n this.refreshGridData(data, totalCount || 0);\n }\n };\n }\n }\n }\n\n initialization(eventHandler: SlickEventHandler) {\n this.options.translater = this.translaterService;\n this._eventHandler = eventHandler;\n this._isAutosizeColsCalled = false;\n\n // when detecting a frozen grid, we'll automatically enable the mousewheel scroll handler so that we can scroll from both left/right frozen containers\n if (\n this.options &&\n ((this.options.frozenRow !== undefined && this.options.frozenRow >= 0) ||\n (this.options.frozenColumn !== undefined && this.options.frozenColumn >= 0)) &&\n this.options.enableMouseWheelScrollHandler === undefined\n ) {\n this.options.enableMouseWheelScrollHandler = true;\n }\n\n this._eventPubSubService.eventNamingStyle = this.options?.eventNamingStyle ?? 'camelCase';\n this._eventPubSubService.publish('onBeforeGridCreate', true);\n\n // make sure the dataset is initialized (if not it will throw an error that it cannot getLength of null)\n this._dataset ||= [];\n this.options = this.mergeGridOptions(this.options);\n this._paginationOptions = this.options?.pagination;\n this.locales = this.options?.locales ?? Constants.locales;\n this.backendServiceApi = this.options?.backendServiceApi;\n this._isLocalGrid = !this.backendServiceApi; // considered a local grid if it doesn't have a backend service set\n\n // unless specified, we'll create an internal postProcess callback (currently only availab