diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 79d78d7ec97..2e5bbf56b2a 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -2,6 +2,9 @@ "extends": "../tsconfig.json", "include": ["**/*.ts"], "compilerOptions": { + /* TODO: interim override — remove once cypress specs are migrated to strict */ + "strict": false, + "noImplicitOverride": true, "sourceMap": false, "types": ["cypress"] } diff --git a/package-lock.json b/package-lock.json index 288d89db75f..26ca1c74235 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,6 +55,7 @@ "@types/express": "^5.0.0", "@types/jasmine": "^5.1.7", "@types/jasminewd2": "^2.0.10", + "@types/lodash-es": "^4.17.12", "@types/node": "^20.17.6", "@types/sass-true": "^6.0.2", "@types/webpack-env": "^1.18.3", @@ -6811,6 +6812,23 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.24", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha1-SuM0/GLA6RXKjtjjXcxtTuspIV8=", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha1-ZfbR5fgFOap8+/yWLeXe8M9PNBs=", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", diff --git a/package.json b/package.json index e793aa920d9..255e11e49fd 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "@types/express": "^5.0.0", "@types/jasmine": "^5.1.7", "@types/jasminewd2": "^2.0.10", + "@types/lodash-es": "^4.17.12", "@types/node": "^20.17.6", "@types/sass-true": "^6.0.2", "@types/webpack-env": "^1.18.3", diff --git a/projects/igniteui-angular-elements/src/app/create-custom-element.ts b/projects/igniteui-angular-elements/src/app/create-custom-element.ts index e2788b3dd14..641b3e73e70 100644 --- a/projects/igniteui-angular-elements/src/app/create-custom-element.ts +++ b/projects/igniteui-angular-elements/src/app/create-custom-element.ts @@ -20,7 +20,7 @@ export function createIgxCustomElement(component: Type, config: IgxNgEleme const componentConfig = config.registerConfig?.find(x => x.component === component); - for (const method of componentConfig?.methods) { + for (const method of componentConfig?.methods!) { elementCtor.prototype[method] = function() { const instance = this.ngElementStrategy.componentRef.instance; return this.ngElementStrategy.runInZone(() => instance[method].apply(instance, arguments)); @@ -29,7 +29,7 @@ export function createIgxCustomElement(component: Type, config: IgxNgEleme // Reuse `createCustomElement`'s approach for Inputs, should work for any prop too: componentConfig?.additionalProperties.forEach((p) => { - let set: (v: any) => void | undefined; + let set!: (v: any) => void | undefined; if (p.name in elementCtor.prototype) { @@ -38,7 +38,7 @@ export function createIgxCustomElement(component: Type, config: IgxNgEleme } if (p.writable) { - set = function (newValue) { + set = function (this: any, newValue: any) { this.ngElementStrategy.setInputValue(p.name, newValue); } } @@ -111,7 +111,7 @@ function guardAttributeNames(strategyFactory: IgxCustomNgElementStrategyFacto // getComponentDef not public, also technically readonly map // the key is the non-minified (template) name - const inputs = reflectComponentType((strategyFactory as any).component).inputs; + const inputs = reflectComponentType((strategyFactory as any).component)!.inputs; inputs.forEach((input) => { const key = input.templateName; @@ -123,7 +123,7 @@ function guardAttributeNames(strategyFactory: IgxCustomNgElementStrategyFacto // const newKey = key.replace(/(?<=[A-Z])[A-Z]+(?![a-z])/g, char => char.toLowerCase()); // no Lookbehind assertion in Safari yet const newKey = key.replace(/([A-Z])([A-Z]+)(?![a-z])/g, (match, p1, p2) => p1 + p2.toLowerCase()); - inputs[newKey] = input; + (inputs as any)[newKey] = input; // TODO: consider deleting the original key } }); diff --git a/projects/igniteui-angular-elements/src/app/custom-strategy.ts b/projects/igniteui-angular-elements/src/app/custom-strategy.ts index eccfb56eb63..d4754a47300 100644 --- a/projects/igniteui-angular-elements/src/app/custom-strategy.ts +++ b/projects/igniteui-angular-elements/src/app/custom-strategy.ts @@ -13,7 +13,7 @@ const SCHEDULE_DELAY = 10; /** @hidden @internal */ export abstract class IgcNgElement extends NgElement { - public override readonly ngElementStrategy: IgxCustomNgElementStrategy; + public override readonly ngElementStrategy!: IgxCustomNgElementStrategy; } /** @@ -23,14 +23,14 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { // public override componentRef: ComponentRef|null = null; - protected element: IgcNgElement; + protected element!: IgcNgElement; /** The parent _component_'s element (a.k.a the semantic parent, rather than the DOM one after projection) */ protected parentElement?: WeakRef; /** Native Angular parent (if any) the Element is created under, usually as template of dynamic component (e.g. HGrid row island paginator) */ - protected angularParent: ComponentRef; + protected angularParent!: ComponentRef; /** Cached child instances per query prop. Used for dynamic components's child templates that normally persist in Angular runtime */ protected cachedChildComponents: Map[]> = new Map(); - private setComponentRef: (value: ComponentRef) => void; + private setComponentRef!: (value: ComponentRef) => void; /** The maximum depth at which event arguments are processed and angular components wrapped with Proxies, that handle template set */ private maxEventProxyDepth = 3; @@ -43,7 +43,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { */ public [ComponentRefKey] = new Promise>((resolve, _) => this.setComponentRef = resolve); - private _templateWrapperRef: ComponentRef; + private _templateWrapperRef!: ComponentRef; protected get templateWrapper(): TemplateWrapperComponent { if (!this._templateWrapperRef) { const componentRef = (this as any).componentRef as ComponentRef; @@ -53,7 +53,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { return this._templateWrapperRef.instance; } - private _configSelectors: string; + private _configSelectors!: string; public get configSelectors(): string { if (!this._configSelectors) { this._configSelectors = this.config.map(x => x.selector).join(','); @@ -82,7 +82,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { // set componentRef to non-null to prevent DOM moves from re-initializing // TODO: Fail handling or cancellation needed? (this as any).componentRef = {}; - const ngContentSelectors = [...reflectComponentType(this._component).ngContentSelectors]; + const ngContentSelectors = [...reflectComponentType(this._component)!.ngContentSelectors]; const contentChildrenTags = Array.from(element.children) .filter(x => ngContentSelectors.some(sel => x.matches(sel))) .map(x => x.tagName.toLocaleLowerCase()); @@ -91,22 +91,22 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { // for (const iterator of toBeOrphanedChildren) { // // TODO: special registration OR config for custom // } - let parentInjector: Injector; - let parentAnchor: ViewContainerRef; + let parentInjector!: Injector; + let parentAnchor!: ViewContainerRef; const parents: WeakRef[] = []; const componentConfig = this.config?.find(x => x.component === this._component); const configParents = componentConfig?.parents .map(parentType => this.config.find(x => x.component === parentType)) - .filter(x => x.selector); + .filter(x => x!.selector); if (configParents?.length) { let node = element as IgcNgElement; while (node?.parentElement) { node = node.parentElement.closest(configParents.flatMap(x => [ - x.selector, - reflectComponentType(x.component).selector - ]).join(',')); + x!.selector, + reflectComponentType(x!.component)!.selector + ]).join(','))!; if (node) { parents.push(new WeakRef(node)); } @@ -115,7 +115,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { let parent = parents[0]?.deref(); // Collected parents may include direct Angular HGrids, so only wait for configured parent elements: - const configParent = configParents.find(x => x.selector === parent?.tagName.toLocaleLowerCase()); + const configParent = configParents.find(x => x!.selector === parent?.tagName.toLocaleLowerCase()); if (configParent && !customElements.get(configParent.selector)) { await customElements.whenDefined(configParent.selector); } @@ -178,7 +178,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { // check if there are any content children associated with a content query collection. // if no, then just emit the event, otherwise we wait for the collection to be updated in updateQuery. const contentChildrenTypes = this.config.filter(x => contentChildrenTags.indexOf(x.selector) !== -1).map(x => x.provideAs ?? x.component); - const contentQueryChildrenCollection = componentConfig.contentQueries.filter(x => contentChildrenTypes.includes(x.childType)); + const contentQueryChildrenCollection = componentConfig!.contentQueries.filter(x => contentChildrenTypes.includes(x.childType)); if (contentQueryChildrenCollection.length === 0) { // no content children, emit event immediately, since there's nothing to be attached. (this as any).componentRef?.instance?.childrenResolved?.emit(); @@ -186,13 +186,13 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { if (parentAnchor && parentInjector) { // attempt to attach the newly created ViewRef to the parents's instead of the App global - const parentViewRef = parentInjector.get(ViewContainerRef); + // const parentViewRef = parentInjector.get(ViewContainerRef); // preserve original position in DOM (in case of projection, e.g. grid pager): const domParent = element.parentElement; const nextSibling = element.nextSibling; parentAnchor.insert((this as any).componentRef.hostView); //bad, moves in DOM, AND need to be in inner anchor :S //restore original DOM position - domParent.insertBefore(element, nextSibling); + domParent!.insertBefore(element, nextSibling); (this as any).componentRef.hostView.detectChanges(); } else if (!parentAnchor) { (this as any).appRef.attachView((this as any).componentRef.hostView); @@ -205,7 +205,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { // componentRef should also likely be protected: const componentRef = (this as any).componentRef as ComponentRef; - const parentQueries = this.getParentContentQueries(componentConfig, parents, configParents); + const parentQueries = this.getParentContentQueries(componentConfig!, parents as any, configParents as any); for (const { parent, query } of parentQueries) { if (query.isQueryList) { @@ -230,11 +230,11 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { componentRef.onDestroy(() => { if (this._templateWrapperRef) { this._templateWrapperRef.destroy(); - this._templateWrapperRef = null; + this._templateWrapperRef = null!; } // also schedule query updates on all parents: - this.getParentContentQueries(componentConfig, parents, configParents) + this.getParentContentQueries(componentConfig!, parents as any, configParents as any) .filter(x => x.parent?.isConnected && x.query.isQueryList) .forEach(({ parent, query }) => { parent.ngElementStrategy.scheduleQueryUpdate(query.property); @@ -289,7 +289,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { } // TODO(D.P.): Check API use and expose needed props to avoid unwrap OR handle component ref props w/ config - if (componentConfig.selector === 'igc-pivot-data-selector' && property === 'grid' && value) { + if (componentConfig!.selector === 'igc-pivot-data-selector' && property === 'grid' && value) { value = value.ngElementStrategy?.componentRef?.instance || value; } super.setInputValue(property, value); @@ -316,7 +316,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { */ public scheduleQueryUpdate(queryName: string) { if (this.schedule.has(queryName)) { - this.schedule.get(queryName)(); + this.schedule.get(queryName)!(); } const id = setTimeout(() => this.updateQuery(queryName), SCHEDULE_DELAY); @@ -328,8 +328,8 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { const componentRef = (this as any).componentRef as ComponentRef; if (componentRef) { const componentConfig = this.config?.find(x => x.component === this._component); - const query = componentConfig.contentQueries.find(x => x.property === queryName); - const children = this.runQueryInDOM(this.element, query); + const query = componentConfig!.contentQueries.find(x => x.property === queryName); + const children = this.runQueryInDOM(this.element, query!); let childRefs = []; for (const child of children) { // D.P. Use sync componentRef to avoid having this being stuck waiting while another update is queued @@ -342,10 +342,10 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { childRefs.push(childRef.instance); } } - if (query.descendants && this.cachedChildComponents.has(queryName)) { - childRefs = [...this.cachedChildComponents.get(queryName), ...childRefs]; + if (query!.descendants && this.cachedChildComponents.has(queryName)) { + childRefs = [...this.cachedChildComponents.get(queryName)!, ...childRefs]; } - const list = (this as any).componentRef.instance[query.property] as QueryList; + const list = (this as any).componentRef.instance[query!.property] as QueryList; list.reset(childRefs); list.notifyOnChanges(); } @@ -369,7 +369,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { const parents = new Set(childConfigs.map(x => x.parents).flat()); const parentSelectors = this.config.filter(x => parents.has(x.component)).map(x => x.selector).filter(x => x).join(','); - children = children.filter(x => x.parentElement.closest(parentSelectors) === element); + children = children.filter(x => x.parentElement!.closest(parentSelectors) === element); } return children; } @@ -408,7 +408,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { if (i > 0 && !query.descendants) { continue; } - queries.push({ parent, query }); + queries.push({ parent: parent!, query }); } } @@ -441,7 +441,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { } }); - fromEvent(this.element, 'igcOpened').pipe(takeUntil(componentRef.instance.destroy$)).subscribe((e: CustomEvent) => { + fromEvent(this.element, 'igcOpened').pipe(takeUntil(componentRef.instance.destroy$)).subscribe(e => { if (!Object.keys(e.detail).length) { // toggle directive-based components emit void details // TODO: need better flag @@ -462,7 +462,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { //#region Handle event args that return reference to components, since they return angular ref and not custom elements. /** Sets up listeners for the component's outputs so that the events stream emits the events. */ protected override initializeOutputs(componentRef: ComponentRef): void { - const eventEmitters: Observable[] = reflectComponentType(this._component).outputs.map( + const eventEmitters: Observable[] = reflectComponentType(this._component)!.outputs.map( ({ propName, templateName }) => { const emitter: EventEmitter = componentRef.instance[propName]; return emitter.pipe(map((value: any) => ({ name: templateName, value: this.patchOutputComponents(propName, value) }))); @@ -530,7 +530,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy { return new Proxy(component, { set(target: any, prop: string, newValue: any) { // For now handle only template props - if (config.templateProps.includes(prop)) { + if (config.templateProps!.includes(prop)) { const oldRef = target[prop]; const oldValue = oldRef && parentThis.templateWrapper.getTemplateFunction(oldRef); if (oldValue === newValue) { diff --git a/projects/igniteui-angular-elements/src/app/wrapper/template-ref-wrapper.ts b/projects/igniteui-angular-elements/src/app/wrapper/template-ref-wrapper.ts index 9638d2dc66b..722cc996161 100644 --- a/projects/igniteui-angular-elements/src/app/wrapper/template-ref-wrapper.ts +++ b/projects/igniteui-angular-elements/src/app/wrapper/template-ref-wrapper.ts @@ -106,7 +106,7 @@ export class TemplateRefWrapper extends TemplateRef { /** @internal */ class TemplateRefWrapperContentContext { - public _id: string; + public _id!: string; public root: any; public templateFunction: any; } diff --git a/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts b/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts index 34579c99771..afca74cb048 100644 --- a/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts +++ b/projects/igniteui-angular-elements/src/app/wrapper/wrapper.component.ts @@ -27,7 +27,7 @@ export class TemplateWrapperComponent { * (internally creates one like the old `>; + public templateRefs!: QueryList>; protected litRender(container: HTMLElement, templateFunc: (arg: any) => TemplateResult, arg: any) { const part = render(templateFunc(arg), container); @@ -68,7 +68,7 @@ export class TemplateWrapperComponent { */ protected embeddedViewDestroyCallback = (container: HTMLElement) => { if (container && this.childParts.has(container)) { - this.childParts.get(container).setConnected(false); + this.childParts.get(container)!.setConnected(false); this.childParts.delete(container); } } diff --git a/projects/igniteui-angular-elements/src/lib/grids/grid.component.ts b/projects/igniteui-angular-elements/src/lib/grids/grid.component.ts index 9bac9cee831..b387067c400 100644 --- a/projects/igniteui-angular-elements/src/lib/grids/grid.component.ts +++ b/projects/igniteui-angular-elements/src/lib/grids/grid.component.ts @@ -158,7 +158,7 @@ export class IgxGridComponent extends IgxGrid { /* blazorCollectionItemName: ActionStrip */ /* ngQueryListName: actionStripComponents */ @ContentChildren(IgxActionStripToken) - protected override actionStripComponents: QueryList; + protected override actionStripComponents!: QueryList; protected override autogenerateColumns() { super.autogenerateColumns(); diff --git a/projects/igniteui-angular-elements/src/lib/grids/hierarchical-grid.component.ts b/projects/igniteui-angular-elements/src/lib/grids/hierarchical-grid.component.ts index 2084b219b0a..493ba302ce0 100644 --- a/projects/igniteui-angular-elements/src/lib/grids/hierarchical-grid.component.ts +++ b/projects/igniteui-angular-elements/src/lib/grids/hierarchical-grid.component.ts @@ -48,7 +48,7 @@ export class IgxChildGridRowComponent extends IgxChildGridRow { /** * @hidden */ - public override hGrid: IgxHierarchicalGridComponent; + public override hGrid!: IgxHierarchicalGridComponent; /** * @hidden @@ -57,7 +57,7 @@ export class IgxChildGridRowComponent extends IgxChildGridRow { const ref = this.container.createComponent(IgxHierarchicalGridComponent, { injector: this.container.injector }); this.hGrid = ref.instance; this.hGrid.setDataInternal(this.data.childGridsData[this.layout.key]); - this.hGrid.nativeElement["__componentRef"] = ref; + (this.hGrid.nativeElement as any)["__componentRef"] = ref; this.layout.layoutChange.subscribe((ch) => { this._handleLayoutChanges(ch); }); @@ -83,21 +83,21 @@ export class IgxChildGridRowComponent extends IgxChildGridRow { // use wc type so that it includes elements specific events: childrenResolved, columnsAutogenerated, etc. const mirror = reflectComponentType(IgxHierarchicalGridComponent); // exclude outputs related to two-way binding functionality - const inputNames = mirror.inputs.map(input => input.propName); - const outputs = mirror.outputs.filter(o => { + const inputNames = mirror!.inputs.map(input => input.propName); + const outputs = mirror!.outputs.filter(o => { const matchingInputPropName = o.propName.slice(0, o.propName.indexOf('Change')); return inputNames.indexOf(matchingInputPropName) === -1; }); // TODO: Skip the `rendered` output. Rendered should be called once per grid. outputs.filter(o => o.propName !== 'rendered').forEach(output => { - if (this.hGrid[output.propName]) { - this.hGrid[output.propName].pipe(destructor).subscribe((args) => { + if ((this.hGrid as any)[output.propName]) { + (this.hGrid as any)[output.propName].pipe(destructor).subscribe((args: any) => { if (!args) { args = {}; } args.owner = this.hGrid; - this.layout[output.propName].emit(args); + (this.layout as any)[output.propName].emit(args); }); } }); @@ -199,7 +199,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGrid { * @hidden */ @ViewChildren(IgxChildGridRowComponent) - public override hierarchicalRows: QueryList; + public override hierarchicalRows!: QueryList; /** * @hidden @@ -211,13 +211,13 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGrid { /* blazorCollectionName: RowIslandCollection */ /* ngQueryListName: childLayoutList */ @ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: false }) - public override childLayoutList: QueryList; + public override childLayoutList!: QueryList; /** * @hidden */ @ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: true }) - public override allLayoutList: QueryList; + public override allLayoutList!: QueryList; @Output() public columnsAutogenerated = new EventEmitter(); @@ -236,7 +236,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGrid { /* blazorCollectionItemName: ActionStrip */ /* ngQueryListName: actionStripComponents */ @ContentChildren(IgxActionStripToken) - protected override actionStripComponents: QueryList; + protected override actionStripComponents!: QueryList; protected override autogenerateColumns() { super.autogenerateColumns(); diff --git a/projects/igniteui-angular-elements/src/lib/grids/row-island.component.ts b/projects/igniteui-angular-elements/src/lib/grids/row-island.component.ts index 3ceb6ddeb1e..0b9d752e8b7 100644 --- a/projects/igniteui-angular-elements/src/lib/grids/row-island.component.ts +++ b/projects/igniteui-angular-elements/src/lib/grids/row-island.component.ts @@ -48,7 +48,7 @@ export class IgxRowIslandComponent extends IgxRowIsland { * @hidden @internal */ @ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: false }) - public override childLayoutList: QueryList; + public override childLayoutList!: QueryList; /** * @hidden @@ -68,7 +68,7 @@ export class IgxRowIslandComponent extends IgxRowIsland { /* blazorCollectionItemName: ActionStrip */ /* ngQueryListName: actionStripComponents */ @ContentChildren(IgxActionStripToken, { read: IgxActionStripToken, descendants: false }) - protected override actionStripComponents: QueryList; + protected override actionStripComponents!: QueryList; protected override autogenerateColumns() { super.autogenerateColumns(); diff --git a/projects/igniteui-angular-elements/src/lib/grids/tree-grid.component.ts b/projects/igniteui-angular-elements/src/lib/grids/tree-grid.component.ts index fb112d8a170..8ae3b31ee33 100644 --- a/projects/igniteui-angular-elements/src/lib/grids/tree-grid.component.ts +++ b/projects/igniteui-angular-elements/src/lib/grids/tree-grid.component.ts @@ -155,7 +155,7 @@ export class IgxTreeGridComponent extends IgxTreeGrid { /* blazorCollectionItemName: ActionStrip */ /* ngQueryListName: actionStripComponents */ @ContentChildren(IgxActionStripToken) - protected override actionStripComponents: QueryList; + protected override actionStripComponents!: QueryList; protected override autogenerateColumns() { super.autogenerateColumns(); diff --git a/projects/igniteui-angular-elements/src/lib/icon.broadcast.service.ts b/projects/igniteui-angular-elements/src/lib/icon.broadcast.service.ts index 13918574976..27e873d9666 100644 --- a/projects/igniteui-angular-elements/src/lib/icon.broadcast.service.ts +++ b/projects/igniteui-angular-elements/src/lib/icon.broadcast.service.ts @@ -28,7 +28,7 @@ export class IgxIconBroadcastService { protected _iconService = inject(IgxIconService); private _platformUtil = inject(PlatformUtil, { optional: true }); - private iconBroadcastChannel: BroadcastChannel | null; + private iconBroadcastChannel!: BroadcastChannel | null; constructor() { if (this._platformUtil?.isBrowser) { @@ -43,11 +43,11 @@ export class IgxIconBroadcastService { const { actionType, collections, references } = data; if (actionType === ActionType.SyncState || ActionType.RegisterIcon) { - this.updateIconsFromCollection(collections); + this.updateIconsFromCollection(collections!); } if (actionType === ActionType.SyncState || ActionType.UpdateIconReference) { - this.updateRefsFromCollection(references); + this.updateRefsFromCollection(references!); } } @@ -76,8 +76,8 @@ export class IgxIconBroadcastService { const collectionKeys = collections.keys(); for (const collectionKey of collectionKeys) { const collection = collections.get(collectionKey); - for (const iconKey of collection.keys()) { - const value = collection.get(iconKey).svg; + for (const iconKey of collection!.keys()) { + const value = collection!.get(iconKey)!.svg; this._iconService.addSvgIconFromText(iconKey, value, collectionKey); } } @@ -88,9 +88,9 @@ export class IgxIconBroadcastService { const collectionKeys = collections.keys(); for (const collectionKey of collectionKeys) { const collection = collections.get(collectionKey); - for (const iconKey of collection.keys()) { - const collectionName = collection.get(iconKey).collection; - const iconName = collection.get(iconKey).name; + for (const iconKey of collection!.keys()) { + const collectionName = collection!.get(iconKey).collection; + const iconName = collection!.get(iconKey).name; this._iconService.setIconRef(iconKey, 'default', { family: collectionName, name: iconName diff --git a/projects/igniteui-angular-elements/src/lib/state.component.ts b/projects/igniteui-angular-elements/src/lib/state.component.ts index a1bb26414a6..95aca8d0139 100644 --- a/projects/igniteui-angular-elements/src/lib/state.component.ts +++ b/projects/igniteui-angular-elements/src/lib/state.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Output, inject, ChangeDetectionStrategy } from '@angular/core'; -import { IFilteringExpressionsTree, IGroupingState, IPagingState, ISortingExpression } from 'igniteui-angular/core'; -import { GridFeatures, GridSelectionRange, GridType, IColumnState, IGridStateCollection, IGX_GRID_BASE, IgxGridStateBaseDirective, IPinningConfig, IPivotConfiguration } from 'igniteui-angular/grids/core'; +import { GridSelectionRange, IFilteringExpressionsTree, IGroupingState, IPagingState, ISortingExpression } from 'igniteui-angular/core'; +import { GridFeatures, GridType, IColumnState, IGridStateCollection, IGX_GRID_BASE, IgxGridStateBaseDirective, IPinningConfig, IPivotConfiguration } from 'igniteui-angular/grids/core'; /* tsPlainInterface */ /* marshalByValue */ @@ -54,7 +54,7 @@ export class IgxGridStateComponent extends IgxGridStateBaseDirective { */ public applyState(state: IGridStateInfo , features: GridFeatures | GridFeatures[] = []) { if (features.length === 0) { - features = null; + features = null!; } super.setStateInternal(state, features); } @@ -66,7 +66,7 @@ export class IgxGridStateComponent extends IgxGridStateBaseDirective { */ public applyStateFromString(state: string, features: GridFeatures | GridFeatures[] = []) { if (features.length === 0) { - features = null; + features = null!; } const gridState = JSON.parse(state) as IGridStateInfo; this.stateParsed.emit(gridState); @@ -83,7 +83,7 @@ export class IgxGridStateComponent extends IgxGridStateBaseDirective { /** Due to return type in getState being union type and having no support for union type in the translators * hiding getState in favor of a simpler extractState method that omits the serialize property and always returns just a string. */ if (features.length === 0) { - features = null; + features = null!; } return super.getStateInternal(false, features) as IGridStateInfo; } @@ -96,7 +96,7 @@ export class IgxGridStateComponent extends IgxGridStateBaseDirective { */ public getStateAsString(features: GridFeatures | GridFeatures[] = []): string { if (features.length === 0) { - features = null; + features = null!; } return super.getStateInternal(true, features) as string; } diff --git a/projects/igniteui-angular-elements/src/polyfills.ts b/projects/igniteui-angular-elements/src/polyfills.ts index 241d7730098..fa9a0b5e9b5 100644 --- a/projects/igniteui-angular-elements/src/polyfills.ts +++ b/projects/igniteui-angular-elements/src/polyfills.ts @@ -59,8 +59,8 @@ import "./app/ssr-shim"; * ~~ Who monkey-patches the monkey-patchers? ~~ */ Zone && Zone.__load_patch('abortSignal_patchEventTarget', (global: Window, Zone: ZoneType, api: _ZonePrivate) => { - const EVENT_TARGET = global['EventTarget']?.prototype; - const ADD_EVENT_LISTENER = api.getGlobalObjects().ADD_EVENT_LISTENER_STR; + const EVENT_TARGET = (global as any)['EventTarget']?.prototype; + const ADD_EVENT_LISTENER = api.getGlobalObjects()!.ADD_EVENT_LISTENER_STR; const originalDelegateName = api.symbol(ADD_EVENT_LISTENER); const newDelegateName = api.symbol(`${ADD_EVENT_LISTENER}__ig_patch`); diff --git a/projects/igniteui-angular-elements/src/public_api.ts b/projects/igniteui-angular-elements/src/public_api.ts index cd99ef84f04..d0fdcb37cae 100644 --- a/projects/igniteui-angular-elements/src/public_api.ts +++ b/projects/igniteui-angular-elements/src/public_api.ts @@ -1,6 +1,6 @@ import { registerI18n, setCurrentI18n } from 'igniteui-i18n-core'; -import { ByLevelTreeGridMergeStrategy, ColumnPinningPosition, DefaultMergeStrategy, DefaultTreeGridMergeStrategy, FilteringExpressionsTree, FilteringExpressionsTreeType, FilteringLogic, HorizontalAlignment, IgxBooleanFilteringOperand, IgxDateFilteringOperand, IgxDateTimeFilteringOperand, IgxFilteringOperand, IgxNumberFilteringOperand, IgxStringFilteringOperand, IgxTimeFilteringOperand, NoopFilteringStrategy, NoopSortingStrategy, SortingDirection, TransactionType, TransactionEventOrigin, VerticalAlignment } from 'igniteui-angular/core'; -import { CsvFileTypes, DropPosition, GridPagingMode, IgxCsvExporterOptions, IgxDateSummaryOperand, IgxExcelExporterOptions, IgxNumberSummaryOperand, IgxPivotAggregate, IgxPivotDateAggregate, IgxPivotDateDimension, IgxPivotNumericAggregate, IgxPivotTimeAggregate, IgxSummaryOperand, IgxTimeSummaryOperand, NoopPivotDimensionsStrategy, PivotDimensionType, RowPinningPosition } from 'igniteui-angular/grids/core'; +import { ByLevelTreeGridMergeStrategy, ColumnPinningPosition, DefaultMergeStrategy, DefaultTreeGridMergeStrategy, FilteringExpressionsTree, FilteringExpressionsTreeType, FilteringLogic, HorizontalAlignment, IgxBooleanFilteringOperand, IgxDateFilteringOperand, IgxDateTimeFilteringOperand, IgxFilteringOperand, IgxNumberFilteringOperand, IgxStringFilteringOperand, IgxTimeFilteringOperand, NoopFilteringStrategy, NoopSortingStrategy, SortingDirection, TransactionType, TransactionEventOrigin, VerticalAlignment, IgxSummaryOperand, IgxDateSummaryOperand, IgxNumberSummaryOperand, IgxTimeSummaryOperand } from 'igniteui-angular/core'; +import { CsvFileTypes, DropPosition, GridPagingMode, IgxCsvExporterOptions, IgxExcelExporterOptions, IgxPivotAggregate, IgxPivotDateAggregate, IgxPivotDateDimension, IgxPivotNumericAggregate, IgxPivotTimeAggregate, NoopPivotDimensionsStrategy, PivotDimensionType, RowPinningPosition } from 'igniteui-angular/grids/core'; import { IgcExcelExporterService } from './lib/excel-exporter'; import { IgcCsvExporterService } from './lib/csv-exporter'; diff --git a/projects/igniteui-angular-elements/src/utils/injector-ref.ts b/projects/igniteui-angular-elements/src/utils/injector-ref.ts index 388a1396813..2beb90b3f43 100644 --- a/projects/igniteui-angular-elements/src/utils/injector-ref.ts +++ b/projects/igniteui-angular-elements/src/utils/injector-ref.ts @@ -31,7 +31,7 @@ const injector = createEnvironmentInjector([ // Still no "direct" public API but at least `ɵprovideZonelessChangeDetectionInternal` exports it somewhat: // https://github.com/angular/angular/commit/45fed3d2011bf6feffa8ee1365a5c88d603f826c#diff-10544e5a7c018dbc5dc5a1d4192919bb839c5d1b7cbcc1b20f57aa74c2ae7febR391-R397 - ɵprovideZonelessChangeDetectionInternal().find((entity) => (entity as ClassProvider).provide === ɵChangeDetectionScheduler), + ɵprovideZonelessChangeDetectionInternal!().find((entity) => (entity as ClassProvider).provide === ɵChangeDetectionScheduler)!, importProvidersFrom(BrowserModule), // Elements specific: provideAnimations(), diff --git a/projects/igniteui-angular-elements/tsconfig.spec.json b/projects/igniteui-angular-elements/tsconfig.spec.json index 21c54a6ea6e..f0adaf74c74 100644 --- a/projects/igniteui-angular-elements/tsconfig.spec.json +++ b/projects/igniteui-angular-elements/tsconfig.spec.json @@ -2,6 +2,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + /* TODO: interim override — remove once spec files are migrated to strict */ + "strict": false, + "noImplicitOverride": true, "allowJs": true, "outDir": "../../out-tsc/spec", "types": ["jasmine"] diff --git a/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.html b/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.html index 998665e53ae..abd35b0f666 100644 --- a/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.html +++ b/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.html @@ -35,7 +35,7 @@ @if (chart.startsWith(chartType)) { -
+
} diff --git a/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.ts b/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.ts index 2ed805da023..906f1fd8036 100644 --- a/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.ts +++ b/projects/igniteui-angular-extras/src/lib/context-menu/chart-dialog/chart-dialog.component.ts @@ -31,7 +31,7 @@ import { SvgPipe } from '../../pipes/svg.pipe'; }) export class IgxChartMenuComponent implements AfterViewInit, OnDestroy { - @ViewChild('chartArea', { read: ViewContainerRef }) public chartArea: ViewContainerRef; + @ViewChild('chartArea', { read: ViewContainerRef }) public chartArea!: ViewContainerRef; @Output() public closed = new EventEmitter(); @@ -53,17 +53,17 @@ export class IgxChartMenuComponent implements AfterViewInit, OnDestroy { } public chartDialogResizeNotify = new Subject(); - private contentObserver: ResizeObserver; + private contentObserver!: ResizeObserver; public images; - public chartDirective; - public currentChartType; - public title; - public allCharts = []; + public chartDirective: any; + public currentChartType: any; + public title: any; + public allCharts: any[] = []; public fullScreen = false; public isConfigAreaExpanded = false; public mainChartTypes = ['Column', 'Area', 'Bar', 'Line', 'Scatter', 'Pie']; - private _width; - private _height; + private _width: any; + private _height: any; private element = inject(ElementRef); constructor() { @@ -90,11 +90,11 @@ export class IgxChartMenuComponent implements AfterViewInit, OnDestroy { this.fullScreen = !this.fullScreen; } - public hasAvailableChart(chartType) { + public hasAvailableChart(chartType: any) { return this.allCharts.some(c => c.includes(chartType)); } - public createChart(chartType) { + public createChart(chartType: any) { if (!chartType || !this.chartDirective || !this.chartArea) { return; } diff --git a/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.html b/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.html index f0334bff4c2..b8f22151494 100644 --- a/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.html +++ b/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.html @@ -17,7 +17,7 @@ -
+
{{condition.replace('10', '10%')}} @@ -46,7 +46,7 @@ - + {{chart}} diff --git a/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.ts b/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.ts index c57c9ae1395..c4e4d128385 100644 --- a/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.ts +++ b/projects/igniteui-angular-extras/src/lib/context-menu/context-menu.component.ts @@ -54,49 +54,49 @@ import { CHART_TYPE } from '../directives/chart-integration/chart-types'; schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class IgxContextMenuComponent implements AfterViewInit, OnDestroy { - @ViewChild('analyticsBtn') public button: ElementRef; - @ViewChild('tabsMenu', { read: IgxToggleDirective }) public tabsMenu: IgxToggleDirective; - @ViewChild('chartPreview', { read: ViewContainerRef }) public chartPreview: ViewContainerRef; - @ViewChild('chartPreviewDialog', { read: IgxToggleDirective }) public chartPreviewDialog: IgxToggleDirective; - @ViewChild(IgxTabsComponent) public tabs: IgxTabsComponent; - - public contextDirective: IgxContextMenuDirective; - public chartTypes = []; - public textFormatters = []; - public currentChartType; - public currentFormatter; + @ViewChild('analyticsBtn') public button!: ElementRef; + @ViewChild('tabsMenu', { read: IgxToggleDirective }) public tabsMenu!: IgxToggleDirective; + @ViewChild('chartPreview', { read: ViewContainerRef }) public chartPreview!: ViewContainerRef; + @ViewChild('chartPreviewDialog', { read: IgxToggleDirective }) public chartPreviewDialog!: IgxToggleDirective; + @ViewChild(IgxTabsComponent) public tabs!: IgxTabsComponent; + + public contextDirective!: IgxContextMenuDirective; + public chartTypes: any[] = []; + public textFormatters: any[] = []; + public currentChartType: any; + public currentFormatter: any; public displayCreationTab = true; private destroy$ = new Subject(); - private _dialogId; + private _dialogId: any; private _chartDialogOS: OverlaySettings = { closeOnOutsideClick: false }; private _tabsMenuOverlaySettings: OverlaySettings = { closeOnOutsideClick: false, modal: false, - outlet: null, + outlet: null!, scrollStrategy: new CloseScrollStrategy(), positionStrategy: new AutoPositionStrategy({ horizontalDirection: HorizontalAlignment.Center, horizontalStartPoint: HorizontalAlignment.Center, verticalStartPoint: VerticalAlignment.Bottom, verticalDirection: VerticalAlignment.Bottom, - openAnimation: null, - closeAnimation: null, + openAnimation: null!, + closeAnimation: null!, }), }; private _chartPreviewDialogOverlaySettings: OverlaySettings = { closeOnOutsideClick: false, modal: false, - outlet: null, + outlet: null!, scrollStrategy: new CloseScrollStrategy(), positionStrategy: new AutoPositionStrategy({ horizontalDirection: HorizontalAlignment.Center, horizontalStartPoint: HorizontalAlignment.Center, verticalStartPoint: VerticalAlignment.Top, verticalDirection: VerticalAlignment.Top, - openAnimation: null, - closeAnimation: null, + openAnimation: null!, + closeAnimation: null!, }), }; @@ -152,17 +152,17 @@ export class IgxContextMenuComponent implements AfterViewInit, OnDestroy { // which is not a reliable or optimal approach. Instead, this should be improved by properly handling // when elements in the overlay are detached and ensuring chart dialog is only available. instance.chartDialogResizeNotify?.subscribe(resizedContentArgs => { - if ((this.overlayService as any)._overlayElement) { - const overlayElement = (this.overlayService as any)._overlayElement; + const overlayElement = this.overlayService.getOverlayById(args.id).elementRef?.nativeElement as HTMLElement; + if (overlayElement) { const visibleChild = Array.from(overlayElement.children).find( - (child: HTMLElement) => + (child: Element) => getComputedStyle(child).visibility !== 'hidden' && child.classList.contains('igx-overlay__wrapper--flex') ) as HTMLElement | null; if (visibleChild) { const targetElement = visibleChild.children[0] as HTMLElement | null; if (targetElement && targetElement.style) { - targetElement.style.width = resizedContentArgs[0].contentRect.width + 'px'; + targetElement.style.width = (resizedContentArgs as any)[0].contentRect.width + 'px'; } } } @@ -196,20 +196,20 @@ export class IgxContextMenuComponent implements AfterViewInit, OnDestroy { } } - public formatCells(condition) { + public formatCells(condition: any) { this.currentFormatter = condition; - this.contextDirective.textFormatter.formatCells(condition); + this.contextDirective.textFormatter!.formatCells(condition); } public clearFormat() { - this.contextDirective.textFormatter.clearFormatting(); + this.contextDirective.textFormatter!.clearFormatting(); this.currentFormatter = undefined; } - public previewChart(currentChartType) { + public previewChart(currentChartType: any) { this.currentChartType = currentChartType; this.chartPreview.clear(); - this.contextDirective.chartsDirective.chartFactory(currentChartType, this.chartPreview); + this.contextDirective.chartsDirective!.chartFactory(currentChartType, this.chartPreview); this._chartPreviewDialogOverlaySettings.target = this.tabsMenu.element; this.chartPreviewDialog.open(this._chartPreviewDialogOverlaySettings); } diff --git a/projects/igniteui-angular-extras/src/lib/context-menu/igx-context-menu.directive.ts b/projects/igniteui-angular-extras/src/lib/context-menu/igx-context-menu.directive.ts index 06261cb5564..59e68a4f7d2 100644 --- a/projects/igniteui-angular-extras/src/lib/context-menu/igx-context-menu.directive.ts +++ b/projects/igniteui-angular-extras/src/lib/context-menu/igx-context-menu.directive.ts @@ -24,12 +24,12 @@ export class IgxContextMenuDirective implements OnInit, AfterViewInit, OnDestroy @Input() public displayCreationTab: boolean = true; @Output() public buttonClose = new EventEmitter(); - public formatters = []; - public charts = []; + public formatters: any[] = []; + public charts: any[] = []; public gridResizeNotify = new Subject(); - private contentObserver: ResizeObserver; - private _range; - private _id; + private contentObserver!: ResizeObserver; + private _range: any; + private _id: any; private _collapsed = true; private destroy$ = new Subject(); private _analyticsBtnSettings: OverlaySettings = { @@ -77,7 +77,7 @@ export class IgxContextMenuDirective implements OnInit, AfterViewInit, OnDestroy this.destroy$.complete(); if (this.contentObserver) { this.contentObserver.disconnect(); - this.contentObserver = null; + this.contentObserver = null!; } if (!this._collapsed) { this.close(); @@ -160,13 +160,13 @@ export class IgxContextMenuDirective implements OnInit, AfterViewInit, OnDestroy horizontalDirection: HorizontalAlignment.Right, horizontalStartPoint: HorizontalAlignment.Right, verticalStartPoint: VerticalAlignment.Bottom, - verticalDirection: VerticalAlignment.Bottom, closeAnimation: null + verticalDirection: VerticalAlignment.Bottom, closeAnimation: null! }); this._analyticsBtnSettings.target = cell.nativeElement; this._analyticsBtnSettings.scrollStrategy = new AbsoluteScrollStrategy(); const info = this.overlayService.getOverlayById(this._id); if (info) { - info.settings.positionStrategy = this._analyticsBtnSettings.positionStrategy; + info.settings!.positionStrategy = this._analyticsBtnSettings.positionStrategy; } if (this._collapsed) { this.show(); @@ -185,7 +185,7 @@ export class IgxContextMenuDirective implements OnInit, AfterViewInit, OnDestroy horizontalDirection: HorizontalAlignment.Right, horizontalStartPoint: HorizontalAlignment.Right, verticalStartPoint: VerticalAlignment.Bottom, - verticalDirection: VerticalAlignment.Bottom, closeAnimation: null + verticalDirection: VerticalAlignment.Bottom, closeAnimation: null! }); const selectedColumnsIndexes = selectedColumns.map(c => c.visibleIndex).sort((a, b) => a - b); @@ -214,7 +214,7 @@ export class IgxContextMenuDirective implements OnInit, AfterViewInit, OnDestroy this._analyticsBtnSettings.scrollStrategy = new AbsoluteScrollStrategy(); const info = this.overlayService.getOverlayById(this._id); if (info) { - info.settings.positionStrategy = this._analyticsBtnSettings.positionStrategy; + info.settings!.positionStrategy = this._analyticsBtnSettings.positionStrategy; } if (this._collapsed) { this.show(); @@ -243,7 +243,7 @@ export class IgxContextMenuDirective implements OnInit, AfterViewInit, OnDestroy this._id = undefined; } - private isWithInRange(rInex, cIndex) { + private isWithInRange(rInex: number, cIndex: number) { return rInex >= this._range.rowStart && rInex <= this._range.rowEnd && cIndex >= this._range.columnStart && cIndex <= this._range.columnEnd; } diff --git a/projects/igniteui-angular-extras/src/lib/directives/chart-integration/chart-integration.directive.ts b/projects/igniteui-angular-extras/src/lib/directives/chart-integration/chart-integration.directive.ts index d53ccc05c9b..c53d70d12a3 100644 --- a/projects/igniteui-angular-extras/src/lib/directives/chart-integration/chart-integration.directive.ts +++ b/projects/igniteui-angular-extras/src/lib/directives/chart-integration/chart-integration.directive.ts @@ -87,11 +87,11 @@ export class IgxChartIntegrationDirective { public useLegend = true; @Input() - public defaultLabelMemberPath: string = undefined; + public defaultLabelMemberPath: string = undefined!; @Input() public set scatterChartYAxisValueMemberPath(path: string) { - this._scatterChartYAxisValueMemberPath = path; + this._scatterChartYAxisValueMemberPath = path!; } public get scatterChartYAxisValueMemberPath() { @@ -102,7 +102,7 @@ export class IgxChartIntegrationDirective { @Input() public set bubbleChartRadiusMemberPath(path: string) { - this._bubbleChartRadiusMemberPath = path; + this._bubbleChartRadiusMemberPath = path!; } public get bubbleChartRadiusMemberPath() { @@ -114,11 +114,11 @@ export class IgxChartIntegrationDirective { private chartTypesAvailability = new Map(); private customChartComponentOptions = new Map(); private dataCharts = new Map>(); - private _scatterChartYAxisValueMemberPath = undefined; - private _bubbleChartRadiusMemberPath = undefined; - private _valueMemberPaths = []; - private _labelMemberPaths = []; - private _chartData: any[]; + private _scatterChartYAxisValueMemberPath: any = undefined; + private _bubbleChartRadiusMemberPath: any = undefined; + private _valueMemberPaths: any[] = []; + private _labelMemberPaths: any[] = []; + private _chartData!: any[]; private _sizeScale = new IgxSizeScaleComponent(); private _dataChartTypes = new Set(); private get _labelMemberPath(): string { @@ -187,9 +187,9 @@ export class IgxChartIntegrationDirective { this.dataCharts.set(CHART_TYPE.Pie, IgxPieChartComponent); const iterable = this.dataCharts.keys(); for (let head = iterable.next().value; head !== undefined; head = iterable.next().value) { - this._dataChartTypes.add(head); - this.chartTypesAvailability.set(head, true); - this.customChartComponentOptions.set(head, {}); + this._dataChartTypes.add(head as any); + this.chartTypesAvailability.set(head as any, true); + this.customChartComponentOptions.set(head as any, {}); } } @@ -198,7 +198,7 @@ export class IgxChartIntegrationDirective { } public getAvailableCharts() { - const res = []; + const res: any[] = []; this.chartTypesAvailability.forEach((isAvailable, chartType) => { if (isAvailable) { res.push(chartType); @@ -245,7 +245,7 @@ export class IgxChartIntegrationDirective { if (this.useLegend) { const legendType = type === CHART_TYPE.Pie ? IgxItemLegendComponent : IgxLegendComponent; const legendComponentRef: ComponentRef = viewContainerRef.createComponent(legendType as any); - options.chartOptions['legend'] = legendComponentRef.instance; + options.chartOptions!['legend'] = legendComponentRef.instance; } chart = initializer.initChart(componentRef.instance, options); } else if (createdChart) { @@ -255,7 +255,7 @@ export class IgxChartIntegrationDirective { return chart; } - private getInitializer(chartType: CHART_TYPE, componentClassRef): ChartInitializer { + private getInitializer(chartType: CHART_TYPE, componentClassRef: any): ChartInitializer { if (chartType.includes('Pie')) { return new IgxPieChartInitializer(); } else if (chartType.includes('Stacked')) { @@ -341,7 +341,7 @@ export class IgxChartIntegrationDirective { chartComponentOptions.seriesOptions = seriesOptions; } - private addIndexMemberPath(dataRecord, index) { + private addIndexMemberPath(dataRecord: any, index: any) { dataRecord = { ...{ [this._labelMemberPath]: index }, ...dataRecord }; return dataRecord; } @@ -372,11 +372,11 @@ export class IgxChartIntegrationDirective { } public setChartComponentOptions(chart: CHART_TYPE, optionsType: OPTIONS_TYPE, options: IOptions) { - if (!this.customChartComponentOptions.get(chart)[optionsType]) { - this.customChartComponentOptions.get(chart)[optionsType] = {}; + if (!this.customChartComponentOptions.get(chart)![optionsType]) { + this.customChartComponentOptions.get(chart)![optionsType] = {}; } Object.keys(options).forEach(property => { - this.customChartComponentOptions.get(chart)[optionsType][property] = options[property]; + this.customChartComponentOptions.get(chart)![optionsType]![property] = options[property]; }); } } diff --git a/projects/igniteui-angular-extras/src/lib/directives/chart-integration/initializers.ts b/projects/igniteui-angular-extras/src/lib/directives/chart-integration/initializers.ts index 3bfcc1f8fdf..7ee67ec524c 100644 --- a/projects/igniteui-angular-extras/src/lib/directives/chart-integration/initializers.ts +++ b/projects/igniteui-angular-extras/src/lib/directives/chart-integration/initializers.ts @@ -28,8 +28,8 @@ export interface IChartComponentOptions { } export abstract class ChartInitializer { - protected yAxis; - protected xAxis; + protected yAxis: any; + protected xAxis: any; protected seriesFactory = new SeriesFactory(); constructor() { } @@ -54,7 +54,7 @@ export class IgxPieChartInitializer extends ChartInitializer { } public initChart(chart: IgxPieChartComponent, options: IChartComponentOptions) { - this.applyOptions(chart, options.chartOptions); + this.applyOptions(chart, options.chartOptions!); return chart; } } @@ -90,16 +90,16 @@ export class IgxDataChartInitializer extends ChartInitializer { if (chart.axes.count) { chart.axes.clear(); } - options.seriesOptions.forEach((option) => { + options.seriesOptions!.forEach((option) => { const series = this.seriesFactory.create(this.seriesType); series.xAxis = this.xAxis; series.yAxis = this.yAxis; this.applyOptions(series, option); chart.series.add(series); }); - this.applyOptions(chart, options.chartOptions); - this.applyOptions(this.xAxis, options.xAxisOptions); - this.applyOptions(this.yAxis, options.yAxisOptions); + this.applyOptions(chart, options.chartOptions!); + this.applyOptions(this.xAxis, options.xAxisOptions!); + this.applyOptions(this.yAxis, options.yAxisOptions!); chart.axes.add(this.xAxis); chart.axes.add(this.yAxis); return chart; @@ -131,15 +131,15 @@ export class IgxStackedDataChartInitializer extends ChartInitializer { const series = this.seriesFactory.create(this.seriesType); series.xAxis = this.xAxis; series.yAxis = this.yAxis; - options.stackedFragmentOptions.forEach(fragOpt => { + options!.stackedFragmentOptions!.forEach((fragOpt: any) => { const frag = new IgxStackedFragmentSeriesComponent(); this.applyOptions(frag, fragOpt); series.series.add(frag); }); - this.applyOptions(series, options.seriesOptions); - this.applyOptions(chart, options.chartOptions); - this.applyOptions(this.xAxis, options.xAxisOptions); - this.applyOptions(this.yAxis, options.yAxisOptions); + this.applyOptions(series, options!.seriesOptions!); + this.applyOptions(chart, options!.chartOptions!); + this.applyOptions(this.xAxis, options!.xAxisOptions!); + this.applyOptions(this.yAxis, options!.yAxisOptions!); chart.series.add(series); chart.axes.add(this.xAxis); chart.axes.add(this.yAxis); diff --git a/projects/igniteui-angular-extras/src/lib/directives/conditional-formatting/conditional-formatting.directive.ts b/projects/igniteui-angular-extras/src/lib/directives/conditional-formatting/conditional-formatting.directive.ts index 03d33954b77..d6ea059eafc 100644 --- a/projects/igniteui-angular-extras/src/lib/directives/conditional-formatting/conditional-formatting.directive.ts +++ b/projects/igniteui-angular-extras/src/lib/directives/conditional-formatting/conditional-formatting.directive.ts @@ -1,4 +1,5 @@ import { AfterViewInit, Directive, EventEmitter, Input, OnDestroy, Output, inject } from '@angular/core'; +import { GridSelectionRange } from 'igniteui-angular/core'; import { IgxGridComponent } from 'igniteui-angular/grids/grid'; import { Subject } from 'rxjs'; import { debounceTime, takeUntil } from 'rxjs/operators'; @@ -25,7 +26,7 @@ export interface IFormatColors { }) export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestroy { @Input() - public formatter: string | ConditionalFormattingType; + public formatter!: string | ConditionalFormattingType; @Input() public set formatColors(val: IFormatColors) { @@ -39,7 +40,7 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr public formattersReady = new EventEmitter(); public colorScale = { - backgroundColor: (_rowData, colname, cellValue, rowIndex) => { + backgroundColor: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (!(typeof cellValue === 'number' && this.isWithInFormattedRange(rowIndex, colname))) { return; } @@ -49,7 +50,7 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr }; public dataBars = { - backgroundImage: (_rowData, colname, cellValue, rowIndex) => { + backgroundImage: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (!(typeof cellValue === 'number' && this.isWithInFormattedRange(rowIndex, colname))) { return; } @@ -74,13 +75,13 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr }; public top10Percent = { - backgroundColor: (_rowData, colname, cellValue, rowIndex) => { + backgroundColor: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (typeof cellValue === 'number' && this.isWithInFormattedRange(rowIndex, colname) && cellValue > this.top10PercentTreshold) { return this.formatColors.info; } }, - color: (_rowData, colname, cellValue, rowIndex) => { + color: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (typeof cellValue === 'number' && this.isWithInFormattedRange(rowIndex, colname) && cellValue > this.top10PercentTreshold) { return this.formatColors.text; @@ -89,13 +90,13 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr }; public greaterThan = { - backgroundColor: (_rowData, colname, cellValue, rowIndex) => { + backgroundColor: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (typeof cellValue === 'number' && this.isWithInFormattedRange(rowIndex, colname) && cellValue > this.avgValue) { return this.formatColors.info; } }, - color: (_rowData, colname, cellValue, rowIndex) => { + color: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (typeof cellValue === 'number' && this.isWithInFormattedRange(rowIndex, colname) && cellValue > this.avgValue) { return this.formatColors.text; @@ -104,12 +105,12 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr }; public empty = { - backgroundColor: (_rowData, colname, cellValue, rowIndex) => { + backgroundColor: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (this.isWithInFormattedRange(rowIndex, colname) && cellValue === undefined) { return this.formatColors.info; } }, - color: (_rowData, colname, cellValue, rowIndex) => { + color: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (this.isWithInFormattedRange(rowIndex, colname) && cellValue === undefined) { return this.formatColors.text; } @@ -117,7 +118,7 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr }; public duplicates = { - backgroundColor: (_rowData, colname, cellValue, rowIndex) => { + backgroundColor: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (!this.isWithInFormattedRange(rowIndex, colname)) { return; } @@ -125,7 +126,7 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr return arr.indexOf(cellValue) !== arr.lastIndexOf(cellValue) ? this.formatColors.info : ''; }, - color: (_rowData, colname, cellValue, rowIndex) => { + color: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (!this.isWithInFormattedRange(rowIndex, colname)) { return; } @@ -135,13 +136,13 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr }; public textContains = { - backgroundColor: (_rowData, colname, cellValue, rowIndex) => { + backgroundColor: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (typeof cellValue === 'string' && this.isWithInFormattedRange(rowIndex, colname) && cellValue.toLowerCase().indexOf(this._valueForComparison.toLowerCase()) !== -1) { return this.formatColors.info; } }, - color: (_rowData, colname, cellValue, rowIndex) => { + color: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (typeof cellValue === 'string' && this.isWithInFormattedRange(rowIndex, colname) && cellValue.toLowerCase().indexOf(this._valueForComparison.toLowerCase()) !== -1) { return this.formatColors.text; @@ -150,14 +151,14 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr }; public uniques = { - backgroundColor: (_rowData, colname, cellValue, rowIndex) => { + backgroundColor: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (!this.isWithInFormattedRange(rowIndex, colname)) { return; } const arr: any[] = typeof cellValue === 'number' ? this.numericData : this.textData; return arr.indexOf(cellValue) === arr.lastIndexOf(cellValue) ? this.formatColors.info : ''; }, - color: (_rowData, colname, cellValue, rowIndex) => { + color: (_rowData: any, colname: string, cellValue: any, rowIndex: number) => { if (!this.isWithInFormattedRange(rowIndex, colname)) { return; } @@ -189,12 +190,12 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr private _numericFormatters = ['Data Bars', 'Color Scale', 'Top 10', 'Greater Than']; private _textFormatters = ['Text Contains']; private _commonFormattersName = ['Duplicate Values', 'Unique Values', 'Empty']; - private _selectedData = []; - private _minValue; - private _maxValue; - private _startColumn; - private _endColumn; - private _valueForComparison; + private _selectedData: any[] = []; + private _minValue: any; + private _maxValue: any; + private _startColumn: any; + private _endColumn: any; + private _valueForComparison: any; private _formattersData = new Map(); private destroy$ = new Subject(); private formatedRange: Map> = new Map>(); @@ -236,7 +237,7 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr this.destroy$.complete(); } - public formatCells(formatterName, formatRange?: [], reset = true) { + public formatCells(formatterName: string, formatRange?: [], reset = true) { if (reset) { this.resetRange(formatRange); } @@ -255,14 +256,14 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr } public clearFormatting() { - this.formatter = undefined; + this.formatter = undefined!; this.grid.visibleColumns.forEach(c => { - c.cellStyles = undefined; + c.cellStyles = null; }); this.grid.cdr.detectChanges(); } - public determineFormatters(fromColumn) { + public determineFormatters(fromColumn: boolean) { const data = fromColumn ? this.grid.getSelectedColumnsData() : this.grid.getSelectedData(); const numericData = this.toArray(data).some(rec => typeof rec === 'number'); const textData = this.toArray(data).some(rec => typeof rec === 'string'); @@ -301,12 +302,12 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr this._minValue = hasNegativeValues ? Math.min(...this.numericData.filter(value => value < 0)) : 0; } - public isWithInFormattedRange(rowIndex, colID) { + public isWithInFormattedRange(rowIndex: number, colID: any) { const visibleIndex = typeof colID === 'string' ? this.grid.getColumnByName(colID).visibleIndex : colID; if (!this.formatedRange.size) { return false; } - return this.formatedRange.has(rowIndex) && this.formatedRange.get(rowIndex).has(visibleIndex); + return this.formatedRange.has(rowIndex) && this.formatedRange.get(rowIndex)!.has(visibleIndex); } private get middleTresholdValue() { @@ -329,18 +330,18 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr return Math.ceil(Math.abs(this._minValue) / (this._maxValue + Math.abs(this._minValue)) * 100); } - private getPositivePercentage(val) { + private getPositivePercentage(val: any) { return Math.ceil(Math.ceil(val) / (this._maxValue + Math.abs(this._minValue)) * 100); } - private getNegativePercentage(val) { + private getNegativePercentage(val: any) { return Math.ceil(Math.abs(val) / (this._maxValue + Math.abs(this._minValue)) * 100); } - private resetRange(formatRange?: []) { + private resetRange(formatRange?: GridSelectionRange[]) { this.formatedRange.clear(); const selectedRanges = this.grid.getSelectedRanges(); - let customRange; + let customRange: GridSelectionRange[]; // Column selection custom range if (selectedRanges.length === 0) { @@ -350,7 +351,7 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr customRange.push({ columnEnd: c.visibleIndex, columnStart: c.visibleIndex, - rowEnd: this.grid.data.length - 1, + rowEnd: this.grid.data!.length - 1, rowStart: 0 }); }); @@ -367,16 +368,16 @@ export class IgxConditionalFormattingDirective implements AfterViewInit, OnDestr this.recalcCachedValues(true); } - private addToCache(rowIndex, colIndex) { + private addToCache(rowIndex: number, colIndex: number) { if (this.formatedRange.has(rowIndex)) { - this.formatedRange.get(rowIndex).add(colIndex); + this.formatedRange.get(rowIndex)!.add(colIndex); } else { - this.formatedRange.set(rowIndex, new Set()).get(rowIndex).add(colIndex); + this.formatedRange.set(rowIndex, new Set()).get(rowIndex)!.add(colIndex); } } private toArray(data: any[]) { - let result = []; + let result: any[] = []; data.forEach(rec => result = result.concat(Object.values(rec))); return result; } diff --git a/projects/igniteui-angular-extras/tsconfig.spec.json b/projects/igniteui-angular-extras/tsconfig.spec.json index f6c5faccd17..423e9f163c2 100644 --- a/projects/igniteui-angular-extras/tsconfig.spec.json +++ b/projects/igniteui-angular-extras/tsconfig.spec.json @@ -1,6 +1,9 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + /* TODO: interim override — remove once spec files are migrated to strict */ + "strict": false, + "noImplicitOverride": true, "outDir": "../../out-tsc/spec", "types": ["jasmine", "node"] }, diff --git a/projects/igniteui-angular/accordion/src/accordion/accordion.component.ts b/projects/igniteui-angular/accordion/src/accordion/accordion.component.ts index a51fb114ead..846b7bc12af 100644 --- a/projects/igniteui-angular/accordion/src/accordion/accordion.component.ts +++ b/projects/igniteui-angular/accordion/src/accordion/accordion.component.ts @@ -328,16 +328,16 @@ export class IgxAccordionComponent implements AfterContentInit, AfterViewInit, O } if (event.altKey && event.shiftKey) { if (isUp) { - this._enabledPanels.forEach(p => p.collapse()); + this._enabledPanels.forEach(p => p.collapse(event)); } else { if (this.singleBranchExpand) { for (let i = 0; i < this._enabledPanels.length - 1; i++) { - this._enabledPanels[i].collapse(); + this._enabledPanels[i].collapse(event); } - this._enabledPanels[this._enabledPanels.length - 1].expand(); + this._enabledPanels[this._enabledPanels.length - 1].expand(event); return; } - this._enabledPanels.forEach(p => p.expand()); + this._enabledPanels.forEach(p => p.expand(event)); } } } @@ -399,7 +399,7 @@ export class IgxAccordionComponent implements AfterContentInit, AfterViewInit, O args.cancel = true; } }); - fromEvent(panel.header.innerElement, 'keydown') + fromEvent(panel.header.innerElement, 'keydown') .pipe(takeUntil(this._unsubChildren$)) .subscribe((e: KeyboardEvent) => { this.handleKeydown(e, panel); diff --git a/projects/igniteui-angular/action-strip/src/action-strip/action-strip.component.ts b/projects/igniteui-angular/action-strip/src/action-strip/action-strip.component.ts index cd2bed4c26a..3a9aaa838bc 100644 --- a/projects/igniteui-angular/action-strip/src/action-strip/action-strip.component.ts +++ b/projects/igniteui-angular/action-strip/src/action-strip/action-strip.component.ts @@ -123,7 +123,7 @@ export class IgxActionStripComponent implements IgxActionStripToken, AfterViewIn * @internal */ @ContentChildren(IgxActionStripMenuItemDirective) - public _menuItems: QueryList; + public _menuItems!: QueryList; /* blazorInclude */ @@ -137,7 +137,7 @@ export class IgxActionStripComponent implements IgxActionStripToken, AfterViewIn * @internal */ @ContentChildren(IgxActionStripActionsToken) - public actionButtons: QueryList; + public actionButtons!: QueryList; /** * Gets/Sets the visibility of the Action Strip. @@ -183,6 +183,7 @@ export class IgxActionStripComponent implements IgxActionStripToken, AfterViewIn return false; } } + return undefined!; } /** @@ -192,7 +193,7 @@ export class IgxActionStripComponent implements IgxActionStripToken, AfterViewIn * @internal */ @ViewChild('dropdown') - public menu: IgxDropDownComponent; + public menu!: IgxDropDownComponent; /** * Getter for menu overlay settings @@ -203,7 +204,7 @@ export class IgxActionStripComponent implements IgxActionStripToken, AfterViewIn public menuOverlaySettings: OverlaySettings = { scrollStrategy: new CloseScrollStrategy() }; private _destroyRef = inject(DestroyRef); - private _resourceStrings: IActionStripResourceStrings = null; + private _resourceStrings: IActionStripResourceStrings = null!; private _defaultResourceStrings = getCurrentResourceStrings(ActionStripResourceStringsEN); private _originalParent!: HTMLElement; @@ -220,7 +221,7 @@ export class IgxActionStripComponent implements IgxActionStripToken, AfterViewIn * @internal */ public get menuItems() { - const actions = []; + const actions: any[] = []; this.actionButtons.forEach(button => { if (button.asMenuItems) { const children = button.buttons; @@ -269,7 +270,7 @@ export class IgxActionStripComponent implements IgxActionStripToken, AfterViewIn public ngAfterViewInit() { this.menu.selectionChanging.subscribe(($event) => { const newSelection = ($event.newSelection as any).elementRef.nativeElement; - let allButtons = []; + let allButtons: any[] = []; this.actionButtons.forEach(actionButtons => { if (actionButtons.asMenuItems) { allButtons = [...allButtons, ...actionButtons.buttons.toArray()]; diff --git a/projects/igniteui-angular/avatar/src/avatar/avatar.component.ts b/projects/igniteui-angular/avatar/src/avatar/avatar.component.ts index d23f48f369f..2c787866313 100644 --- a/projects/igniteui-angular/avatar/src/avatar/avatar.component.ts +++ b/projects/igniteui-angular/avatar/src/avatar/avatar.component.ts @@ -97,7 +97,7 @@ export class IgxAvatarComponent implements OnInit { * ``` */ @HostBinding('attr.aria-roledescription') - public roleDescription: string; + public roleDescription!: string; /** * Sets the `id` of the avatar. If not set, the first avatar component will have `id` = `"igx-avatar-0"`. @@ -147,7 +147,7 @@ export class IgxAvatarComponent implements OnInit { @HostBinding('style.color') @Input() - public color: string; + public color!: string; /** * Sets the background color of the avatar. @@ -162,7 +162,7 @@ export class IgxAvatarComponent implements OnInit { @HostBinding('style.background') @Input() - public bgColor: string; + public bgColor!: string; /** * Sets initials to the avatar. @@ -173,7 +173,7 @@ export class IgxAvatarComponent implements OnInit { * ``` */ @Input() - public initials: string; + public initials!: string; /** * Sets an icon to the avatar. All icons from the material icon set are supported. @@ -184,7 +184,7 @@ export class IgxAvatarComponent implements OnInit { * ``` */ @Input() - public icon: string; + public icon!: string; /** * Sets the image source of the avatar. @@ -206,26 +206,26 @@ export class IgxAvatarComponent implements OnInit { /** @hidden @internal */ @ViewChild('defaultTemplate', { read: TemplateRef, static: true }) - protected defaultTemplate: TemplateRef; + protected defaultTemplate!: TemplateRef; /** @hidden @internal */ @ViewChild('imageTemplate', { read: TemplateRef, static: true }) - protected imageTemplate: TemplateRef; + protected imageTemplate!: TemplateRef; /** @hidden @internal */ @ViewChild('initialsTemplate', { read: TemplateRef, static: true }) - protected initialsTemplate: TemplateRef; + protected initialsTemplate!: TemplateRef; /** @hidden @internal */ @ViewChild('iconTemplate', { read: TemplateRef, static: true }) - protected iconTemplate: TemplateRef; + protected iconTemplate!: TemplateRef; /** * @hidden * @internal */ - private _size: string | IgxAvatarSize; - private _src: string; + private _size!: string | IgxAvatarSize; + private _src!: string; /** * Returns the size of the avatar. diff --git a/projects/igniteui-angular/badge/src/badge/badge.component.ts b/projects/igniteui-angular/badge/src/badge/badge.component.ts index 7430385f650..e6ed63022b8 100644 --- a/projects/igniteui-angular/badge/src/badge/badge.component.ts +++ b/projects/igniteui-angular/badge/src/badge/badge.component.ts @@ -103,13 +103,13 @@ export class IgxBadgeComponent { * ``` */ @Input() - public icon: string; + public icon!: string; /** * The name of the icon set. Used in case the icon is from a different icon set. */ @Input() - public iconSet: string; + public iconSet!: string; /** * Sets/gets the role attribute value. @@ -157,6 +157,7 @@ export class IgxBadgeComponent { if (!this.dot) { return this.shape === 'square'; } + return undefined!; } /** diff --git a/projects/igniteui-angular/banner/src/banner/banner.component.html b/projects/igniteui-angular/banner/src/banner/banner.component.html index d8cf0bb0adf..e90bd994c9f 100644 --- a/projects/igniteui-angular/banner/src/banner/banner.component.html +++ b/projects/igniteui-angular/banner/src/banner/banner.component.html @@ -14,7 +14,7 @@
@if (useDefaultTemplate) { - } @else { diff --git a/projects/igniteui-angular/banner/src/banner/banner.component.ts b/projects/igniteui-angular/banner/src/banner/banner.component.ts index 674766ee07d..fb5d957e237 100644 --- a/projects/igniteui-angular/banner/src/banner/banner.component.ts +++ b/projects/igniteui-angular/banner/src/banner/banner.component.ts @@ -63,7 +63,7 @@ export class IgxBannerComponent implements IToggleView { * @hidden */ @ContentChild(IgxIconComponent) - public bannerIcon: IgxIconComponent; + public bannerIcon!: IgxIconComponent; /** * Fires after the banner shows up @@ -234,17 +234,17 @@ export class IgxBannerComponent implements IToggleView { } @ViewChild('expansionPanel', { static: true }) - private _expansionPanel: IgxExpansionPanelComponent; + private _expansionPanel!: IgxExpansionPanelComponent; @ContentChild(IgxBannerActionsDirective) - private _bannerActionTemplate: IgxBannerActionsDirective; + private _bannerActionTemplate!: IgxBannerActionsDirective; private _destroyRef = inject(DestroyRef); private _expanded: boolean = false; private _shouldFireEvent: boolean = false; - private _bannerEvent: BannerEventArgs; - private _animationSettings: ToggleAnimationSettings; - private _resourceStrings: IBannerResourceStrings = null; + private _bannerEvent!: BannerEventArgs; + private _animationSettings!: ToggleAnimationSettings; + private _resourceStrings: IBannerResourceStrings = null!; private _defaultResourceStrings = getCurrentResourceStrings(BannerResourceStringsEN); constructor() { @@ -267,7 +267,7 @@ export class IgxBannerComponent implements IToggleView { * * ``` */ - public open(event?: Event) { + public open(event?: MouseEvent) { this._bannerEvent = { owner: this, event }; const openingArgs: BannerCancelEventArgs = { owner: this, @@ -297,7 +297,7 @@ export class IgxBannerComponent implements IToggleView { * * ``` */ - public close(event?: Event) { + public close(event?: MouseEvent) { this._bannerEvent = { owner: this, event}; const closingArgs: BannerCancelEventArgs = { owner: this, @@ -327,7 +327,7 @@ export class IgxBannerComponent implements IToggleView { * * ``` */ - public toggle(event?: Event) { + public toggle(event?: MouseEvent) { if (this.collapsed) { this.open(event); } else { diff --git a/projects/igniteui-angular/button-group/src/button-group/button-group.component.ts b/projects/igniteui-angular/button-group/src/button-group/button-group.component.ts index c86c7526edb..62dfae5ce64 100644 --- a/projects/igniteui-angular/button-group/src/button-group/button-group.component.ts +++ b/projects/igniteui-angular/button-group/src/button-group/button-group.component.ts @@ -257,8 +257,8 @@ export class IgxButtonGroupComponent implements AfterViewInit, OnDestroy { @Output() public deselected = new EventEmitter(); - @ViewChildren(IgxButtonDirective) private viewButtons: QueryList; - @ContentChildren(IgxButtonDirective) private templateButtons: QueryList; + @ViewChildren(IgxButtonDirective) private viewButtons!: QueryList; + @ContentChildren(IgxButtonDirective) private templateButtons!: QueryList; /** * Returns true if the `igx-buttongroup` alignment is vertical. @@ -287,12 +287,12 @@ export class IgxButtonGroupComponent implements AfterViewInit, OnDestroy { protected buttonClickNotifier$ = new Subject(); protected queryListNotifier$ = new Subject(); - private _isVertical: boolean; - private _itemContentCssClass: string; + private _isVertical!: boolean; + private _itemContentCssClass!: string; private _disabled = false; private _selectionMode: 'single' | 'singleRequired' | 'multi' = 'single'; - private mutationObserver: MutationObserver; + private mutationObserver!: MutationObserver; private observerConfig: MutationObserverInit = { attributeFilter: ["data-selected"], childList: true, @@ -430,7 +430,7 @@ export class IgxButtonGroupComponent implements AfterViewInit, OnDestroy { }); }; - this.mutationObserver = this.setMutationsObserver(); + this.mutationObserver = this.setMutationsObserver()!; this.viewButtons.changes.pipe(takeUntil(this.queryListNotifier$)).subscribe(() => { this.mutationObserver.disconnect(); diff --git a/projects/igniteui-angular/calendar/src/calendar/calendar-base.ts b/projects/igniteui-angular/calendar/src/calendar/calendar-base.ts index 98315a6fa0e..16c7574dbd0 100644 --- a/projects/igniteui-angular/calendar/src/calendar/calendar-base.ts +++ b/projects/igniteui-angular/calendar/src/calendar/calendar-base.ts @@ -133,7 +133,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { /** * @hidden */ - public selectedDates: Date[]; + public selectedDates!: Date[]; /** * @hidden @@ -143,7 +143,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { /** * @hidden */ - public lastSelectedDate: Date; + public lastSelectedDate!: Date; /** * @hidden @@ -199,47 +199,47 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { /** * @hidden */ - protected _deselectDate: boolean; + protected _deselectDate!: boolean; /** * @hidden */ - private initialSelection: Date | Date[]; + private initialSelection!: Date | Date[]; /** * @hidden */ - private _locale: string; + private _locale!: string; /** * @hidden */ - private _defaultLocale: string; + private _defaultLocale!: string; /** * @hidden */ - private _weekStart: WEEKDAYS | number; + private _weekStart!: WEEKDAYS | number; /** * @hidden */ - private _localeWeekStart: WEEKDAYS | number; + private _localeWeekStart!: WEEKDAYS | number; /** * @hidden */ - private _viewDate: Date; + private _viewDate!: Date; /** * @hidden */ - private _startDate: Date; + private _startDate!: Date; /** * @hidden */ - private _endDate: Date; + private _endDate!: Date; /** * @hidden @@ -255,7 +255,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { * @hidden */ private _selection: CalendarSelection | string = CalendarSelection.SINGLE; - private _resourceStrings: ICalendarResourceStrings = null; + private _resourceStrings: ICalendarResourceStrings = null!; private _defaultResourceStrings = getCurrentResourceStrings(CalendarResourceStringsEN); /** @@ -427,12 +427,12 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { * @hidden */ @ViewChildren('yearsBtn') - public yearsBtns: QueryList; + public yearsBtns!: QueryList; /** * @hidden @internal */ - public previousViewDate: Date; + public previousViewDate!: Date; /** * @hidden @@ -451,7 +451,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { */ public formattedYear(value: Date | Date[]): string { if (Array.isArray(value)) { - return; + return undefined!; } if (this.formatViews.year) { @@ -471,9 +471,9 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { case 'month': return `${this.resourceStrings.igx_calendar_previous_month}, ${detail}` case 'year': - return this.resourceStrings.igx_calendar_previous_year; + return this.resourceStrings.igx_calendar_previous_year!; case 'decade': - return this.resourceStrings.igx_calendar_previous_years.replace('{0}', '15'); + return this.resourceStrings.igx_calendar_previous_years!.replace('{0}', '15'); } } @@ -482,9 +482,9 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { case 'month': return `${this.resourceStrings.igx_calendar_next_month}, ${detail}` case 'year': - return this.resourceStrings.igx_calendar_next_year; + return this.resourceStrings.igx_calendar_next_year!; case 'decade': - return this.resourceStrings.igx_calendar_next_years.replace('{0}', '15'); + return this.resourceStrings.igx_calendar_next_years!.replace('{0}', '15'); } } @@ -516,7 +516,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { public set selection(value: string) { switch (value) { case CalendarSelection.SINGLE: - this.selectedDates = null; + this.selectedDates = null!; break; case CalendarSelection.MULTI: case CalendarSelection.RANGE: @@ -547,7 +547,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { } if (typeof value === 'string') { - value = DateTimeUtil.parseIsoDate(value); + value = DateTimeUtil.parseIsoDate(value)!; } const validDate = this.validateDate(value); @@ -595,7 +595,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { } if (typeof date === 'string') { - date = DateTimeUtil.parseIsoDate(date); + date = DateTimeUtil.parseIsoDate(date)!; } return isDateInRanges(date, this.disabledDates); @@ -635,7 +635,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { @Input() public get value(): Date | Date[] { if (this.selection === CalendarSelection.SINGLE) { - return this.selectedDates?.at(0); + return this.selectedDates?.at(0)!; } return this.selectedDates; @@ -651,7 +651,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { public set value(value: Date | Date[] | string) { // Validate the date if it is of type string and it is IsoDate if (typeof value === 'string') { - value = DateTimeUtil.parseIsoDate(value); + value = DateTimeUtil.parseIsoDate(value)!; } // Check if value is set initially by the user, @@ -718,7 +718,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { */ public selectDate(value: Date | Date[] | string) { if (typeof value === 'string') { - value = DateTimeUtil.parseIsoDate(value); + value = DateTimeUtil.parseIsoDate(value)!; } if (value === null || value === undefined || (Array.isArray(value) && value.length === 0)) { @@ -749,11 +749,11 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { } if (typeof value === 'string') { - value = DateTimeUtil.parseIsoDate(value); + value = DateTimeUtil.parseIsoDate(value)!; } if (value === null || value === undefined) { - this.selectedDates = this.selection === CalendarSelection.SINGLE ? null : []; + this.selectedDates = this.selection === CalendarSelection.SINGLE ? null! : []; this.rangeStarted = false; this._onChangeCallback(this.selectedDates); return; @@ -780,7 +780,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { private selectSingle(value: Date) { if (!isEqual(this.selectedDates?.at(0), value)) { this.selectedDates = [this.getDateOnly(value)]; - this._onChangeCallback(this.selectedDates.at(0)); + this._onChangeCallback(this.selectedDates.at(0)!); } } @@ -791,8 +791,8 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { */ private deselectSingle(value: Date) { if (this.selectedDates !== null && - this.getDateOnlyInMs(value as Date) === this.getDateOnlyInMs(this.selectedDates.at(0))) { - this.selectedDates = null; + this.getDateOnlyInMs(value as Date) === this.getDateOnlyInMs(this.selectedDates.at(0)!)) { + this.selectedDates = null!; this._onChangeCallback(this.selectedDates); } } @@ -818,7 +818,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { this.selectedDates = Array.from(new Set([...newDates, ...selDates])).map(v => new Date(v)); } } else { - let newSelection = []; + let newSelection: Date[] = []; if (this.shiftKey && this.lastSelectedDate) { @@ -844,7 +844,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { this._deselectDate = true; } - this._startDate = this._endDate = undefined; + this._startDate = this._endDate = undefined!; } else if (this.selectedDates.every((date: Date) => date.getTime() !== value.getTime())) { newSelection.push(value); @@ -935,7 +935,7 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { } else if (!this.rangeStarted) { this.rangeStarted = true; this.selectedDates = [value]; - this._startDate = this._endDate = undefined; + this._startDate = this._endDate = undefined!; } else { this.rangeStarted = false; @@ -1035,8 +1035,8 @@ export class IgxCalendarBaseDirective implements ControlValueAccessor { onResourceChangeHandle(this._destroyRef, this.onResourceChange, this); } - private onResourceChange(args: CustomEvent) { - this._defaultLocale = args.detail.newLocale; + private onResourceChange(args?: CustomEvent) { + this._defaultLocale = args!.detail.newLocale; if (!this._locale) { this._defaultResourceStrings = getCurrentResourceStrings(CalendarResourceStringsEN, false); } diff --git a/projects/igniteui-angular/calendar/src/calendar/calendar.component.html b/projects/igniteui-angular/calendar/src/calendar/calendar.component.html index bcca8927465..960b8013039 100644 --- a/projects/igniteui-angular/calendar/src/calendar/calendar.component.html +++ b/projects/igniteui-angular/calendar/src/calendar/calendar.component.html @@ -55,7 +55,7 @@ @if (monthsViewNumber < 2 || obj.index < 1) { {{ monthsViewNumber > 1 ? - (resourceStrings.igx_calendar_first_picker_of.replace('{0}', monthsViewNumber.toString()) + ' ' + + (resourceStrings.igx_calendar_first_picker_of!.replace('{0}', monthsViewNumber.toString()) + ' ' + (obj.date | date: 'LLLL yyyy')) : resourceStrings.igx_calendar_selected_month_is + (obj.date | date: 'LLLL yyyy')}} @@ -196,17 +196,17 @@

@switch (selection) { @case ('multi') { {{ monthsViewNumber && monthsViewNumber > 1 ? - resourceStrings.igx_calendar_multi_selection.replace('{0}', monthsViewNumber.toString()) : + resourceStrings.igx_calendar_multi_selection!.replace('{0}', monthsViewNumber.toString()) : resourceStrings.igx_calendar_singular_multi_selection}} } @case ('range') { {{ monthsViewNumber && monthsViewNumber > 1 ? - resourceStrings.igx_calendar_range_selection.replace('{0}', monthsViewNumber.toString()) : + resourceStrings.igx_calendar_range_selection!.replace('{0}', monthsViewNumber.toString()) : resourceStrings.igx_calendar_singular_range_selection}} } @default { {{ monthsViewNumber && monthsViewNumber > 1 ? - resourceStrings.igx_calendar_single_selection.replace('{0}', monthsViewNumber.toString()) : + resourceStrings.igx_calendar_single_selection!.replace('{0}', monthsViewNumber.toString()) : resourceStrings.igx_calendar_singular_single_selection}} } } diff --git a/projects/igniteui-angular/calendar/src/calendar/calendar.component.ts b/projects/igniteui-angular/calendar/src/calendar/calendar.component.ts index 58f152f0791..153bdf3a3d1 100644 --- a/projects/igniteui-angular/calendar/src/calendar/calendar.component.ts +++ b/projects/igniteui-angular/calendar/src/calendar/calendar.component.ts @@ -79,14 +79,14 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @hidden * @internal */ - private _activeDescendant: number; + private _activeDescendant!: number; /** * @hidden * @internal */ @ViewChild("wrapper") - public wrapper: ElementRef; + public wrapper!: ElementRef; /** * Sets/gets the `id` of the calendar. @@ -194,7 +194,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ViewChildren('monthsBtn') - public monthsBtns: QueryList; + public monthsBtns!: QueryList; /** * ViewChild that represents the decade view. @@ -203,7 +203,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ViewChild('decade', { read: IgxYearsViewComponent }) - public dacadeView: IgxYearsViewComponent; + public dacadeView!: IgxYearsViewComponent; /** * ViewChild that represents the months view. @@ -212,7 +212,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ViewChild('months', { read: IgxMonthsViewComponent }) - public monthsView: IgxMonthsViewComponent; + public monthsView!: IgxMonthsViewComponent; /** * ViewChild that represents the days view. @@ -221,7 +221,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ViewChild('days', { read: IgxDaysViewComponent }) - public daysView: IgxDaysViewComponent; + public daysView!: IgxDaysViewComponent; /** * ViewChildrenden representing all of the rendered days views. @@ -230,7 +230,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ViewChildren('days', { read: IgxDaysViewComponent }) - public monthViews: QueryList; + public monthViews!: QueryList; /** * Button for previous month. @@ -239,7 +239,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ViewChild('prevPageBtn') - public prevPageBtn: ElementRef; + public prevPageBtn!: ElementRef; /** * Button for next month. @@ -248,7 +248,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ViewChild('nextPageBtn') - public nextPageBtn: ElementRef; + public nextPageBtn!: ElementRef; /** * Denote if the year view is active. @@ -387,21 +387,21 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @internal */ @ContentChild(forwardRef(() => IgxCalendarHeaderTemplateDirective), { read: IgxCalendarHeaderTemplateDirective, static: true }) - private headerTemplateDirective: IgxCalendarHeaderTemplateDirective; + private headerTemplateDirective!: IgxCalendarHeaderTemplateDirective; /** * @hidden * @internal */ @ContentChild(forwardRef(() => IgxCalendarHeaderTitleTemplateDirective), { read: IgxCalendarHeaderTitleTemplateDirective, static: true }) - private headerTitleTemplateDirective: IgxCalendarHeaderTitleTemplateDirective; + private headerTitleTemplateDirective!: IgxCalendarHeaderTitleTemplateDirective; /** * @hidden * @internal */ @ContentChild(forwardRef(() => IgxCalendarSubheaderTemplateDirective), { read: IgxCalendarSubheaderTemplateDirective, static: true }) - private subheaderTemplateDirective: IgxCalendarSubheaderTemplateDirective; + private subheaderTemplateDirective!: IgxCalendarSubheaderTemplateDirective; /** * @hidden @@ -413,7 +413,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @hidden * @internal */ - protected previewRangeDate: Date; + protected previewRangeDate!: Date; /** * Used to apply the active date when the calendar view is changed @@ -421,7 +421,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af * @hidden * @internal */ - public nextDate: Date; + public nextDate!: Date; /** * Denote if the calendar view was changed with the keyboard @@ -445,7 +445,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af } } - private _showActiveDay: boolean; + private _showActiveDay!: boolean; /** * @hidden @@ -453,7 +453,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af */ protected set showActiveDay(value: boolean) { this._showActiveDay = value; - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } protected get showActiveDay() { @@ -473,7 +473,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af } public ngAfterViewInit() { - this.keyboardNavigation + this.keyboardNavigation! .attachKeyboardHandlers(this.wrapper, this) .set("ArrowUp", this.onArrowUp) .set("ArrowDown", this.onArrowDown) @@ -516,7 +516,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af }); this._destroyRef.onDestroy(() => { - this.keyboardNavigation.detachKeyboardHandlers(); + this.keyboardNavigation!.detachKeyboardHandlers(); }); } @@ -559,7 +559,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af if (this.activeView === IgxCalendarView.Month && event.shiftKey) { this.viewDate = CalendarDay.from(this.viewDate).add('year', delta).native; this.resetActiveDate(this.viewDate); - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } else { this.changePage(false, dir); } @@ -576,7 +576,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af private onArrowUp(event: KeyboardEvent) { if (this.activeView === IgxCalendarView.Month) { this.handleArrowKeydown(event, -7); - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } if (this.activeView === IgxCalendarView.Year) { @@ -591,7 +591,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af private onArrowDown(event: KeyboardEvent) { if (this.activeView === IgxCalendarView.Month) { this.handleArrowKeydown(event, 7); - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } if (this.activeView === IgxCalendarView.Year) { @@ -606,7 +606,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af private onArrowLeft(event: KeyboardEvent) { if (this.activeView === IgxCalendarView.Month) { this.handleArrowKeydown(event, -1); - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } if (this.activeView === IgxCalendarView.Year) { @@ -621,7 +621,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af private onArrowRight(event: KeyboardEvent) { if (this.activeView === IgxCalendarView.Month) { this.handleArrowKeydown(event, 1); - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } if (this.activeView === IgxCalendarView.Year) { @@ -636,7 +636,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af private onEnter(event: KeyboardEvent) { if (this.activeView === IgxCalendarView.Month) { this.handleDateSelection(this.activeDate); - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } if (this.activeView === IgxCalendarView.Year) { @@ -656,8 +656,8 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af .flatMap((view) => view.dates.toArray()) .filter((d) => d.isCurrentMonth && d.isFocusable); - this.activeDate = dates.at(0).date.native; - this.cdr.detectChanges(); + this.activeDate = dates.at(0)!.date.native; + this.cdr!.detectChanges(); } if (this.activeView === IgxCalendarView.Year) { @@ -675,8 +675,8 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af .flatMap((view) => view.dates.toArray()) .filter((d) => d.isCurrentMonth && d.isFocusable); - this.activeDate = dates.at(-1).date.native; - this.cdr.detectChanges(); + this.activeDate = dates.at(-1)!.date.native; + this.cdr!.detectChanges(); } if (this.activeView === IgxCalendarView.Year) { @@ -1102,7 +1102,7 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af const formatObject = Array.isArray(value) ? value.map((date, index) => construct(date, index)) - : construct(value, i); + : construct(value, i!); return { $implicit: formatObject }; } diff --git a/projects/igniteui-angular/calendar/src/calendar/calendar.directives.ts b/projects/igniteui-angular/calendar/src/calendar/calendar.directives.ts index 223fbf6ebb5..d6d300a5129 100644 --- a/projects/igniteui-angular/calendar/src/calendar/calendar.directives.ts +++ b/projects/igniteui-angular/calendar/src/calendar/calendar.directives.ts @@ -18,10 +18,10 @@ export abstract class IgxCalendarViewBaseDirective { public elementRef = inject(ElementRef); @Input() - public value: Date; + public value!: Date; @Input() - public date: Date; + public date!: Date; @Input() public showActive = false; @@ -152,7 +152,7 @@ export class IgxCalendarScrollPageDirective implements AfterViewInit, OnDestroy * @hidden */ @Input() - public startScroll: (keydown?: boolean) => void; + public startScroll!: (keydown?: boolean) => void; /** * A callback function to be invoked when increment/decrement page stops. @@ -160,7 +160,7 @@ export class IgxCalendarScrollPageDirective implements AfterViewInit, OnDestroy * @hidden */ @Input() - public stopScroll: (event: any) => void; + public stopScroll!: (event: any) => void; /** * @hidden @@ -188,7 +188,7 @@ export class IgxCalendarScrollPageDirective implements AfterViewInit, OnDestroy * @hidden */ public ngAfterViewInit() { - fromEvent(this.element.nativeElement, 'keyup').pipe( + fromEvent(this.element.nativeElement, 'keyup').pipe( debounce(() => interval(100)), takeUntil(this.destroy$) ).subscribe((event: KeyboardEvent) => { @@ -196,7 +196,7 @@ export class IgxCalendarScrollPageDirective implements AfterViewInit, OnDestroy }); this.zone.runOutsideAngular(() => { - fromEvent(this.element.nativeElement, 'keydown').pipe( + fromEvent(this.element.nativeElement, 'keydown').pipe( tap((event: KeyboardEvent) => { if (this.platform.isActivationKey(event)) { event.preventDefault(); diff --git a/projects/igniteui-angular/calendar/src/calendar/common/calendar-view.directive.ts b/projects/igniteui-angular/calendar/src/calendar/common/calendar-view.directive.ts index ee239701fa3..4d6b3f313bb 100644 --- a/projects/igniteui-angular/calendar/src/calendar/common/calendar-view.directive.ts +++ b/projects/igniteui-angular/calendar/src/calendar/common/calendar-view.directive.ts @@ -73,7 +73,7 @@ export abstract class IgxCalendarViewDirective implements ControlValueAccessor { * according to the locale and format, if any. */ @Input({ transform: booleanAttribute }) - public formatView: boolean; + public formatView!: boolean; /** * Applies styles to the active item on view focus. @@ -111,7 +111,7 @@ export abstract class IgxCalendarViewDirective implements ControlValueAccessor { * @internal */ @ViewChildren(IGX_CALENDAR_VIEW_ITEM, { read: IGX_CALENDAR_VIEW_ITEM }) - public viewItems: QueryList< + public viewItems!: QueryList< IgxCalendarMonthDirective | IgxCalendarYearDirective >; @@ -125,12 +125,12 @@ export abstract class IgxCalendarViewDirective implements ControlValueAccessor { /** * @hidden */ - protected _locale; + protected _locale!: string; /** * @hidden */ - protected _defaultLocale; + protected _defaultLocale!: string; private _date = new Date(); private _destroyRef = inject(DestroyRef); @@ -234,7 +234,7 @@ export abstract class IgxCalendarViewDirective implements ControlValueAccessor { event.preventDefault(); event.stopPropagation(); - this.date = this.range.at(0); + this.date = this.range.at(0)!; this.activeDateChanged.emit(this.date); } @@ -246,7 +246,7 @@ export abstract class IgxCalendarViewDirective implements ControlValueAccessor { event.preventDefault(); event.stopPropagation(); - this.date = this.range.at(-1); + this.date = this.range.at(-1)!; this.activeDateChanged.emit(this.date); } @@ -329,7 +329,7 @@ export abstract class IgxCalendarViewDirective implements ControlValueAccessor { const outOfRange = !isDateInRanges(date, [ { type: DateRangeType.Between, - dateRange: [this.range.at(0), this.range.at(-1)], + dateRange: [this.range.at(0)!, this.range.at(-1)!], }, ]); @@ -348,8 +348,8 @@ export abstract class IgxCalendarViewDirective implements ControlValueAccessor { private initLocale() { this._defaultLocale = getCurrentI18n(); - onResourceChangeHandle(this._destroyRef, (args: CustomEvent) => { - this._defaultLocale = args.detail.newLocale; + onResourceChangeHandle(this._destroyRef, (args?: CustomEvent) => { + this._defaultLocale = args!.detail.newLocale; }, this); } } diff --git a/projects/igniteui-angular/calendar/src/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/calendar/src/calendar/days-view/day-item.component.ts index 69c708164a9..1646784b5a3 100644 --- a/projects/igniteui-angular/calendar/src/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/calendar/src/calendar/days-view/day-item.component.ts @@ -15,13 +15,13 @@ export class IgxDayItemComponent { private elementRef = inject(ElementRef); @Input() - public date: CalendarDay; + public date!: CalendarDay; @Input() - public viewDate: Date; + public viewDate!: Date; @Input() - public selection: string; + public selection!: string; /** * Returns boolean indicating if the day is selected @@ -40,10 +40,10 @@ export class IgxDayItemComponent { } @Input() - public disabledDates: DateRangeDescriptor[]; + public disabledDates!: DateRangeDescriptor[]; @Input() - public specialDates: DateRangeDescriptor[]; + public specialDates!: DateRangeDescriptor[]; @Input({ transform: booleanAttribute }) public hideOutsideDays = false; diff --git a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts index b6ccda0b399..cf9bede75aa 100644 --- a/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/calendar/src/calendar/days-view/days-view.component.ts @@ -112,7 +112,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af * `` */ @Input({ transform: booleanAttribute }) - public showWeekNumbers: boolean; + public showWeekNumbers!: boolean; /** * @hidden @@ -200,13 +200,13 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af * @hidden */ @ViewChildren(IgxDayItemComponent, { read: IgxDayItemComponent }) - public dates: QueryList; + public dates!: QueryList; - private _activeDate: Date; - private _previewRangeDate: Date; - private _hideLeadingDays: boolean; - private _hideTrailingDays: boolean; - private _showActiveDay: boolean; + private _activeDate!: Date; + private _previewRangeDate!: Date; + private _hideLeadingDays!: boolean; + private _hideTrailingDays!: boolean; + private _showActiveDay!: boolean; private _theme: IgxTheme; @HostBinding('class.igx-days-view') @@ -458,7 +458,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af const weekdays = []; const rawFormatter = getDateFormatter().getIntlFormatter(this.locale, { weekday: 'long' }); - for (const day of this.monthWeeks.at(0)) { + for (const day of this.monthWeeks.at(0)!) { weekdays.push({ long: rawFormatter.format(day.native), formatted: this.formatterWeekday.format(day.native) @@ -479,8 +479,8 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af } return { - short: weekOfYear('narrow').substring(0, 1), - long: weekOfYear('long'), + short: weekOfYear('narrow')!.substring(0, 1), + long: weekOfYear('long')!, } } @@ -503,7 +503,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af */ public isSelected(date: CalendarDay): boolean { const dates = this.value as Date[]; - const hasValue = this.value || (Array.isArray(this.value) && this.value.length === 1); + const hasValue = this.value || (Array.isArray(this.value) && dates.length === 1); if (isDateInRanges(date, this.disabledDates)) { return false; @@ -530,10 +530,12 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af return isDateInRanges(date, [ { type: DateRangeType.Between, - dateRange: [dates.at(0), dates.at(-1)], + dateRange: [dates.at(0)!, dates.at(-1)!], }, ]); } + + return undefined!; } /** @@ -546,7 +548,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af return false; } - let target = dates.at(0); + let target = dates.at(0)!; if (this.previewRangeDate && this.previewRangeDate < target) { target = this.previewRangeDate; @@ -565,7 +567,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af return false; } - let target = dates.at(-1); + let target = dates.at(-1)!; if (this.previewRangeDate && this.previewRangeDate > target) { target = this.previewRangeDate; @@ -591,8 +593,8 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af return false; } - min = min ? min : dates.at(0); - max = max ? max : dates.at(-1); + min = min ? min : dates.at(0)!; + max = max ? max : dates.at(-1)!; return isDateInRanges(date, [ @@ -616,7 +618,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af return isDateInRanges(date, [ { type: DateRangeType.Between, - dateRange: [dates.at(0), this.previewRangeDate], + dateRange: [dates.at(0)!, this.previewRangeDate], }, ]); } @@ -635,7 +637,7 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af const dates = this.value as Date[]; if (this.selection === 'range' && dates.length === 1) { - const first = CalendarDay.from(dates.at(0)); + const first = CalendarDay.from(dates.at(0)!); if (!first.equalTo(date)) { this.setPreviewRangeDate(date); @@ -653,6 +655,6 @@ export class IgxDaysViewComponent extends IgxCalendarBaseDirective implements Af } private setPreviewRangeDate(value?: Date) { - this.previewRangeDate = value; + this.previewRangeDate = value!; } } diff --git a/projects/igniteui-angular/calendar/src/calendar/month-picker/month-picker.component.ts b/projects/igniteui-angular/calendar/src/calendar/month-picker/month-picker.component.ts index a258192d5f6..268fb30f966 100644 --- a/projects/igniteui-angular/calendar/src/calendar/month-picker/month-picker.component.ts +++ b/projects/igniteui-angular/calendar/src/calendar/month-picker/month-picker.component.ts @@ -58,14 +58,14 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements * @hidden * @internal */ - private _activeDescendant: number; + private _activeDescendant!: number; /** * @hidden * @internal */ @ViewChild("wrapper") - public wrapper: ElementRef; + public wrapper!: ElementRef; /** * The default css class applied to the component. @@ -79,25 +79,25 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements * @hidden */ @ViewChild("months", { read: IgxMonthsViewComponent }) - public monthsView: IgxMonthsViewComponent; + public monthsView!: IgxMonthsViewComponent; /** * @hidden */ @ViewChild("decade", { read: IgxYearsViewComponent }) - public dacadeView: IgxYearsViewComponent; + public dacadeView!: IgxYearsViewComponent; /** * @hidden */ @ViewChild("days", { read: IgxDaysViewComponent }) - public daysView: IgxDaysViewComponent; + public daysView!: IgxDaysViewComponent; /** * @hidden */ @ViewChild("yearsBtn") - public yearsBtn: ElementRef; + public yearsBtn!: ElementRef; /** * @hidden @@ -292,7 +292,7 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements } } - private _showActiveDay: boolean; + private _showActiveDay!: boolean; /** * @hidden @@ -300,7 +300,7 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements */ protected set showActiveDay(value: boolean) { this._showActiveDay = value; - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } protected get showActiveDay() { @@ -328,7 +328,7 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements } public ngAfterViewInit() { - this.keyboardNavigation + this.keyboardNavigation! .attachKeyboardHandlers(this.wrapper, this) .set("ArrowUp", this.onArrowUp) .set("ArrowDown", this.onArrowDown) @@ -351,7 +351,7 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements }); this._destroyRef.onDestroy(() => { - this.keyboardNavigation.detachKeyboardHandlers(); + this.keyboardNavigation!.detachKeyboardHandlers(); }); } @@ -373,7 +373,7 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements if (this.isDefaultView && event.shiftKey) { this.viewDate = CalendarDay.from(this.viewDate).add('year', delta).native; - this.cdr.detectChanges(); + this.cdr!.detectChanges(); } else { delta > 0 ? this.nextPage() : this.previousPage(); } @@ -509,7 +509,7 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements const formatObject = Array.isArray(value) ? value.map((date, index) => construct(date, index)) - : construct(value, i); + : construct(value, i!); return { $implicit: formatObject }; } diff --git a/projects/igniteui-angular/card/src/card/card.component.ts b/projects/igniteui-angular/card/src/card/card.component.ts index 90eb010d07f..54183860e6b 100644 --- a/projects/igniteui-angular/card/src/card/card.component.ts +++ b/projects/igniteui-angular/card/src/card/card.component.ts @@ -328,7 +328,7 @@ export class IgxCardActionsComponent implements OnInit, OnChanges { * @internal */ public ngOnInit() { - if (!this.isVerticalSet && this.card.horizontal) { + if (!this.isVerticalSet && this.card!.horizontal) { this.vertical = true; } } diff --git a/projects/igniteui-angular/carousel/src/carousel/carousel-base.ts b/projects/igniteui-angular/carousel/src/carousel/carousel-base.ts index e2b7eb87bf1..e6538fca1ba 100644 --- a/projects/igniteui-angular/carousel/src/carousel/carousel-base.ts +++ b/projects/igniteui-angular/carousel/src/carousel/carousel-base.ts @@ -33,9 +33,9 @@ export abstract class IgxCarouselComponentBase implements OnDestroy { public leaveAnimationDone = new EventEmitter(); /** @hidden */ - protected currentItem: IgxSlideComponentBase; + protected currentItem!: IgxSlideComponentBase; /** @hidden */ - protected previousItem: IgxSlideComponentBase; + protected previousItem!: IgxSlideComponentBase; /** @hidden */ protected enterAnimationPlayer?: AnimationPlayer; /** @hidden */ @@ -52,18 +52,18 @@ export abstract class IgxCarouselComponentBase implements OnDestroy { public ngOnDestroy(): void { if (this.enterAnimationPlayer) { this.enterAnimationPlayer.destroy(); - this.enterAnimationPlayer = null; + this.enterAnimationPlayer = null!; } if (this.leaveAnimationPlayer) { this.leaveAnimationPlayer.destroy(); - this.leaveAnimationPlayer = null; + this.leaveAnimationPlayer = null!; } } /** @hidden */ protected triggerAnimations() { if (this.animationType !== CarouselAnimationType.none) { - if (this.animationStarted(this.leaveAnimationPlayer) || this.animationStarted(this.enterAnimationPlayer)) { + if (this.animationStarted(this.leaveAnimationPlayer!) || this.animationStarted(this.enterAnimationPlayer!)) { requestAnimationFrame(() => { this.resetAnimations(); this.playAnimations(); @@ -86,13 +86,13 @@ export abstract class IgxCarouselComponentBase implements OnDestroy { } private resetAnimations() { - if (this.animationStarted(this.leaveAnimationPlayer)) { - this.leaveAnimationPlayer.reset(); + if (this.animationStarted(this.leaveAnimationPlayer!)) { + this.leaveAnimationPlayer!.reset(); this.leaveAnimationDone.emit(); } - if (this.animationStarted(this.enterAnimationPlayer)) { - this.enterAnimationPlayer.reset(); + if (this.animationStarted(this.enterAnimationPlayer!)) { + this.enterAnimationPlayer!.reset(); this.enterAnimationDone.emit(); this.cdr.markForCheck(); } @@ -137,12 +137,12 @@ export abstract class IgxCarouselComponentBase implements OnDestroy { return { enterAnimation: useAnimation(fadeIn, { params: { duration: `${duration}ms`, startOpacity: `${this.animationPosition}` } }), - leaveAnimation: null + leaveAnimation: null! }; } return { - enterAnimation: null, - leaveAnimation: null + enterAnimation: null!, + leaveAnimation: null! }; } @@ -157,7 +157,7 @@ export abstract class IgxCarouselComponentBase implements OnDestroy { // TODO: animation may never end. Find better way to clean up the player if (this.enterAnimationPlayer) { this.enterAnimationPlayer.destroy(); - this.enterAnimationPlayer = null; + this.enterAnimationPlayer = null!; } this.animationPosition = 0; this.newDuration = 0; @@ -180,7 +180,7 @@ export abstract class IgxCarouselComponentBase implements OnDestroy { // TODO: animation may never end. Find better way to clean up the player if (this.leaveAnimationPlayer) { this.leaveAnimationPlayer.destroy(); - this.leaveAnimationPlayer = null; + this.leaveAnimationPlayer = null!; } this.animationPosition = 0; this.newDuration = 0; diff --git a/projects/igniteui-angular/carousel/src/carousel/carousel.component.ts b/projects/igniteui-angular/carousel/src/carousel/carousel.component.ts index 08f5d295a05..8cacf44fe48 100644 --- a/projects/igniteui-angular/carousel/src/carousel/carousel.component.ts +++ b/projects/igniteui-angular/carousel/src/carousel/carousel.component.ts @@ -2,7 +2,7 @@ import { NgClass, NgTemplateOutlet } from '@angular/common'; import { AfterContentInit, Component, ContentChild, ContentChildren, ElementRef, EventEmitter, HostBinding, HostListener, Input, IterableChangeRecord, IterableDiffer, IterableDiffers, OnDestroy, Output, QueryList, TemplateRef, ViewChild, ViewChildren, booleanAttribute, inject, ChangeDetectionStrategy } from '@angular/core'; import { merge, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -import { CarouselResourceStringsEN, ICarouselResourceStrings, isLeftToRight } from 'igniteui-angular/core'; +import { CarouselResourceStringsEN, ICarouselResourceStrings, IgxGestureEvent, isLeftToRight } from 'igniteui-angular/core'; import { first, IBaseEventArgs, IgxTouchManager, last, PlatformUtil } from 'igniteui-angular/core'; import { CarouselAnimationDirection, IgxCarouselComponentBase } from './carousel-base'; import { IgxCarouselIndicatorDirective, IgxCarouselNextButtonDirective, IgxCarouselPrevButtonDirective } from './carousel.directives'; @@ -235,7 +235,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On * ``` */ @ContentChild(IgxCarouselIndicatorDirective, { read: TemplateRef, static: false }) - public indicatorTemplate: TemplateRef = null; + public indicatorTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering carousel next button @@ -258,7 +258,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On * ``` */ @ContentChild(IgxCarouselNextButtonDirective, { read: TemplateRef, static: false }) - public nextButtonTemplate: TemplateRef = null; + public nextButtonTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering carousel previous button @@ -281,7 +281,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On * ``` */ @ContentChild(IgxCarouselPrevButtonDirective, { read: TemplateRef, static: false }) - public prevButtonTemplate: TemplateRef = null; + public prevButtonTemplate: TemplateRef = null!; /** * The collection of `slides` currently in the carousel. @@ -292,7 +292,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On * @memberOf IgxCarouselComponent */ @ContentChildren(IgxSlideComponent) - public slides: QueryList; + public slides!: QueryList; /** * An event that is emitted after a slide transition has happened. @@ -350,33 +350,33 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On @Output() public carouselPlaying = new EventEmitter(); @ViewChild('defaultIndicator', { read: TemplateRef, static: true }) - private defaultIndicator: TemplateRef; + private defaultIndicator!: TemplateRef; @ViewChild('defaultNextButton', { read: TemplateRef, static: true }) - private defaultNextButton: TemplateRef; + private defaultNextButton!: TemplateRef; @ViewChild('defaultPrevButton', { read: TemplateRef, static: true }) - private defaultPrevButton: TemplateRef; + private defaultPrevButton!: TemplateRef; @ViewChildren('indicators', { read: ElementRef }) - private _indicators: QueryList>; + private _indicators!: QueryList>; /** * @hidden * @internal */ - public stoppedByInteraction: boolean; - protected override currentItem: IgxSlideComponent; - protected override previousItem: IgxSlideComponent; - private _interval: number; - private _resourceStrings: ICarouselResourceStrings = null; + public stoppedByInteraction!: boolean; + protected override currentItem!: IgxSlideComponent; + protected override previousItem!: IgxSlideComponent; + private _interval!: number; + private _resourceStrings: ICarouselResourceStrings = null!; private _defaultResourceStrings = getCurrentResourceStrings(CarouselResourceStringsEN); private lastInterval: any; - private playing: boolean; - private destroyed: boolean; + private playing!: boolean; + private destroyed!: boolean; private destroy$ = new Subject(); private differ: IterableDiffer | null = null; - private incomingSlide: IgxSlideComponent; + private incomingSlide!: IgxSlideComponent; private _hasKeyboardFocusOnIndicators = false; /** @@ -532,14 +532,14 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On constructor() { super(); - this.differ = this.iterableDiffers.find([]).create(null); + this.differ = this.iterableDiffers.find([]).create(null!); onResourceChangeHandle(this.destroy$, () => { this._defaultResourceStrings = getCurrentResourceStrings(CarouselResourceStringsEN, false); }, this); } /** @hidden */ - public onTap(event) { + public onTap(event: IgxGestureEvent) { // Play/pause only when the tap lands on a slide (or its content), // not on the navigation buttons or indicators. const slide = (event.target as Element)?.closest?.('.igx-slide'); @@ -574,28 +574,28 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On } /** @hidden */ - public onPanLeft(event) { + public onPanLeft(event: IgxGestureEvent) { if (!this.vertical) { this.pan(event); } } /** @hidden */ - public onPanRight(event) { + public onPanRight(event: IgxGestureEvent) { if (!this.vertical) { this.pan(event); } } /** @hidden */ - public onPanUp(event) { + public onPanUp(event: IgxGestureEvent) { if (this.vertical) { this.pan(event); } } /** @hidden */ - public onPanDown(event) { + public onPanDown(event: IgxGestureEvent) { if (this.vertical) { this.pan(event); } @@ -604,7 +604,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On /** * @hidden */ - public onPanEnd(event) { + public onPanEnd(event: IgxGestureEvent) { if (!this.gesturesSupport) { return; } @@ -740,7 +740,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On * @memberOf IgxCarouselComponent */ public get(index: number): IgxSlideComponent { - return this.slides.find((slide) => slide.index === index); + return this.slides.find((slide) => slide.index === index)!; } /** @@ -906,7 +906,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On * * @hidden */ - private onPan(event) { + private onPan(event: IgxGestureEvent) { if (Math.abs(event.deltaX) >= Math.abs(event.deltaY)) { if (event.deltaX < 0) { this.onPanLeft(event); @@ -982,7 +982,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On slide.nativeElement.style.opacity = ''; } - private pan(event) { + private pan(event: any) { const slideSize = this.vertical ? this.currentItem.nativeElement.offsetHeight : this.currentItem.nativeElement.offsetWidth; @@ -996,7 +996,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On } if (!this.loop && ((this.current === 0 && delta > 0) || (this.current === this.total - 1 && delta < 0))) { - this.incomingSlide = null; + this.incomingSlide = null!; return; } @@ -1066,17 +1066,17 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On private finishAnimations() { - if (this.animationStarted(this.leaveAnimationPlayer)) { - this.leaveAnimationPlayer.finish(); + if (this.animationStarted(this.leaveAnimationPlayer!)) { + this.leaveAnimationPlayer!.finish(); } - if (this.animationStarted(this.enterAnimationPlayer)) { - this.enterAnimationPlayer.finish(); + if (this.animationStarted(this.enterAnimationPlayer!)) { + this.enterAnimationPlayer!.finish(); } } private initSlides(change: QueryList) { - const diff = this.differ.diff(change.toArray()); + const diff = this.differ!.diff(change.toArray()); if (diff) { this.slides.reduce((_any, c, ind) => c.index = ind, 0); // reset slides indexes diff.forEachAddedItem((record: IterableChangeRecord) => { diff --git a/projects/igniteui-angular/carousel/src/carousel/slide.component.ts b/projects/igniteui-angular/carousel/src/carousel/slide.component.ts index edca27ccadf..891ce2a3850 100644 --- a/projects/igniteui-angular/carousel/src/carousel/slide.component.ts +++ b/projects/igniteui-angular/carousel/src/carousel/slide.component.ts @@ -33,7 +33,7 @@ export class IgxSlideComponent implements AfterContentChecked, OnDestroy, IgxSli * * @memberOf IgxSlideComponent */ - @Input() public index: number; + @Input() public index!: number; /** * Gets/sets the target `direction` for the slide. @@ -45,10 +45,10 @@ export class IgxSlideComponent implements AfterContentChecked, OnDestroy, IgxSli * * @memberOf IgxSlideComponent */ - @Input() public direction: CarouselAnimationDirection; + @Input() public direction!: CarouselAnimationDirection; @Input() - public total: number; + public total!: number; /** * Returns the `tabIndex` of the slide component. @@ -68,7 +68,7 @@ export class IgxSlideComponent implements AfterContentChecked, OnDestroy, IgxSli * @hidden */ @HostBinding('attr.id') - public id: string; + public id!: string; /** * Returns the `role` of the slide component. @@ -81,7 +81,7 @@ export class IgxSlideComponent implements AfterContentChecked, OnDestroy, IgxSli /** @hidden */ @HostBinding('attr.aria-labelledby') - public ariaLabelledBy; + public ariaLabelledBy: any; /** * Returns the class of the slide component. diff --git a/projects/igniteui-angular/chips/src/chips/chip.component.ts b/projects/igniteui-angular/chips/src/chips/chip.component.ts index fe5f2996585..77988e130b6 100644 --- a/projects/igniteui-angular/chips/src/chips/chip.component.ts +++ b/projects/igniteui-angular/chips/src/chips/chip.component.ts @@ -150,7 +150,7 @@ export class IgxChipComponent implements OnInit, OnDestroy { if (this._tabIndex !== null) { return this._tabIndex; } - return !this.disabled ? 0 : null; + return !this.disabled ? 0 : null!; } /** @@ -222,7 +222,7 @@ export class IgxChipComponent implements OnInit, OnDestroy { * ``` */ @Input() - public removeIcon: TemplateRef; + public removeIcon!: TemplateRef; /** * Defines if the chip can be selected on click or through navigation, @@ -246,7 +246,7 @@ export class IgxChipComponent implements OnInit, OnDestroy { * ``` */ @Input() - public selectIcon: TemplateRef; + public selectIcon!: TemplateRef; /** * @hidden @@ -536,28 +536,28 @@ export class IgxChipComponent implements OnInit, OnDestroy { * ``` */ @ViewChild('chipArea', { read: IgxDragDirective, static: true }) - public dragDirective: IgxDragDirective; + public dragDirective!: IgxDragDirective; /** * @hidden * @internal */ @ViewChild('chipArea', { read: ElementRef, static: true }) - public chipArea: ElementRef; + public chipArea!: ElementRef; /** * @hidden * @internal */ @ViewChild('defaultRemoveIcon', { read: TemplateRef, static: true }) - public defaultRemoveIcon: TemplateRef; + public defaultRemoveIcon!: TemplateRef; /** * @hidden * @internal */ @ViewChild('defaultSelectIcon', { read: TemplateRef, static: true }) - public defaultSelectIcon: TemplateRef; + public defaultSelectIcon!: TemplateRef; /** * @hidden @@ -605,12 +605,12 @@ export class IgxChipComponent implements OnInit, OnDestroy { protected get chipSize(): ɵSize { return this.computedStyles?.getPropertyValue('--ig-size') || ɵSize.Medium; } - protected _tabIndex = null; + protected _tabIndex: number | null = null; protected _selected = false; protected _selectedItemClass = 'igx-chip__item--selected'; protected _movedWhileRemoving = false; - protected computedStyles; - private _resourceStrings: IChipResourceStrings = null; + protected computedStyles: any; + private _resourceStrings: IChipResourceStrings = null!; private _defaultResourceStrings = getCurrentResourceStrings(ChipResourceStringsEN); constructor() { @@ -641,16 +641,6 @@ export class IgxChipComponent implements OnInit, OnDestroy { }; } - public onSelectTransitionDone(event) { - if (event.target.tagName) { - // Trigger onSelectionDone on when `width` property is changed and the target is valid element(not comment). - this.selectedChanged.emit({ - owner: this, - originalEvent: event - }); - } - } - /** * @hidden * @internal @@ -881,7 +871,7 @@ export class IgxChipComponent implements OnInit, OnDestroy { } // End chip igxDrop behavior - protected changeSelection(newValue: boolean, srcEvent = null) { + protected changeSelection(newValue: boolean, srcEvent: IDragBaseEventArgs | IDropBaseEventArgs | KeyboardEvent | MouseEvent | TouchEvent = null!) { const onSelectArgs: IChipSelectEventArgs = { originalEvent: srcEvent, owner: this, @@ -918,7 +908,7 @@ export class IgxChipComponent implements OnInit, OnDestroy { } public ngOnInit(): void { - this.computedStyles = this.document.defaultView.getComputedStyle(this.nativeElement); + this.computedStyles = this.document.defaultView!.getComputedStyle(this.nativeElement); } public ngOnDestroy(): void { diff --git a/projects/igniteui-angular/chips/src/chips/chips-area.component.ts b/projects/igniteui-angular/chips/src/chips/chips-area.component.ts index 0b613359ad6..927d1ee283c 100644 --- a/projects/igniteui-angular/chips/src/chips/chips-area.component.ts +++ b/projects/igniteui-angular/chips/src/chips/chips-area.component.ts @@ -89,7 +89,7 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy * ``` */ @Input() - public width: number; + public width!: number; /** @hidden @internal */ @HostBinding('style.width.rem') @@ -106,7 +106,7 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy * ``` */ @Input() - public height: number; + public height!: number; /** @hidden @internal */ @HostBinding('style.height.rem') @@ -172,18 +172,18 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy * ``` */ @ContentChildren(IgxChipComponent, { descendants: true }) - public chipsList: QueryList; + public chipsList!: QueryList; protected destroy$ = new Subject(); @HostBinding('class') protected hostClass = 'igx-chip-area'; - private modifiedChipsArray: IgxChipComponent[]; + private modifiedChipsArray!: IgxChipComponent[]; private _differ: IterableDiffer | null = null; constructor() { - this._differ = this._iterableDiffers.find([]).create(null); + this._differ = this._iterableDiffers.find([]).create(null!); } /** @@ -196,7 +196,7 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy const selectedChips = this.chipsList.filter((item: IgxChipComponent) => item.selected); if (selectedChips.length) { this.selectionChange.emit({ - originalEvent: null, + originalEvent: null!, newSelection: selectedChips, owner: this }); @@ -210,7 +210,7 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy */ public ngDoCheck(): void { if (this.chipsList) { - const changes = this._differ.diff(this.chipsList.toArray()); + const changes = this._differ!.diff(this.chipsList.toArray()); if (changes) { changes.forEachAddedItem((addedChip) => { addedChip.item.moveStart.pipe(takeUntil(addedChip.item.destroy$)).subscribe((args) => { @@ -258,7 +258,7 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy orderChanged = this.positionChipAtIndex(dragChipIndex, dragChipIndex - 1, false, event.originalEvent); if (orderChanged) { setTimeout(() => { - this.chipsList.get(dragChipIndex - 1).nativeElement.focus(); + this.chipsList.get(dragChipIndex - 1)!.nativeElement.focus(); }); } } else if (event.originalEvent.key === 'ArrowRight' || event.originalEvent.key === 'Right') { @@ -316,7 +316,7 @@ export class IgxChipsAreaComponent implements DoCheck, AfterViewInit, OnDestroy * @hidden * @internal */ - protected positionChipAtIndex(chipIndex, targetIndex, shiftRestLeft, originalEvent) { + protected positionChipAtIndex(chipIndex: number, targetIndex: number, shiftRestLeft: boolean, originalEvent: IDragBaseEventArgs | IDropBaseEventArgs | KeyboardEvent | MouseEvent | TouchEvent) { if (chipIndex < 0 || this.chipsList.length <= chipIndex || targetIndex < 0 || this.chipsList.length <= targetIndex) { return false; diff --git a/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts b/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts index 61392952a86..9cc1aded856 100644 --- a/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts +++ b/projects/igniteui-angular/combo/src/combo/combo-add-item.component.ts @@ -22,7 +22,7 @@ export class IgxComboAddItemComponent extends IgxComboItemComponent { public override set selected(value: boolean) { } - public override clicked(event?) {// eslint-disable-line + public override clicked(_event?: MouseEvent) { this.comboAPI.disableTransitions = false; this.comboAPI.add_custom_item(); } diff --git a/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts b/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts index 96a31533d58..cba4eb15118 100644 --- a/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts +++ b/projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts @@ -27,7 +27,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I * @internal */ @ContentChildren(IgxComboItemComponent, { descendants: true }) - public override children: QueryList = null; + public override children: QueryList = null!; /** @hidden @internal */ public override get scrollContainer(): HTMLElement { @@ -37,7 +37,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I protected get isScrolledToLast(): boolean { const scrollTop = this.virtDir.scrollPosition; - const scrollHeight = this.virtDir.getScroll().scrollHeight; + const scrollHeight = this.virtDir.getScroll()!.scrollHeight; return Math.floor(scrollTop + this.virtDir.igxForContainerSize) === scrollHeight; } @@ -52,7 +52,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I return this.children.toArray() .sort((a: IgxDropDownItemBaseDirective, b: IgxDropDownItemBaseDirective) => a.index - b.index); } - return null; + return null!; } /** @@ -119,7 +119,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I /** * @hidden @internal */ - public onBlur(_evt?) { + public onBlur(_evt?: Event) { this.focusedItem = null; this.combo.setActiveDescendant(); } @@ -135,7 +135,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I * @hidden */ public override navigateFirst() { - this.navigateItem(this.virtDir.igxForOf.findIndex(e => !e?.isHeader)); + this.navigateItem(this.virtDir.igxForOf!.findIndex(e => !e?.isHeader)); this.combo.setActiveDescendant(); } @@ -157,7 +157,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I * @hidden */ public override navigateNext() { - const lastIndex = this.combo.totalItemCount ? this.combo.totalItemCount - 1 : this.virtDir.igxForOf.length - 1; + const lastIndex = this.combo.totalItemCount ? this.combo.totalItemCount - 1 : this.virtDir.igxForOf!.length - 1; if (this._focusedItem && this._focusedItem.index === lastIndex) { this.focusAddItemButton(); } else { @@ -183,7 +183,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I * @hidden @internal */ public override updateScrollPosition() { - this.virtDir.getScroll().scrollTop = this._scrollPosition; + this.virtDir.getScroll()!.scrollTop = this._scrollPosition; } /** @@ -206,14 +206,14 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I } public override ngAfterViewInit() { - this.virtDir.getScroll().addEventListener('scroll', this.scrollHandler); + this.virtDir.getScroll()!.addEventListener('scroll', this.scrollHandler); } /** * @hidden @internal */ public override ngOnDestroy(): void { - this.virtDir.getScroll().removeEventListener('scroll', this.scrollHandler); + this.virtDir.getScroll()!.removeEventListener('scroll', this.scrollHandler); super.ngOnDestroy(); } @@ -239,7 +239,7 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I if (this.isAddItemFocused()) { return; } else { - this.selectItem(this.focusedItem); + this.selectItem(this.focusedItem!); } } diff --git a/projects/igniteui-angular/combo/src/combo/combo-item.component.ts b/projects/igniteui-angular/combo/src/combo/combo-item.component.ts index ebeefba3fde..9e149770e24 100644 --- a/projects/igniteui-angular/combo/src/combo/combo-item.component.ts +++ b/projects/igniteui-angular/combo/src/combo/combo-item.component.ts @@ -47,7 +47,7 @@ export class IgxComboItemComponent extends IgxDropDownItemComponent { /** @hidden @internal */ @Input({ transform: booleanAttribute }) - public singleMode: boolean; + public singleMode!: boolean; /** * @hidden @@ -110,7 +110,7 @@ export class IgxComboItemComponent extends IgxDropDownItemComponent { return rect.y >= parentDiv.y; } - public override clicked(event): void { + public override clicked(event: MouseEvent): void { this.comboAPI.disableTransitions = false; if (!this.isSelectable) { return; diff --git a/projects/igniteui-angular/combo/src/combo/combo.api.ts b/projects/igniteui-angular/combo/src/combo/combo.api.ts index bf48875c880..e0f67630fff 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.api.ts +++ b/projects/igniteui-angular/combo/src/combo/combo.api.ts @@ -7,7 +7,7 @@ import { Injectable } from '@angular/core'; @Injectable() export class IgxComboAPIService { public disableTransitions = false; - protected combo: IgxComboBase; + protected combo!: IgxComboBase; public get valueKey() { return this.combo.valueKey !== null && this.combo.valueKey !== undefined ? this.combo.valueKey : null; @@ -29,7 +29,7 @@ export class IgxComboAPIService { } public clear(): void { - this.combo = null; + this.combo = null!; } public add_custom_item(): void { diff --git a/projects/igniteui-angular/combo/src/combo/combo.common.ts b/projects/igniteui-angular/combo/src/combo/combo.common.ts index bfabf4df31b..6ddf69ddee8 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.common.ts +++ b/projects/igniteui-angular/combo/src/combo/combo.common.ts @@ -163,7 +163,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public overlaySettings: OverlaySettings = null; + public overlaySettings: OverlaySettings = null!; /** * Gets/gets combo id. @@ -211,7 +211,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh */ @HostBinding('style.width') @Input() - public width: string; + public width!: string; /** * Controls whether custom values can be added to the collection @@ -247,7 +247,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh if (this.itemHeight && !this._itemsMaxHeight) { return this.itemHeight * this.itemsInContainer; } - return this._itemsMaxHeight; + return this._itemsMaxHeight!; } public set itemsMaxHeight(val: number) { @@ -276,7 +276,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh */ @Input() public get itemHeight(): number { - return this._itemHeight; + return this._itemHeight!; } public set itemHeight(val: number) { @@ -297,7 +297,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public itemsWidth: string; + public itemsWidth!: string; /** * Defines the placeholder value for the combo value field @@ -313,7 +313,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public placeholder: string; + public placeholder!: string; /** * Combo data source. @@ -351,7 +351,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public valueKey: string = null; + public valueKey: string = null!; @Input() public set displayKey(val: string) { @@ -432,7 +432,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public filterFunction: (collection: any[], searchValue: any, filteringOptions: IComboFilteringOptions) => any[]; + public filterFunction!: (collection: any[], searchValue: any, filteringOptions: IComboFilteringOptions) => any[]; /** * Sets aria-labelledby attribute value. @@ -441,7 +441,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @Input() - public ariaLabelledBy: string; + public ariaLabelledBy!: string; /** @hidden @internal */ @HostBinding('class.igx-combo') @@ -594,7 +594,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboItemDirective, { read: TemplateRef }) - public itemTemplate: TemplateRef = null; + public itemTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering the HEADER for the combo items list @@ -617,7 +617,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboHeaderDirective, { read: TemplateRef }) - public headerTemplate: TemplateRef = null; + public headerTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering the FOOTER for the combo items list @@ -640,7 +640,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboFooterDirective, { read: TemplateRef }) - public footerTemplate: TemplateRef = null; + public footerTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering HEADER ITEMS for groups in the combo list @@ -661,7 +661,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboHeaderItemDirective, { read: TemplateRef }) - public headerItemTemplate: TemplateRef = null; + public headerItemTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down @@ -684,7 +684,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboAddItemDirective, { read: TemplateRef }) - public addItemTemplate: TemplateRef = null; + public addItemTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down @@ -707,7 +707,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboEmptyDirective, { read: TemplateRef }) - public emptyTemplate: TemplateRef = null; + public emptyTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering the combo TOGGLE(open/close) button @@ -728,7 +728,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboToggleIconDirective, { read: TemplateRef }) - public toggleIconTemplate: TemplateRef = null; + public toggleIconTemplate: TemplateRef = null!; /** * The custom template, if any, that should be used when rendering the combo CLEAR button @@ -749,47 +749,47 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ @ContentChild(IgxComboClearIconDirective, { read: TemplateRef }) - public clearIconTemplate: TemplateRef = null; + public clearIconTemplate: TemplateRef = null!; /** @hidden @internal */ - @ContentChild(forwardRef(() => IgxLabelDirective), { static: true }) public label: IgxLabelDirective; + @ContentChild(forwardRef(() => IgxLabelDirective), { static: true }) public label?: IgxLabelDirective; /** @hidden @internal */ @ViewChild('inputGroup', { read: IgxInputGroupComponent, static: true }) - public inputGroup: IgxInputGroupComponent; + public inputGroup!: IgxInputGroupComponent; /** @hidden @internal */ @ViewChild('comboInput', { read: IgxInputDirective, static: true }) - public comboInput: IgxInputDirective; + public comboInput!: IgxInputDirective; /** @hidden @internal */ @ViewChild('searchInput') - public searchInput: ElementRef = null; + public searchInput: ElementRef = null!; /** @hidden @internal */ @ViewChild(IgxForOfDirective, { static: true }) - public virtualScrollContainer: IgxForOfDirective; + public virtualScrollContainer!: IgxForOfDirective; @ViewChild(IgxForOfDirective, { read: IgxForOfDirective, static: true }) - protected virtDir: IgxForOfDirective; + protected virtDir!: IgxForOfDirective; @ViewChild('dropdownItemContainer', { static: true }) - protected dropdownContainer: ElementRef = null; + protected dropdownContainer: ElementRef = null!; @ViewChild('primitive', { read: TemplateRef, static: true }) - protected primitiveTemplate: TemplateRef; + protected primitiveTemplate!: TemplateRef; @ViewChild('complex', { read: TemplateRef, static: true }) - protected complexTemplate: TemplateRef; + protected complexTemplate!: TemplateRef; @ContentChildren(IgxPrefixDirective, { descendants: true }) - protected prefixes: QueryList; + protected prefixes!: QueryList; @ContentChildren(IgxSuffixDirective, { descendants: true }) - protected suffixes: QueryList; + protected suffixes!: QueryList; @ViewChildren(IgxSuffixDirective) - protected internalSuffixes: QueryList; + protected internalSuffixes!: QueryList; /** @hidden @internal */ public get searchValue(): string { @@ -802,9 +802,9 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh /** @hidden @internal */ public get isRemote() { - return this.totalItemCount > 0 && + return !!(this.totalItemCount > 0 && this.valueKey && - this.dataType === DataTypes.COMPLEX; + this.dataType === DataTypes.COMPLEX); } /** @hidden @internal */ @@ -964,35 +964,35 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh this._filteringOptions = value; } - protected containerSize = undefined; + protected containerSize: number | undefined = undefined; protected itemSize = undefined; - protected _data = []; - protected _value = []; + protected _data: any[] = []; + protected _value: any[] = []; protected _displayValue = ''; protected _groupKey = ''; protected _searchValue = ''; - protected _filteredData = []; - protected _displayKey: string; + protected _filteredData: any[] = []; + protected _displayKey!: string; protected _remoteSelection = {}; - protected _resourceStrings: IComboResourceStrings = null; + protected _resourceStrings: IComboResourceStrings = null!; protected _defaultResourceStrings = getCurrentResourceStrings(ComboResourceStringsEN); protected _valid = IgxInputState.INITIAL; - protected ngControl: NgControl = null; + protected ngControl: NgControl = null!; protected destroy$ = new Subject(); protected _onTouchedCallback: () => void = noop; protected _onChangeCallback: (_: any) => void = noop; protected compareCollator = new Intl.Collator(); - protected computedStyles; + protected computedStyles: any; private _id: string = `igx-combo-${NEXT_ID++}`; private _disableFiltering = false; - private _type = null; + private _type: IgxInputGroupType | null = null; private _dataType = ''; - private _itemHeight = undefined; - private _itemsMaxHeight = null; - private _overlaySettings: OverlaySettings; + private _itemHeight: number | undefined = undefined; + private _itemsMaxHeight: number | null = null; + private _overlaySettings!: OverlaySettings; private _groupSortingDirection: SortingDirection = SortingDirection.Asc; - private _filteringOptions: IComboFilteringOptions; + private _filteringOptions!: IComboFilteringOptions; private _defaultFilteringOptions: IComboFilteringOptions = { caseSensitive: false }; private itemsInContainer = 10; @@ -1039,17 +1039,17 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh /** @hidden @internal */ public ngOnInit() { - this.ngControl = this._injector.get(NgControl, null); + this.ngControl = this._injector!.get(NgControl, null); this.selectionService.set(this.id, new Set()); this._iconService?.addSvgIconFromText(caseSensitive.name, caseSensitive.value, 'imx-icons'); - this.computedStyles = this.document.defaultView.getComputedStyle(this.elementRef.nativeElement); + this.computedStyles = this.document.defaultView!.getComputedStyle(this.elementRef.nativeElement); } /** @hidden @internal */ public ngAfterViewInit(): void { - this.filteredData = [...this.data]; + this.filteredData = [...this.data!]; if (this.ngControl) { - this.ngControl.statusChanges.pipe(takeUntil(this.destroy$)).subscribe(this.onStatusChanged); + this.ngControl.statusChanges!.pipe(takeUntil(this.destroy$)).subscribe(this.onStatusChanged); this.manageRequiredAsterisk(); this.cdr.detectChanges(); } @@ -1175,8 +1175,8 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh Object.assign(addedItem, { [this.groupKey]: this.defaultFallbackGroup }); } // expose shallow copy instead of this.data in event args so this.data can't be mutated - const oldCollection = [...this.data]; - const newCollection = [...this.data, addedItem]; + const oldCollection = [...this.data!]; + const newCollection = [...this.data!, addedItem]; const args: IComboItemAdditionEvent = { oldCollection, addedItem, newCollection, owner: this, cancel: false }; @@ -1184,9 +1184,9 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh if (args.cancel) { return; } - this.data.push(args.addedItem); + this.data!.push(args.addedItem); // trigger re-render - this.data = cloneArray(this.data); + this.data = cloneArray(this.data!); this.select(this.valueKey !== null && this.valueKey !== undefined ? [args.addedItem[this.valueKey]] : [args.addedItem], false); this.customValueFlag = false; @@ -1211,7 +1211,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh }; this.searchInputUpdate.emit(args); if (args.cancel) { - this.filterValue = null; + this.filterValue = null!; } } this.checkMatch(); @@ -1266,7 +1266,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh /** @hidden @internal */ public getAriaLabel(): string { - return this.displayValue ? this.resourceStrings.igx_combo_aria_label_options : this.resourceStrings.igx_combo_aria_label_no_options; + return (this.displayValue ? this.resourceStrings.igx_combo_aria_label_options : this.resourceStrings.igx_combo_aria_label_no_options)!; } @@ -1286,7 +1286,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh } /** @hidden @internal */ - public onClick(event: Event) { + public onClick(event: MouseEvent) { event.stopPropagation(); event.preventDefault(); @@ -1337,11 +1337,11 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh } private get isTouchedOrDirty(): boolean { - return (this.ngControl.control.touched || this.ngControl.control.dirty); + return (this.ngControl.control!.touched || this.ngControl.control!.dirty); } private get hasValidators(): boolean { - return (!!this.ngControl.control.validator || !!this.ngControl.control.asyncValidator); + return (!!this.ngControl.control!.validator || !!this.ngControl.control!.asyncValidator); } /** if there is a valueKey - map the keys to data items, else - just return the keys */ @@ -1351,14 +1351,14 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh } return keys.map(key => { - const item = this.data.find(entry => isEqual(entry[this.valueKey], key)); + const item = this.data!.find(entry => isEqual(entry[this.valueKey], key)); return item !== undefined ? item : { [this.valueKey]: key }; }); } protected checkMatch(): void { - const itemMatch = this.filteredData.some(this.findMatch); + const itemMatch = this.filteredData!.some(this.findMatch); this.customValueFlag = this.allowCustomValues && !itemMatch; } @@ -1379,11 +1379,11 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh if (add) { const selection = this.getValueDisplayPairs(ids); for (const entry of selection) { - this._remoteSelection[entry[this.valueKey]] = entry[this.displayKey]; + (this._remoteSelection as any)[entry[this.valueKey]] = entry[this.displayKey]; } } else { for (const entry of ids) { - delete this._remoteSelection[entry]; + delete (this._remoteSelection as any)[entry]; } } } @@ -1392,7 +1392,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * For `id: any[]` returns a mapped `{ [combo.valueKey]: any, [combo.displayKey]: any }[]` */ protected getValueDisplayPairs(ids: any[]) { - return this.data.filter(entry => ids.indexOf(entry[this.valueKey]) > -1).map(e => ({ + return this.data!.filter(entry => ids.indexOf(entry[this.valueKey]) > -1).map(e => ({ [this.valueKey]: e[this.valueKey], [this.displayKey]: e[this.displayKey] })); @@ -1408,7 +1408,7 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh const addedItems = newSelection.filter(e => oldSelection.indexOf(e) < 0); this.registerRemoteEntries(addedItems); this.registerRemoteEntries(removedItems, false); - return Object.keys(this._remoteSelection).map(e => this._remoteSelection[e]).join(', '); + return Object.keys(this._remoteSelection).map(e => (this._remoteSelection as any)[e]).join(', '); } protected get required(): boolean { @@ -1424,9 +1424,9 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh public abstract get filteredData(): any[] | null; public abstract set filteredData(val: any[] | null); - public abstract handleOpened(); - public abstract onArrowDown(event: Event); - public abstract focusSearchInput(opening?: boolean); + public abstract handleOpened(): any; + public abstract onArrowDown(event: Event): any; + public abstract focusSearchInput(opening?: boolean): any; public abstract select(newItem: any): void; public abstract select(newItems: Array | any, clearCurrentSelection?: boolean, event?: Event): void; @@ -1436,5 +1436,5 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh public abstract writeValue(value: any): void; protected abstract setSelection(newSelection: Set, event?: Event): void; - protected abstract createDisplayText(newSelection: any[], oldSelection: any[]); + protected abstract createDisplayText(newSelection: any[], oldSelection: any[]): any; } diff --git a/projects/igniteui-angular/combo/src/combo/combo.component.html b/projects/igniteui-angular/combo/src/combo/combo.component.html index 418d6434ab8..6dc7ebf5705 100644 --- a/projects/igniteui-angular/combo/src/combo/combo.component.html +++ b/projects/igniteui-angular/combo/src/combo/combo.component.html @@ -127,7 +127,7 @@ - @if (filteredData.length === 0) { + @if (filteredData!.length === 0) {
(defaultEN: T, init = true, locale?: const newResourceStrings: T = {} as T; // Append back `igx_` prefix for compatibility with older versions. - const igxResourceStringKeys = Object.keys(defaultEN); + const igxResourceStringKeys = Object.keys(defaultEN as object); for (const igxKey of igxResourceStringKeys) { let coreKey = igxKey; if (coreKey.startsWith("igx_")) { coreKey = coreKey.replace("igx_", ""); } if (resourceStringsKeys.includes(coreKey)) { - normalizedResourceStrings[igxKey] = resourceStrings[coreKey]; + (normalizedResourceStrings as any)[igxKey] = (resourceStrings as any)[coreKey]; } else { - normalizedResourceStrings[igxKey] = defaultEN[igxKey]; - newResourceStrings[coreKey] = defaultEN[igxKey]; + (normalizedResourceStrings as any)[igxKey] = (defaultEN as any)[igxKey]; + (newResourceStrings as any)[coreKey] = (defaultEN as any)[igxKey]; } } if (init) { // Register only new resources. We don't want to accidentally override any default set by user. - getI18nManager().registerI18n(newResourceStrings, getI18nManager().defaultLocale); + getI18nManager().registerI18n(newResourceStrings as IResourceStringsCore, getI18nManager().defaultLocale); } return normalizedResourceStrings; diff --git a/projects/igniteui-angular/core/src/core/navigation/IToggleView.ts b/projects/igniteui-angular/core/src/core/navigation/IToggleView.ts index 3ff8a7915a5..7ef099cbb8e 100644 --- a/projects/igniteui-angular/core/src/core/navigation/IToggleView.ts +++ b/projects/igniteui-angular/core/src/core/navigation/IToggleView.ts @@ -2,9 +2,9 @@ * Common interface for Components with show and collapse functionality */ export interface IToggleView { - element; + element: any; - open(...args); - close(...args); - toggle(...args); + open(...args: any[]): any; + close(...args: any[]): any; + toggle(...args: any[]): any; } diff --git a/projects/igniteui-angular/core/src/core/navigation/directives.ts b/projects/igniteui-angular/core/src/core/navigation/directives.ts index c900ad410f6..0ea6582939a 100644 --- a/projects/igniteui-angular/core/src/core/navigation/directives.ts +++ b/projects/igniteui-angular/core/src/core/navigation/directives.ts @@ -15,7 +15,7 @@ import { IgxNavigationService } from './nav.service'; standalone: true }) export class IgxNavigationToggleDirective { - @Input('igxNavToggle') private target; + @Input('igxNavToggle') private target: any; public state: IgxNavigationService; @@ -45,7 +45,7 @@ export class IgxNavigationToggleDirective { standalone: true }) export class IgxNavigationCloseDirective { - @Input('igxNavClose') private target; + @Input('igxNavClose') private target: any; public state: IgxNavigationService; diff --git a/projects/igniteui-angular/core/src/core/navigation/nav.service.ts b/projects/igniteui-angular/core/src/core/navigation/nav.service.ts index d8b5e6f667a..6bead800117 100644 --- a/projects/igniteui-angular/core/src/core/navigation/nav.service.ts +++ b/projects/igniteui-angular/core/src/core/navigation/nav.service.ts @@ -26,19 +26,20 @@ export class IgxNavigationService { if (id) { return this.navs[id]; } + return undefined!; } - public toggle(id: string, ...args) { + public toggle(id: string, ...args: any[]) { if (this.navs[id]) { return this.navs[id].toggle(...args); } } - public open(id: string, ...args) { + public open(id: string, ...args: any[]) { if (this.navs[id]) { return this.navs[id].open(...args); } } - public close(id: string, ...args) { + public close(id: string, ...args: any[]) { if (this.navs[id]) { return this.navs[id].close(...args); } diff --git a/projects/igniteui-angular/core/src/core/selection.ts b/projects/igniteui-angular/core/src/core/selection.ts index f8d94ae7604..920a533ea1d 100644 --- a/projects/igniteui-angular/core/src/core/selection.ts +++ b/projects/igniteui-angular/core/src/core/selection.ts @@ -17,7 +17,7 @@ export class IgxSelectionAPIService { * @param componentID ID of the component. */ public get(componentID: string): Set { - return this.selection.get(componentID); + return this.selection.get(componentID)!; } /** @@ -72,7 +72,7 @@ export class IgxSelectionAPIService { * * @returns Selection after the new item is added. */ - public add_item(componentID: string, itemID, sel?: Set): Set { + public add_item(componentID: string, itemID: any, sel?: Set): Set { if (!sel) { sel = new Set(this.get(componentID)); } @@ -96,7 +96,7 @@ export class IgxSelectionAPIService { * @returns Selection after the new items are added. */ public add_items(componentID: string, itemIDs: any[], clearSelection?: boolean): Set { - let selection: Set; + let selection!: Set; if (clearSelection) { selection = this.get_empty(); } else if (itemIDs && itemIDs.length === 0) { @@ -113,7 +113,7 @@ export class IgxSelectionAPIService { * @param itemID ID of the item to add to component selection. * @param sel Used internally only by the selection (select_items method) to accumulate selection for multiple items. */ - public select_item(componentID: string, itemID, sel?: Set) { + public select_item(componentID: string, itemID: any, sel?: Set) { this.set(componentID, this.add_item(componentID, itemID, sel)); } @@ -140,7 +140,7 @@ export class IgxSelectionAPIService { * * @returns Selection after the item is removed. */ - public delete_item(componentID: string, itemID, sel?: Set) { + public delete_item(componentID: string, itemID: any, sel?: Set) { if (!sel) { sel = new Set(this.get(componentID)); } @@ -163,8 +163,8 @@ export class IgxSelectionAPIService { * @returns Selection after the items are removed. */ public delete_items(componentID: string, itemIDs: any[]): Set { - let selection: Set; - itemIDs.forEach((deselectedItem) => selection = this.delete_item(componentID, deselectedItem, selection)); + let selection!: Set; + itemIDs.forEach((deselectedItem) => selection = this.delete_item(componentID, deselectedItem, selection)!); return selection; } @@ -175,8 +175,8 @@ export class IgxSelectionAPIService { * @param itemID ID of the item to remove from component selection. * @param sel Used internally only by the selection (deselect_items method) to accumulate selection for multiple items. */ - public deselect_item(componentID: string, itemID, sel?: Set) { - this.set(componentID, this.delete_item(componentID, itemID, sel)); + public deselect_item(componentID: string, itemID: any, sel?: Set) { + this.set(componentID, this.delete_item(componentID, itemID, sel)!); } /** @@ -197,7 +197,7 @@ export class IgxSelectionAPIService { * * @returns If item is selected. */ - public is_item_selected(componentID: string, itemID): boolean { + public is_item_selected(componentID: string, itemID: any): boolean { const sel = this.get(componentID); if (!sel) { return false; @@ -253,9 +253,9 @@ export class IgxSelectionAPIService { * * @returns Array of identifiers, either primary key values or the entire data array. */ - public get_all_ids(data, primaryKey?) { + public get_all_ids(data: any, primaryKey?: any) { // If primaryKey is 0, this should still map to the property - return primaryKey !== undefined && primaryKey !== null ? data.map((x) => x[primaryKey]) : data; + return primaryKey !== undefined && primaryKey !== null ? data.map((x: any) => x[primaryKey]) : data; } /** diff --git a/projects/igniteui-angular/core/src/core/touch.ts b/projects/igniteui-angular/core/src/core/touch.ts index df5b1fde977..92aa85ebcfc 100644 --- a/projects/igniteui-angular/core/src/core/touch.ts +++ b/projects/igniteui-angular/core/src/core/touch.ts @@ -24,7 +24,7 @@ export interface IgxGestureEvent { /** Current pointer position. */ center: { x: number; y: number }; /** The original event target. */ - target: EventTarget; + target: EventTarget | null; /** The underlying native pointer event. */ originalEvent: PointerEvent; /** Prevents the default action of the underlying native pointer event. */ @@ -235,7 +235,10 @@ export class IgxTouchManager { }; } - private _onPointerDown = (event: PointerEvent) => { + private _onPointerDown = (event: Event) => { + if (!(event instanceof PointerEvent)) { + return; + } if (this._tracking || !this._accepts(event.pointerType) || this._canStart?.(event) === false) { return; } @@ -269,7 +272,10 @@ export class IgxTouchManager { } }; - private _onPointerMove = (event: PointerEvent) => { + private _onPointerMove = (event: Event) => { + if (!(event instanceof PointerEvent)) { + return; + } if (!this._tracking || event.pointerId !== this._pointerId || !this._accepts(event.pointerType)) { return; } @@ -279,7 +285,7 @@ export class IgxTouchManager { if (!this._panStarted) { this._panStarted = true; if (this.callbacks.panStart) { - this._runInAngular(() => this.callbacks.panStart(gesture)); + this._runInAngular(() => this.callbacks.panStart?.(gesture)); } } // `panMove` is intentionally invoked outside of the Angular zone (when one is provided) @@ -288,7 +294,10 @@ export class IgxTouchManager { this.callbacks.panMove?.(gesture); }; - private _onPointerUp = (event: PointerEvent) => { + private _onPointerUp = (event: Event) => { + if (!(event instanceof PointerEvent)) { + return; + } if (!this._tracking || event.pointerId !== this._pointerId || !this._accepts(event.pointerType)) { return; } @@ -312,7 +321,10 @@ export class IgxTouchManager { }); }; - private _onPointerCancel = (event: PointerEvent) => { + private _onPointerCancel = (event: Event) => { + if (!(event instanceof PointerEvent)) { + return; + } if (!this._tracking || event.pointerId !== this._pointerId) { return; } @@ -320,11 +332,14 @@ export class IgxTouchManager { this._pointerId = null; if (this.callbacks.panCancel) { const gesture = this._createEvent(event); - this._runInAngular(() => this.callbacks.panCancel(gesture)); + this._runInAngular(() => this.callbacks.panCancel?.(gesture)); } }; - - private _onTouchMove = (event: TouchEvent) => { + + private _onTouchMove = (event: Event) => { + if (!(event instanceof TouchEvent)) { + return; + } // Prevent scrolling only while a gesture is actively tracked. if (this._tracking && event.cancelable) { event.preventDefault(); diff --git a/projects/igniteui-angular/core/src/core/utils.ts b/projects/igniteui-angular/core/src/core/utils.ts index b58c660f2a7..588bae542f6 100644 --- a/projects/igniteui-angular/core/src/core/utils.ts +++ b/projects/igniteui-angular/core/src/core/utils.ts @@ -105,7 +105,7 @@ export const cloneHierarchicalArray = (array: any[], childDataKey: any): any[] = * @param obj Source to copy prototype and descriptors from * @returns New object with cloned prototype and property descriptors */ -export const copyDescriptors = (obj) => { +export const copyDescriptors = (obj: any) => { if (obj) { return Object.create( Object.getPrototypeOf(obj), @@ -123,7 +123,7 @@ export const copyDescriptors = (obj) => { * @returns Obj1 with merged cloned keys from Obj2 * @hidden */ -export const mergeObjects = (obj1: any, obj2: any): any => mergeWith(obj1, obj2, (objValue, srcValue) => { +export const mergeObjects = (obj1: any, obj2: any): any => mergeWith(obj1, obj2, (objValue: any, srcValue: any) => { if (Array.isArray(srcValue)) { objValue = srcValue; return objValue; @@ -152,7 +152,7 @@ export const cloneValue = (value: any): any => { } if (isObject(value)) { - const result = {}; + const result: Record = {}; for (const key of Object.keys(value)) { if (key === "externalObject") { @@ -194,7 +194,7 @@ export const cloneValueCached = (value: any, cache: Map): any => { return cache.get(value); } - const result = {}; + const result: Record = {}; cache.set(value, result); for (const key of Object.keys(value)) { @@ -264,7 +264,7 @@ export const isDate = (value: any): value is Date => { * @returns: `boolean` * @hidden */ -export const isEqual = (obj1, obj2): boolean => { +export const isEqual = (obj1: any, obj2: any): boolean => { if (isDate(obj1) && isDate(obj2)) { return obj1.getTime() === obj2.getTime(); } @@ -301,7 +301,7 @@ export class PlatformUtil { public isEdge = this.isBrowser && /Edge[\/\s](\d+\.\d+)/.test(navigator.userAgent); public isChromium = this.isBrowser && (/Chrom|e?ium/g.test(navigator.userAgent) || /Google Inc/g.test(navigator.vendor)) && !/Edge/g.test(navigator.userAgent); - public browserVersion = this.isBrowser ? parseFloat(navigator.userAgent.match(/Version\/([\d.]+)/)?.at(1)) : 0; + public browserVersion = this.isBrowser ? parseFloat(navigator.userAgent.match(/Version\/([\d.]+)/)?.at(1)!) : 0; /** @hidden @internal */ public isElements = inject(ELEMENTS_TOKEN, { optional: true }); @@ -347,7 +347,7 @@ export class PlatformUtil { */ public getNodeSizeViaRange(range: Range, node: HTMLElement, sizeHoldingNode?: HTMLElement) { let overflow = null; - let nodeStyles: string[]; + let nodeStyles!: string[]; if (!this.isFirefox) { overflow = node.style.overflow; @@ -369,7 +369,7 @@ export class PlatformUtil { if (!this.isFirefox) { // we need that hack - otherwise content won't be measured correctly in IE/Edge - node.style.overflow = overflow; + node.style.overflow = overflow!; } if (sizeHoldingNode) { @@ -428,7 +428,7 @@ export class PlatformUtil { * @hidden */ export const flatten = (arr: any[]) => { - let result = []; + let result: any[] = []; arr.forEach(el => { result.push(el); @@ -559,7 +559,7 @@ export function resolveNestedPath(obj: unknown, pathParts: for (const key of pathParts) { if (_isObject(current) && key in (current as T)) { - current = current[key]; + current = (current as any)[key]; } else { return defaultValue; } @@ -590,14 +590,14 @@ export const reverseMapper = (path: string, value: any) => { let mapping: any; // Initial binding for first level bindings - obj[_prop] = value; + (obj as any)[_prop!] = value; mapping = obj; parts.forEach(prop => { // Start building the hierarchy - mapping[_prop] = {}; + mapping[_prop!] = {}; // Go down a level - mapping = mapping[_prop]; + mapping = mapping[_prop!]; // Bind the value and move the key mapping[prop] = value; _prop = prop; diff --git a/projects/igniteui-angular/core/src/data-operations/data-util.ts b/projects/igniteui-angular/core/src/data-operations/data-util.ts index 93c6c54fbb3..9c64c068650 100644 --- a/projects/igniteui-angular/core/src/data-operations/data-util.ts +++ b/projects/igniteui-angular/core/src/data-operations/data-util.ts @@ -44,7 +44,7 @@ export class DataUtil { result: ITreeGridRecord[]; }[] = []; - stack.push({ original: hierarchicalData, parent: null, result: res }); + stack.push({ original: hierarchicalData, parent: null!, result: res }); while (stack.length > 0) { const { original, parent, result } = stack.pop()!; @@ -61,7 +61,7 @@ export class DataUtil { const childClones: ITreeGridRecord[] = []; rec.children = childClones; stack.push({ - original: treeRecord.children, + original: treeRecord.children!, parent: rec, result: childClones }); @@ -90,15 +90,15 @@ export class DataUtil { return rec; } - public static group(data: T[], state: IGroupingState, grouping: IGridGroupingStrategy = new IgxGrouping(), grid: GridTypeBase = null, + public static group(data: T[], state: IGroupingState, grouping: IGridGroupingStrategy = new IgxGrouping(), grid: GridTypeBase = null!, groupsRecords: any[] = [], fullResult: IGroupByResult = { data: [], metadata: [] }): IGroupByResult { groupsRecords.splice(0, groupsRecords.length); return grouping.groupBy(data, state, grid, groupsRecords, fullResult); } - public static merge(data: T[], columns: ColumnType[], strategy: IGridMergeStrategy = new DefaultMergeStrategy(), activeRowIndexes = [], grid: GridTypeBase = null, + public static merge(data: T[], columns: ColumnType[], strategy: IGridMergeStrategy = new DefaultMergeStrategy(), activeRowIndexes: number[] = [], grid: GridTypeBase = null!, ): any[] { - const result = []; + const result: any[] = []; for (const col of columns) { const isDate = col?.dataType === 'date' || col?.dataType === 'dateTime'; const isTime = col?.dataType === 'time' || col?.dataType === 'dateTime'; @@ -121,7 +121,7 @@ export class DataUtil { } const len = dataLength !== undefined ? dataLength : data.length; const index = state.index; - const res = []; + const res: T[] = []; const recordsPerPage = dataLength !== undefined && state.recordsPerPage > dataLength ? dataLength : state.recordsPerPage; state.metadata = { countPages: 0, @@ -184,7 +184,7 @@ export class DataUtil { transactions .filter(t => t.type === TransactionType.DELETE) .forEach(t => { - const index = primaryKey ? data.findIndex(d => d[primaryKey] === t.id) : data.findIndex(d => d === t.id); + const index = primaryKey ? data.findIndex(d => (d as any)[primaryKey] === t.id) : data.findIndex(d => d === t.id); if (0 <= index && index < data.length) { data.splice(index, 1); } @@ -219,28 +219,29 @@ export class DataUtil { if (transaction.path) { const parent = this.findParentFromPath(data, primaryKey, childDataKey, transaction.path); let collection: any[] = parent ? parent[childDataKey] : data; + let updateIndex = -1; switch (transaction.type) { - case TransactionType.ADD: - // if there is no parent this is ADD row at root level - if (parent && !parent[childDataKey]) { - parent[childDataKey] = collection = []; - } - collection.push(transaction.newValue); - break; - case TransactionType.UPDATE: - const updateIndex = collection.findIndex(x => x[primaryKey] === transaction.id); - if (updateIndex !== -1) { - collection[updateIndex] = mergeObjects(cloneStrategy.clone(collection[updateIndex]), transaction.newValue); - } - break; - case TransactionType.DELETE: - if (deleteRows) { - const deleteIndex = collection.findIndex(r => r[primaryKey] === transaction.id); - if (deleteIndex !== -1) { - collection.splice(deleteIndex, 1); - } + case TransactionType.ADD: + // if there is no parent this is ADD row at root level + if (parent && !parent[childDataKey]) { + parent[childDataKey] = collection = []; + } + collection.push(transaction.newValue); + break; + case TransactionType.UPDATE: + updateIndex = collection.findIndex(x => x[primaryKey] === transaction.id); + if (updateIndex !== -1) { + collection[updateIndex] = mergeObjects(cloneStrategy.clone(collection[updateIndex]), transaction.newValue); + } + break; + case TransactionType.DELETE: + if (deleteRows) { + const deleteIndex = collection.findIndex(r => r[primaryKey] === transaction.id); + if (deleteIndex !== -1) { + collection.splice(deleteIndex, 1); } - break; + } + break; } } else { // if there is no path this is ADD row in root. Push the newValue to data diff --git a/projects/igniteui-angular/core/src/data-operations/expressions-tree-util.ts b/projects/igniteui-angular/core/src/data-operations/expressions-tree-util.ts index 550bca65229..47617320aee 100644 --- a/projects/igniteui-angular/core/src/data-operations/expressions-tree-util.ts +++ b/projects/igniteui-angular/core/src/data-operations/expressions-tree-util.ts @@ -19,7 +19,7 @@ export class ExpressionsTreeUtil { return tree.filteringOperands[index]; } - return null; + return null!; } /** @@ -125,7 +125,7 @@ function getFilteringCondition(dataType: string, name: string): IFilteringOperat */ function recreateOperatorFromDataType(expression: IFilteringExpression, dataType: string): IFilteringOperation { if (!expression.condition?.logic) { - return getFilteringCondition(dataType, expression.conditionName || expression.condition?.name); + return getFilteringCondition(dataType, (expression.conditionName || expression.condition?.name)!); } return expression.condition; @@ -145,7 +145,7 @@ export function recreateExpression(expression: IFilteringExpression, fields: Fie if (!field.filters) { expression.condition = recreateOperatorFromDataType(expression, field.dataType); } else { - expression.condition = field.filters.condition(expression.conditionName || expression.condition?.name); + expression.condition = field.filters.condition((expression.conditionName || expression.condition?.name)!); } } @@ -157,7 +157,7 @@ export function recreateExpression(expression: IFilteringExpression, fields: Fie expression.conditionName = expression.condition?.name; } - expression.searchVal = recreateSearchValue(expression.searchVal, field?.dataType); + expression.searchVal = recreateSearchValue(expression.searchVal, field?.dataType!); return expression; } diff --git a/projects/igniteui-angular/core/src/data-operations/filtering-condition.ts b/projects/igniteui-angular/core/src/data-operations/filtering-condition.ts index edf766bffcc..5a9f421533b 100644 --- a/projects/igniteui-angular/core/src/data-operations/filtering-condition.ts +++ b/projects/igniteui-angular/core/src/data-operations/filtering-condition.ts @@ -5,7 +5,7 @@ * @export */ export class IgxFilteringOperand { - protected static _instance: IgxFilteringOperand = null; + protected static _instance: IgxFilteringOperand = null!; public operations: IFilteringOperation[]; constructor() { @@ -65,7 +65,7 @@ export class IgxFilteringOperand { * @param name The name of the condition. */ public condition(name: string): IFilteringOperation { - return this.operations.find((element) => element.name === name); + return this.operations.find((element) => element.name === name)!; } /** @@ -151,14 +151,14 @@ class IgxBaseDateTimeFilteringOperand extends IgxFilteringOperand { * @memberof IgxDateFilteringOperand */ public static getDateParts(date: Date, dateFormat?: string): IDateParts { - const res = { - day: null, - hours: null, - milliseconds: null, - minutes: null, - month: null, - seconds: null, - year: null + const res: IDateParts = { + day: null!, + hours: null!, + milliseconds: null!, + minutes: null!, + month: null!, + seconds: null!, + year: null! }; if (!date || !dateFormat) { return res; @@ -817,8 +817,8 @@ export class IgxStringFilteringOperand extends IgxFilteringOperand { isUnary: false, iconName: 'filter_contains', logic: (target: string, searchVal: string, ignoreCase?: boolean) => { - const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase); - target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase); + const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase!); + target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase!); return target.indexOf(search) !== -1; } }, { @@ -826,8 +826,8 @@ export class IgxStringFilteringOperand extends IgxFilteringOperand { isUnary: false, iconName: 'filter_does_not_contain', logic: (target: string, searchVal: string, ignoreCase?: boolean) => { - const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase); - target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase); + const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase!); + target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase!); return target.indexOf(search) === -1; } }, { @@ -835,8 +835,8 @@ export class IgxStringFilteringOperand extends IgxFilteringOperand { isUnary: false, iconName: 'filter_starts_with', logic: (target: string, searchVal: string, ignoreCase?: boolean) => { - const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase); - target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase); + const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase!); + target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase!); return target.startsWith(search); } }, { @@ -844,8 +844,8 @@ export class IgxStringFilteringOperand extends IgxFilteringOperand { isUnary: false, iconName: 'filter_ends_with', logic: (target: string, searchVal: string, ignoreCase?: boolean) => { - const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase); - target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase); + const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase!); + target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase!); return target.endsWith(search); } }, { @@ -853,8 +853,8 @@ export class IgxStringFilteringOperand extends IgxFilteringOperand { isUnary: false, iconName: 'filter_equal', logic: (target: string, searchVal: string, ignoreCase?: boolean) => { - const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase); - target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase); + const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase!); + target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase!); return target === search; } }, { @@ -862,8 +862,8 @@ export class IgxStringFilteringOperand extends IgxFilteringOperand { isUnary: false, iconName: 'filter_not_equal', logic: (target: string, searchVal: string, ignoreCase?: boolean) => { - const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase); - target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase); + const search = IgxStringFilteringOperand.applyIgnoreCase(searchVal, ignoreCase!); + target = IgxStringFilteringOperand.applyIgnoreCase(target, ignoreCase!); return target !== search; } }, { diff --git a/projects/igniteui-angular/core/src/data-operations/filtering-strategy.ts b/projects/igniteui-angular/core/src/data-operations/filtering-strategy.ts index 6f6cd2ff253..8e822d84587 100644 --- a/projects/igniteui-angular/core/src/data-operations/filtering-strategy.ts +++ b/projects/igniteui-angular/core/src/data-operations/filtering-strategy.ts @@ -40,7 +40,7 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { // protected public findMatchByExpression(rec: any, expr: IFilteringExpression, isDate?: boolean, isTime?: boolean, grid?: GridTypeBase): boolean { if (expr.searchTree) { - const records = rec[expr.searchTree.entity]; + const records = rec[expr.searchTree.entity!]; const shouldMatchRecords = expr.conditionName === 'inQuery'; if (!records) { // child grid is not yet created return true; @@ -48,8 +48,8 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { for (let index = 0; index < records.length; index++) { const record = records[index]; - if ((shouldMatchRecords && this.matchRecord(record, expr.searchTree, grid, expr.searchTree.entity)) || - (!shouldMatchRecords && !this.matchRecord(record, expr.searchTree, grid, expr.searchTree.entity))) { + if ((shouldMatchRecords && this.matchRecord(record, expr.searchTree, grid, expr.searchTree.entity!)) || + (!shouldMatchRecords && !this.matchRecord(record, expr.searchTree, grid, expr.searchTree.entity!))) { return true; } } @@ -61,6 +61,7 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { if (expr.condition?.logic) { return expr.condition.logic(val, expr.searchVal, expr.ignoreCase); } + return undefined!; } // protected @@ -86,7 +87,7 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { } } - return matchOperand; + return matchOperand!; } return true; @@ -96,8 +97,8 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { if (!entity) { const column = grid && grid.getColumnByName(expression.fieldName); dataType = column?.dataType; - } else if (grid.type === 'hierarchical') { - const schema = grid.schema; + } else if (grid!.type === 'hierarchical') { + const schema = grid!.schema; const entityMatch = this.findEntityByName(schema, entity); dataType = entityMatch?.fields.find(f => f.field === expression.fieldName)?.dataType; } @@ -139,7 +140,7 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { for (let i = 0; i < data.length; ++i) { const record = data[i] const rawValue = resolveNestedPath(record, pathParts); - const formattedValue = applyFormatter ? column.formatter(rawValue, record) : rawValue; + const formattedValue = applyFormatter ? column.formatter!(rawValue, record) : rawValue; const { key, finalValue } = this.getFilterItemKeyValue(formattedValue, column); // Deduplicate by normalized key if (!seenFormattedFilterItems.has(key)) { @@ -233,7 +234,7 @@ export class NoopFilteringStrategy extends BaseFilteringStrategy { protected getFieldValue(rec: any, _fieldName: string) { return rec; } - private static _instance: NoopFilteringStrategy = null; + private static _instance: NoopFilteringStrategy = null!; public static instance() { return this._instance || (this._instance = new NoopFilteringStrategy()); @@ -246,7 +247,7 @@ export class NoopFilteringStrategy extends BaseFilteringStrategy { export class FilteringStrategy extends BaseFilteringStrategy { - private static _instance: FilteringStrategy = null; + private static _instance: FilteringStrategy = null!; public static instance() { diff --git a/projects/igniteui-angular/core/src/data-operations/grid-sorting-strategy.ts b/projects/igniteui-angular/core/src/data-operations/grid-sorting-strategy.ts index 9cfba2b3075..f3b84935787 100644 --- a/projects/igniteui-angular/core/src/data-operations/grid-sorting-strategy.ts +++ b/projects/igniteui-angular/core/src/data-operations/grid-sorting-strategy.ts @@ -88,7 +88,7 @@ export class IgxSorting implements IGridSortingStrategy { * Returns a new array with the data sorted according to the sorting expressions. */ public sort(data: any[], expressions: ISortingExpression[], grid?: GridTypeBase): any[] { - return this.sortData(data, expressions, grid); + return this.sortData(data, expressions, grid!); } /** @@ -132,7 +132,7 @@ export class IgxSorting implements IGridSortingStrategy { } for (let i = sortingExpressions.length - 1; i >= 0; i--) { - data = sortingExpressions[i].strategy.sort(data, sortingExpressions[i].fieldName, sortingExpressions[i].dir, sortingExpressions[i].ignoreCase, this.getFieldValue, sortingExpressions[i].isDate, sortingExpressions[i].isTime, grid) + data = sortingExpressions[i].strategy!.sort(data, sortingExpressions[i].fieldName, sortingExpressions[i].dir, sortingExpressions[i].ignoreCase!, this.getFieldValue, sortingExpressions[i].isDate, sortingExpressions[i].isTime, grid) } return data; @@ -186,7 +186,7 @@ export class IgxGrouping extends IgxSorting implements IGridGroupingStrategy { protected groupData( data: any[], state: IGroupingState, - grid: GridTypeBase = null, + grid: GridTypeBase = null!, groupsRecords: any[] = [], fullResult: IGroupByResult ): IGroupByResult { @@ -244,7 +244,7 @@ export class IgxGrouping extends IgxSorting implements IGridGroupingStrategy { level, records: cloneArray(group), value: this.getFieldValue(group[0], expressions[level].fieldName, isDate, isTime), - groupParent: parentGroup, + groupParent: parentGroup!, groups: [], height: grid ? grid.renderedRowHeight : null, column @@ -252,14 +252,14 @@ export class IgxGrouping extends IgxSorting implements IGridGroupingStrategy { // Link to parent's groups list if (parentGroup) { - parentGroup.groups.push(groupRow); + parentGroup.groups!.push(groupRow); } else { groupsRecords.push(groupRow) } // Determine expansion state for this groupRow const hierarchy = getHierarchy(groupRow); - const expandState: IGroupByExpandState = expansion.find((s) => + const expandState: IGroupByExpandState | undefined = expansion.find((s) => isHierarchyMatch( s.hierarchy || [{ fieldName: groupRow.expression.fieldName, value: groupRow.value }], hierarchy, @@ -270,12 +270,12 @@ export class IgxGrouping extends IgxSorting implements IGridGroupingStrategy { // Add the group row to the full result set fullResult.data.push(groupRow); - fullResult.metadata.push(null); + fullResult.metadata.push(null!); // Add the group row to the visible results (if its parent was expanded or it's a root group) if (isExpandingChildren) { result.push(groupRow); - metadata.push(null); + metadata.push(null!); } // Advance the current frame's index for the next iteration of its loop @@ -357,7 +357,7 @@ export class IgxGrouping extends IgxSorting implements IGridGroupingStrategy { * It performs no sorting and returns the data as it is. */ export class NoopSortingStrategy implements IGridSortingStrategy { - private static _instance: NoopSortingStrategy = null; + private static _instance: NoopSortingStrategy = null!; private constructor() { } diff --git a/projects/igniteui-angular/grids/core/src/summaries/grid-summary.ts b/projects/igniteui-angular/core/src/data-operations/grid-summary.ts similarity index 97% rename from projects/igniteui-angular/grids/core/src/summaries/grid-summary.ts rename to projects/igniteui-angular/core/src/data-operations/grid-summary.ts index 4e979cd62b4..f59efa36339 100644 --- a/projects/igniteui-angular/grids/core/src/summaries/grid-summary.ts +++ b/projects/igniteui-angular/core/src/data-operations/grid-summary.ts @@ -1,8 +1,10 @@ -import { IGroupByRecord, IgxSummaryResult } from 'igniteui-angular/core'; +import { IgxSummaryResult } from './grid-types'; +import { IGroupByRecord } from './groupby-record.interface'; -const clear = (el) => el === 0 || Boolean(el); -const first = (arr) => arr[0]; -const last = (arr) => arr[arr.length - 1]; + +const clear = (el: any) => el === 0 || Boolean(el); +const first = (arr: any[]) => arr[0]; +const last = (arr: any[]) => arr[arr.length - 1]; /* blazorCSSuppress */ export class IgxSummaryOperand { diff --git a/projects/igniteui-angular/core/src/data-operations/grid-types.ts b/projects/igniteui-angular/core/src/data-operations/grid-types.ts index d4895133204..16b768fd211 100644 --- a/projects/igniteui-angular/core/src/data-operations/grid-types.ts +++ b/projects/igniteui-angular/core/src/data-operations/grid-types.ts @@ -4,11 +4,13 @@ * The actual implementations are in igniteui-angular/grids. */ -import { QueryList, TemplateRef } from '@angular/core'; +import { InjectionToken, QueryList, TemplateRef } from '@angular/core'; import { WEEKDAYS } from '../core/enums'; import { IgxFilteringOperand } from './filtering-condition'; import { ISortingStrategy } from './sorting-strategy'; import { FilteringExpressionsTree } from './filtering-expressions-tree'; +import { IgxSummaryOperand } from './grid-summary'; +import { State, Transaction, TransactionService } from '../services/transaction/transaction'; /* IgxGrid column types */ @@ -206,7 +208,8 @@ export interface ColumnType extends FieldType { * Custom CSS styling, applied to every column * calcWidth, minWidthPx, maxWidthPx, minWidth, maxWidth, minWidthPercent, maxWidthPercent, resolvedWidth */ - calcWidth: any; + calcWidth: string | number | null; + defaultWidth: string; minWidthPx: number; maxWidthPx: number; minWidth: string; @@ -289,7 +292,7 @@ export interface ColumnType extends FieldType { */ filteringExpressionsTree: FilteringExpressionsTree; hasSummary: boolean; - summaries: any; + summaries: IgxSummaryOperand; disabledSummaries?: string[]; /** * The template reference for a summary of the column @@ -466,6 +469,112 @@ export interface ISummaryRecord { cellIndentation?: number; } +/* tsPlainInterface */ +/* marshalByValue */ +/** + * Represents a range selection between certain rows and columns of the grid. + * Range selection can be made either through drag selection or through keyboard selection. + */ +export interface GridSelectionRange { + /** The index of the starting row of the selection range. */ + rowStart: number; + /** The index of the ending row of the selection range. */ + rowEnd: number; + /* blazorAlternateType: double */ + /** + * The identifier or index of the starting column of the selection range. + * It can be either a string representing the column's field name or a numeric index. + */ + columnStart: string | number; + /* blazorAlternateType: double */ + /** + * The identifier or index of the ending column of the selection range. + * It can be either a string representing the column's field name or a numeric index. + */ + columnEnd: string | number; +} + +/** + * Represents a single selected cell or node in a grid. + */ +export interface ISelectionNode { + /** + * The index of the selected row. + */ + row: number; + /** + * The index of the selected column. + */ + column: number; + /** + * (Optional) + * Additional layout information for multi-row selection nodes. + */ + layout?: IMultiRowLayoutNode; + /** + * (Optional) + * Indicates if the selected node is a summary row. + * This property is true if the selected row is a summary row; otherwise, it is false. + */ + isSummaryRow?: boolean; +} + +export interface IMultiRowLayoutNode { + rowStart: number; + colStart: number; + rowEnd: number; + colEnd: number; + columnVisibleIndex: number; +} + +/** + * Represents the state of the keyboard when selecting. + */ +export interface ISelectionKeyboardState { + /** The selected node in the grid, if any. Can be null if no node is selected. */ + node: null | ISelectionNode; + /** Indicates whether the Shift key is currently pressed during the selection. */ + shift: boolean; + /** The range of the selected cells in the grid. Can be null when resetting the selection. */ + range: GridSelectionRange; + /** Indicates whether the selection is currently active (being performed). `False` when resetting the selection. */ + active: boolean; +} + +/** + * Represents the state of the grid selection using pointer interactions (mouse). + * Extends ISelectionKeyboardState to include pointer-specific properties. + */ +export interface ISelectionPointerState extends ISelectionKeyboardState { + /** Indicates whether the Ctrl key is currently pressed during the selection. */ + ctrl: boolean; + /** Indicates whether the primary pointer button is pressed during the selection (clicked). */ + primaryButton: boolean; +} + +/** + * Represents the state of the columns in the grid. + */ +export interface IColumnSelectionState { + /** Represents the field name of the selected column, if any. Can be null if no column is selected. */ + field: null | string; + /** An array of strings representing the ranges of selected columns in the grid. */ + range: string[]; +} + +/** + * Represents the overall state of grid selection, combining both keyboard and pointer interaction states. + * It can be either an ISelectionKeyboardState or an ISelectionPointerState. + */ +export type SelectionState = ISelectionKeyboardState | ISelectionPointerState; + +/** + * Injection token for accessing the grid transaction object. + * This allows injecting the grid transaction object into components or services. + */ +export const IgxGridTransaction = /*@__PURE__*/new InjectionToken>('IgxGridTransaction'); + + /** * Enumeration representing different calculation modes for grid summaries. * - rootLevelOnly: Summaries are calculated only for the root level. diff --git a/projects/igniteui-angular/core/src/data-operations/merge-strategy.ts b/projects/igniteui-angular/core/src/data-operations/merge-strategy.ts index b073d80251f..82e297d9135 100644 --- a/projects/igniteui-angular/core/src/data-operations/merge-strategy.ts +++ b/projects/igniteui-angular/core/src/data-operations/merge-strategy.ts @@ -43,7 +43,7 @@ export interface IGridMergeStrategy { /* csSuppress */ export class DefaultMergeStrategy implements IGridMergeStrategy { - protected static _instance: DefaultMergeStrategy = null; + protected static _instance: DefaultMergeStrategy = null!; public static instance(): DefaultMergeStrategy { return this._instance || (this._instance = new this()); @@ -66,7 +66,7 @@ export class DefaultMergeStrategy implements IGridMergeStrategy { const recData = result[index]; // if this is active row or some special record type - add and skip merging - if (activeRowIndexes.indexOf(index) != -1 || (grid && grid.isDetailRecord(rec) || grid.isGroupByRecord(rec) || grid.isChildGridRecord(rec) || grid.isSummaryRow(rec))) { + if (activeRowIndexes.indexOf(index) != -1 || (grid && grid.isDetailRecord(rec) || grid!.isGroupByRecord(rec) || grid!.isChildGridRecord(rec) || grid!.isSummaryRow(rec))) { if (!recData) { result.push(rec); } @@ -74,7 +74,7 @@ export class DefaultMergeStrategy implements IGridMergeStrategy { index++; continue; } - const recToUpdateData = recData ?? { recordRef: grid.isGhostRecord(rec) ? rec.recordRef : rec, cellMergeMeta: new Map(), ghostRecord: rec.ghostRecord, index: index }; + const recToUpdateData = recData ?? { recordRef: grid!.isGhostRecord(rec) ? rec.recordRef : rec, cellMergeMeta: new Map(), ghostRecord: rec.ghostRecord, index: index }; recToUpdateData.cellMergeMeta.set(field, { rowSpan: 1, childRecords: [] }); if (prev && comparer.call(this, prev.recordRef, recToUpdateData.recordRef, field, isDate, isTime) && prev.ghostRecord === recToUpdateData.ghostRecord) { const root = prev.cellMergeMeta.get(field)?.root ?? prev; @@ -132,7 +132,7 @@ export class DefaultMergeStrategy implements IGridMergeStrategy { let resolvedValue; if (isDate && isTime) { // date + time - resolvedValue = date.getTime(); + resolvedValue = date!.getTime(); } else if (date && isDate && !isTime) { // date, but no time resolvedValue = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0).getTime(); diff --git a/projects/igniteui-angular/core/src/data-operations/operations.ts b/projects/igniteui-angular/core/src/data-operations/operations.ts index 5f597c057dc..a03c54ce46e 100644 --- a/projects/igniteui-angular/core/src/data-operations/operations.ts +++ b/projects/igniteui-angular/core/src/data-operations/operations.ts @@ -9,7 +9,7 @@ export const isHierarchyMatch = (h1: Array, h2: Array, } return h1.every((level, index): boolean => { const expr = expressions.find(e => e.fieldName === level.fieldName); - const comparer = expr.groupingComparer || DefaultSortingStrategy.instance().compareValues; + const comparer = expr!.groupingComparer || DefaultSortingStrategy.instance().compareValues; return level.fieldName === h2[index].fieldName && comparer(level.value, h2[index].value) === 0; }); }; diff --git a/projects/igniteui-angular/core/src/data-operations/pipes.ts b/projects/igniteui-angular/core/src/data-operations/pipes.ts index 6da27095a64..5ea29ce9c50 100644 --- a/projects/igniteui-angular/core/src/data-operations/pipes.ts +++ b/projects/igniteui-angular/core/src/data-operations/pipes.ts @@ -10,7 +10,7 @@ export class IgxDateFormatterPipe implements PipeTransform { private locale_ID = inject(LOCALE_ID); public transform(value: Date | string | number | null | undefined, format?: string, timezone?: string, locale?: string) { - return this.i18nFormatter.formatDate(value, format, locale ?? this.locale_ID, timezone); + return this.i18nFormatter.formatDate(value, format!, locale ?? this.locale_ID, timezone); } } @@ -22,7 +22,7 @@ export class IgxNumberFormatterPipe implements PipeTransform { private i18nFormatter = inject(I18N_FORMATTER); public transform(value: number | string | null | undefined, digitsInfo?: string, locale?: string) { - return this.i18nFormatter.formatNumber(value, locale, digitsInfo); + return this.i18nFormatter.formatNumber(value, locale!, digitsInfo); } } @@ -34,7 +34,7 @@ export class IgxPercentFormatterPipe implements PipeTransform { private i18nFormatter = inject(I18N_FORMATTER); public transform(value: number | string | null | undefined, digitsInfo?: string, locale?: string) { - return this.i18nFormatter.formatPercent(value, locale, digitsInfo); + return this.i18nFormatter.formatPercent(value, locale!, digitsInfo); } } diff --git a/projects/igniteui-angular/core/src/data-operations/sorting-strategy.ts b/projects/igniteui-angular/core/src/data-operations/sorting-strategy.ts index e8d9eabbe5f..f90c18709a8 100644 --- a/projects/igniteui-angular/core/src/data-operations/sorting-strategy.ts +++ b/projects/igniteui-angular/core/src/data-operations/sorting-strategy.ts @@ -34,7 +34,7 @@ export interface ISortingStrategy { } export class DefaultSortingStrategy implements ISortingStrategy { - protected static _instance: DefaultSortingStrategy = null; + protected static _instance: DefaultSortingStrategy = null!; protected constructor() { } @@ -61,14 +61,14 @@ export class DefaultSortingStrategy implements ISortingStrategy { * where n is the length of the datasource. * This, on a very large dataset of 1 million records, gives a significant performance boost. */ - const resolver = valueResolver.bind(this); + const resolver = valueResolver.bind(this) as (obj: any, key: string, isDate?: boolean, isTime?: boolean) => any; const preparedData = data.map(item => { return { original: item, sortValue: this.prepareSortValue(resolver(item, key, isDate, isTime), ignoreCase) } }); - const compareFn = (a, b) => reverse * this.compareValues(a.sortValue, b.sortValue); + const compareFn = (a: any, b: any) => reverse * this.compareValues(a.sortValue, b.sortValue); preparedData.sort(compareFn); return preparedData.map(item => item.original); @@ -114,7 +114,7 @@ export class DefaultSortingStrategy implements ISortingStrategy { } export class GroupMemberCountSortingStrategy implements ISortingStrategy { - protected static _instance: GroupMemberCountSortingStrategy = null; + protected static _instance: GroupMemberCountSortingStrategy = null!; protected constructor() { } @@ -126,7 +126,7 @@ export class GroupMemberCountSortingStrategy implements ISortingStrategy { const groupedArray = this.groupBy(data, fieldName); const reverse = (dir === SortingDirection.Desc ? -1 : 1); - const cmpFunc = (a, b) => { + const cmpFunc = (a: any, b: any) => { return this.compareObjects(a, b, groupedArray, fieldName, reverse); }; @@ -135,8 +135,8 @@ export class GroupMemberCountSortingStrategy implements ISortingStrategy { .sort(cmpFunc); } - public groupBy(data, key) { - return data.reduce((acc, curr) => { + public groupBy(data: any, key: any) { + return data.reduce((acc: any, curr: any) => { (acc[curr[key]] = acc[curr[key]] || []).push(curr); return acc; }, {}) @@ -151,7 +151,7 @@ export class GroupMemberCountSortingStrategy implements ISortingStrategy { } export class FormattedValuesSortingStrategy extends DefaultSortingStrategy { - protected static override _instance: FormattedValuesSortingStrategy = null; + protected static override _instance: FormattedValuesSortingStrategy = null!; constructor() { super(); @@ -173,7 +173,7 @@ export class FormattedValuesSortingStrategy extends DefaultSortingStrategy { ) { const key = fieldName; const reverse = (dir === SortingDirection.Desc ? -1 : 1); - const cmpFunc = (obj1: any, obj2: any) => this.compareObjects(obj1, obj2, key, reverse, ignoreCase, valueResolver, isDate, isTime, grid); + const cmpFunc = (obj1: any, obj2: any) => this.compareObjects(obj1, obj2, key, reverse, ignoreCase, valueResolver, isDate!, isTime!, grid); return this.arraySort(data, cmpFunc); } diff --git a/projects/igniteui-angular/core/src/data-operations/test-util/data-generator.ts b/projects/igniteui-angular/core/src/data-operations/test-util/data-generator.ts index f4d83cfdc3d..3d3402db052 100644 --- a/projects/igniteui-angular/core/src/data-operations/test-util/data-generator.ts +++ b/projects/igniteui-angular/core/src/data-operations/test-util/data-generator.ts @@ -28,21 +28,21 @@ export class DataGenerator { this.columns = this.generateColumns(countCols); this.data = this.generateData(countRows); } - public generateArray(startValue, endValue) { + public generateArray(startValue: any, endValue: any) { const len = Math.abs(startValue - endValue); const decrement = startValue > endValue; return Array.from({ length: len + 1 }, (_e, i) => decrement ? startValue - i : startValue + i); } - public getValuesForColumn(data, fieldName) { - return data.map((x) => x[fieldName]); + public getValuesForColumn(data: any, fieldName: any) { + return data.map((x: any) => x[fieldName]); } - public getGroupRecords(data) { - return data.map((x) => x['groupParent']); + public getGroupRecords(data: any) { + return data.map((x: any) => x['groupParent']); } - public isSuperset(haystack, arr) { - return arr.every((val) => haystack.indexOf(val) >= 0); + public isSuperset(haystack: any, arr: any) { + return arr.every((val: any) => haystack.indexOf(val) >= 0); } - private generateColumns(countCols): IDataColumn[] { + private generateColumns(countCols: number): IDataColumn[] { let i: number; const defaultColumns: IDataColumn[] = [ { @@ -81,7 +81,7 @@ export class DataGenerator { private generateData(countRows: number) { let i; let j; - let rec; + let rec: any; let val; let col; const data = []; diff --git a/projects/igniteui-angular/core/src/data-operations/tree-grid-filtering-strategy.ts b/projects/igniteui-angular/core/src/data-operations/tree-grid-filtering-strategy.ts index 447526bf011..8a21ec80526 100644 --- a/projects/igniteui-angular/core/src/data-operations/tree-grid-filtering-strategy.ts +++ b/projects/igniteui-angular/core/src/data-operations/tree-grid-filtering-strategy.ts @@ -13,7 +13,7 @@ export class TreeGridFilteringStrategy extends BaseFilteringStrategy { public filter(data: ITreeGridRecord[], expressionsTree: IFilteringExpressionsTree, advancedExpressionsTree?: IFilteringExpressionsTree, grid?: GridTypeBase): ITreeGridRecord[] { - return this.filterImpl(data, expressionsTree, advancedExpressionsTree, undefined, grid); + return this.filterImpl(data, expressionsTree, advancedExpressionsTree!, undefined!, grid); } protected getFieldValue(rec: any, fieldName: string, isDate = false, isTime = false, grid?: GridTypeBase): any { @@ -30,7 +30,7 @@ export class TreeGridFilteringStrategy extends BaseFilteringStrategy { return value; } - private getHierarchicalFieldValue(record: ITreeGridRecord, field: string) { + private getHierarchicalFieldValue(record: ITreeGridRecord, field: string): string { const value = resolveNestedPath(record.data, columnFieldPath(field)); return record.parent ? @@ -52,7 +52,7 @@ export class TreeGridFilteringStrategy extends BaseFilteringStrategy { rec.parent = parent; if (rec.children) { const filteredChildren = this.filterImpl(rec.children, expressionsTree, advancedExpressionsTree, rec, grid); - rec.children = filteredChildren.length > 0 ? filteredChildren : null; + rec.children = filteredChildren.length > 0 ? filteredChildren : null!; } if (this.matchRecord(rec, expressionsTree, grid) && this.matchRecord(rec, advancedExpressionsTree, grid)) { @@ -98,7 +98,7 @@ export class TreeGridFilteringStrategy extends BaseFilteringStrategy { const applyFormatter = column.formatter && this.shouldFormatFilterValues(column); value = applyFormatter ? - column.formatter(value, record.data) : + column.formatter!(value, record.data) : value; const hierarchicalValue = parent ? @@ -107,7 +107,7 @@ export class TreeGridFilteringStrategy extends BaseFilteringStrategy { const filterItem: IgxFilterItem = { value: hierarchicalValue }; filterItem.label = this.getFilterItemLabel(column, value, !applyFormatter, record.data); - filterItem.children = this.getHierarchicalFilterItems(record.children, column, filterItem); + filterItem.children = this.getHierarchicalFilterItems(record.children!, column, filterItem); return filterItem; }); } @@ -132,7 +132,7 @@ export class TreeGridFormattedValuesFilteringStrategy extends TreeGridFilteringS export class TreeGridMatchingRecordsOnlyFilteringStrategy extends TreeGridFilteringStrategy { public override filter(data: ITreeGridRecord[], expressionsTree: IFilteringExpressionsTree, advancedExpressionsTree?: IFilteringExpressionsTree, grid?: GridTypeBase): ITreeGridRecord[] { - return this.filterImplementation(data, expressionsTree, advancedExpressionsTree, undefined, grid); + return this.filterImplementation(data, expressionsTree, advancedExpressionsTree!, undefined!, grid); } private filterImplementation(data: ITreeGridRecord[], expressionsTree: IFilteringExpressionsTree, @@ -149,13 +149,13 @@ export class TreeGridMatchingRecordsOnlyFilteringStrategy extends TreeGridFilter rec.parent = parent; if (rec.children) { const filteredChildren = this.filterImplementation(rec.children, expressionsTree, advancedExpressionsTree, rec, grid); - rec.children = filteredChildren.length > 0 ? filteredChildren : null; + rec.children = filteredChildren.length > 0 ? filteredChildren : null!; } if (this.matchRecord(rec, expressionsTree, grid) && this.matchRecord(rec, advancedExpressionsTree, grid)) { res.push(rec); } else if (rec.children && rec.children.length > 0) { rec = this.setCorrectLevelToFilteredRecords(rec); - res.push(...rec.children); + res.push(...rec.children!); } } return res; @@ -164,7 +164,7 @@ export class TreeGridMatchingRecordsOnlyFilteringStrategy extends TreeGridFilter private setCorrectLevelToFilteredRecords(rec: ITreeGridRecord): ITreeGridRecord { if (rec.children && rec.children.length > 0) { rec.children.map(child => { - child.level = child.level - 1; + child.level = child.level! - 1; return this.setCorrectLevelToFilteredRecords(child); }); } diff --git a/projects/igniteui-angular/core/src/date-common/util/date-time.util.ts b/projects/igniteui-angular/core/src/date-common/util/date-time.util.ts index e99c7b8aad0..25b14e0a5d9 100644 --- a/projects/igniteui-angular/core/src/date-common/util/date-time.util.ts +++ b/projects/igniteui-angular/core/src/date-common/util/date-time.util.ts @@ -114,10 +114,10 @@ export abstract class DateTimeUtil { /** Parse the mask into date/time and literal parts */ public static parseDateTimeFormat(mask: string, formatter: BaseFormatter, locale?: string): DatePartInfo[] { - const format = mask || DateTimeUtil.getDefaultInputFormat(locale, formatter); + const format = mask || DateTimeUtil.getDefaultInputFormat(locale!, formatter); const dateTimeParts: DatePartInfo[] = []; const formatArray = Array.from(format); - let currentPart: DatePartInfo = null; + let currentPart: DatePartInfo = null!; let position = 0; let lastPartAdded = false; for (let i = 0; i < formatArray.length; i++, position++) { @@ -174,7 +174,7 @@ export abstract class DateTimeUtil { } public static getPartValue(value: Date, datePartInfo: DatePartInfo, partLength: number): string { - let maskedValue; + let maskedValue: any; const datePart = datePartInfo.type; switch (datePart) { case DatePart.Date: @@ -436,7 +436,7 @@ export abstract class DateTimeUtil { public static validateMinMax(value: Date, minValue: Date | string, maxValue: Date | string, includeTime = true, includeDate = true): ValidationErrors { if (!value) { - return null; + return null!; } const errors = {}; const min = DateTimeUtil.isValidDate(minValue) ? minValue : DateTimeUtil.parseIsoDate(minValue); @@ -515,7 +515,7 @@ export abstract class DateTimeUtil { return resultFormat; } if (predefinedNumericFormats.has(format)) { - resultFormat = DateTimeUtil.getLocaleInputFormatFromParts(locale, formatter, predefinedNumericFormats.get(format)); + resultFormat = DateTimeUtil.getLocaleInputFormatFromParts(locale, formatter, predefinedNumericFormats.get(format)!); } else if (DateTimeUtil.isFormatNumeric(locale, format, formatter)) { resultFormat = format; @@ -525,7 +525,7 @@ export abstract class DateTimeUtil { /** Gets the locale-based format from an array of date parts */ private static getLocaleInputFormatFromParts(locale: string, formatter: BaseFormatter, dateParts: DateParts[]): string { - const options = {}; + const options: any = {}; dateParts.forEach(p => { if (p === DateParts.Year) { options[p] = FormatDesc.Numeric; diff --git a/projects/igniteui-angular/core/src/date-common/util/helpers.ts b/projects/igniteui-angular/core/src/date-common/util/helpers.ts index 5b0c9b6ea11..4785f84a048 100644 --- a/projects/igniteui-angular/core/src/date-common/util/helpers.ts +++ b/projects/igniteui-angular/core/src/date-common/util/helpers.ts @@ -197,7 +197,7 @@ export function formatToParts( partType: string, ): IFormattedParts => { const part = formattedParts.find(({ type }) => type === partType); - const nextPart = formattedParts[formattedParts.indexOf(part) + 1]; + const nextPart = formattedParts[formattedParts.indexOf(part!) + 1]; const value = part?.value || ""; const literal = nextPart?.type === "literal" ? nextPart.value : ""; return { diff --git a/projects/igniteui-angular/core/src/public_api.ts b/projects/igniteui-angular/core/src/public_api.ts index 3c920d31b2f..8c14403f201 100644 --- a/projects/igniteui-angular/core/src/public_api.ts +++ b/projects/igniteui-angular/core/src/public_api.ts @@ -32,6 +32,7 @@ export * from './data-operations/grouping-expression.interface'; export * from './data-operations/sorting-strategy'; export * from './data-operations/grid-sorting-strategy'; export * from './data-operations/paging-state.interface'; +export * from './data-operations/grid-summary'; export * from './data-operations/data-util'; export * from './data-operations/grid-types'; export * from './data-operations/operations'; diff --git a/projects/igniteui-angular/core/src/services/animation/angular-animation-service.ts b/projects/igniteui-angular/core/src/services/animation/angular-animation-service.ts index 042a9609965..96bcac76a20 100644 --- a/projects/igniteui-angular/core/src/services/animation/angular-animation-service.ts +++ b/projects/igniteui-angular/core/src/services/animation/angular-animation-service.ts @@ -9,7 +9,7 @@ export class IgxAngularAnimationService implements AnimationService { public buildAnimation(animationMetaData: AnimationReferenceMetadata, element: HTMLElement): AnimationPlayer { if (!animationMetaData) { - return null; + return null!; } const animationBuilder = this.builder.build(animationMetaData); const player = new IgxAngularAnimationPlayer(animationBuilder.create(element)); diff --git a/projects/igniteui-angular/core/src/services/overlay/overlay.ts b/projects/igniteui-angular/core/src/services/overlay/overlay.ts index ef4bcb72b19..0c982bdeb5d 100644 --- a/projects/igniteui-angular/core/src/services/overlay/overlay.ts +++ b/projects/igniteui-angular/core/src/services/overlay/overlay.ts @@ -118,10 +118,10 @@ export class IgxOverlayService implements OnDestroy { private _componentId = 0; private _overlayInfos: OverlayInfo[] = []; private _document: Document; - private _keyPressEventListener: Subscription; + private _keyPressEventListener!: Subscription; private destroy$ = new Subject(); private _cursorStyleIsSet = false; - private _cursorOriginalValue: string; + private _cursorOriginalValue!: string; private _defaultSettings: OverlaySettings = { excludeFromOutsideClick: [], @@ -169,7 +169,7 @@ export class IgxOverlayService implements OnDestroy { scrollStrategy: new NoOpScrollStrategy(), modal: false, closeOnOutsideClick: true, - outlet + outlet: outlet! }; return overlaySettings; } @@ -198,7 +198,7 @@ export class IgxOverlayService implements OnDestroy { return overlaySettings; } - private static createAbsolutePositionSettings(position: AbsolutePosition): PositionSettings { + private static createAbsolutePositionSettings(position?: AbsolutePosition): PositionSettings { let positionSettings: PositionSettings; switch (position) { case AbsolutePosition.Bottom: @@ -229,7 +229,7 @@ export class IgxOverlayService implements OnDestroy { return positionSettings; } - private static createRelativePositionSettings(position: RelativePosition): PositionSettings { + private static createRelativePositionSettings(position?: RelativePosition): PositionSettings { let positionSettings: PositionSettings; switch (position) { case RelativePosition.Above: @@ -287,7 +287,7 @@ export class IgxOverlayService implements OnDestroy { return positionSettings; } - private static createPositionStrategy(strategy: RelativePositionStrategy, positionSettings: PositionSettings): IPositionStrategy { + private static createPositionStrategy(strategy?: RelativePositionStrategy, positionSettings?: PositionSettings): IPositionStrategy { switch (strategy) { case RelativePositionStrategy.Connected: return new ConnectedPositioningStrategy(positionSettings); @@ -332,11 +332,11 @@ export class IgxOverlayService implements OnDestroy { componentOrElement: ElementRef | Type, viewContainerRefOrSettings?: ViewContainerRef | OverlayCreateSettings, settings?: OverlaySettings): string { - const info: OverlayInfo = this.getOverlayInfo(componentOrElement, viewContainerRefOrSettings, settings); + const info: OverlayInfo | null = this.getOverlayInfo(componentOrElement, viewContainerRefOrSettings, settings); if (!info) { console.warn('Overlay was not able to attach provided component!'); - return null; + return null!; } info.id = (this._componentId++).toString(); @@ -345,25 +345,25 @@ export class IgxOverlayService implements OnDestroy { const eventArgs = { id: info.id, elementRef: info.elementRef, componentRef: info.componentRef, settings: info.settings }; this.contentAppending.emit(eventArgs); // Append the content to the overlay - info.settings = eventArgs.settings; + info.settings = eventArgs.settings!; this._overlayInfos.push(info); - const elementRect = info.elementRef.nativeElement.getBoundingClientRect(); + const elementRect = info.elementRef!.nativeElement.getBoundingClientRect(); info.initialSize = { width: elementRect.width, height: elementRect.height }; // Get the size before moving the container into the overlay so that it does not forget about inherited styles. this.getComponentSize(info); info.wrapperElement = this.getWrapperElement(); - const contentElement = this.getContentElement(info.wrapperElement, info.settings.modal); + const contentElement = this.getContentElement(info.wrapperElement, info.settings.modal!); this.insertWrapper(info); - contentElement.appendChild(info.elementRef.nativeElement); + contentElement.appendChild(info.elementRef!.nativeElement); // Update the container size after wrapping/moving if there is size. if (info.size) { - info.elementRef.nativeElement.parentElement.style.setProperty('--ig-size', info.size); + info.elementRef!.nativeElement.parentElement.style.setProperty('--ig-size', info.size); } this.contentAppended.emit({ id: info.id, componentRef: info.componentRef }); - info.settings.scrollStrategy.initialize(this._document, this, info.id); - info.settings.scrollStrategy.attach(); + info.settings.scrollStrategy!.initialize(this._document, this, info.id); + info.settings.scrollStrategy!.attach(); this.addOutsideClickListener(info); this.addResizeHandler(); this.addCloseOnEscapeListener(info); @@ -388,10 +388,10 @@ export class IgxOverlayService implements OnDestroy { } info.detached = true; this.finishAnimations(info); - info.settings.scrollStrategy.detach(); + info.settings!.scrollStrategy!.detach(); // Dispose position strategy if it has a dispose method - if (typeof (info.settings.positionStrategy as any).dispose === 'function') { - (info.settings.positionStrategy as any).dispose(); + if (typeof (info.settings!.positionStrategy as any).dispose === 'function') { + (info.settings!.positionStrategy as any).dispose(); } this.removeOutsideClickListener(info); this.removeResizeHandler(); @@ -406,7 +406,7 @@ export class IgxOverlayService implements OnDestroy { */ public detachAll() { for (let i = this._overlayInfos.length; i--;) { - this.detach(this._overlayInfos[i].id); + this.detach(this._overlayInfos[i].id!); } } @@ -428,23 +428,23 @@ export class IgxOverlayService implements OnDestroy { return; } if (settings) { - const newScrollStrategy = settings.scrollStrategy && info.settings.scrollStrategy !== settings.scrollStrategy; - if (newScrollStrategy && info.settings.scrollStrategy) { - info.settings.scrollStrategy.detach(); + const newScrollStrategy = settings.scrollStrategy && info.settings!.scrollStrategy !== settings.scrollStrategy; + if (newScrollStrategy && info.settings!.scrollStrategy) { + info.settings!.scrollStrategy.detach(); } - settings.positionStrategy ??= info.settings.positionStrategy; - settings.scrollStrategy ??= info.settings.scrollStrategy; + settings.positionStrategy ??= info.settings!.positionStrategy; + settings.scrollStrategy ??= info.settings!.scrollStrategy; info.settings = { ...info.settings, ...settings }; if (newScrollStrategy) { - info.settings.scrollStrategy.initialize(this._document, this, info.id); - info.settings.scrollStrategy.attach(); + info.settings.scrollStrategy!.initialize(this._document, this, info.id!); + info.settings.scrollStrategy!.attach(); } } this.updateSize(info); - const openAnimation = info.settings.positionStrategy.settings.openAnimation; - const closeAnimation = info.settings.positionStrategy.settings.closeAnimation; + const openAnimation = info.settings!.positionStrategy!.settings.openAnimation; + const closeAnimation = info.settings!.positionStrategy!.settings.closeAnimation; // Show the overlay using Popover API BEFORE positioning // This ensures the element is in the top layer when position calculations happen if (info.wrapperElement?.isConnected && typeof info.wrapperElement.showPopover === 'function') { @@ -454,26 +454,26 @@ export class IgxOverlayService implements OnDestroy { // Popover API call failed, element may already be showing } } - info.settings.positionStrategy.position( - info.elementRef.nativeElement.parentElement, - { width: info.initialSize.width, height: info.initialSize.height }, + info.settings!.positionStrategy!.position( + info.elementRef!.nativeElement.parentElement, + { width: info.initialSize!.width, height: info.initialSize!.height }, this._document, true, - info.settings.target); - if (openAnimation !== info.settings.positionStrategy.settings.openAnimation || - closeAnimation !== info.settings.positionStrategy.settings.closeAnimation){ + info.settings!.target); + if (openAnimation !== info.settings!.positionStrategy!.settings.openAnimation || + closeAnimation !== info.settings!.positionStrategy!.settings.closeAnimation){ this.buildAnimationPlayers(info); } this.addModalClasses(info); - if (info.settings.positionStrategy.settings.openAnimation) { + if (info.settings!.positionStrategy!.settings.openAnimation) { // TODO: should we build players again. This was already done in attach!!! // this.buildAnimationPlayers(info); this.playOpenAnimation(info); } else { // to eliminate flickering show the element just before opened fires - info.wrapperElement.style.visibility = ''; + info.wrapperElement!.style.visibility = ''; info.visible = true; - this.opened.emit({ id: info.id, componentRef: info.componentRef }); + this.opened.emit({ id: info.id!, componentRef: info.componentRef }); } } @@ -495,7 +495,7 @@ export class IgxOverlayService implements OnDestroy { */ public hideAll() { for (let i = this._overlayInfos.length; i--;) { - this.hide(this._overlayInfos[i].id); + this.hide(this._overlayInfos[i].id!); } } @@ -516,9 +516,9 @@ export class IgxOverlayService implements OnDestroy { if (!overlayInfo.visible) { return; } - const contentElement = overlayInfo.elementRef.nativeElement.parentElement; + const contentElement = overlayInfo.elementRef!.nativeElement.parentElement; const contentElementRect = contentElement.getBoundingClientRect(); - overlayInfo.settings.positionStrategy.position( + overlayInfo.settings.positionStrategy!.position( contentElement, { width: contentElementRect.width, @@ -554,8 +554,8 @@ export class IgxOverlayService implements OnDestroy { break; case OffsetMode.Add: default: - info.transformX += deltaX; - info.transformY += deltaY; + info.transformX! += deltaX; + info.transformY! += deltaY; break; } @@ -563,13 +563,13 @@ export class IgxOverlayService implements OnDestroy { const transformY = info.transformY; const translate = `translate(${transformX}px, ${transformY}px)`; - info.elementRef.nativeElement.parentElement.style.transform = translate; + info.elementRef!.nativeElement.parentElement.style.transform = translate; } /** @hidden */ public repositionAll = () => { for (let i = this._overlayInfos.length; i--;) { - this.reposition(this._overlayInfos[i].id); + this.reposition(this._overlayInfos[i].id!); } }; @@ -582,12 +582,12 @@ export class IgxOverlayService implements OnDestroy { } /** @hidden @internal */ - public getOverlayById(id: string): OverlayInfo { + public getOverlayById(id: string | undefined): OverlayInfo { if (!id) { - return null; + return null!; } const info = this._overlayInfos.find(e => e.id === id); - return info; + return info!; } private _hide(id: string, event?: Event) { @@ -602,7 +602,7 @@ export class IgxOverlayService implements OnDestroy { return; } this.removeModalClasses(info); - if (info.settings.positionStrategy.settings.closeAnimation) { + if (info.settings!.positionStrategy!.settings.closeAnimation) { this.playCloseAnimation(info, event); } else { this.closeDone(info); @@ -636,7 +636,7 @@ export class IgxOverlayService implements OnDestroy { } else { const environmentInjector = this._appRef.injector; const createSettings = viewContainerRefOrSettings as OverlayCreateSettings | undefined; - let elementInjector: Injector; + let elementInjector: Injector | undefined; if (createSettings) { ({ injector: elementInjector, ...overlaySettings } = createSettings); } @@ -646,7 +646,7 @@ export class IgxOverlayService implements OnDestroy { if (dynamicComponent.onDestroy) { dynamicComponent.onDestroy(() => { if (!info.detached && this._overlayInfos.indexOf(info) !== -1) { - this.detach(info.id); + this.detach(info.id!); } }) } @@ -662,7 +662,7 @@ export class IgxOverlayService implements OnDestroy { private placeElementHook(element: HTMLElement): HTMLElement { if (!element.parentElement) { - return null; + return null!; } const hook = this._document.createElement('div'); hook.style.display = 'none'; @@ -676,14 +676,14 @@ export class IgxOverlayService implements OnDestroy { * The absence of a hook indicates the element had no parent and was appended to the body. */ private insertWrapper(info: OverlayInfo) { - const element = info.elementRef.nativeElement; + const element = info.elementRef!.nativeElement; if (element.parentElement) { info.hook = this.placeElementHook(element); } // TODO: This check for ContainerPositionStrategy is temporary and should be removed once a proper long-term // solution for container-based positioning is in place. - if (info.settings.positionStrategy instanceof ContainerPositionStrategy) { + if (info.settings!.positionStrategy instanceof ContainerPositionStrategy) { this.insertWrapperInContainer(info); } else { this.appendWrapperTo(info, this.getWrapperParent(info)); @@ -692,8 +692,8 @@ export class IgxOverlayService implements OnDestroy { /** Resolves the DOM node that should host the wrapper element. */ private getWrapperParent(info: OverlayInfo): HTMLElement { - if (info.settings.outlet) { - return info.settings.outlet.nativeElement || info.settings.outlet; + if (info.settings!.outlet) { + return info.settings!.outlet.nativeElement || info.settings!.outlet; } return info.hook?.parentElement || this._document.body; } @@ -703,16 +703,16 @@ export class IgxOverlayService implements OnDestroy { * parent, the wrapper is inserted right before the original element to preserve DOM order. */ private appendWrapperTo(info: OverlayInfo, parent: HTMLElement) { - const ref = info.hook?.parentElement === parent ? info.elementRef.nativeElement : null; - parent.insertBefore(info.wrapperElement, ref); + const ref = info.hook?.parentElement === parent ? info.elementRef!.nativeElement : null; + parent.insertBefore(info.wrapperElement!, ref); } /** * Creates an absolutely-positioned container div around the wrapper for ContainerPositionStrategy. */ private insertWrapperInContainer(info: OverlayInfo) { - const parent = info.settings.outlet?.nativeElement || - info.settings.outlet || + const parent = info.settings!.outlet?.nativeElement || + info.settings!.outlet || info.hook?.parentElement || this._document.body; @@ -721,7 +721,7 @@ export class IgxOverlayService implements OnDestroy { container.style.position = 'absolute'; container.style.inset = '0'; container.style.pointerEvents = 'none'; - container.appendChild(info.wrapperElement); + container.appendChild(info.wrapperElement!); parent.appendChild(container); } @@ -758,12 +758,12 @@ export class IgxOverlayService implements OnDestroy { // if we are positioning component this is first time it gets visible // and we can finally get its size info.componentRef.changeDetectorRef.detectChanges(); - info.initialSize = info.elementRef.nativeElement.getBoundingClientRect(); + info.initialSize = info.elementRef!.nativeElement.getBoundingClientRect(); } // set content div width only if element to show has width - if (info.initialSize.width !== 0) { - info.elementRef.nativeElement.parentElement.style.width = info.initialSize.width + 'px'; + if (info.initialSize!.width !== 0) { + info.elementRef!.nativeElement.parentElement.style.width = info.initialSize!.width + 'px'; } } @@ -784,7 +784,7 @@ export class IgxOverlayService implements OnDestroy { } } if (!info.closeAnimationDetaching) { - this.closed.emit({ id: info.id, componentRef: info.componentRef, event: info.event }); + this.closed.emit({ id: info.id!, componentRef: info.componentRef, event: info.event }); } delete info.event; } @@ -801,25 +801,25 @@ export class IgxOverlayService implements OnDestroy { * Reverses the wrapper insertion performed by `insertWrapper`, restoring the element to its original DOM position. */ private removeWrapper(info: OverlayInfo) { - const child: HTMLElement = info.elementRef.nativeElement; + const child: HTMLElement = info.elementRef!.nativeElement; if (!info.hook) { // No hook means element had no parent and was appended to body. // Just remove the wrapper; the dynamic component will be destroyed in cleanUp. info.wrapperElement?.parentElement?.removeChild(info.wrapperElement); - } else if (info.settings.positionStrategy instanceof ContainerPositionStrategy) { + } else if (info.settings!.positionStrategy instanceof ContainerPositionStrategy) { // Unwrap from container: move element back, then remove both wrapper and container div const container = info.wrapperElement?.parentElement; if (container) { - container.insertBefore(child, info.wrapperElement); - container.removeChild(info.wrapperElement); + container.insertBefore(child, info.wrapperElement!); + container.removeChild(info.wrapperElement!); container.remove(); } - } else if (info.settings.outlet) { - const outlet = info.settings.outlet?.nativeElement || info.settings.outlet; + } else if (info.settings!.outlet) { + const outlet = info.settings!.outlet?.nativeElement || info.settings!.outlet; // if same element is shown in other overlay outlet will not contain // the element and we should not remove it from outlet if (outlet.contains(child)) { - outlet.removeChild(child.parentNode.parentNode); + outlet.removeChild(child.parentNode!.parentNode); } } else { // Unwrap in-place: move element back to wrapper's position, then remove wrapper @@ -836,8 +836,8 @@ export class IgxOverlayService implements OnDestroy { */ private restoreHook(info: OverlayInfo) { if (info.hook) { - info.hook.parentElement.insertBefore(info.elementRef.nativeElement, info.hook); - info.hook.parentElement.removeChild(info.hook); + info.hook.parentElement!.insertBefore(info.elementRef!.nativeElement, info.hook); + info.hook.parentElement!.removeChild(info.hook); delete info.hook; } } @@ -876,9 +876,8 @@ export class IgxOverlayService implements OnDestroy { info.closeAnimationDetaching = true; info.closeAnimationPlayer?.destroy(); delete info.closeAnimationPlayer; - delete info.ngZone; + delete (info as any).ngZone; delete info.wrapperElement; - info = null; } private playOpenAnimation(info: OverlayInfo) { @@ -889,15 +888,15 @@ export class IgxOverlayService implements OnDestroy { if (info.closeAnimationPlayer?.hasStarted()) { const position = info.closeAnimationPlayer.position; info.closeAnimationPlayer.reset(); - info.openAnimationPlayer.init(); - info.openAnimationPlayer.position = 1 - position; + info.openAnimationPlayer!.init(); + info.openAnimationPlayer!.position = 1 - position; } - this.animationStarting.emit({ id: info.id, animationPlayer: info.openAnimationPlayer, animationType: 'open' }); + this.animationStarting.emit({ id: info.id!, animationPlayer: info.openAnimationPlayer!, animationType: 'open' }); // to eliminate flickering show the element just before animation start - info.wrapperElement.style.visibility = ''; + info.wrapperElement!.style.visibility = ''; info.visible = true; - info.openAnimationPlayer.play(); + info.openAnimationPlayer!.play(); } private playCloseAnimation(info: OverlayInfo, event?: Event) { @@ -908,16 +907,16 @@ export class IgxOverlayService implements OnDestroy { if (info.openAnimationPlayer?.hasStarted()) { const position = info.openAnimationPlayer.position; info.openAnimationPlayer.reset(); - info.closeAnimationPlayer.init(); - info.closeAnimationPlayer.position = 1 - position; + info.closeAnimationPlayer!.init(); + info.closeAnimationPlayer!.position = 1 - position; } - this.animationStarting.emit({ id: info.id, animationPlayer: info.closeAnimationPlayer, animationType: 'close' }); + this.animationStarting.emit({ id: info.id!, animationPlayer: info.closeAnimationPlayer!, animationType: 'close' }); info.event = event; - info.closeAnimationPlayer.play(); + info.closeAnimationPlayer!.play(); } // TODO: check if applyAnimationParams will work with complex animations - private applyAnimationParams(wrapperElement: HTMLElement, animationOptions: AnimationReferenceMetadata) { + private applyAnimationParams(wrapperElement: HTMLElement, animationOptions: AnimationReferenceMetadata | undefined) { if (!animationOptions) { wrapperElement.style.transitionDuration = '0ms'; return; @@ -943,36 +942,36 @@ export class IgxOverlayService implements OnDestroy { // not close the overlay and check next for (let i = this._overlayInfos.length; i--;) { const info = this._overlayInfos[i]; - if (info.settings.modal) { + if (info.settings!.modal) { return; } - if (info.settings.closeOnOutsideClick) { + if (info.settings!.closeOnOutsideClick) { const target = ev.composed ? ev.composedPath()[0] : ev.target; - const overlayElement = info.elementRef.nativeElement; + const overlayElement = info.elementRef!.nativeElement; // check if the click is on the overlay element or on an element from the exclusion list, and if so do not close the overlay - const excludeElements = info.settings.excludeFromOutsideClick ? - [...info.settings.excludeFromOutsideClick, overlayElement] : [overlayElement]; + const excludeElements = info.settings!.excludeFromOutsideClick ? + [...info.settings!.excludeFromOutsideClick, overlayElement] : [overlayElement]; const isInsideClick: boolean = excludeElements.some(e => e.contains(target as Node)); if (isInsideClick) { return; // if the click is outside click, but close animation has started do nothing } else if (!(info.closeAnimationPlayer?.hasStarted())) { - this._hide(info.id, ev); + this._hide(info.id!, ev); } } } }; private addOutsideClickListener(info: OverlayInfo) { - if (info.settings.closeOnOutsideClick) { - if (info.settings.modal) { - fromEvent(info.elementRef.nativeElement.parentElement.parentElement, 'click') + if (info.settings!.closeOnOutsideClick) { + if (info.settings!.modal) { + fromEvent(info.elementRef!.nativeElement.parentElement.parentElement, 'click') .pipe(takeUntil(this.destroy$)) - .subscribe((e: Event) => this._hide(info.id, e)); + .subscribe((e: Event) => this._hide(info.id!, e)); } else if ( // if all overlays minus closing overlays equals one add the handler - this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal).length - - this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal && + this._overlayInfos.filter(x => x.settings!.closeOnOutsideClick && !x.settings!.modal).length - + this._overlayInfos.filter(x => x.settings!.closeOnOutsideClick && !x.settings!.modal && x.closeAnimationPlayer?.hasStarted()).length === 1) { // click event is not fired on iOS. To make element "clickable" we are @@ -988,10 +987,10 @@ export class IgxOverlayService implements OnDestroy { } private removeOutsideClickListener(info: OverlayInfo) { - if (info.settings.modal === false) { + if (info.settings!.modal === false) { let shouldRemoveClickEventListener = true; this._overlayInfos.forEach(o => { - if (o.settings.modal === false && o.id !== info.id) { + if (o.settings!.modal === false && o.id !== info.id) { shouldRemoveClickEventListener = false; } }); @@ -1012,7 +1011,7 @@ export class IgxOverlayService implements OnDestroy { .filter(o => o.closeAnimationPlayer?.hasStarted()) .length; if (this._overlayInfos.length - closingOverlaysCount === 1) { - this._document.defaultView.addEventListener('resize', this.repositionAll); + this._document.defaultView!.addEventListener('resize', this.repositionAll); } } @@ -1022,13 +1021,13 @@ export class IgxOverlayService implements OnDestroy { .filter(o => o.closeAnimationPlayer?.hasStarted()) .length; if (this._overlayInfos.length - closingOverlaysCount === 1) { - this._document.defaultView.removeEventListener('resize', this.repositionAll); + this._document.defaultView!.removeEventListener('resize', this.repositionAll); } } private addCloseOnEscapeListener(info: OverlayInfo) { - if (info.settings.closeOnEscape && !this._keyPressEventListener) { - this._keyPressEventListener = fromEvent(this._document, 'keydown').pipe( + if (info.settings!.closeOnEscape && !this._keyPressEventListener) { + this._keyPressEventListener = fromEvent(this._document, 'keydown').pipe( filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc') ).subscribe((ev) => { const visibleOverlays = this._overlayInfos.filter(o => o.visible); @@ -1036,8 +1035,8 @@ export class IgxOverlayService implements OnDestroy { return; } const targetOverlayInfo = visibleOverlays[visibleOverlays.length - 1]; - if (targetOverlayInfo.visible && targetOverlayInfo.settings.closeOnEscape) { - this.hide(targetOverlayInfo.id, ev); + if (targetOverlayInfo.visible && targetOverlayInfo.settings!.closeOnEscape) { + this.hide(targetOverlayInfo.id!, ev); } }); } @@ -1046,15 +1045,15 @@ export class IgxOverlayService implements OnDestroy { private removeCloseOnEscapeListener() { if (this._keyPressEventListener) { this._keyPressEventListener.unsubscribe(); - this._keyPressEventListener = null; + this._keyPressEventListener = null!; } } private addModalClasses(info: OverlayInfo) { - if (info.settings.modal) { - const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement; + if (info.settings!.modal) { + const wrapperElement = info.elementRef!.nativeElement.parentElement.parentElement; wrapperElement.classList.remove('igx-overlay__wrapper'); - this.applyAnimationParams(wrapperElement, info.settings.positionStrategy.settings.openAnimation); + this.applyAnimationParams(wrapperElement, info.settings!.positionStrategy!.settings.openAnimation); requestAnimationFrame(() => { wrapperElement.classList.add('igx-overlay__wrapper--modal'); }); @@ -1062,25 +1061,25 @@ export class IgxOverlayService implements OnDestroy { } private removeModalClasses(info: OverlayInfo) { - if (info.settings.modal) { - const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement; - this.applyAnimationParams(wrapperElement, info.settings.positionStrategy.settings.closeAnimation); + if (info.settings!.modal) { + const wrapperElement = info.elementRef!.nativeElement.parentElement.parentElement; + this.applyAnimationParams(wrapperElement, info.settings!.positionStrategy!.settings.closeAnimation); wrapperElement.classList.remove('igx-overlay__wrapper--modal'); wrapperElement.classList.add('igx-overlay__wrapper'); } } private buildAnimationPlayers(info: OverlayInfo) { - if (info.settings.positionStrategy.settings.openAnimation) { + if (info.settings!.positionStrategy!.settings.openAnimation) { info.openAnimationPlayer = this.animationService - .buildAnimation(info.settings.positionStrategy.settings.openAnimation, info.elementRef.nativeElement); + .buildAnimation(info.settings!.positionStrategy!.settings.openAnimation, info.elementRef!.nativeElement); info.openAnimationPlayer.animationEnd .pipe(takeUntil(this.destroy$)) .subscribe(() => this.openAnimationDone(info)); } - if (info.settings.positionStrategy.settings.closeAnimation) { + if (info.settings!.positionStrategy!.settings.closeAnimation) { info.closeAnimationPlayer = this.animationService - .buildAnimation(info.settings.positionStrategy.settings.closeAnimation, info.elementRef.nativeElement); + .buildAnimation(info.settings!.positionStrategy!.settings.closeAnimation, info.elementRef!.nativeElement); info.closeAnimationPlayer.animationEnd .pipe(takeUntil(this.destroy$)) .subscribe(() => this.closeAnimationDone(info)); @@ -1089,7 +1088,7 @@ export class IgxOverlayService implements OnDestroy { private openAnimationDone(info: OverlayInfo) { if (!info.openAnimationDetaching) { - this.opened.emit({ id: info.id, componentRef: info.componentRef }); + this.opened.emit({ id: info.id!, componentRef: info.componentRef }); } if (info.openAnimationPlayer) { info.openAnimationPlayer.reset(); @@ -1121,7 +1120,7 @@ export class IgxOverlayService implements OnDestroy { private getComponentSize(info: OverlayInfo) { if (info.elementRef?.nativeElement instanceof Element) { - const styles = this._document.defaultView.getComputedStyle(info.elementRef.nativeElement); + const styles = this._document.defaultView!.getComputedStyle(info.elementRef.nativeElement); const componentSize = styles.getPropertyValue('--component-size'); const globalSize = styles.getPropertyValue('--ig-size'); const size = componentSize || globalSize; diff --git a/projects/igniteui-angular/core/src/services/overlay/position/auto-position-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/position/auto-position-strategy.ts index 9f7f6b05dae..a4c831b76be 100644 --- a/projects/igniteui-angular/core/src/services/overlay/position/auto-position-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/position/auto-position-strategy.ts @@ -17,7 +17,7 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy { */ protected fitInViewport(element: HTMLElement, connectedFit: ConnectedFit) { const transformString: string[] = []; - if (connectedFit.fitHorizontal.back < 0 || connectedFit.fitHorizontal.forward < 0) { + if (connectedFit.fitHorizontal!.back < 0 || connectedFit.fitHorizontal!.forward < 0) { if (this.canFlipHorizontal(connectedFit)) { this.flipHorizontal(); this.flipAnimation(FlipDirection.Horizontal); @@ -27,7 +27,7 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy { } } - if (connectedFit.fitVertical.back < 0 || connectedFit.fitVertical.forward < 0) { + if (connectedFit.fitVertical!.back < 0 || connectedFit.fitVertical!.forward < 0) { if (this.canFlipVertical(connectedFit)) { this.flipVertical(); this.flipAnimation(FlipDirection.Vertical); @@ -54,13 +54,13 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy { // (-1) * (Left + 1) = 0 = Right // (-1) * (Center + 1) = -0.5 = Center // (-1) * (Right + 1) = -1 = Left - const flippedStartPoint = (-1) * (this.settings.horizontalStartPoint + 1); - const flippedDirection = (-1) * (this.settings.horizontalDirection + 1); + const flippedStartPoint = (-1) * (this.settings.horizontalStartPoint! + 1); + const flippedDirection = (-1) * (this.settings.horizontalDirection! + 1); const leftBorder = this.calculateLeft( - connectedFit.targetRect, connectedFit.contentElementRect, flippedStartPoint, flippedDirection, 0); - const rightBorder = leftBorder + connectedFit.contentElementRect.width; - return 0 < leftBorder && rightBorder < connectedFit.viewPortRect.width; + connectedFit.targetRect!, connectedFit.contentElementRect!, flippedStartPoint, flippedDirection, 0); + const rightBorder = leftBorder + connectedFit.contentElementRect!.width!; + return 0 < leftBorder && rightBorder < connectedFit.viewPortRect!.width!; } /** @@ -70,13 +70,13 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy { * @returns true if element can be flipped and stain in viewport */ private canFlipVertical(connectedFit: ConnectedFit): boolean { - const flippedStartPoint = (-1) * (this.settings.verticalStartPoint + 1); - const flippedDirection = (-1) * (this.settings.verticalDirection + 1); + const flippedStartPoint = (-1) * (this.settings.verticalStartPoint! + 1); + const flippedDirection = (-1) * (this.settings.verticalDirection! + 1); const topBorder = this.calculateTop( - connectedFit.targetRect, connectedFit.contentElementRect, flippedStartPoint, flippedDirection, 0); - const bottomBorder = topBorder + connectedFit.contentElementRect.height; - return 0 < topBorder && bottomBorder < connectedFit.viewPortRect.height; + connectedFit.targetRect!, connectedFit.contentElementRect!, flippedStartPoint, flippedDirection, 0); + const bottomBorder = topBorder + connectedFit.contentElementRect!.height!; + return 0 < topBorder && bottomBorder < connectedFit.viewPortRect!.height!; } /** @@ -130,8 +130,8 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy { * @returns amount of necessary translation which will push the element into viewport */ private horizontalPush(connectedFit: ConnectedFit): number { - const leftExtend = connectedFit.left; - const rightExtend = connectedFit.right - connectedFit.viewPortRect.width; + const leftExtend = connectedFit.left!; + const rightExtend = connectedFit.right! - connectedFit.viewPortRect!.width!; // if leftExtend < 0 overlay goes beyond left end of the screen. We should push it back with exactly // as much as it is beyond the screen. // if rightExtend > 0 overlay goes beyond right end of the screen. We should push it back with the @@ -153,8 +153,8 @@ export class AutoPositionStrategy extends BaseFitPositionStrategy { * @returns amount of necessary translation which will push the element into viewport */ private verticalPush(connectedFit: ConnectedFit): number { - const topExtend = connectedFit.top; - const bottomExtend = connectedFit.bottom - connectedFit.viewPortRect.height; + const topExtend = connectedFit.top!; + const bottomExtend = connectedFit.bottom! - connectedFit.viewPortRect!.height!; if (topExtend < 0) { return Math.abs(topExtend); } else if (bottomExtend > 0) { diff --git a/projects/igniteui-angular/core/src/services/overlay/position/base-fit-position-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/position/base-fit-position-strategy.ts index b1a88c284f0..9c0d1f40607 100644 --- a/projects/igniteui-angular/core/src/services/overlay/position/base-fit-position-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/position/base-fit-position-strategy.ts @@ -2,8 +2,8 @@ import { ConnectedFit, HorizontalAlignment, Point, PositionSettings, Size, Util, import { ConnectedPositioningStrategy } from './connected-positioning-strategy'; export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrategy { - protected _initialSize: Size; - protected _initialSettings: PositionSettings; + protected _initialSize!: Size; + protected _initialSettings!: PositionSettings; /** * Position the element based on the PositionStrategy implementing this interface. @@ -19,14 +19,14 @@ export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrate */ public override position( contentElement: HTMLElement, _size: Size, document?: Document, initialCall?: boolean, target?: Point | HTMLElement): void { - const rects = super.calculateElementRectangles(contentElement, target); + const rects = super.calculateElementRectangles(contentElement, target!); const connectedFit: ConnectedFit = {}; if (initialCall) { connectedFit.targetRect = rects.targetRect; connectedFit.contentElementRect = rects.elementRect; this._initialSettings = this._initialSettings || Object.assign({}, this.settings); this.settings = Object.assign({}, this._initialSettings); - connectedFit.viewPortRect = Util.getViewportRect(document); + connectedFit.viewPortRect = Util.getViewportRect(document!); this.updateViewPortFit(connectedFit); if (this.shouldFitInViewPort(connectedFit)) { this.fitInViewport(contentElement, connectedFit); @@ -45,27 +45,27 @@ export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrate const { horizontalOffset, verticalOffset } = super.getElementOffsets(connectedFit); connectedFit.left = this.calculateLeft( - connectedFit.targetRect, - connectedFit.contentElementRect, - this.settings.horizontalStartPoint, - this.settings.horizontalDirection, + connectedFit.targetRect!, + connectedFit.contentElementRect!, + this.settings.horizontalStartPoint!, + this.settings.horizontalDirection!, horizontalOffset); - connectedFit.right = connectedFit.left + connectedFit.contentElementRect.width; + connectedFit.right = connectedFit.left + connectedFit.contentElementRect!.width!; connectedFit.fitHorizontal = { back: Math.round(connectedFit.left), - forward: Math.round(connectedFit.viewPortRect.width - connectedFit.right) + forward: Math.round(connectedFit.viewPortRect!.width! - connectedFit.right) }; connectedFit.top = this.calculateTop( - connectedFit.targetRect, - connectedFit.contentElementRect, - this.settings.verticalStartPoint, - this.settings.verticalDirection, + connectedFit.targetRect!, + connectedFit.contentElementRect!, + this.settings.verticalStartPoint!, + this.settings.verticalDirection!, verticalOffset); - connectedFit.bottom = connectedFit.top + connectedFit.contentElementRect.height; + connectedFit.bottom = connectedFit.top + connectedFit.contentElementRect!.height!; connectedFit.fitVertical = { back: Math.round(connectedFit.top), - forward: Math.round(connectedFit.viewPortRect.height - connectedFit.bottom) + forward: Math.round(connectedFit.viewPortRect!.height! - connectedFit.bottom) }; } @@ -84,7 +84,7 @@ export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrate startPoint: HorizontalAlignment, direction: HorizontalAlignment, offset?: number): number { - return targetRect.right + targetRect.width * startPoint + elementRect.width * direction + offset; + return targetRect.right! + targetRect.width! * startPoint + elementRect.width! * direction + offset!; } /** @@ -102,7 +102,7 @@ export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrate startPoint: VerticalAlignment, direction: VerticalAlignment, offset?: number): number { - return targetRect.bottom + targetRect.height * startPoint + elementRect.height * direction + offset; + return targetRect.bottom! + targetRect.height! * startPoint + elementRect.height! * direction + offset!; } /** @@ -111,8 +111,8 @@ export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrate * @param connectedFit connectedFit object containing all necessary parameters */ protected shouldFitInViewPort(connectedFit: ConnectedFit) { - return connectedFit.fitHorizontal.back < 0 || connectedFit.fitHorizontal.forward < 0 || - connectedFit.fitVertical.back < 0 || connectedFit.fitVertical.forward < 0; + return connectedFit.fitHorizontal!.back < 0 || connectedFit.fitHorizontal!.forward < 0 || + connectedFit.fitVertical!.back < 0 || connectedFit.fitVertical!.forward < 0; } /** @@ -123,5 +123,5 @@ export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrate */ protected abstract fitInViewport( element: HTMLElement, - connectedFit: ConnectedFit); + connectedFit: ConnectedFit): void; } diff --git a/projects/igniteui-angular/core/src/services/overlay/position/connected-positioning-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/position/connected-positioning-strategy.ts index 9497008fe45..3cf036bcb5f 100644 --- a/projects/igniteui-angular/core/src/services/overlay/position/connected-positioning-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/position/connected-positioning-strategy.ts @@ -47,7 +47,7 @@ export class ConnectedPositioningStrategy implements IPositionStrategy { * ``` */ public position(contentElement: HTMLElement, _size: Size, _document?: Document, _initialCall?: boolean, target?: Point | HTMLElement): void { - const rects = this.calculateElementRectangles(contentElement, target); + const rects = this.calculateElementRectangles(contentElement, target!); this.setStyle(contentElement, rects.targetRect, rects.elementRect, {}); } @@ -64,7 +64,7 @@ export class ConnectedPositioningStrategy implements IPositionStrategy { * * @returns target and element DomRect objects */ - protected calculateElementRectangles(contentElement, target: Point | HTMLElement): + protected calculateElementRectangles(contentElement: HTMLElement, target: Point | HTMLElement): { targetRect: Partial; elementRect: Partial } { return { targetRect: Util.getTargetRect(target), @@ -98,10 +98,10 @@ export class ConnectedPositioningStrategy implements IPositionStrategy { const { horizontalOffset, verticalOffset } = this.getElementOffsets(connectedFit); const startPoint: Point = { - x: targetRect.right + targetRect.width * this.settings.horizontalStartPoint + horizontalOffset, - y: targetRect.bottom + targetRect.height * this.settings.verticalStartPoint + verticalOffset + x: targetRect.right! + targetRect.width! * this.settings.horizontalStartPoint! + horizontalOffset, + y: targetRect.bottom! + targetRect.height! * this.settings.verticalStartPoint! + verticalOffset }; - const wrapperRect: ClientRect = element.parentElement.getBoundingClientRect(); + const wrapperRect: ClientRect = element.parentElement!.getBoundingClientRect(); // clean up styles - if auto position strategy is chosen we may pass here several times element.style.right = ''; @@ -114,7 +114,7 @@ export class ConnectedPositioningStrategy implements IPositionStrategy { element.style.right = `${Math.round(wrapperRect.right - startPoint.x)}px`; break; case HorizontalAlignment.Center: - element.style.left = `${Math.round(startPoint.x - wrapperRect.left - elementRect.width / 2)}px`; + element.style.left = `${Math.round(startPoint.x - wrapperRect.left - elementRect.width! / 2)}px`; break; case HorizontalAlignment.Right: element.style.left = `${Math.round(startPoint.x - wrapperRect.left)}px`; @@ -126,7 +126,7 @@ export class ConnectedPositioningStrategy implements IPositionStrategy { element.style.bottom = `${Math.round(wrapperRect.bottom - startPoint.y)}px`; break; case VerticalAlignment.Middle: - element.style.top = `${Math.round(startPoint.y - wrapperRect.top - elementRect.height / 2)}px`; + element.style.top = `${Math.round(startPoint.y - wrapperRect.top - elementRect.height! / 2)}px`; break; case VerticalAlignment.Bottom: element.style.top = `${Math.round(startPoint.y - wrapperRect.top)}px`; diff --git a/projects/igniteui-angular/core/src/services/overlay/position/container-position-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/position/container-position-strategy.ts index 40a33f016f6..3cfc53e59b4 100644 --- a/projects/igniteui-angular/core/src/services/overlay/position/container-position-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/position/container-position-strategy.ts @@ -17,7 +17,7 @@ export class ContainerPositionStrategy extends GlobalPositionStrategy { public override position(contentElement: HTMLElement): void { // Set up intersection observer this.io?.disconnect(); - const containerElement = contentElement.parentElement.parentElement; + const containerElement = contentElement.parentElement!.parentElement; if (!containerElement) { super.position(contentElement); return; @@ -40,7 +40,7 @@ export class ContainerPositionStrategy extends GlobalPositionStrategy { private internalPosition(contentElement: HTMLElement, container: HTMLElement): void { contentElement.classList.add('igx-overlay__content--relative'); - contentElement.parentElement.classList.add('igx-overlay__wrapper--flex-container'); + contentElement.parentElement!.classList.add('igx-overlay__wrapper--flex-container'); this.setPosition(contentElement); this.updatePosition(contentElement, container); } @@ -52,9 +52,9 @@ export class ContainerPositionStrategy extends GlobalPositionStrategy { // TODO: consider using new anchor() CSS function when it becomes more widely // supported: https://caniuse.com/mdn-css_properties_anchor const containerRect = container.getBoundingClientRect(); - contentElement.parentElement.style.width = `${containerRect.width}px`; - contentElement.parentElement.style.height = `${containerRect.height}px`; - contentElement.parentElement.style.top = `${containerRect.top}px`; - contentElement.parentElement.style.left = `${containerRect.left}px`; + contentElement.parentElement!.style.width = `${containerRect.width}px`; + contentElement.parentElement!.style.height = `${containerRect.height}px`; + contentElement.parentElement!.style.top = `${containerRect.top}px`; + contentElement.parentElement!.style.left = `${containerRect.left}px`; } } diff --git a/projects/igniteui-angular/core/src/services/overlay/position/elastic-position-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/position/elastic-position-strategy.ts index 12b23619297..0e17e80d388 100644 --- a/projects/igniteui-angular/core/src/services/overlay/position/elastic-position-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/position/elastic-position-strategy.ts @@ -15,12 +15,12 @@ export class ElasticPositionStrategy extends BaseFitPositionStrategy { protected fitInViewport(element: HTMLElement, connectedFit: ConnectedFit) { element.classList.add('igx-overlay__content--elastic'); const transformString: string[] = []; - if (connectedFit.fitHorizontal.back < 0 || connectedFit.fitHorizontal.forward < 0) { - const maxReduction = Math.max(0, connectedFit.contentElementRect.width - this.settings.minSize.width); - const leftExtend = Math.max(0, -connectedFit.fitHorizontal.back); - const rightExtend = Math.max(0, -connectedFit.fitHorizontal.forward); + if (connectedFit.fitHorizontal!.back < 0 || connectedFit.fitHorizontal!.forward < 0) { + const maxReduction = Math.max(0, connectedFit.contentElementRect!.width! - this.settings.minSize!.width); + const leftExtend = Math.max(0, -connectedFit.fitHorizontal!.back); + const rightExtend = Math.max(0, -connectedFit.fitHorizontal!.forward); const reduction = Math.min(maxReduction, leftExtend + rightExtend); - element.style.width = `${connectedFit.contentElementRect.width - reduction}px`; + element.style.width = `${connectedFit.contentElementRect!.width! - reduction}px`; // if direction is center and element goes off the screen in left direction we should push the // element to the right. Prevents left still going out of view when normally positioned @@ -36,12 +36,12 @@ export class ElasticPositionStrategy extends BaseFitPositionStrategy { } } - if (connectedFit.fitVertical.back < 0 || connectedFit.fitVertical.forward < 0) { - const maxReduction = Math.max(0, connectedFit.contentElementRect.height - this.settings.minSize.height); - const topExtend = Math.max(0, -connectedFit.fitVertical.back); - const bottomExtend = Math.max(0, -connectedFit.fitVertical.forward); + if (connectedFit.fitVertical!.back < 0 || connectedFit.fitVertical!.forward < 0) { + const maxReduction = Math.max(0, connectedFit.contentElementRect!.height! - this.settings.minSize!.height); + const topExtend = Math.max(0, -connectedFit.fitVertical!.back); + const bottomExtend = Math.max(0, -connectedFit.fitVertical!.forward); const reduction = Math.min(maxReduction, topExtend + bottomExtend); - element.style.height = `${connectedFit.contentElementRect.height - reduction}px`; + element.style.height = `${connectedFit.contentElementRect!.height! - reduction}px`; // if direction is middle and element goes off the screen in top direction we should push the // element to the bottom. Prevents top still going out of view when normally positioned diff --git a/projects/igniteui-angular/core/src/services/overlay/position/global-position-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/position/global-position-strategy.ts index 87514aec482..8d9d3054f5b 100644 --- a/projects/igniteui-angular/core/src/services/overlay/position/global-position-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/position/global-position-strategy.ts @@ -36,7 +36,7 @@ export class GlobalPositionStrategy implements IPositionStrategy { */ public position(contentElement: HTMLElement): void { contentElement.classList.add('igx-overlay__content--relative'); - contentElement.parentElement.classList.add('igx-overlay__wrapper--flex'); + contentElement.parentElement!.classList.add('igx-overlay__wrapper--flex'); this.setPosition(contentElement); } @@ -53,13 +53,13 @@ export class GlobalPositionStrategy implements IPositionStrategy { protected setPosition(contentElement: HTMLElement) { switch (this.settings.horizontalDirection) { case HorizontalAlignment.Left: - contentElement.parentElement.style.justifyContent = 'flex-start'; + contentElement.parentElement!.style.justifyContent = 'flex-start'; break; case HorizontalAlignment.Center: - contentElement.parentElement.style.justifyContent = 'center'; + contentElement.parentElement!.style.justifyContent = 'center'; break; case HorizontalAlignment.Right: - contentElement.parentElement.style.justifyContent = 'flex-end'; + contentElement.parentElement!.style.justifyContent = 'flex-end'; break; default: break; @@ -67,13 +67,13 @@ export class GlobalPositionStrategy implements IPositionStrategy { switch (this.settings.verticalDirection) { case VerticalAlignment.Top: - contentElement.parentElement.style.alignItems = 'flex-start'; + contentElement.parentElement!.style.alignItems = 'flex-start'; break; case VerticalAlignment.Middle: - contentElement.parentElement.style.alignItems = 'center'; + contentElement.parentElement!.style.alignItems = 'center'; break; case VerticalAlignment.Bottom: - contentElement.parentElement.style.alignItems = 'flex-end'; + contentElement.parentElement!.style.alignItems = 'flex-end'; break; default: break; diff --git a/projects/igniteui-angular/core/src/services/overlay/scroll/IScrollStrategy.ts b/projects/igniteui-angular/core/src/services/overlay/scroll/IScrollStrategy.ts index 32efa2b0035..720ff90f2d2 100644 --- a/projects/igniteui-angular/core/src/services/overlay/scroll/IScrollStrategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/scroll/IScrollStrategy.ts @@ -15,7 +15,7 @@ export interface IScrollStrategy { * settings.scrollStrategy.initialize(document, overlay, id); * ``` */ - initialize(document: Document, overlayService: IgxOverlayService, id: string); + initialize(document: Document, overlayService: IgxOverlayService, id: string): void; /** * Attaches the strategy diff --git a/projects/igniteui-angular/core/src/services/overlay/scroll/absolute-scroll-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/scroll/absolute-scroll-strategy.ts index d4d85d57306..1f1ad33f660 100644 --- a/projects/igniteui-angular/core/src/services/overlay/scroll/absolute-scroll-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/scroll/absolute-scroll-strategy.ts @@ -7,15 +7,15 @@ import { ScrollStrategy } from './scroll-strategy'; */ export class AbsoluteScrollStrategy extends ScrollStrategy { private _initialized = false; - private _document: Document; - private _overlayService: IgxOverlayService; - private _id: string; + private _document!: Document; + private _overlayService!: IgxOverlayService; + private _id!: string; private _scrollContainer: HTMLElement; - private _zone: NgZone; + private _zone!: NgZone; constructor(scrollContainer?: HTMLElement) { super(); - this._scrollContainer = scrollContainer; + this._scrollContainer = scrollContainer!; } /** @@ -85,7 +85,7 @@ export class AbsoluteScrollStrategy extends ScrollStrategy { if (!overlayInfo) { return; } - if (!overlayInfo.elementRef.nativeElement.contains(e.target)) { + if (!overlayInfo.elementRef!.nativeElement.contains(e.target)) { this._overlayService.reposition(this._id); } }; diff --git a/projects/igniteui-angular/core/src/services/overlay/scroll/block-scroll-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/scroll/block-scroll-strategy.ts index 1412795bceb..2b2d76b8964 100644 --- a/projects/igniteui-angular/core/src/services/overlay/scroll/block-scroll-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/scroll/block-scroll-strategy.ts @@ -5,10 +5,10 @@ import { ScrollStrategy } from './scroll-strategy'; */ export class BlockScrollStrategy extends ScrollStrategy { private _initialized = false; - private _document: Document; - private _initialScrollTop: number; - private _initialScrollLeft: number; - private _sourceElement: Element; + private _document!: Document; + private _initialScrollTop!: number; + private _initialScrollLeft!: number; + private _sourceElement!: Element; constructor() { super(); @@ -45,7 +45,7 @@ export class BlockScrollStrategy extends ScrollStrategy { */ public detach(): void { this._document.removeEventListener('scroll', this.onScroll, true); - this._sourceElement = null; + this._sourceElement = null!; this._initialScrollTop = 0; this._initialScrollLeft = 0; this._initialized = false; diff --git a/projects/igniteui-angular/core/src/services/overlay/scroll/close-scroll-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/scroll/close-scroll-strategy.ts index f7dff177fee..8636fa8cb94 100644 --- a/projects/igniteui-angular/core/src/services/overlay/scroll/close-scroll-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/scroll/close-scroll-strategy.ts @@ -6,20 +6,20 @@ import { ScrollStrategy } from './scroll-strategy'; * Uses a tolerance and closes the shown component upon scrolling if the tolerance is exceeded */ export class CloseScrollStrategy extends ScrollStrategy { - private _document: Document; - private _overlayService: IgxOverlayService; - private _id: string; - private initialScrollTop: number; - private initialScrollLeft: number; + private _document!: Document; + private _overlayService!: IgxOverlayService; + private _id!: string; + private initialScrollTop!: number; + private initialScrollLeft!: number; private _threshold: number; private _initialized = false; - private _sourceElement: Element; + private _sourceElement!: Element; private _scrollContainer: HTMLElement; - private _overlayInfo: OverlayInfo; + private _overlayInfo!: OverlayInfo; constructor(scrollContainer?: HTMLElement) { super(); - this._scrollContainer = scrollContainer; + this._scrollContainer = scrollContainer!; this._threshold = 10; } @@ -72,7 +72,7 @@ export class CloseScrollStrategy extends ScrollStrategy { } else { this._document.removeEventListener('scroll', this.onScroll, true); } - this._sourceElement = null; + this._sourceElement = null!; this._initialized = false; } @@ -83,7 +83,7 @@ export class CloseScrollStrategy extends ScrollStrategy { this.initialScrollLeft = this._sourceElement.scrollLeft; } - if (this._overlayInfo.elementRef.nativeElement.contains(this._sourceElement)) { + if (this._overlayInfo.elementRef!.nativeElement.contains(this._sourceElement)) { return; } if (Math.abs(this._sourceElement.scrollTop - this.initialScrollTop) > this._threshold || diff --git a/projects/igniteui-angular/core/src/services/overlay/scroll/scroll-strategy.ts b/projects/igniteui-angular/core/src/services/overlay/scroll/scroll-strategy.ts index 946afa27b83..ed2e3dc20dc 100644 --- a/projects/igniteui-angular/core/src/services/overlay/scroll/scroll-strategy.ts +++ b/projects/igniteui-angular/core/src/services/overlay/scroll/scroll-strategy.ts @@ -12,7 +12,7 @@ export abstract class ScrollStrategy implements IScrollStrategy { * settings.scrollStrategy.initialize(document, overlay, id); * ``` */ - public abstract initialize(document: Document, overlayService: IgxOverlayService, id: string); + public abstract initialize(document: Document, overlayService: IgxOverlayService, id: string): void; /** * Attaches the strategy diff --git a/projects/igniteui-angular/core/src/services/overlay/utilities.ts b/projects/igniteui-angular/core/src/services/overlay/utilities.ts index c611c9de2ac..0f0fb554788 100644 --- a/projects/igniteui-angular/core/src/services/overlay/utilities.ts +++ b/projects/igniteui-angular/core/src/services/overlay/utilities.ts @@ -294,7 +294,7 @@ export class Util { return new Point(horizontalScrollPosition, verticalScrollPosition); } - public static cloneInstance(object) { + public static cloneInstance(object: any) { const clonedObj = Object.assign(Object.create(Object.getPrototypeOf(object)), object); clonedObj.settings = cloneValue(clonedObj.settings); return clonedObj; @@ -367,8 +367,8 @@ export class Util { const viewPortRect = Util.getViewportRect(doc); const rootMargin = { top: -Math.abs(rect.top), - right: -Math.abs(viewPortRect.width - rect.right), - bottom: -Math.abs(viewPortRect.height - rect.bottom), + right: -Math.abs(viewPortRect.width! - rect.right), + bottom: -Math.abs(viewPortRect.height! - rect.bottom), left: -Math.abs(rect.left), }; const options = { diff --git a/projects/igniteui-angular/core/src/services/transaction/base-transaction.ts b/projects/igniteui-angular/core/src/services/transaction/base-transaction.ts index 1bac4a0bfd0..b261cde928d 100644 --- a/projects/igniteui-angular/core/src/services/transaction/base-transaction.ts +++ b/projects/igniteui-angular/core/src/services/transaction/base-transaction.ts @@ -105,7 +105,7 @@ export class IgxBaseTransactionService i * @returns State of the record if any */ public getState(id: any): S { - return this._pendingStates.get(id); + return this._pendingStates.get(id)!; } /** diff --git a/projects/igniteui-angular/core/src/services/transaction/igx-hierarchical-transaction.ts b/projects/igniteui-angular/core/src/services/transaction/igx-hierarchical-transaction.ts index f460699d1c0..36614581999 100644 --- a/projects/igniteui-angular/core/src/services/transaction/igx-hierarchical-transaction.ts +++ b/projects/igniteui-angular/core/src/services/transaction/igx-hierarchical-transaction.ts @@ -54,8 +54,8 @@ export class IgxHierarchicalTransactionService exten * @returns State of the record if any */ public override getState(id: any, pending = false): S { - return pending ? this._pendingStates.get(id) : this._states.get(id); + return pending ? this._pendingStates.get(id)! : this._states.get(id)!; } /** @@ -123,8 +123,8 @@ export class IgxTransactionService exten for (const transaction of this._pendingTransactions) { const pendingState = this._pendingStates.get(transaction.id); this._transactions.push(transaction); - this.updateState(this._states, transaction, pendingState.recordRef); - actions.push({ transaction, recordRef: pendingState.recordRef }); + this.updateState(this._states, transaction, pendingState!.recordRef); + actions.push({ transaction, recordRef: pendingState!.recordRef }); } this._undoStack.push(actions); @@ -186,7 +186,7 @@ export class IgxTransactionService exten return; } - const lastActions: Action[] = this._undoStack.pop(); + const lastActions: Action[] = this._undoStack.pop()!; this._transactions.splice(this._transactions.length - lastActions.length); this._redoStack.push(lastActions); @@ -205,7 +205,7 @@ export class IgxTransactionService exten */ public override redo(): void { if (this._redoStack.length > 0) { - const actions: Action[] = this._redoStack.pop(); + const actions: Action[] = this._redoStack.pop()!; for (const action of actions) { this.updateState(this._states, action.transaction, action.recordRef); this._transactions.push(action.transaction); diff --git a/projects/igniteui-angular/date-picker/src/date-picker/calendar-container/calendar-container.component.ts b/projects/igniteui-angular/date-picker/src/date-picker/calendar-container/calendar-container.component.ts index f357310ed47..c94f2d1e662 100644 --- a/projects/igniteui-angular/date-picker/src/date-picker/calendar-container/calendar-container.component.ts +++ b/projects/igniteui-angular/date-picker/src/date-picker/calendar-container/calendar-container.component.ts @@ -30,7 +30,7 @@ import { IgxPredefinedRangesAreaComponent } from '../../date-range-picker/predef }) export class IgxCalendarContainerComponent { @ViewChild(IgxCalendarComponent, { static: true }) - public calendar: IgxCalendarComponent; + public calendar!: IgxCalendarComponent; @Output() public calendarClose = new EventEmitter(); @@ -57,16 +57,16 @@ export class IgxCalendarContainerComponent { public customRanges: CustomDateRange[] = []; public resourceStrings!: IDateRangePickerResourceStrings; public vertical = false; - public closeButtonLabel: string; + public closeButtonLabel!: string; public closeButtonType: IgxButtonType = 'flat'; - public cancelButtonLabel: string; + public cancelButtonLabel!: string; public cancelButtonType: IgxButtonType = 'flat'; - public todayButtonLabel: string; + public todayButtonLabel!: string; public mode: PickerInteractionMode = PickerInteractionMode.DropDown; - public pickerActions: IgxPickerActionsDirective; + public pickerActions!: IgxPickerActionsDirective; @HostListener('keydown.alt.arrowup', ['$event']) - public onEscape(event) { + public onEscape(event: KeyboardEvent) { event.preventDefault(); // Prevent the event from reaching IgxDatePickerComponent/IgxDateRangePickerComponent, diff --git a/projects/igniteui-angular/date-picker/src/date-picker/date-picker.component.html b/projects/igniteui-angular/date-picker/src/date-picker/date-picker.component.html index 551816ddb1c..d011651e47c 100644 --- a/projects/igniteui-angular/date-picker/src/date-picker/date-picker.component.html +++ b/projects/igniteui-angular/date-picker/src/date-picker/date-picker.component.html @@ -16,7 +16,7 @@ string; + public formatter!: (val: Date) => string; /** * Gets/Sets the today button's label. @@ -207,7 +207,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr * ``` */ @Input() - public todayButtonLabel: string; + public todayButtonLabel!: string; /** * Gets/Sets the cancel button's label. @@ -218,7 +218,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr * ``` */ @Input() - public cancelButtonLabel: string; + public cancelButtonLabel!: string; /** * Specify if the currently spun date segment should loop over. @@ -241,7 +241,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr * ``` */ @Input() - public spinDelta: Pick; + public spinDelta!: Pick; /** * Gets/Sets the value of `id` attribute. @@ -268,7 +268,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr * ``` */ @Input() - public formatViews: IFormattingViews; + public formatViews!: IFormattingViews; /** * Gets/Sets the disabled dates descriptors. @@ -315,7 +315,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr * ``` */ @Input() - public calendarFormat: IFormattingOptions; + public calendarFormat!: IFormattingOptions; //#endregion @@ -378,7 +378,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr * By default it uses EN resources. */ @Input() - public resourceStrings: IDatePickerResourceStrings; + public resourceStrings!: IDatePickerResourceStrings; /** @hidden @internal */ @Input({ transform: booleanAttribute }) @@ -411,31 +411,31 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr /** @hidden @internal */ @ContentChild(IgxLabelDirective) - public label: IgxLabelDirective; + public label?: IgxLabelDirective; @ContentChild(IgxCalendarHeaderTitleTemplateDirective) - private headerTitleTemplate: IgxCalendarHeaderTitleTemplateDirective; + private headerTitleTemplate!: IgxCalendarHeaderTitleTemplateDirective; @ContentChild(IgxCalendarHeaderTemplateDirective) - private headerTemplate: IgxCalendarHeaderTemplateDirective; + private headerTemplate!: IgxCalendarHeaderTemplateDirective; @ViewChild(IgxDateTimeEditorDirective, { static: true }) - private dateTimeEditor: IgxDateTimeEditorDirective; + private dateTimeEditor!: IgxDateTimeEditorDirective; @ViewChild(IgxInputGroupComponent, { read: ViewContainerRef }) - private viewContainerRef: ViewContainerRef; + private viewContainerRef!: ViewContainerRef; @ViewChild(IgxLabelDirective) - private labelDirective: IgxLabelDirective; + private labelDirective!: IgxLabelDirective; @ViewChild(IgxInputDirective) - private inputDirective: IgxInputDirective; + private inputDirective!: IgxInputDirective; @ContentChild(IgxCalendarSubheaderTemplateDirective) - private subheaderTemplate: IgxCalendarSubheaderTemplateDirective; + private subheaderTemplate!: IgxCalendarSubheaderTemplateDirective; @ContentChild(IgxPickerActionsDirective) - private pickerActions: IgxPickerActionsDirective; + private pickerActions!: IgxPickerActionsDirective; private get dialogOverlaySettings(): OverlaySettings { return Object.assign({}, this._dialogOverlaySettings, this.overlaySettings); @@ -446,7 +446,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr } private get inputGroupElement(): HTMLElement { - return this.inputGroup?.element.nativeElement.querySelector('.igx-input-group__bundle'); + return this.inputGroup?.element.nativeElement.querySelector('.igx-input-group__bundle')!; } private get dateValue(): Date { @@ -465,16 +465,16 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr public displayValue: PipeTransform = { transform: (date: Date) => this.formatter(date) }; private _resourceStrings = getCurrentResourceStrings(DatePickerResourceStringsEN); - private _dateValue: Date; - private _overlayId: string; - private _value: Date | string; - private _ngControl: NgControl = null; - private _statusChanges$: Subscription; - private _calendar: IgxCalendarComponent; + private _dateValue!: Date; + private _overlayId: string = ''; + private _value!: Date | string; + private _ngControl: NgControl = null!; + private _statusChanges$!: Subscription; + private _calendar!: IgxCalendarComponent; private _calendarContainer?: HTMLElement; - private _specialDates: DateRangeDescriptor[] = null; - private _disabledDates: DateRangeDescriptor[] = null; - private _activeDate: Date = null; + private _specialDates: DateRangeDescriptor[] = null!; + private _disabledDates: DateRangeDescriptor[] = null!; + private _activeDate: Date = null!; private _overlaySubFilter: [MonoTypeOperatorFunction, MonoTypeOperatorFunction] = [ @@ -748,7 +748,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr if (value && this.disabledDates && isDateInRanges(value, this.disabledDates)) { Object.assign(errors, { dateIsDisabled: true }); } - Object.assign(errors, DateTimeUtil.validateMinMax(value, this.minValue, this.maxValue, false)); + Object.assign(errors, DateTimeUtil.validateMinMax(value!, this.minValue, this.maxValue, false)); return Object.keys(errors).length > 0 ? errors : null; } @@ -779,8 +779,8 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr if (this._ngControl) { this._statusChanges$ = - this._ngControl.statusChanges.subscribe(this.onStatusChanged.bind(this)); - if (this._ngControl.control.validator) { + this._ngControl.statusChanges!.subscribe(this.onStatusChanged.bind(this)); + if (this._ngControl.control!.validator) { this.inputGroup.isRequired = this.required; this.cdr.detectChanges(); } @@ -802,7 +802,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr } if (this._overlayId) { this._overlayService.detach(this._overlayId); - delete this._overlayId; + this._overlayId = ''; } } @@ -826,7 +826,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr this._dateValue = value; return; } - this._dateValue = DateTimeUtil.isValidDate(value) ? value : DateTimeUtil.parseIsoDate(value); + this._dateValue = DateTimeUtil.isValidDate(value) ? value : DateTimeUtil.parseIsoDate(value)!; if (this._calendar) { this._calendar.selectDate(this._dateValue); this._calendar.activeDate = this.activeDate; @@ -849,15 +849,15 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr } private get isTouchedOrDirty(): boolean { - return (this._ngControl.control.touched || this._ngControl.control.dirty); + return (this._ngControl.control!.touched || this._ngControl.control!.dirty); } private get hasValidators(): boolean { - return (!!this._ngControl.control.validator || !!this._ngControl.control.asyncValidator); + return (!!this._ngControl.control!.validator || !!this._ngControl.control!.asyncValidator); } private onStatusChanged = () => { - this.disabled = this._ngControl.disabled; + this.disabled = this._ngControl.disabled!; this.updateValidity(); this.inputGroup.isRequired = this.required; }; @@ -886,24 +886,24 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr takeUntil(this._destroy$)).subscribe((event) => { this.validationFailed.emit({ owner: this, - prevValue: event.oldValue, + prevValue: event.oldValue!, currentValue: this.value }); }); } private subscribeToOverlayEvents() { - this._overlayService.opening.pipe(...this._overlaySubFilter).subscribe((e: OverlayCancelableEventArgs) => { - const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: e.cancel }; + this._overlayService.opening.pipe(...this._overlaySubFilter).subscribe((e: OverlayEventArgs | OverlayCancelableEventArgs) => { + const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: (e as OverlayCancelableEventArgs).cancel }; this.opening.emit(args); - e.cancel = args.cancel; + (e as OverlayCancelableEventArgs).cancel = args.cancel; if (args.cancel) { this._overlayService.detach(this._overlayId); return; } - this._initializeCalendarContainer(e.componentRef.instance); - this._calendarContainer = e.componentRef.location.nativeElement; + this._initializeCalendarContainer(e.componentRef!.instance); + this._calendarContainer = e.componentRef!.location.nativeElement; this._collapsed = false; this.cdr.markForCheck(); }); @@ -914,10 +914,10 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr this._calendar.wrapper?.nativeElement?.focus(); }); - this._overlayService.closing.pipe(...this._overlaySubFilter).subscribe((e: OverlayCancelableEventArgs) => { - const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: e.cancel }; + this._overlayService.closing.pipe(...this._overlaySubFilter).subscribe((e: OverlayEventArgs | OverlayCancelableEventArgs) => { + const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: (e as OverlayCancelableEventArgs).cancel }; this.closing.emit(args); - e.cancel = args.cancel; + (e as OverlayCancelableEventArgs).cancel = args.cancel; if (args.cancel) { return; } @@ -935,8 +935,8 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr this.closed.emit({ owner: this }); this._overlayService.detach(this._overlayId); this._collapsed = true; - this._overlayId = null; - this._calendar = null; + this._overlayId = ''; + this._calendar = null!; this._calendarContainer = undefined; this.cdr.markForCheck(); }); @@ -975,7 +975,7 @@ export class IgxDatePickerComponent extends PickerBaseDirective implements Contr this._calendar.monthsViewNumber = this.displayMonthsCount; this._calendar.showWeekNumbers = this.showWeekNumbers; this._calendar.orientation = this.orientation; - this._calendar.selected.pipe(takeUntil(this._destroy$)).subscribe((ev: Date) => this.handleSelection(ev)); + this._calendar.selected.pipe(takeUntil(this._destroy$)).subscribe((ev: Date | Date []) => this.handleSelection(ev as Date)); this.setDisabledDates(); if (DateTimeUtil.isValidDate(this.dateValue)) { diff --git a/projects/igniteui-angular/date-picker/src/date-picker/picker-base.directive.ts b/projects/igniteui-angular/date-picker/src/date-picker/picker-base.directive.ts index f82d4bbbbd7..dfc0b35142d 100644 --- a/projects/igniteui-angular/date-picker/src/date-picker/picker-base.directive.ts +++ b/projects/igniteui-angular/date-picker/src/date-picker/picker-base.directive.ts @@ -130,7 +130,7 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider * ``` */ @Input() - public overlaySettings: OverlaySettings; + public overlaySettings!: OverlaySettings; /** * Enables or disables the picker. @@ -201,7 +201,7 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider * DOM tree position instead. */ @Input() - public outlet: IgxOverlayOutletDirective | ElementRef; + public outlet!: IgxOverlayOutletDirective | ElementRef; /** * Determines how the picker's input will be styled. @@ -231,7 +231,7 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider * ``` */ @Input() - public tabIndex: number | string; + public tabIndex!: number | string; /** * Emitted when the calendar has started opening, cancelable. @@ -279,30 +279,30 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider /** @hidden @internal */ @ContentChildren(IgxPickerToggleComponent, { descendants: true }) - public toggleComponents: QueryList; + public toggleComponents!: QueryList; /** @hidden @internal */ @ContentChildren(IgxPickerClearComponent, { descendants: true }) - public clearComponents: QueryList; + public clearComponents!: QueryList; @ContentChildren(IgxPrefixDirective, { descendants: true }) - protected prefixes: QueryList; + protected prefixes!: QueryList; @ContentChildren(IgxSuffixDirective, { descendants: true }) - protected suffixes: QueryList; + protected suffixes!: QueryList; @ViewChild(IgxInputGroupComponent) - protected inputGroup: IgxInputGroupComponent; + protected inputGroup!: IgxInputGroupComponent; - protected _locale: string; - protected _defaultLocale: string; - protected _inputFormat: string; - protected _displayFormat: string; + protected _locale!: string; + protected _defaultLocale!: string; + protected _inputFormat!: string; + protected _displayFormat!: string; protected _collapsed = true; - protected _type: IgxInputGroupType; - protected _minValue: Date | string; - protected _maxValue: Date | string; - protected _weekStart: WEEKDAYS | number; + protected _type!: IgxInputGroupType; + protected _minValue!: Date | string; + protected _maxValue!: Date | string; + protected _weekStart!: WEEKDAYS | number; protected abstract get toggleContainer(): HTMLElement | undefined; /** @@ -331,7 +331,7 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider if (!document?.activeElement) return false; return this.element.nativeElement.contains(document.activeElement) - || !this.collapsed && this.toggleContainer.contains(document.activeElement); + || !this.collapsed && this.toggleContainer!.contains(document.activeElement); } protected _destroy$ = new Subject(); @@ -372,7 +372,7 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider components: QueryList, handler: () => void ): void { - const subscribeToClick = componentList => { + const subscribeToClick = (componentList: QueryList) => { componentList.forEach(component => { component.clicked .pipe(takeUntil(merge(componentList.changes, this._destroy$))) @@ -389,7 +389,7 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider protected initLocale() { this._defaultLocale = getCurrentI18n(); this._locale = this._localeId !== DEFAULT_LOCALE ? this._localeId : this._locale; - onResourceChangeHandle(this._destroy$, this.onResourceChange, this); + onResourceChangeHandle(this._destroy$, this.onResourceChange as (event?: CustomEvent) => void, this); } protected onResourceChange(args: CustomEvent) { diff --git a/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker-inputs.common.ts b/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker-inputs.common.ts index fdde9cfe7b1..d778d1a68ed 100644 --- a/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker-inputs.common.ts +++ b/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker-inputs.common.ts @@ -24,13 +24,13 @@ export class DateRangePickerFormatPipe implements PipeTransform { } let { start, end } = values; if (!isDate(start)) { - start = DateTimeUtil.parseIsoDate(start); + start = DateTimeUtil.parseIsoDate(start)!; } if (!isDate(end)) { - end = DateTimeUtil.parseIsoDate(end); + end = DateTimeUtil.parseIsoDate(end)!; } - const startDate = this.i18nFormatter.formatDate(start, appliedFormat, locale); - const endDate = this.i18nFormatter.formatDate(end, appliedFormat, locale); + const startDate = this.i18nFormatter.formatDate(start, appliedFormat!, locale!); + const endDate = this.i18nFormatter.formatDate(end, appliedFormat!, locale!); let formatted; if (start) { formatted = `${startDate} - `; @@ -53,13 +53,13 @@ export class DateRangePickerFormatPipe implements PipeTransform { }) export class IgxDateRangeInputsBaseComponent extends IgxInputGroupComponent { @ContentChild(IgxDateTimeEditorDirective) - public dateTimeEditor: IgxDateTimeEditorDirective; + public dateTimeEditor!: IgxDateTimeEditorDirective; @ContentChild(IgxInputDirective) - public inputDirective: IgxInputDirective; + public inputDirective!: IgxInputDirective; @ContentChild(NgControl) - protected ngControl: NgControl; + protected ngControl!: NgControl; /** @hidden @internal */ public get nativeElement() { @@ -74,7 +74,7 @@ export class IgxDateRangeInputsBaseComponent extends IgxInputGroupComponent { /** @hidden @internal */ public updateInputValue(value: Date) { if (this.ngControl) { - this.ngControl.control.setValue(value); + this.ngControl.control!.setValue(value); } else { this.dateTimeEditor.value = value; } diff --git a/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.html b/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.html index c36bec0f213..5c4baf671ee 100644 --- a/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.html +++ b/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.html @@ -30,7 +30,7 @@ + [value]="value! | dateRange: appliedFormat : locale : formatter" /> @if (!toggleComponents.length) { diff --git a/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.ts b/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.ts index a6ffd043bb5..9296985adce 100644 --- a/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.ts +++ b/projects/igniteui-angular/date-picker/src/date-range-picker/date-range-picker.component.ts @@ -157,7 +157,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective * ``` */ @Input({ transform: booleanAttribute }) - public hideOutsideDays: boolean; + public hideOutsideDays!: boolean; /** * A custom formatter function, applied on the selected or passed in date. @@ -176,7 +176,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective * ``` */ @Input() - public formatter: (val: DateRange) => string; + public formatter!: (val: DateRange) => string; /** * Overrides the default text of the calendar dialog **Done** button. @@ -197,7 +197,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective public get doneButtonText(): string { if (this._doneButtonText === null) { - return this.resourceStrings.igx_date_range_picker_done_button; + return this.resourceStrings.igx_date_range_picker_done_button!; } return this._doneButtonText; } @@ -220,7 +220,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective public get cancelButtonText(): string { if (this._cancelButtonText === null) { - return this.resourceStrings.igx_date_range_picker_cancel_button; + return this.resourceStrings.igx_date_range_picker_cancel_button!; } return this._cancelButtonText; } @@ -233,7 +233,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective * ``` */ @Input() - public override overlaySettings: OverlaySettings; + public override overlaySettings!: OverlaySettings; /** * The format used when editable inputs are not focused. @@ -423,43 +423,43 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective public cssClass = 'igx-date-range-picker'; @ViewChild("container", { read: ViewContainerRef }) - private viewContainerRef: ViewContainerRef; + private viewContainerRef!: ViewContainerRef; /** @hidden @internal */ @ViewChild(IgxInputDirective) - public inputDirective: IgxInputDirective; + public inputDirective!: IgxInputDirective; /** @hidden @internal */ @ContentChildren(IgxDateRangeInputsBaseComponent) - public projectedInputs: QueryList; + public projectedInputs!: QueryList; @ContentChild(IgxLabelDirective) - public label: IgxLabelDirective; + public label?: IgxLabelDirective; @ContentChild(IgxHintDirective) - public hint: IgxHintDirective; + public hint!: IgxHintDirective; @ContentChild(IgxPickerActionsDirective) - public pickerActions: IgxPickerActionsDirective; + public pickerActions!: IgxPickerActionsDirective; /** @hidden @internal */ @ContentChild(IgxDateRangeSeparatorDirective, { read: TemplateRef }) - public dateSeparatorTemplate: TemplateRef; + public dateSeparatorTemplate!: TemplateRef; @ContentChild(IgxCalendarHeaderTitleTemplateDirective) - private headerTitleTemplate: IgxCalendarHeaderTitleTemplateDirective; + private headerTitleTemplate!: IgxCalendarHeaderTitleTemplateDirective; @ContentChild(IgxCalendarHeaderTemplateDirective) - private headerTemplate: IgxCalendarHeaderTemplateDirective; + private headerTemplate!: IgxCalendarHeaderTemplateDirective; @ContentChild(IgxCalendarSubheaderTemplateDirective) - private subheaderTemplate: IgxCalendarSubheaderTemplateDirective; + private subheaderTemplate!: IgxCalendarSubheaderTemplateDirective; /** @hidden @internal */ public get dateSeparator(): string { if (this._dateSeparator === null) { - return this.resourceStrings.igx_date_range_picker_date_separator; + return this.resourceStrings.igx_date_range_picker_date_separator!; } return this._dateSeparator; } @@ -555,9 +555,9 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective @Input() public set value(value: DateRange | null) { - this.updateValue(value); - this.onChangeCallback(value); - this.valueChange.emit(value); + this.updateValue(value!); + this.onChangeCallback(value!); + this.valueChange.emit(value!); } /** @hidden @internal */ @@ -605,23 +605,23 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective return range?.start ?? range?.end ?? null; } - private _resourceStrings: IDateRangePickerResourceStrings = null; + private _resourceStrings: IDateRangePickerResourceStrings = null!; private _defaultResourceStrings = getCurrentResourceStrings(DateRangePickerResourceStringsEN); - private _doneButtonText = null; - private _cancelButtonText = null; + private _doneButtonText: string = null!; + private _cancelButtonText: string = null!; private _dateSeparator = null; - private _value: DateRange | null; - private _originalValue: DateRange | null; - private _overlayId: string; - private _ngControl: NgControl; - private _statusChanges$: Subscription; - private _calendar: IgxCalendarComponent; + private _value!: DateRange | null; + private _originalValue!: DateRange | null; + private _overlayId: string = ''; + private _ngControl!: NgControl; + private _statusChanges$!: Subscription; + private _calendar!: IgxCalendarComponent; private _calendarContainer?: HTMLElement; - private _positionSettings: PositionSettings; - private _focusedInput: IgxDateRangeInputsBaseComponent; + private _positionSettings!: PositionSettings; + private _focusedInput!: IgxDateRangeInputsBaseComponent; private _displayMonthsCount = 2; - private _specialDates: DateRangeDescriptor[] = null; - private _disabledDates: DateRangeDescriptor[] = null; + private _specialDates: DateRangeDescriptor[] = null!; + private _disabledDates: DateRangeDescriptor[] = null!; private _activeDate: Date | null = null; private _overlaySubFilter: [MonoTypeOperatorFunction, MonoTypeOperatorFunction] = [ @@ -850,7 +850,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective this.setRequiredToInputs(); if (this._ngControl) { - this._statusChanges$ = this._ngControl.statusChanges.subscribe(this.onStatusChanged.bind(this)); + this._statusChanges$ = this._ngControl.statusChanges!.subscribe(this.onStatusChanged.bind(this)); } // delay invocations until the current change detection cycle has completed @@ -925,17 +925,17 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective } private get isTouchedOrDirty(): boolean { - return (this._ngControl.control.touched || this._ngControl.control.dirty); + return (this._ngControl.control!.touched || this._ngControl.control!.dirty); } private get hasValidators(): boolean { - return (!!this._ngControl.control.validator || !!this._ngControl.control.asyncValidator); + return (!!this._ngControl.control!.validator || !!this._ngControl.control!.asyncValidator); } private handleSelection(selectionData: Date[]): void { let newValue = this.extractRange(selectionData); if (!newValue.start && !newValue.end) { - newValue = null; + newValue = null!; } this.value = newValue; if (this.isDropdown && selectionData?.length > 1) { @@ -978,8 +978,8 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective return; } - this._initializeCalendarContainer(e.componentRef.instance); - this._calendarContainer = e.componentRef.location.nativeElement; + this._initializeCalendarContainer(e.componentRef!.instance); + this._calendarContainer = e.componentRef!.location.nativeElement; this._collapsed = false; this.updateCalendar(); }); @@ -989,9 +989,9 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective this.opened.emit({ owner: this }); }); - this._overlayService.closing.pipe(...this._overlaySubFilter).subscribe((e: OverlayCancelableEventArgs) => { + this._overlayService.closing.pipe(...this._overlaySubFilter).subscribe((e: any) => { const isEscape = e.event && (e.event as KeyboardEvent).key === this.platform.KEYMAP.ESCAPE; - if (this.isProjectedInputTarget(e.event) && !isEscape) { + if (this.isProjectedInputTarget(e.event!) && !isEscape) { e.cancel = true; } this.handleClosing(e as OverlayCancelableEventArgs); @@ -1000,8 +1000,8 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective this._overlayService.closed.pipe(...this._overlaySubFilter).subscribe(() => { this._overlayService.detach(this._overlayId); this._collapsed = true; - this._overlayId = null; - this._calendar = null; + this._overlayId = ''; + this._calendar = null!; this._calendarContainer = undefined; this.closed.emit({ owner: this }); }); @@ -1024,7 +1024,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective } private updateValidityOnBlur() { - this._focusedInput = null; + this._focusedInput = null!; this.onTouchCallback(); if (this._ngControl) { if (this.hasProjectedInputs) { @@ -1070,11 +1070,11 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective } private parseMinValue(value: string | Date): Date | null { - let minValue: Date = parseDate(value); + let minValue: Date = parseDate(value)!; if (!minValue && this.hasProjectedInputs) { const start = this.projectedInputs.filter(i => i instanceof IgxDateRangeStartComponent)[0]; if (start) { - minValue = parseDate(start.dateTimeEditor.minValue); + minValue = parseDate(start.dateTimeEditor.minValue)!; } } @@ -1082,11 +1082,11 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective } private parseMaxValue(value: string | Date): Date | null { - let maxValue: Date = parseDate(value); + let maxValue: Date = parseDate(value)!; if (!maxValue && this.projectedInputs) { const end = this.projectedInputs.filter(i => i instanceof IgxDateRangeEndComponent)[0]; if (end) { - maxValue = parseDate(end.dateTimeEditor.maxValue); + maxValue = parseDate(end.dateTimeEditor.maxValue)!; } } @@ -1129,14 +1129,14 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective const start = this.projectedInputs.find(i => i instanceof IgxDateRangeStartComponent) as IgxDateRangeStartComponent; const end = this.projectedInputs.find(i => i instanceof IgxDateRangeEndComponent) as IgxDateRangeEndComponent; [start.dateTimeEditor.value, end.dateTimeEditor.value] = [end.dateTimeEditor.value, start.dateTimeEditor.value]; - [this.value.start, this.value.end] = [this.value.end, this.value.start]; + [this.value!.start, this.value!.end] = [this.value!.end, this.value!.start]; } } private extractRange(selection: Date[]): DateRange { return { start: selection[0] || null, - end: selection.length > 0 ? selection[selection.length - 1] : null + end: selection.length > 0 ? selection[selection.length - 1] : null! }; } @@ -1151,7 +1151,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective } if (start || end) { - return { start, end }; + return { start: start!, end: end! }; } return { start: range.start as Date, end: range.end as Date }; @@ -1183,10 +1183,10 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective if (this.value) { this.value = { start: value, end: this.value.end }; } else { - this.value = { start: value, end: null }; + this.value = { start: value, end: null! }; } if (this.calendar) { - this._setCalendarActiveDate(parseDate(value)); + this._setCalendarActiveDate(parseDate(value)!!); this._cdr.detectChanges(); } }); @@ -1196,7 +1196,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective if (this.value) { this.value = { start: this.value.start, end: value as Date }; } else { - this.value = { start: null, end: value as Date }; + this.value = { start: null!, end: value as Date }; } if (this.calendar) { this._setCalendarActiveDate(parseDate(value)); @@ -1267,8 +1267,8 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective const start = this.projectedInputs.find(i => i instanceof IgxDateRangeStartComponent); const end = this.projectedInputs.find(i => i instanceof IgxDateRangeEndComponent); this._value = { - start: start.dateTimeEditor.value as Date, - end: end.dateTimeEditor.value as Date + start: start!.dateTimeEditor.value as Date, + end: end!.dateTimeEditor.value as Date }; } } @@ -1278,8 +1278,8 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective const end = this.projectedInputs?.find(i => i instanceof IgxDateRangeEndComponent) as IgxDateRangeEndComponent; if (start && end) { const _value = this.value ? this.toRangeOfDates(this.value) : null; - start.updateInputValue(_value?.start || null); - end.updateInputValue(_value?.end || null); + start.updateInputValue(_value?.start || null!); + end.updateInputValue(_value?.end || null!); } } @@ -1334,14 +1334,14 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective this._calendar.headerOrientation = this.headerOrientation; this._calendar.orientation = this.orientation; this._calendar.specialDates = this.specialDates; - this._calendar.selected.pipe(takeUntil(this._destroy$)).subscribe((ev: Date[]) => this.handleSelection(ev)); + this._calendar.selected.pipe(takeUntil(this._destroy$)).subscribe((ev: any) => this.handleSelection(ev)); this._setDisabledDates(); this._setCalendarActiveDate(); componentInstance.mode = this.mode; - componentInstance.closeButtonLabel = !this.isDropdown ? this.doneButtonText : null; - componentInstance.cancelButtonLabel = !this.isDropdown ? this.cancelButtonText : null; + componentInstance.closeButtonLabel = !this.isDropdown ? this.doneButtonText : null!; + componentInstance.cancelButtonLabel = !this.isDropdown ? this.cancelButtonText : null!; if (!this.isDropdown && this.themeToken.theme === 'indigo') { componentInstance.closeButtonType = 'contained'; componentInstance.cancelButtonType = 'outlined'; @@ -1392,8 +1392,8 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective if (value && value.start && value.end && this.disabledDates) { const isOutsideDisabledRange = Array.from( calendarRange({ - start: parseDate(this.value.start), - end: parseDate(this.value.end), + start: parseDate(this.value!.start)!, + end: parseDate(this.value!.end)!, inclusive: true })).every((date) => !isDateInRanges(date, this.disabledDates)); return !isOutsideDisabledRange; @@ -1401,7 +1401,7 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective return false; } - private _setCalendarActiveDate(value = null): void { + private _setCalendarActiveDate(value: Date | null = null): void { if (this._calendar) { this._calendar.activeDate = value ?? this.activeDate; this._calendar.viewDate = value ?? this.activeDate; diff --git a/projects/igniteui-angular/dialog/src/dialog/dialog.component.ts b/projects/igniteui-angular/dialog/src/dialog/dialog.component.ts index d9e8902f220..beaf51accf8 100644 --- a/projects/igniteui-angular/dialog/src/dialog/dialog.component.ts +++ b/projects/igniteui-angular/dialog/src/dialog/dialog.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Even import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { IgxNavigationService, IToggleView } from 'igniteui-angular/core'; -import { IgxButtonType, IgxButtonDirective } from 'igniteui-angular/directives'; +import { IgxButtonType, IgxButtonDirective, ToggleViewCancelableEventArgs, ToggleViewEventArgs } from 'igniteui-angular/directives'; import { IgxRippleDirective } from 'igniteui-angular/directives'; import { IgxToggleDirective } from 'igniteui-angular/directives'; import { OverlaySettings, GlobalPositionStrategy, NoOpScrollStrategy, PositionSettings } from 'igniteui-angular/core'; @@ -56,7 +56,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After @ViewChild(IgxToggleDirective, { static: true }) - public toggleRef: IgxToggleDirective; + public toggleRef!: IgxToggleDirective; /** * Sets the value of the `id` attribute. If not provided it will be automatically generated. @@ -464,7 +464,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After * ``` */ public open(overlaySettings: OverlaySettings = this._overlayDefaultSettings) { - const eventArgs: IDialogCancellableEventArgs = { dialog: this, event: null, cancel: false }; + const eventArgs: IDialogCancellableEventArgs = { dialog: this, event: null!, cancel: false }; this.opening.emit(eventArgs); if (!eventArgs.cancel) { overlaySettings = { ...{}, ... this._overlayDefaultSettings, ...overlaySettings }; @@ -512,12 +512,12 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After /** * @hidden */ - public onDialogSelected(event) { + public onDialogSelected(event: PointerEvent) { event.stopPropagation(); if ( this.isOpen && this.closeOnOutsideSelect && - event.target.classList.contains(IgxDialogComponent.DIALOG_CLASS) + (event.target as HTMLElement)?.classList.contains(IgxDialogComponent.DIALOG_CLASS) ) { this.close(); } @@ -526,14 +526,14 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After /** * @hidden */ - public onInternalLeftButtonSelect(event) { + public onInternalLeftButtonSelect(event: PointerEvent) { this.leftButtonSelect.emit({ dialog: this, event }); } /** * @hidden */ - public onInternalRightButtonSelect(event) { + public onInternalRightButtonSelect(event: PointerEvent) { this.rightButtonSelect.emit({ dialog: this, event }); } @@ -554,7 +554,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After } } - private emitCloseFromDialog(eventArgs) { + private emitCloseFromDialog(eventArgs: ToggleViewCancelableEventArgs) { const dialogEventsArgs = { dialog: this, event: eventArgs.event, cancel: eventArgs.cancel }; this.closing.emit(dialogEventsArgs); eventArgs.cancel = dialogEventsArgs.cancel; @@ -563,18 +563,18 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After } } - private emitClosedFromDialog(eventArgs) { + private emitClosedFromDialog(eventArgs: ToggleViewEventArgs) { this.closed.emit({ dialog: this, event: eventArgs.event }); } - private emitOpenedFromDialog(eventArgs) { + private emitOpenedFromDialog(eventArgs: ToggleViewEventArgs) { this.opened.emit({ dialog: this, event: eventArgs.event }); } } export interface IDialogEventArgs extends IBaseEventArgs { dialog: IgxDialogComponent; - event: Event; + event?: Event; } export interface IDialogCancellableEventArgs extends IDialogEventArgs, CancelableEventArgs { } diff --git a/projects/igniteui-angular/directives/src/directives/button/button-base.ts b/projects/igniteui-angular/directives/src/directives/button/button-base.ts index f07aa008621..1ced9297ee1 100644 --- a/projects/igniteui-angular/directives/src/directives/button/button-base.ts +++ b/projects/igniteui-angular/directives/src/directives/button/button-base.ts @@ -26,7 +26,7 @@ export abstract class IgxButtonBaseDirective implements AfterViewInit, OnDestroy private _platformUtil = inject(PlatformUtil); public element = inject(ElementRef); private _viewInit = false; - private _animationScheduler: Subscription; + private _animationScheduler!: Subscription; /** * Emitted when the button is clicked. diff --git a/projects/igniteui-angular/directives/src/directives/button/button.directive.ts b/projects/igniteui-angular/directives/src/directives/button/button.directive.ts index e60ba67208c..fc8cc10df87 100644 --- a/projects/igniteui-angular/directives/src/directives/button/button.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/button/button.directive.ts @@ -67,25 +67,25 @@ export class IgxButtonDirective extends IgxButtonBaseDirective { * @hidden * @internal */ - private _type: IgxButtonType; + private _type!: IgxButtonType; /** * @hidden * @internal */ - private _color: string; + private _color!: string; /** * @hidden * @internal */ - private _label: string; + private _label!: string; /** * @hidden * @internal */ - private _backgroundColor: string; + private _backgroundColor!: string; /** * @hidden diff --git a/projects/igniteui-angular/directives/src/directives/button/icon-button.directive.ts b/projects/igniteui-angular/directives/src/directives/button/icon-button.directive.ts index beeea335120..05394f1d548 100644 --- a/projects/igniteui-angular/directives/src/directives/button/icon-button.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/button/icon-button.directive.ts @@ -38,7 +38,7 @@ export class IgxIconButtonDirective extends IgxButtonBaseDirective { * @hidden * @internal */ - private _type: IgxIconButtonType; + private _type!: IgxIconButtonType; /** * Sets the type of the icon button. diff --git a/projects/igniteui-angular/directives/src/directives/checkbox/checkbox-base.directive.ts b/projects/igniteui-angular/directives/src/directives/checkbox/checkbox-base.directive.ts index b5ff879b848..6cefd42aa32 100644 --- a/projects/igniteui-angular/directives/src/directives/checkbox/checkbox-base.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/checkbox/checkbox-base.directive.ts @@ -51,7 +51,7 @@ export class CheckboxBaseDirective implements AfterViewInit { * ``` */ @ViewChild('checkbox', { static: true }) - public nativeInput: ElementRef; + public nativeInput!: ElementRef; /** * Returns reference to the native label element. @@ -62,14 +62,14 @@ export class CheckboxBaseDirective implements AfterViewInit { * ``` */ @ViewChild('label', { static: true }) - public nativeLabel: ElementRef; + public nativeLabel!: ElementRef; - public cssClass: string; - public disabled: boolean; - public readonly: boolean; - public indeterminate: boolean; - public focused: boolean; - public invalid: boolean; + public cssClass!: string; + public disabled!: boolean; + public readonly!: boolean; + public indeterminate!: boolean; + public focused!: boolean; + public invalid!: boolean; @Input({ transform: booleanAttribute }) public get checked() { @@ -104,7 +104,7 @@ export class CheckboxBaseDirective implements AfterViewInit { * ``` */ @ViewChild('placeholderLabel', { static: true }) - public placeholderLabel: ElementRef; + public placeholderLabel!: ElementRef; /** * Sets/gets the `id` of the checkbox component. @@ -160,7 +160,7 @@ export class CheckboxBaseDirective implements AfterViewInit { * let name = this.checkbox.name; * ``` */ - @Input() public name: string; + @Input() public name!: string; /** * Sets/gets the value of the `tabindex` attribute. @@ -173,7 +173,7 @@ export class CheckboxBaseDirective implements AfterViewInit { * let tabIndex = this.checkbox.tabindex; * ``` */ - @Input() public tabindex: number = null; + @Input() public tabindex: number = null!; /** * Sets/gets the position of the `label`. @@ -280,15 +280,15 @@ export class CheckboxBaseDirective implements AfterViewInit { */ public ngAfterViewInit() { if (this.ngControl) { - this.ngControl.statusChanges + this.ngControl.statusChanges! .pipe(takeUntil(this.destroy$)) .subscribe(this.updateValidityState.bind(this)); if ( - this.ngControl.control.validator || - this.ngControl.control.asyncValidator + this.ngControl.control!.validator || + this.ngControl.control!.asyncValidator ) { - this._required = this.ngControl?.control?.hasValidator( + this._required = this.ngControl.control!.hasValidator( Validators.required ); this.cdr.detectChanges(); @@ -457,10 +457,10 @@ export class CheckboxBaseDirective implements AfterViewInit { if ( !this.disabled && !this.readonly && - (this.ngControl.control.touched || this.ngControl.control.dirty) + (this.ngControl.control!.touched || this.ngControl.control!.dirty) ) { // the control is not disabled and is touched or dirty - this.invalid = this.ngControl.invalid; + this.invalid = this.ngControl.invalid!; } else { // if the control is untouched, pristine, or disabled, its state is initial. This is when the user did not interact // with the checkbox or when the form/control is reset diff --git a/projects/igniteui-angular/directives/src/directives/date-time-editor/date-time-editor.directive.ts b/projects/igniteui-angular/directives/src/directives/date-time-editor/date-time-editor.directive.ts index 0d822899f96..b7b1cbbc58a 100644 --- a/projects/igniteui-angular/directives/src/directives/date-time-editor/date-time-editor.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/date-time-editor/date-time-editor.directive.ts @@ -69,7 +69,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh * ``` */ @Input() - public locale: string; + public locale!: string; /** * Minimum value required for the editor to remain valid. @@ -172,14 +172,14 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh * ``` */ @Input() - public set value(value: Date | string | undefined | null) { + public set value(value: Date | string | null) { this._value = value; this.setDateValue(value); this.onChangeCallback(value); this.updateMask(); } - public get value(): Date | string | undefined | null { + public get value(): Date | string | null { return this._value; } @@ -205,7 +205,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh * ``` */ @Input() - public spinDelta: DatePartDeltas; + public spinDelta!: DatePartDeltas; /** * Emitted when the editor's value has changed. @@ -216,7 +216,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh * ``` */ @Output() - public valueChange = new EventEmitter(); + public valueChange = new EventEmitter(); /** * Emitted when the editor is not within a specified range or when the editor's value is in an invalid state. @@ -231,18 +231,18 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh private readonly SCROLL_THRESHOLD = 50; - private _inputFormat: string; + private _inputFormat!: string; private _scrollAccumulator = 0; - private _displayFormat: string; - private _oldValue: Date; - private _dateValue: Date; - private _onClear: boolean; + private _displayFormat!: string; + private _oldValue!: Date; + private _dateValue!: Date; + private _onClear!: boolean; private document: Document; - private _defaultInputFormat: string; - private _value?: Date | string; - private _minValue: Date | string; - private _maxValue: Date | string; - private _inputDateParts: DatePartInfo[]; + private _defaultInputFormat!: string; + private _value!: Date | string | null; + private _minValue!: Date | string; + private _maxValue!: Date | string; + private _inputDateParts!: DatePartInfo[]; private _datePartDeltas: DatePartDeltas = { date: 1, month: 1, @@ -261,10 +261,10 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh } private get emptyMask(): string { - return this.maskParser.applyMask(null, this.maskOptions); + return this.maskParser.applyMask(null!, this.maskOptions); } - private get targetDatePart(): DatePart { + private get targetDatePart(): DatePart | undefined { // V.K. May 16th, 2022 #11554 Get correct date part in shadow DOM if (this.document.activeElement === this.nativeElement || this.document.activeElement?.shadowRoot?.activeElement === this.nativeElement) { @@ -403,8 +403,8 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh const minValueDate = DateTimeUtil.isValidDate(this.minValue) ? this.minValue : this.parseDate(this.minValue); const maxValueDate = DateTimeUtil.isValidDate(this.maxValue) ? this.maxValue : this.parseDate(this.maxValue); if (minValueDate || maxValueDate) { - errors = DateTimeUtil.validateMinMax(value, - minValueDate, maxValueDate, + errors = DateTimeUtil.validateMinMax(value!, + minValueDate!, maxValueDate!, this.hasTimeParts, this.hasDateParts); } @@ -438,7 +438,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh } /** @hidden @internal */ - public override onInputChanged(event): void { + public override onInputChanged(event: InputEvent): void { super.onInputChanged(event); if (this._composing) { return; @@ -450,7 +450,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh this.updateValue(parsedDate); } else { const oldValue = this.value && new Date(this.dateValue.getTime()); - const args: IgxDateTimeEditorEventArgs = { oldValue, newValue: parsedDate, userInput: this.inputValue }; + const args: IgxDateTimeEditorEventArgs = { oldValue: oldValue as Date | undefined, newValue: parsedDate!, userInput: this.inputValue }; this.validationFailed.emit(args); if (DateTimeUtil.isValidDate(args.newValue)) { this.updateValue(args.newValue); @@ -575,7 +575,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh private getMaskedValue(): string { let mask = this.emptyMask; - if (DateTimeUtil.isValidDate(this.value) || DateTimeUtil.parseIsoDate(this.value)) { + if (DateTimeUtil.isValidDate(this.value) || DateTimeUtil.parseIsoDate(this.value as string)) { for (const part of this._inputDateParts) { if (part.type === DatePart.Literal) { continue; @@ -609,7 +609,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh return Object.keys(errors).length === 0; } - private spinValue(datePart: DatePart, delta: number): Date { + private spinValue(datePart: DatePart, delta: number): Date | null { if (!this.dateValue || !DateTimeUtil.isValidDate(this.dateValue)) { return null; } @@ -640,7 +640,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh break; case DatePart.AmPm: formatPart = this._inputDateParts.find(dp => dp.type === DatePart.AmPm); - amPmFromMask = this.inputValue.substring(formatPart.start, formatPart.end); + amPmFromMask = this.inputValue.substring(formatPart!.start, formatPart!.end); return DateTimeUtil.spinAmPm(newDate, this.dateValue, amPmFromMask); } @@ -650,19 +650,19 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh private trySpinValue(datePart: DatePart, delta?: number, negative = false): Date { if (!delta) { // default to 1 if a delta is set to 0 or any other falsy value - delta = this.datePartDeltas[datePart] || 1; + delta = this.datePartDeltas[datePart as keyof DatePartDeltas] || 1; } const spinValue = negative ? -Math.abs(delta) : Math.abs(delta); return this.spinValue(datePart, spinValue) || new Date(); } - private setDateValue(value: Date | string): void { + private setDateValue(value: Date | string | undefined | null): void { this._dateValue = DateTimeUtil.isValidDate(value) ? value - : DateTimeUtil.parseIsoDate(value); + : DateTimeUtil.parseIsoDate(value as string)!; } - private updateValue(newDate: Date): void { + private updateValue(newDate: Date | null): void { this._oldValue = this.dateValue; this.value = newDate; @@ -687,7 +687,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnCh } private getPartValue(datePartInfo: DatePartInfo, partLength: number): string { - let maskedValue; + let maskedValue: any; const datePart = datePartInfo.type; switch (datePart) { case DatePart.Date: diff --git a/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.directive.ts b/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.directive.ts index 489805e51c7..630cf0f0113 100644 --- a/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.directive.ts @@ -3,7 +3,6 @@ import { ElementRef, EventEmitter, HostBinding, - HostListener, Input, NgZone, OnDestroy, @@ -97,7 +96,7 @@ export interface IDragBaseEventArgs extends IBaseEventArgs { * Reference to the original event that caused the interaction with the element. * Can be PointerEvent, TouchEvent or MouseEvent. */ - originalEvent: PointerEvent | MouseEvent | TouchEvent; + originalEvent: PointerEvent | MouseEvent | TouchEvent | TransitionEvent | null; /** The owner igxDrag directive that triggered this event. */ owner: IgxDragDirective; /** The initial position of the pointer on X axis when the dragged element began moving */ @@ -148,7 +147,7 @@ export class IgxDragLocation { public pageX: number; public pageY: number; - constructor(private _pageX, private _pageY) { + constructor(private _pageX: any, private _pageY: any) { this.pageX = parseFloat(_pageX); this.pageY = parseFloat(_pageY); } @@ -167,7 +166,7 @@ export class IgxDragHandleDirective { /** * @hidden */ - public parentDragElement: HTMLElement = null; + public parentDragElement: HTMLElement = null!; } @Directive({ @@ -250,7 +249,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * @memberof IgxDragDirective */ @Input() - public dragChannel: number | string | number[] | string[]; + public dragChannel!: number | string | number[] | string[]; /** * Sets whether the base element should be moved, or a ghost element should be rendered that represents it instead. @@ -310,7 +309,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * @memberof IgxDragDirective */ @Input() - public ghostTemplate: TemplateRef; + public ghostTemplate!: TemplateRef; /** * Sets the element to which the dragged element will be appended. @@ -325,13 +324,13 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * @memberof IgxDragDirective */ @Input() - public ghostHost; + public ghostHost: any; /** * Overrides the scroll container of the dragged element. By default its the window. */ @Input() - public scrollContainer: HTMLElement = null + public scrollContainer: HTMLElement = null! /** * Event triggered when the draggable element drag starts. @@ -463,13 +462,13 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * @hidden */ @ContentChildren(IgxDragHandleDirective, { descendants: true }) - public dragHandles: QueryList; + public dragHandles!: QueryList; /** * @hidden */ @ContentChildren(IgxDragIgnoreDirective, { descendants: true }) - public dragIgnoredElems: QueryList; + public dragIgnoredElems!: QueryList; /** * @hidden @@ -551,7 +550,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { protected set ghostLeft(pageX: number) { if (this.ghostElement) { // We need to take into account marginLeft, since top style does not include margin, but pageX includes the margin. - const ghostMarginLeft = parseInt(this.document.defaultView.getComputedStyle(this.ghostElement)['margin-left'], 10); + const ghostMarginLeft = parseInt((this.document.defaultView!.getComputedStyle(this.ghostElement) as any)['margin-left'], 10); // If ghost host is defined it needs to be taken into account. this.ghostElement.style.left = (pageX - ghostMarginLeft - this._ghostHostX) + 'px'; } @@ -561,12 +560,13 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { if (this.ghostElement) { return parseInt(this.ghostElement.style.left, 10) + this._ghostHostX; } + return undefined!; } protected set ghostTop(pageY: number) { if (this.ghostElement) { // We need to take into account marginTop, since top style does not include margin, but pageY includes the margin. - const ghostMarginTop = parseInt(this.document.defaultView.getComputedStyle(this.ghostElement)['margin-top'], 10); + const ghostMarginTop = parseInt((this.document.defaultView!.getComputedStyle(this.ghostElement) as any)['margin-top'], 10); // If ghost host is defined it needs to be taken into account. this.ghostElement.style.top = (pageY - ghostMarginTop - this._ghostHostY) + 'px'; } @@ -576,6 +576,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { if (this.ghostElement) { return parseInt(this.ghostElement.style.top, 10) + this._ghostHostY; } + return undefined!; } protected get windowScrollTop() { @@ -602,7 +603,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { /** * @hidden */ - public ghostElement; + public ghostElement: any; /** * @hidden @@ -617,19 +618,19 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { protected _dragStarted = false; /** Drag ghost related properties */ - protected _defaultOffsetX; - protected _defaultOffsetY; - protected _offsetX; - protected _offsetY; - protected _ghostStartX; - protected _ghostStartY; + protected _defaultOffsetX: any; + protected _defaultOffsetY: any; + protected _offsetX: any; + protected _offsetY: any; + protected _ghostStartX: any; + protected _ghostStartY: any; protected _ghostHostX = 0; protected _ghostHostY = 0; - protected _dynamicGhostRef: EmbeddedViewRef; + protected _dynamicGhostRef!: EmbeddedViewRef; - protected _pointerDownId = null; + protected _pointerDownId: number | null = null; protected _clicked = false; - protected _lastDropArea = null; + protected _lastDropArea: any = null; protected _destroy = new Subject(); protected _removeOnDestroy = true; @@ -640,7 +641,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { protected _scrollContainerStep = 5; protected _scrollContainerStepMs = 10; protected _scrollContainerThreshold = 25; - protected _containerScrollIntervalId = null; + protected _containerScrollIntervalId: ReturnType | null = null; private document = inject(DOCUMENT); /** @@ -723,48 +724,48 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { : [this.element.nativeElement]; targetElements.forEach((element) => { if (this.pointerEventsEnabled) { - fromEvent(element, 'pointerdown').pipe(takeUntil(this._destroy)) + fromEvent(element, 'pointerdown').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerDown(res)); - fromEvent(element, 'pointermove').pipe( + fromEvent(element, 'pointermove').pipe( throttle(() => interval(0, animationFrameScheduler)), takeUntil(this._destroy) ).subscribe((res) => this.onPointerMove(res)); - fromEvent(element, 'pointerup').pipe(takeUntil(this._destroy)) + fromEvent(element, 'pointerup').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerUp(res)); if (!this.ghost) { // Do not bind `lostpointercapture` to the target, because we will bind it on the ghost later. - fromEvent(element, 'lostpointercapture').pipe(takeUntil(this._destroy)) + fromEvent(element, 'lostpointercapture').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerLost(res)); } } else if (this.touchEventsEnabled) { - fromEvent(element, 'touchstart').pipe(takeUntil(this._destroy)) + fromEvent(element, 'touchstart').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerDown(res)); } else { // We don't have pointer events and touch events. Use then mouse events. - fromEvent(element, 'mousedown').pipe(takeUntil(this._destroy)) + fromEvent(element, 'mousedown').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerDown(res)); } }); // We should bind to document events only once when there are no pointer events. if (!this.pointerEventsEnabled && this.touchEventsEnabled) { - fromEvent(this.document.defaultView, 'touchmove').pipe( + fromEvent(this.document.defaultView!, 'touchmove').pipe( throttle(() => interval(0, animationFrameScheduler)), takeUntil(this._destroy) - ).subscribe((res) => this.onPointerMove(res)); + ).subscribe((res) => this.onPointerMove(res as TouchEvent)); - fromEvent(this.document.defaultView, 'touchend').pipe(takeUntil(this._destroy)) + fromEvent(this.document.defaultView!, 'touchend').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerUp(res)); } else if (!this.pointerEventsEnabled) { - fromEvent(this.document.defaultView, 'mousemove').pipe( + fromEvent(this.document.defaultView!, 'mousemove').pipe( throttle(() => interval(0, animationFrameScheduler)), takeUntil(this._destroy) ).subscribe((res) => this.onPointerMove(res)); - fromEvent(this.document.defaultView, 'mouseup').pipe(takeUntil(this._destroy)) + fromEvent(this.document.defaultView!, 'mouseup').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerUp(res)); } this.element.nativeElement.addEventListener('transitionend', this.onTransitionEnd); @@ -926,7 +927,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * Method bound to the PointerDown event of the base element igxDrag is initialized. * @param event PointerDown event captured */ - public onPointerDown(event) { + public onPointerDown(event: PointerEvent | TouchEvent | MouseEvent) { const ignoredElement = this.dragIgnoredElems.find(elem => elem.element.nativeElement === event.target); if (ignoredElement) { return; @@ -936,7 +937,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { const handleFound = this.dragHandles.find(handle => handle.element.nativeElement === event.target); const targetElement = handleFound ? handleFound.element.nativeElement : event.target || this.element.nativeElement; if (this.pointerEventsEnabled && targetElement.isConnected) { - this._pointerDownId = event.pointerId; + this._pointerDownId = (event as PointerEvent).pointerId; targetElement.setPointerCapture(this._pointerDownId); } else if (targetElement.isConnected) { targetElement.focus(); @@ -948,11 +949,15 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { this._clicked = true; if (this.pointerEventsEnabled || !this.touchEventsEnabled) { // Check first for pointer events or non touch, because we can have pointer events and touch events at once. - this._startX = event.pageX; - this._startY = event.pageY; + this._startX = (event as PointerEvent).pageX; + this._startY = (event as PointerEvent).pageY; } else if (this.touchEventsEnabled) { - this._startX = event.touches[0].pageX; - this._startY = event.touches[0].pageY; + this._startX = (event as TouchEvent).touches[0].pageX; + this._startY = (event as TouchEvent).touches[0].pageY; + } else { + // Fallback for MouseEvent + this._startX = (event as MouseEvent).pageX; + this._startY = (event as MouseEvent).pageY; } this._defaultOffsetX = this.baseLeft - this._startX + this.windowScrollLeft; @@ -970,19 +975,23 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * If dragging starts and after the ghostElement is rendered the pointerId is reassigned it. Then this method is bound to it. * @param event PointerMove event captured */ - public onPointerMove(event) { + public onPointerMove(event: PointerEvent | TouchEvent | MouseEvent) { if (this._clicked) { - let pageX; let pageY; + let pageX = 0; let pageY = 0; if (this.pointerEventsEnabled || !this.touchEventsEnabled) { // Check first for pointer events or non touch, because we can have pointer events and touch events at once. - pageX = event.pageX; - pageY = event.pageY; + pageX = (event as PointerEvent).pageX; + pageY = (event as PointerEvent).pageY; } else if (this.touchEventsEnabled) { - pageX = event.touches[0].pageX; - pageY = event.touches[0].pageY; + pageX = (event as TouchEvent).touches[0].pageX; + pageY = (event as TouchEvent).touches[0].pageY; // Prevent scrolling on touch while dragging event.preventDefault(); + } else { + // Fallback for MouseEvent + pageX = (event as MouseEvent).pageX; + pageY = (event as MouseEvent).pageY; } const totalMovedX = pageX - this._startX; @@ -1070,7 +1079,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * If dragging starts and after the ghostElement is rendered the pointerId is reassigned to it. Then this method is bound to it. * @param event PointerUp event captured */ - public onPointerUp(event) { + public onPointerUp(event: PointerEvent | TouchEvent | MouseEvent) { if (!this._clicked) { return; } @@ -1078,14 +1087,18 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { let pageX; let pageY; if (this.pointerEventsEnabled || !this.touchEventsEnabled) { // Check first for pointer events or non touch, because we can have pointer events and touch events at once. - pageX = event.pageX; - pageY = event.pageY; + pageX = (event as PointerEvent).pageX; + pageY = (event as PointerEvent).pageY; } else if (this.touchEventsEnabled) { - pageX = event.touches[0].pageX; - pageY = event.touches[0].pageY; + pageX = (event as TouchEvent).touches[0].pageX; + pageY = (event as TouchEvent).touches[0].pageY; // Prevent scrolling on touch while dragging event.preventDefault(); + } else { + // Fallback for MouseEvent + pageX = (event as MouseEvent).pageX; + pageY = (event as MouseEvent).pageY; } const eventArgs: IDragBaseEventArgs = { @@ -1100,7 +1113,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { this._clicked = false; if (this._dragStarted) { if (this._lastDropArea && this._lastDropArea !== this.element.nativeElement) { - this.dispatchDropEvent(event.pageX, event.pageY, event); + this.dispatchDropEvent(pageX, pageY, event); } this.zone.run(() => { @@ -1130,7 +1143,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * This method will ensure that the drag state is being reset in this case as if the user released the dragged element. * @param event Event captured */ - public onPointerLost(event) { + public onPointerLost(event: PointerEvent) { if (!this._clicked) { return; } @@ -1169,7 +1182,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { this.dragEnd.emit(eventArgs); }); if (!this.animInProgress) { - this.onTransitionEnd(null); + this.onTransitionEnd(event); } } } @@ -1177,7 +1190,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { /** * @hidden */ - public onTransitionEnd(event) { + public onTransitionEnd(event: TransitionEvent | PointerEvent | TouchEvent | MouseEvent | null) { if ((!this._dragStarted && !this.animInProgress) || this._clicked) { // Return if no dragging started and there is no animation in progress. return; @@ -1233,7 +1246,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { if (this._dynamicGhostRef) { this._dynamicGhostRef.destroy(); - this._dynamicGhostRef = null; + this._dynamicGhostRef = null!; } } @@ -1246,7 +1259,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * @param pageY Latest pointer position on the Y axis relative to the page. * @param node The Node object to be cloned. */ - protected createGhost(pageX, pageY, node: any = null) { + protected createGhost(pageX: number, pageY: number, node: any = null) { if (!this.ghost) { return; } @@ -1303,8 +1316,8 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { this.document.body.appendChild(this.ghostElement); } - const ghostMarginLeft = parseInt(this.document.defaultView.getComputedStyle(this.ghostElement)['margin-left'], 10); - const ghostMarginTop = parseInt(this.document.defaultView.getComputedStyle(this.ghostElement)['margin-top'], 10); + const ghostMarginLeft = parseInt((this.document.defaultView!.getComputedStyle(this.ghostElement) as any)['margin-left'], 10); + const ghostMarginTop = parseInt((this.document.defaultView!.getComputedStyle(this.ghostElement) as any)['margin-top'], 10); this.ghostElement.style.left = (this._ghostStartX - ghostMarginLeft + totalMovedX - this._ghostHostX) + 'px'; this.ghostElement.style.top = (this._ghostStartY - ghostMarginTop + totalMovedY - this._ghostHostY) + 'px'; @@ -1328,7 +1341,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * @hidden * Dispatch custom igxDragEnter/igxDragLeave events based on current pointer position and if drop area is under. */ - protected dispatchDragEvents(pageX: number, pageY: number, originalEvent) { + protected dispatchDragEvents(pageX: number, pageY: number, originalEvent: any) { let topDropArea; const customEventArgs: IgxDragCustomEventDetails = { startX: this._startX, @@ -1340,7 +1353,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { }; const elementsFromPoint = this.getElementsAtPoint(pageX, pageY); - let targetElements = []; + let targetElements: Element[] = []; // Check for shadowRoot instance and use it if present for (const elFromPoint of elementsFromPoint) { if (elFromPoint?.shadowRoot) { @@ -1381,10 +1394,10 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * @hidden * Traverse shadow dom in depth. */ - protected getFromShadowRoot(elem, pageX, pageY, parentDomElems) { + protected getFromShadowRoot(elem: any, pageX: number, pageY: number, parentDomElems: any): any[] { const elementsFromPoint = elem.shadowRoot.elementsFromPoint(pageX, pageY); - const shadowElements = elementsFromPoint.filter(cur => parentDomElems.indexOf(cur) === -1); - let res = []; + const shadowElements = elementsFromPoint.filter((cur: any) => parentDomElems.indexOf(cur) === -1); + let res: any[] = []; for (const elFromPoint of shadowElements) { if (!!elFromPoint?.shadowRoot && elFromPoint.shadowRoot !== elem.shadowRoot) { res = res.concat(this.getFromShadowRoot(elFromPoint, pageX, pageY, elementsFromPoint)); @@ -1399,7 +1412,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { * Dispatch custom igxDrop event based on current pointer position if there is last recorder drop area under the pointer. * Last recorder drop area is updated in @dispatchDragEvents method. */ - protected dispatchDropEvent(pageX: number, pageY: number, originalEvent) { + protected dispatchDropEvent(pageX: number, pageY: number, originalEvent: any) { const eventArgs: IgxDragCustomEventDetails = { startX: this._startX, startY: this._startY, @@ -1417,16 +1430,16 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { /** * @hidden */ - protected getElementsAtPoint(pageX: number, pageY: number) { + public getElementsAtPoint(pageX: number, pageY: number) { // correct the coordinates with the current scroll position, because // document.elementsFromPoint consider position within the current viewport // window.pageXOffset == window.scrollX; // always true // using window.pageXOffset for IE9 compatibility const viewPortX = pageX - window.pageXOffset; const viewPortY = pageY - window.pageYOffset; - if (this.document['msElementsFromPoint']) { + if ((this.document as any)['msElementsFromPoint']) { // Edge and IE special snowflakes - const elements = this.document['msElementsFromPoint'](viewPortX, viewPortY); + const elements = (this.document as any)['msElementsFromPoint'](viewPortX, viewPortY); return elements === null ? [] : elements; } else { // Other browsers like Chrome, Firefox, Opera @@ -1437,7 +1450,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { /** * @hidden */ - protected dispatchEvent(target, eventName: string, eventArgs: IgxDragCustomEventDetails) { + protected dispatchEvent(target: any, eventName: string, eventArgs: IgxDragCustomEventDetails) { // This way is IE11 compatible. // const dragLeaveEvent = document.createEvent('CustomEvent'); // dragLeaveEvent.initCustomEvent(eventName, false, false, eventArgs); @@ -1446,22 +1459,22 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { target.dispatchEvent(new CustomEvent(eventName, { detail: eventArgs })); } - protected getTransformX(elem) { + protected getTransformX(elem: any) { let posX = 0; if (elem.style.transform) { const matrix = elem.style.transform; - const values = matrix ? matrix.match(/-?[\d\.]+/g) : undefined; + const values = matrix ? matrix.match(/-?[\d.]+/g) : undefined; posX = values ? Number(values[1]) : 0; } return posX; } - protected getTransformY(elem) { + protected getTransformY(elem: any) { let posY = 0; if (elem.style.transform) { const matrix = elem.style.transform; - const values = matrix ? matrix.match(/-?[\d\.]+/g) : undefined; + const values = matrix ? matrix.match(/-?[\d.]+/g) : undefined; posY = values ? Number(values[2]) : 0; } @@ -1490,7 +1503,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { protected getGhostHostBaseOffsetX() { if (!this.ghostHost) return 0; - const ghostPosition = this.document.defaultView.getComputedStyle(this.ghostHost).getPropertyValue('position'); + const ghostPosition = this.document.defaultView!.getComputedStyle(this.ghostHost).getPropertyValue('position'); if (ghostPosition === 'static' && this.ghostHost.offsetParent && this.ghostHost.offsetParent === this.document.body) { return 0; } else if (ghostPosition === 'static' && this.ghostHost.offsetParent) { @@ -1502,7 +1515,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { protected getGhostHostBaseOffsetY() { if (!this.ghostHost) return 0; - const ghostPosition = this.document.defaultView.getComputedStyle(this.ghostHost).getPropertyValue('position'); + const ghostPosition = this.document.defaultView!.getComputedStyle(this.ghostHost).getPropertyValue('position'); if (ghostPosition === 'static' && this.ghostHost.offsetParent && this.ghostHost.offsetParent === this.document.body) { return 0; } else if (ghostPosition === 'static' && this.ghostHost.offsetParent) { @@ -1516,16 +1529,16 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { const scrolledX = !this.scrollContainer ? this.windowScrollLeft > 0 : this.scrollContainer.scrollLeft > 0; const scrolledY = !this.scrollContainer ? this.windowScrollTop > 0 : this.scrollContainer.scrollTop > 0; // Take into account window scroll top because we do not use fixed positioning to the window. - const topBorder = (!this.scrollContainer ? 0 : containerBounds.top) + this.windowScrollTop + this._scrollContainerThreshold; + const topBorder = (!this.scrollContainer ? 0 : containerBounds!.top) + this.windowScrollTop + this._scrollContainerThreshold; // Subtract the element height because we position it from top left corner. const elementHeight = this.ghost && this.ghostElement ? this.ghostElement.offsetHeight : this.element.nativeElement.offsetHeight; - const bottomBorder = (!this.scrollContainer ? window.innerHeight : containerBounds.bottom) + + const bottomBorder = (!this.scrollContainer ? window.innerHeight : containerBounds!.bottom) + this.windowScrollTop - this._scrollContainerThreshold - elementHeight; // Same for window scroll left - const leftBorder = (!this.scrollContainer ? 0 : containerBounds.left) + this.windowScrollLeft + this._scrollContainerThreshold; + const leftBorder = (!this.scrollContainer ? 0 : containerBounds!.left) + this.windowScrollLeft + this._scrollContainerThreshold; // Subtract the element width again because we position it from top left corner. const elementWidth = this.ghost && this.ghostElement ? this.ghostElement.offsetWidth : this.element.nativeElement.offsetWidth; - const rightBorder = (!this.scrollContainer ? window.innerWidth : containerBounds.right) + + const rightBorder = (!this.scrollContainer ? window.innerWidth : containerBounds!.right) + this.windowScrollLeft - this._scrollContainerThreshold - elementWidth if (this.pageY <= topBorder && scrolledY) { @@ -1608,7 +1621,10 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { @Directive({ exportAs: 'drop', selector: '[igxDrop]', - standalone: true + standalone: true, + host: { + '(igxDrop)': 'onDragDrop($any($event))' + } }) export class IgxDropDirective implements OnInit, OnDestroy { /** @@ -1643,7 +1659,7 @@ export class IgxDropDirective implements OnInit, OnDestroy { * @memberof IgxDropDirective */ @Input() - public dropChannel: number | string | number[] | string[]; + public dropChannel!: number | string | number[] | string[]; /** * Sets a drop strategy type that will be executed when an drag element is released inside @@ -1781,8 +1797,7 @@ export class IgxDropDirective implements OnInit, OnDestroy { /** * @hidden */ - @HostListener('igxDrop', ['$event']) - public onDragDrop(event) { + public onDragDrop(event: CustomEvent) { if (!this.isDragLinked(event.detail.owner)) { return; } @@ -1820,11 +1835,11 @@ export class IgxDropDirective implements OnInit, OnDestroy { */ public ngOnInit() { this._zone.runOutsideAngular(() => { - fromEvent(this.element.nativeElement, 'igxDragEnter').pipe(takeUntil(this._destroy)) - .subscribe((res) => this.onDragEnter(res as CustomEvent)); + fromEvent>(this.element.nativeElement, 'igxDragEnter').pipe(takeUntil(this._destroy)) + .subscribe((res) => this.onDragEnter(res)); - fromEvent(this.element.nativeElement, 'igxDragLeave').pipe(takeUntil(this._destroy)).subscribe((res) => this.onDragLeave(res)); - fromEvent(this.element.nativeElement, 'igxDragOver').pipe(takeUntil(this._destroy)).subscribe((res) => this.onDragOver(res)); + fromEvent>(this.element.nativeElement, 'igxDragLeave').pipe(takeUntil(this._destroy)).subscribe((res) => this.onDragLeave(res)); + fromEvent>(this.element.nativeElement, 'igxDragOver').pipe(takeUntil(this._destroy)).subscribe((res) => this.onDragOver(res)); }); } @@ -1839,7 +1854,7 @@ export class IgxDropDirective implements OnInit, OnDestroy { /** * @hidden */ - public onDragOver(event) { + public onDragOver(event: CustomEvent) { const elementPosX = this.element.nativeElement.getBoundingClientRect().left + this.getWindowScrollLeft(); const elementPosY = this.element.nativeElement.getBoundingClientRect().top + this.getWindowScrollTop(); const offsetX = event.detail.pageX - elementPosX; @@ -1893,7 +1908,7 @@ export class IgxDropDirective implements OnInit, OnDestroy { /** * @hidden */ - public onDragLeave(event) { + public onDragLeave(event: CustomEvent) { if (!this.isDragLinked(event.detail.owner)) { return; } diff --git a/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.spec.ts b/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.spec.ts index 35290451d67..6822c8b58e7 100644 --- a/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.spec.ts +++ b/projects/igniteui-angular/directives/src/directives/drag-drop/drag-drop.spec.ts @@ -2009,7 +2009,7 @@ describe('igxDrag touch, mouse, pointerLost and shadow root coverage', () => { spyOn(firstDrag.dragEnd, 'emit'); // _clicked starts as false — calling onPointerLost should return immediately - firstDrag.onPointerLost({ pageX: 100, pageY: 100 }); + firstDrag.onPointerLost({ pageX: 100, pageY: 100 } as unknown as PointerEvent); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); }); diff --git a/projects/igniteui-angular/directives/src/directives/filter/filter.directive.ts b/projects/igniteui-angular/directives/src/directives/filter/filter.directive.ts index 411b9357ef4..25d2c2bf8f1 100644 --- a/projects/igniteui-angular/directives/src/directives/filter/filter.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/filter/filter.directive.ts @@ -14,10 +14,10 @@ export class IgxFilterOptions { public inputValue = ''; // Item property, which value should be used for filtering - public key: string | string[]; + public key!: string | string[]; // Represent items of the list. It should be used to handle declaratively defined widgets - public items: any[]; + public items!: any[]; // Function - get value to be tested from the item // item - single item of the list to be filtered @@ -81,7 +81,7 @@ export class IgxFilterDirective implements OnChanges { @Output() public filtering = new EventEmitter(false); // synchronous event emitter @Output() public filtered = new EventEmitter(); - @Input('igxFilter') public filterOptions: IgxFilterOptions; + @Input('igxFilter') public filterOptions!: IgxFilterOptions; constructor() { } diff --git a/projects/igniteui-angular/directives/src/directives/focus-trap/focus-trap.directive.ts b/projects/igniteui-angular/directives/src/directives/focus-trap/focus-trap.directive.ts index 9f0c0790e71..57b6399fb88 100644 --- a/projects/igniteui-angular/directives/src/directives/focus-trap/focus-trap.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/focus-trap/focus-trap.directive.ts @@ -39,7 +39,7 @@ export class IgxFocusTrapDirective implements AfterViewInit, OnDestroy { /** @hidden */ public ngAfterViewInit(): void { - fromEvent(this.element, 'keydown') + fromEvent(this.element!, 'keydown') .pipe(takeUntil(this.destroy$)) .subscribe((event: KeyboardEvent) => { if (this._focusTrap && event.key === this.platformUtil.KEYMAP.TAB) { @@ -53,8 +53,8 @@ export class IgxFocusTrapDirective implements AfterViewInit, OnDestroy { this.destroy$.complete(); } - private handleTab(event) { - const elements = this.getFocusableElements(this.element); + private handleTab(event: KeyboardEvent) { + const elements = this.getFocusableElements(this.element!); if (elements.length > 0) { const focusedElement = this.getFocusedElement(); const focusedElementIndex = elements.findIndex((element) => element as HTMLElement === focusedElement); @@ -68,7 +68,7 @@ export class IgxFocusTrapDirective implements AfterViewInit, OnDestroy { } (elements[nextFocusableElementIndex] as HTMLElement).focus(); } else { - this.element.focus(); + this.element!.focus(); } event.preventDefault(); diff --git a/projects/igniteui-angular/directives/src/directives/focus/focus.directive.ts b/projects/igniteui-angular/directives/src/directives/focus/focus.directive.ts index 7ce6ad51901..696b6b85dad 100644 --- a/projects/igniteui-angular/directives/src/directives/focus/focus.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/focus/focus.directive.ts @@ -10,7 +10,8 @@ import { EditorProvider, EDITOR_PROVIDER } from 'igniteui-angular/core'; export class IgxFocusDirective { private element = inject(ElementRef); private comp = inject(NG_VALUE_ACCESSOR, { self: true, optional: true }); - private control = inject(EDITOR_PROVIDER, { self: true, optional: true }); + // EDITOR_PROVIDER is registered as a multi provider, so the injected value is an array. + private control = inject(EDITOR_PROVIDER, { self: true, optional: true }) as unknown as EditorProvider[] | null; private focusState = true; @@ -60,7 +61,7 @@ export class IgxFocusDirective { return (this.comp[0] as EditorProvider).getEditElement(); } - if (this.control && this.control[0] && this.control[0].getEditElement) { + if (this.control && this.control[0] && this.control[0].getEditElement !== undefined) { return this.control[0].getEditElement(); } diff --git a/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts b/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts index 7a5b0160a38..6e4366fbde2 100644 --- a/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts +++ b/projects/igniteui-angular/directives/src/directives/for-of/base.helper.component.ts @@ -27,7 +27,7 @@ export class VirtualHelperBaseDirective implements OnDestroy, AfterViewInit { public scrollAmount = 0; public _size = 0; - public destroyed; + public destroyed!: boolean; protected destroy$ = new Subject(); @@ -131,7 +131,7 @@ export class VirtualHelperBaseDirective implements OnDestroy, AfterViewInit { } - protected handleMutations(event) { + protected handleMutations(event: ResizeObserverEntry[]) { const hasSize = !(event[0].contentRect.height === 0 && event[0].contentRect.width === 0); if (!hasSize && !this.isAttachedToDom) { // scroll bar detached from DOM diff --git a/projects/igniteui-angular/directives/src/directives/for-of/display.container.ts b/projects/igniteui-angular/directives/src/directives/for-of/display.container.ts index 61300db2550..af107c7a56e 100644 --- a/projects/igniteui-angular/directives/src/directives/for-of/display.container.ts +++ b/projects/igniteui-angular/directives/src/directives/for-of/display.container.ts @@ -19,10 +19,10 @@ export class DisplayContainerComponent { public _viewContainer = inject(ViewContainerRef); @ViewChild('display_container', { read: ViewContainerRef, static: true }) - public _vcr; + public _vcr!: ViewContainerRef; @ViewChild('display_container', { read: IgxScrollInertiaDirective, static: true }) - public _scrollInertia: IgxScrollInertiaDirective; + public _scrollInertia!: IgxScrollInertiaDirective; @HostBinding('class') public cssClass = 'igx-display-container'; @@ -30,7 +30,7 @@ export class DisplayContainerComponent { @HostBinding('class.igx-display-container--inactive') public notVirtual = true; - public scrollDirection: string; + public scrollDirection!: string; - public scrollContainer; + public scrollContainer: any; } diff --git a/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts b/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts index 059443a4b27..b9788ce4863 100644 --- a/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts @@ -1,5 +1,5 @@ import { NgForOfContext } from '@angular/common'; -import { ChangeDetectorRef, ComponentRef, Directive, EmbeddedViewRef, EventEmitter, Input, IterableChanges, IterableDiffer, IterableDiffers, NgZone, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, TemplateRef, TrackByFunction, ViewContainerRef, booleanAttribute, DOCUMENT, inject, EnvironmentInjector, AfterViewInit } from '@angular/core'; +import { ChangeDetectorRef, ComponentRef, Directive, EmbeddedViewRef, EventEmitter, Input, IterableChanges, IterableDiffer, IterableDiffers, NgZone, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, TemplateRef, TrackByFunction, ViewContainerRef, booleanAttribute, DOCUMENT, inject, EnvironmentInjector, AfterViewInit, IterableChangeRecord } from '@angular/core'; import { DisplayContainerComponent } from './display.container'; import { HVirtualHelperComponent } from './horizontal.virtual.helper.component'; @@ -120,7 +120,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken; + public dc!: ComponentRef; /** * The current state of the directive. It contains `startIndex` and `chunkSize`. @@ -269,11 +269,11 @@ export class IgxForOfDirective extends IgxForOfToken void; protected _sizesCache: number[] = []; - protected scrollComponent: VirtualHelperBaseDirective; + protected scrollComponent!: VirtualHelperBaseDirective; protected _differ: IterableDiffer | null = null; - protected _trackByFn: TrackByFunction; + protected _trackByFn!: TrackByFunction; protected individualSizeCache: number[] = []; /** * @hidden @@ -285,8 +285,8 @@ export class IgxForOfDirective extends IgxForOfToken> = []; protected contentResizeNotify = new Subject(); - protected contentObserver: ResizeObserver; - protected viewObserver: ResizeObserver; + protected contentObserver!: ResizeObserver; + protected viewObserver!: ResizeObserver; protected viewResizeNotify = new Subject(); /** Size that is being virtualized. */ protected _virtSize = 0; @@ -295,11 +295,11 @@ export class IgxForOfDirective extends IgxForOfToken(); - private _totalItemCount: number = null; - private _adjustToIndex; + private _totalItemCount: number = null!; + private _adjustToIndex!: number | null; // Start properties related to virtual size handling due to browser limitation /** Maximum size for an element of the browser. */ - private _maxSize; + private _maxSize!: number; /** * Ratio for height that's being virtualizaed and the one visible * If _virtHeightRatio = 1, the visible height and the virtualized are the same, also _maxSize > _virtHeight. @@ -336,12 +336,12 @@ export class IgxForOfDirective extends IgxForOfToken val; + const lastChunkExceeded = this.state.startIndex! + this.state.chunkSize! > val; if (lastChunkExceeded) { - this.state.startIndex = val - this.state.chunkSize; + this.state.startIndex = val - this.state.chunkSize!; } this._adjustScrollPositionAfterSizeChange(sizeDiff); } @@ -410,10 +410,10 @@ export class IgxForOfDirective extends IgxForOfToken this.igxForOf.length; + return this.igxForOf && this.state.startIndex! + this.state.chunkSize! > this.igxForOf.length; } - public verticalScrollHandler(event) { + public verticalScrollHandler(event: any) { this.onScroll(event); } @@ -449,19 +449,19 @@ export class IgxForOfDirective extends IgxForOfToken(input, this.igxForOf, this.getContextIndex(input), this.igxForOf.length) + new IgxForOfContext(input, this.igxForOf, this.getContextIndex(input), this.igxForOf.length) as any ); this._embeddedViews.push(embeddedView); } @@ -469,7 +469,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken this.onHScroll(evt); - this.scrollComponent = this.syncScrollService.getScrollMaster(this.igxForScrollOrientation); + this.scrollComponent = this.syncScrollService.getScrollMaster(this.igxForScrollOrientation)!; if (!this.scrollComponent) { this.scrollComponent = vc.createComponent(HVirtualHelperComponent).instance; this.scrollComponent.size = this.igxForOf ? this._calcSize() : 0; @@ -602,14 +602,14 @@ export class IgxForOfDirective extends IgxForOfToken { this._applyChanges(); this.cdr.markForCheck(); this._updateScrollOffset(); - const args: IForOfDataChangingEventArgs = { + const args: IForOfDataChangeEventArgs = { containerSize: this.igxForContainerSize, state: this.state }; @@ -689,11 +689,11 @@ export class IgxForOfDirective extends IgxForOfToken (this.isRemote ? this.totalItemCount : this.igxForOf.length) - 1) { + if (index < 0 || index > (this.isRemote ? this.totalItemCount : this.igxForOf!.length) - 1) { return; } const containerSize = parseFloat(this.igxForContainerSize); - const isPrevItem = index < this.state.startIndex || this.scrollPosition > this.sizesCache[index]; + const isPrevItem = index < this.state.startIndex! || this.scrollPosition > this.sizesCache[index]; let nextScroll = isPrevItem ? this.sizesCache[index] : this.sizesCache[index + 1] - containerSize; if (nextScroll < 0) { return; @@ -729,7 +729,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken= this.state.startIndex && index <= this.state.startIndex + this.state.chunkSize ? - this.embeddedViewNodes[index - this.state.startIndex] : null; + const targetNode = index >= this.state.startIndex! && index <= this.state.startIndex! + this.state.chunkSize! ? + this.embeddedViewNodes[index - this.state.startIndex!] : null; const rowHeight = this.getSizeAt(index); const containerSize = parseFloat(this.igxForContainerSize); - const containerOffset = -(this.scrollPosition - this.sizesCache[this.state.startIndex]); + const containerOffset = -(this.scrollPosition - this.sizesCache[this.state.startIndex!]); const endTopOffset = targetNode ? targetNode.offsetTop + rowHeight + containerOffset : containerSize + rowHeight; return !targetNode || targetNode.offsetTop < Math.abs(containerOffset) || containerSize && endTopOffset - containerSize > 5; @@ -868,7 +868,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken 0) { - for (let j = this.state.startIndex + this.state.chunkSize + 1; j < this.sizesCache.length; j++) { + for (let j = this.state.startIndex! + this.state.chunkSize! + 1; j < this.sizesCache.length; j++) { this.sizesCache[j] = (this.sizesCache[j] || 0) + totalDiff; } // update scrBar heights/widths - const reducer = (acc, val) => acc + val; + const reducer = (acc: number, val: number) => acc + val; this._virtSize += totalDiff; if (this._virtSize > this._maxSize) { @@ -907,7 +907,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken count) { - newStart = count - this.state.chunkSize; + if (newStart + this.state.chunkSize! > count) { + newStart = count - this.state.chunkSize!; } - const prevStart = this.state.startIndex; - const diff = newStart - this.state.startIndex; + const prevStart = this.state.startIndex!; + const diff = newStart - this.state.startIndex!; this.state.startIndex = newStart; if (diff) { @@ -1047,16 +1047,16 @@ export class IgxForOfDirective extends IgxForOfToken node.nodeType === Node.ELEMENT_NODE) || embView.rootNodes[0].nextElementSibling); - const view = container.detach(0); + const view = container.detach(0)!; this.updateTemplateContext(embView.context, i); // Because in Elements the whole parent div (containing data-index) gets removed (possibly due to being disconnected). In Angular it just gets moved. @@ -1075,13 +1075,13 @@ export class IgxForOfDirective extends IgxForOfToken= this.state.startIndex && this.igxForOf[i] !== undefined; i--) { + for (let i = prevIndex - 1; i >= this.state.startIndex! && this.igxForOf![i] !== undefined; i--) { const embView = this._embeddedViews.pop(); if (embView && !embView.destroyed) { this.scrollFocus(embView.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE) || embView.rootNodes[0].nextElementSibling); // embView and view both refer to the same collections - const view = container.detach(container.length - 1); + const view = container.detach(container.length - 1)!; this.updateTemplateContext(embView.context, i); view.detectChanges(); @@ -1094,8 +1094,8 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken> = Object.assign([], this._embeddedViews); + let startIndex = this.state.startIndex!; + let endIndex = this.state.chunkSize! + this.state.startIndex!; if (this.isRemote) { startIndex = 0; endIndex = this.igxForOf.length; } for (let i = startIndex; i < endIndex && this.igxForOf[i] !== undefined; i++) { const embView = embeddedViewCopy.shift(); - this.updateTemplateContext(embView.context, i); + this.updateTemplateContext(embView!.context, i); } if (prevChunkSize !== this.state.chunkSize) { this.chunkLoad.emit(this.state); @@ -1263,7 +1263,7 @@ export class IgxForOfDirective extends IgxForOfToken this.igxForOf.length) { @@ -1280,7 +1280,7 @@ export class IgxForOfDirective extends IgxForOfToken 0 ? elem[0] : null; } @@ -1308,11 +1308,11 @@ export class IgxForOfDirective extends IgxForOfToken 0 ? this.individualSizeCache.reduce((acc, val) => acc + val) : 0; - const newHeight = this.initSizesCache(this.igxForOf); + const newHeight = this.initSizesCache(this.igxForOf!); const diff = oldHeight - newHeight; this._adjustScrollPositionAfterSizeChange(diff); @@ -1325,7 +1325,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken accumulator + this._getItemSize(currentItem, dimension); - for (i; i < this.igxForOf.length; i++) { - let item: T | { value: T, height: number } = this.igxForOf[i]; + const reducer = (accumulator: number, currentItem: any) => accumulator + this._getItemSize(currentItem, dimension); + for (i; i < this.igxForOf!.length; i++) { + let item: T | { value: T, height: number } = this.igxForOf![i]; if (dimension === 'height') { - item = { value: this.igxForOf[i], height: this.individualSizeCache[i] }; + item = { value: this.igxForOf![i], height: this.individualSizeCache[i] }; } const size = dimension === 'height' ? this.individualSizeCache[i] : @@ -1346,18 +1346,18 @@ export class IgxForOfDirective extends IgxForOfToken= 0 && sum <= availableSize) { curItem = dimension === 'height' ? arr[0].value : arr[0]; - prevIndex = this.igxForOf.indexOf(curItem) - 1; - const prevItem = this.igxForOf[prevIndex]; + prevIndex = this.igxForOf!.indexOf(curItem) - 1; + const prevItem = this.igxForOf![prevIndex]; const prevSize = dimension === 'height' ? this.individualSizeCache[prevIndex] : - parseFloat(prevItem[dimension]); + parseFloat((prevItem as any)[dimension]); sum = arr.reduce(reducer, prevSize); arr.unshift(prevItem); length = arr.length; @@ -1378,7 +1378,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken containerSizeInfo.prevSize : this.isScrollable(); if (this.igxForScrollOrientation === 'horizontal') { const totalWidth = parseFloat(this.igxForContainerSize) > 0 ? this._calcSize() : 0; @@ -1430,7 +1430,7 @@ export class IgxForOfDirective extends IgxForOfToken 0) { size = this.individualSizeCache.reduce((acc, val) => acc + val, 0); } else { - size = this.initSizesCache(this.igxForOf); + size = this.initSizesCache(this.igxForOf!); } this._virtSize = size; if (size > this._maxSize) { @@ -1440,7 +1440,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken node.nodeType === Node.ELEMENT_NODE) || oldElem.rootNodes[0].nextElementSibling); // also detach from ViewContainerRef to make absolutely sure this is removed from the view container. @@ -1462,7 +1462,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken= this.igxForOf.length) { - elemIndex = this.igxForOf.length - this.state.chunkSize; + if (elemIndex >= this.igxForOf!.length) { + elemIndex = this.igxForOf!.length - this.state.chunkSize!; } - const input = this.igxForOf[elemIndex]; + const input = this.igxForOf![elemIndex]; const embeddedView = this.dc.instance._vcr.createEmbeddedView( this._template, - new IgxForOfContext(input, this.igxForOf, this.getContextIndex(input), this.igxForOf.length) + new IgxForOfContext(input, this.igxForOf!, this.getContextIndex(input), this.igxForOf!.length) as any ); this._embeddedViews.push(embeddedView); - this.state.chunkSize++; + this.state.chunkSize!++; this._zone.run(() => this.cdr.markForCheck()); } @@ -1499,13 +1499,13 @@ export class IgxForOfDirective extends IgxForOfToken this.state.chunkSize) { - const diff = chunkSize - this.state.chunkSize; + if (chunkSize > this.state.chunkSize!) { + const diff = chunkSize - this.state.chunkSize!; for (let i = 0; i < diff; i++) { this.addLastElem(); } - } else if (chunkSize < this.state.chunkSize) { - const diff = this.state.chunkSize - chunkSize; + } else if (chunkSize < this.state.chunkSize!) { + const diff = this.state.chunkSize! - chunkSize; for (let i = 0; i < diff; i++) { this.removeLastElem(); } @@ -1520,7 +1520,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfToken extends IgxForOfToken 0 && this.scrollPosition > 0) { const offset = this.igxForScrollOrientation === 'horizontal' ? parseFloat(this.dc.instance._viewContainer.element.nativeElement.style.left) : Number(this.dc.instance._viewContainer.element.nativeElement.style.transform?.match(/translateY\((-?\d+\.?\d*)px\)/)?.[1]); - const newSize = this.sizesCache[this.state.startIndex] - offset; + const newSize = this.sizesCache[this.state.startIndex!] - offset; this.scrollPosition = newSize; if (this.scrollPosition !== newSize) { this.scrollComponent.scrollAmount = newSize; @@ -1557,7 +1557,7 @@ export class IgxForOfDirective extends IgxForOfToken extends IgxForOfDirec this.dataChanging.emit(args); // re-init cache. if (!this.igxForOf) { - this.igxForOf = [] as U; + this.igxForOf = [] as unknown as U; } /* we need to reset the master dir if all rows are removed (e.g. because of filtering); if all columns are hidden, rows are @@ -1764,7 +1764,7 @@ export class IgxGridForOfDirective extends IgxForOfDirec } } - public override onScroll(event) { + public override onScroll(event: any) { this.scrollComponent.scrollAmount = event.target.scrollTop; if (!this.scrollComponent.size) { return; @@ -1784,7 +1784,7 @@ export class IgxGridForOfDirective extends IgxForOfDirec this.cdr.markForCheck(); } - public override onHScroll(scrollAmount) { + public override onHScroll(scrollAmount: number) { /* in certain situations this may be called when no scrollbar is visible */ const firstScrollChild = this.scrollComponent.nativeElement.children.item(0) as HTMLElement; if (!this.scrollComponent || !parseFloat(firstScrollChild.style.width)) { @@ -1802,7 +1802,7 @@ export class IgxGridForOfDirective extends IgxForOfDirec } } - protected getItemSize(item) { + protected getItemSize(item: any) { let size = 0; const dimension = this.igxForSizePropName || 'height'; if (this.igxForScrollOrientation === 'vertical') { @@ -1841,14 +1841,14 @@ export class IgxGridForOfDirective extends IgxForOfDirec protected override getNodeSize(rNode: Element, index?: number): number { if (this.igxForScrollOrientation === 'vertical') { - const view = this._embeddedViews[index]; + const view = this._embeddedViews[index!]; return this._embeddedViewSizesCache.get(view) || parseFloat(this.igxForItemSize); } else { - return super.getNodeSize(rNode, index); + return super.getNodeSize(rNode, index!); } } - protected override _updateSizeCache(changes: IterableChanges = null) { + protected override _updateSizeCache(changes: IterableChanges | null = null) { const oldSize = this.individualSizeCache.length > 0 ? this.individualSizeCache.reduce((acc, val) => acc + val) : 0; let newSize = oldSize; if (changes && !this.isRemote) { @@ -1862,9 +1862,9 @@ export class IgxGridForOfDirective extends IgxForOfDirec } protected handleCacheChanges(changes: IterableChanges) { - const identityChanges = []; - const newHeightCache = []; - const newSizesCache = []; + const identityChanges: Array> = []; + const newHeightCache: number[] = []; + const newSizesCache: number[] = []; newSizesCache.push(0); let newHeight = 0; @@ -1876,25 +1876,25 @@ export class IgxGridForOfDirective extends IgxForOfDirec changes.forEachIdentityChange((item) => { if (item.currentIndex !== item.previousIndex) { // Filter out ones that have not changed their index. - identityChanges[item.currentIndex] = item; + identityChanges[item.currentIndex!] = item; } }); // Processing each item that is passed to the igxForOf so far seem to be most reliable. We parse the updated list of items. changes.forEachItem((item) => { if (item.previousIndex !== null && - (numRemovedItems < 2 || !identityChanges.length || identityChanges[item.currentIndex]) + (numRemovedItems < 2 || !identityChanges.length || identityChanges[item.currentIndex!]) && this.igxForScrollOrientation !== "horizontal" && this.individualSizeCache.length > 0) { // Reuse cache on those who have previousIndex. // When there are more than one removed items currently the changes are not readable so ones with identity change // should be racalculated. - newHeightCache[item.currentIndex] = this.individualSizeCache[item.previousIndex]; + newHeightCache[item.currentIndex!] = this.individualSizeCache[item.previousIndex]; } else { // Assign default item size. - newHeightCache[item.currentIndex] = this.getItemSize(item.item); + newHeightCache[item.currentIndex!] = this.getItemSize(item.item); } - newSizesCache[item.currentIndex + 1] = newSizesCache[item.currentIndex] + newHeightCache[item.currentIndex]; - newHeight += newHeightCache[item.currentIndex]; + newSizesCache[item.currentIndex! + 1] = newSizesCache[item.currentIndex!] + newHeightCache[item.currentIndex!]; + newHeight += newHeightCache[item.currentIndex!]; }); this.individualSizeCache = newHeightCache; this.sizesCache = newSizesCache; @@ -1902,28 +1902,28 @@ export class IgxGridForOfDirective extends IgxForOfDirec } protected override addLastElem() { - let elemIndex = this.state.startIndex + this.state.chunkSize; + let elemIndex = this.state.startIndex! + this.state.chunkSize!; if (!this.isRemote && !this.igxForOf) { return; } - if (elemIndex >= this.igxForOf.length) { - elemIndex = this.igxForOf.length - this.state.chunkSize; + if (elemIndex >= this.igxForOf!.length) { + elemIndex = this.igxForOf!.length - this.state.chunkSize!; } - const input = this.igxForOf[elemIndex]; + const input = this.igxForOf![elemIndex]; const embeddedView = this.dc.instance._vcr.createEmbeddedView( this._template, - new IgxGridForOfContext(input, this.igxForOf, this.getContextIndex(input), this.igxForOf.length) + new IgxGridForOfContext(input, this.igxForOf!, this.getContextIndex(input), this.igxForOf!.length) as any ); this._embeddedViews.push(embeddedView); this.subscribeToViewObserver(embeddedView.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE) || embeddedView.rootNodes[0].nextElementSibling); - this.state.chunkSize++; + this.state.chunkSize!++; } - protected _updateViews(prevChunkSize) { + protected _updateViews(prevChunkSize: number | undefined) { if (this.igxForOf && this.igxForOf.length && this.dc) { - const embeddedViewCopy = Object.assign([], this._embeddedViews); + const embeddedViewCopy: Array> = Object.assign([], this._embeddedViews); let startIndex; let endIndex; if (this.isRemote) { @@ -1931,16 +1931,16 @@ export class IgxGridForOfDirective extends IgxForOfDirec endIndex = this.igxForOf.length; } else { startIndex = this.getIndexAt(this.scrollPosition, this.sizesCache); - if (startIndex + this.state.chunkSize > this.igxForOf.length) { - startIndex = this.igxForOf.length - this.state.chunkSize; + if (startIndex + this.state.chunkSize! > this.igxForOf.length) { + startIndex = this.igxForOf.length - this.state.chunkSize!; } this.state.startIndex = startIndex; - endIndex = this.state.chunkSize + this.state.startIndex; + endIndex = this.state.chunkSize! + this.state.startIndex; } for (let i = startIndex; i < endIndex && this.igxForOf[i] !== undefined; i++) { const embView = embeddedViewCopy.shift(); - this.updateTemplateContext(embView.context, i); + this.updateTemplateContext(embView!.context, i); } if (prevChunkSize !== this.state.chunkSize) { this.chunkLoad.emit(this.state); diff --git a/projects/igniteui-angular/directives/src/directives/for-of/for_of.sync.service.ts b/projects/igniteui-angular/directives/src/directives/for-of/for_of.sync.service.ts index 9599a551e5f..bbbb1992794 100644 --- a/projects/igniteui-angular/directives/src/directives/for-of/for_of.sync.service.ts +++ b/projects/igniteui-angular/directives/src/directives/for-of/for_of.sync.service.ts @@ -42,14 +42,14 @@ export class IgxForOfSyncService { * @hidden */ public sizesCache(dir: string): number[] { - return this._master.get(dir).sizesCache; + return this._master.get(dir)!.sizesCache; } /** * @hidden */ public chunkSize(dir: string): number { - return this._master.get(dir).state.chunkSize; + return this._master.get(dir)!.state.chunkSize!; } } diff --git a/projects/igniteui-angular/directives/src/directives/for-of/horizontal.virtual.helper.component.ts b/projects/igniteui-angular/directives/src/directives/for-of/horizontal.virtual.helper.component.ts index aee71934dd0..484e49a8da3 100644 --- a/projects/igniteui-angular/directives/src/directives/for-of/horizontal.virtual.helper.component.ts +++ b/projects/igniteui-angular/directives/src/directives/for-of/horizontal.virtual.helper.component.ts @@ -11,9 +11,9 @@ import { VirtualHelperBaseDirective } from './base.helper.component'; standalone: true }) export class HVirtualHelperComponent extends VirtualHelperBaseDirective { - @ViewChild('horizontal_container', { read: ViewContainerRef, static: true }) public _vcr; + @ViewChild('horizontal_container', { read: ViewContainerRef, static: true }) public _vcr!: ViewContainerRef; - @Input() public width: number; + @Input() public width!: number; @HostBinding('class') public cssClasses = 'igx-vhelper--horizontal'; diff --git a/projects/igniteui-angular/directives/src/directives/for-of/virtual.helper.component.ts b/projects/igniteui-angular/directives/src/directives/for-of/virtual.helper.component.ts index b411749388c..eaddfedcc81 100644 --- a/projects/igniteui-angular/directives/src/directives/for-of/virtual.helper.component.ts +++ b/projects/igniteui-angular/directives/src/directives/for-of/virtual.helper.component.ts @@ -13,12 +13,12 @@ import { VirtualHelperBaseDirective } from './base.helper.component'; }) export class VirtualHelperComponent extends VirtualHelperBaseDirective implements OnInit, OnDestroy { @HostBinding('scrollTop') - public scrollTop; + public scrollTop!: number; - public scrollWidth; + public scrollWidth!: number; - @ViewChild('container', { read: ViewContainerRef, static: true }) public _vcr; - @Input() public itemsLength: number; + @ViewChild('container', { read: ViewContainerRef, static: true }) public _vcr!: ViewContainerRef; + @Input() public itemsLength!: number; @HostBinding('class') public cssClasses = 'igx-vhelper--vertical'; diff --git a/projects/igniteui-angular/directives/src/directives/form-control/form-control.directive.ts b/projects/igniteui-angular/directives/src/directives/form-control/form-control.directive.ts index 734387f33c1..522771dff93 100644 --- a/projects/igniteui-angular/directives/src/directives/form-control/form-control.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/form-control/form-control.directive.ts @@ -30,24 +30,24 @@ export class IgcFormControlDirective implements ControlValueAccessor { /** @hidden @internal */ @HostListener('igcChange', ['$event.detail']) - public listenForValueChange(value) { + public listenForValueChange(value: any) { this.onChange(value); } /** @hidden @internal */ - public writeValue(value): void { + public writeValue(value: any): void { if (value) { this.elementRef.nativeElement.value = value; } } /** @hidden @internal */ - public registerOnChange(fn): void { + public registerOnChange(fn: any): void { this.onChange = fn; } /** @hidden @internal */ - public registerOnTouched(fn): void { + public registerOnTouched(fn: any): void { this.onTouched = fn; } diff --git a/projects/igniteui-angular/directives/src/directives/mask/mask-parsing.service.ts b/projects/igniteui-angular/directives/src/directives/mask/mask-parsing.service.ts index 7bfd0169e04..cd013b2949d 100644 --- a/projects/igniteui-angular/directives/src/directives/mask/mask-parsing.service.ts +++ b/projects/igniteui-angular/directives/src/directives/mask/mask-parsing.service.ts @@ -149,7 +149,7 @@ export class MaskParsingService { let char = maskOptions.promptChar; if (chars.length) { cursor = i + 1; - char = chars.shift(); + char = chars.shift()!; } if (value.length < 1) { // on `delete` the cursor should move forward @@ -191,9 +191,9 @@ export class MaskParsingService { } private replaceIMENumbers(value: string): string { - return value.replace(/[0123456789]/g, (num) => ({ + return value.replace(/[0123456789]/g, (num) => (({ '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '0': '0' - }[num])); + } as Record)[num])); } } diff --git a/projects/igniteui-angular/directives/src/directives/mask/mask.directive.spec.ts b/projects/igniteui-angular/directives/src/directives/mask/mask.directive.spec.ts index 9d81bc6e5ec..c78c9966038 100644 --- a/projects/igniteui-angular/directives/src/directives/mask/mask.directive.spec.ts +++ b/projects/igniteui-angular/directives/src/directives/mask/mask.directive.spec.ts @@ -675,7 +675,7 @@ describe('igxMaskDirective ControlValueAccessor Unit', () => { inputGet.and.returnValue('test_2___'); spyOnProperty(mask as any, 'selectionEnd').and.returnValue(6); const setSelectionSpy = spyOn(mask as any, 'setSelectionRange'); - mask.onInputChanged(false); + mask.onInputChanged(new InputEvent('input')); expect(mockParser.replaceInMask).toHaveBeenCalledWith('', 'test_2', jasmine.objectContaining({ format }), 0, 0); expect(inputSet).toHaveBeenCalledWith('test_2__'); expect(setSelectionSpy).toHaveBeenCalledWith(6); diff --git a/projects/igniteui-angular/directives/src/directives/mask/mask.directive.ts b/projects/igniteui-angular/directives/src/directives/mask/mask.directive.ts index a52e2f7b8f0..69b3d697e0d 100644 --- a/projects/igniteui-angular/directives/src/directives/mask/mask.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/mask/mask.directive.ts @@ -54,7 +54,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA * ``` */ @Input({ transform: booleanAttribute }) - public includeLiterals: boolean; + public includeLiterals!: boolean; /** * Specifies a pipe to be used on blur. @@ -63,7 +63,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA * ``` */ @Input() - public displayValuePipe: PipeTransform; + public displayValuePipe?: PipeTransform; /** * Specifies a pipe to be used on focus. @@ -72,7 +72,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA * ``` */ @Input() - public focusedValuePipe: PipeTransform; + public focusedValuePipe!: PipeTransform; /** * Emits an event each time the value changes. @@ -110,13 +110,13 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA protected get selectionStart(): number { // Edge(classic) and FF don't select text on drop return this.nativeElement.selectionStart === this.nativeElement.selectionEnd && this._hasDropAction ? - this.nativeElement.selectionEnd - this._droppedData.length : - this.nativeElement.selectionStart; + this.nativeElement.selectionEnd! - this._droppedData.length : + this.nativeElement.selectionStart!; } /** @hidden */ protected get selectionEnd(): number { - return this.nativeElement.selectionEnd; + return this.nativeElement.selectionEnd!; } /** @hidden */ @@ -129,18 +129,18 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA return this._end; } - protected _composing: boolean; - protected _compositionStartIndex: number; + protected _composing!: boolean; + protected _compositionStartIndex!: number; protected _focused = false; - private _compositionValue: string; + private _compositionValue!: string; private _end = 0; private _start = 0; - private _key: string; - private _mask: string; + private _key!: string; + private _mask!: string; private _oldText = ''; private _dataValue = ''; - private _droppedData: string; - private _hasDropAction: boolean; + private _droppedData!: string; + private _hasDropAction!: boolean; private readonly defaultMask = 'CCCCCCCCCC'; @@ -186,7 +186,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA /** @hidden @internal */ @HostListener('input', ['$event']) - public onInputChanged(event): void { + public onInputChanged(event: InputEvent): void { /** * '!this._focused' is a fix for #8165 * On page load IE triggers input events before focus events and @@ -270,7 +270,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA /** @hidden */ @HostListener('blur', ['$event']) public onBlur(event: FocusEvent): void { - const value = event.target['value']; + const value = (event.target as HTMLInputElement).value; this._focused = false; this.showDisplayValue(value); this._onTouchedCallback(); @@ -296,7 +296,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA @HostListener('drop', ['$event']) public onDrop(event: DragEvent): void { this._hasDropAction = true; - this._droppedData = event.dataTransfer.getData('text'); + this._droppedData = event.dataTransfer!.getData('text'); } /** @hidden */ @@ -365,7 +365,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA this._hasDropAction = false; this._start = 0; this._end = 0; - this._key = null; + this._key = null!; this._composing = false; } @@ -405,7 +405,7 @@ export class IgxMaskDirective implements OnInit, AfterViewChecked, ControlValueA private showDisplayValue(value: string) { if (this.displayValuePipe) { this.inputValue = this.displayValuePipe.transform(value); - } else if (value === this.maskParser.applyMask(null, this.maskOptions)) { + } else if (value === this.maskParser.applyMask(null!, this.maskOptions)) { this.inputValue = ''; } } diff --git a/projects/igniteui-angular/directives/src/directives/notification/notifications.directive.ts b/projects/igniteui-angular/directives/src/directives/notification/notifications.directive.ts index 823762f1add..57c0f67d8bc 100644 --- a/projects/igniteui-angular/directives/src/directives/notification/notifications.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/notification/notifications.directive.ts @@ -40,7 +40,7 @@ export abstract class IgxNotificationsDirective extends IgxToggleDirective * DOM tree position instead and use `positioning` property as needed. */ @Input() - public outlet: IgxOverlayOutletDirective | ElementRef; + public outlet!: IgxOverlayOutletDirective | ElementRef; /** * Controls whether positioning is relative to the viewport or to the nearest positioned container. @@ -78,12 +78,12 @@ export abstract class IgxNotificationsDirective extends IgxToggleDirective /** * @hidden */ - public timeoutId: number; + public timeoutId!: number; /** * @hidden */ - protected strategy: IPositionStrategy; + protected strategy!: IPositionStrategy; /** * @hidden diff --git a/projects/igniteui-angular/directives/src/directives/ripple/ripple.directive.ts b/projects/igniteui-angular/directives/src/directives/ripple/ripple.directive.ts index 51ce260c485..5a11b00199a 100644 --- a/projects/igniteui-angular/directives/src/directives/ripple/ripple.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/ripple/ripple.directive.ts @@ -53,7 +53,7 @@ export class IgxRippleDirective { * @memberof IgxRippleDirective */ @Input('igxRipple') - public rippleColor: string; + public rippleColor!: string; /** * Sets/gets the ripple duration(in milliseconds). * Default value is `600`. @@ -106,7 +106,7 @@ export class IgxRippleDirective { private rippleElementClass = 'igx-ripple__inner'; private rippleHostClass = 'igx-ripple'; private _centered = false; - private animationQueue = []; + private animationQueue: Animation[] = []; /** * @hidden */ diff --git a/projects/igniteui-angular/directives/src/directives/scroll-inertia/scroll_inertia.directive.ts b/projects/igniteui-angular/directives/src/directives/scroll-inertia/scroll_inertia.directive.ts index cc5f16f05d4..aff0ef5af11 100644 --- a/projects/igniteui-angular/directives/src/directives/scroll-inertia/scroll_inertia.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/scroll-inertia/scroll_inertia.directive.ts @@ -34,10 +34,10 @@ export class IgxScrollInertiaDirective implements OnInit, OnDestroy { @Input() - public IgxScrollInertiaDirection: string; + public IgxScrollInertiaDirection!: string; @Input() - public IgxScrollInertiaScrollContainer: HTMLElement; + public IgxScrollInertiaScrollContainer!: HTMLElement; @Input() public wheelStep = 50; @@ -63,26 +63,26 @@ export class IgxScrollInertiaDirective implements OnInit, OnDestroy { @Input() public inertiaDuration = 0.5; - private _touchInertiaAnimID: ReturnType; - private _startX: number; - private _startY: number; - private _touchStartX: number; - private _touchStartY: number; - private _lastTouchEnd: number; - private _lastTouchX: number; - private _lastTouchY: number; + private _touchInertiaAnimID!: ReturnType; + private _startX!: number; + private _startY!: number; + private _touchStartX!: number; + private _touchStartY!: number; + private _lastTouchEnd!: number; + private _lastTouchX!: number; + private _lastTouchY!: number; private _savedSpeedsX: number[] = []; private _savedSpeedsY: number[] = []; - private _totalMovedX: number; - private _offsetRecorded: boolean; - private _offsetDirection: number; - private _lastMovedX: number; - private _lastMovedY: number; - private _nextX: number; - private _nextY: number; + private _totalMovedX!: number; + private _offsetRecorded!: boolean; + private _offsetDirection!: number; + private _lastMovedX!: number; + private _lastMovedY!: number; + private _nextX!: number; + private _nextY!: number; private _speedsIndexX = 0; private _speedsIndexY = 0; - private parentElement: HTMLElement; + private parentElement!: HTMLElement; private _cachedFirstChild: HTMLElement | null = null; public ngOnInit(): void { @@ -175,7 +175,7 @@ export class IgxScrollInertiaDirective implements OnInit, OnDestroy { scrollDeltaY = this.calcAxisCoords(deltaScaledY, -1, 1); } - if (evt.composedPath && this.didChildScroll(evt, scrollDeltaX, scrollDeltaY)) { + if (evt.composedPath !== undefined && this.didChildScroll(evt, scrollDeltaX!, scrollDeltaY!)) { return; } diff --git a/projects/igniteui-angular/directives/src/directives/template-outlet/template_outlet.directive.ts b/projects/igniteui-angular/directives/src/directives/template-outlet/template_outlet.directive.ts index 9e3023d52e4..cd53d3db417 100644 --- a/projects/igniteui-angular/directives/src/directives/template-outlet/template_outlet.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/template-outlet/template_outlet.directive.ts @@ -55,7 +55,7 @@ export class IgxTemplateOutletDirective implements OnChanges { switch (actionType) { case TemplateOutletAction.CreateView: this._recreateView(); break; case TemplateOutletAction.MoveView: this._moveView(); break; - case TemplateOutletAction.UseCachedView: this._useCachedView(cachedView); break; + case TemplateOutletAction.UseCachedView: this._useCachedView(cachedView!); break; case TemplateOutletAction.UpdateViewContext: this._updateExistingContext(this.igxTemplateOutletContext); break; } } @@ -79,7 +79,7 @@ export class IgxTemplateOutletDirective implements OnChanges { if (view) { view.destroy(); - this._embeddedViewsMap.get(templateId.type).delete(templateId.id); + this._embeddedViewsMap.get(templateId.type)!.delete(templateId.id); } } @@ -187,7 +187,7 @@ export class IgxTemplateOutletDirective implements OnChanges { const movedView = this.igxTemplateOutletContext['moveView']; const templateId = this.igxTemplateOutletContext['templateID']; const cachedView = templateId ? - this._embeddedViewsMap.get(templateId.type)?.get(templateId.id) : + this._embeddedViewsMap.get(templateId.type)?.get(templateId.id) as EmbeddedViewRef | null : null; const shouldRecreate = this._shouldRecreateView(changes); @@ -204,6 +204,7 @@ export class IgxTemplateOutletDirective implements OnChanges { // has context, update context return { actionType: TemplateOutletAction.UpdateViewContext, cachedView }; } + return undefined!; } } enum TemplateOutletAction { diff --git a/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.directive.ts b/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.directive.ts index 23f5b7bc6d7..766ecd79130 100644 --- a/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.directive.ts @@ -55,7 +55,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke * ``` */ @Input() - public cssClass: string; + public cssClass!: string; /** * Determines the `CSS` class of the active highlight element. @@ -69,13 +69,13 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke * ``` */ @Input() - public activeCssClass: string; + public activeCssClass!: string; /** * @hidden */ @Input() - public containerClass: string; + public containerClass!: string; /** * Identifies the highlight within a unique group. @@ -165,7 +165,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke * ``` */ @Input() - public metadata: Map; + public metadata!: Map; /** * @hidden @@ -183,13 +183,13 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke private destroy$ = new Subject(); private _value = ''; - private _lastSearchInfo: IBaseSearchInfo; - private _div = null; - private _observer: MutationObserver = null; + private _lastSearchInfo!: IBaseSearchInfo; + private _div: any = null; + private _observer: MutationObserver | null = null; private _nodeWasRemoved = false; private _forceEvaluation = false; private _activeElementIndex = -1; - private _valueChanged: boolean; + private _valueChanged!: boolean; private _defaultCssClass = 'igx-highlight'; private _defaultActiveCssClass = 'igx-highlight--active'; @@ -314,7 +314,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke public activateIfNecessary(): void { const group = this.service.highlightGroupsMap.get(this.groupName); - if (group && group.index >= 0 && group.column === this.column && group.row === this.row && compareMaps(this.metadata, group.metadata)) { + if (group && group.index >= 0 && group.column === this.column && group.row === this.row && compareMaps(this.metadata, group.metadata!)) { this.activate(group.index); } } @@ -325,7 +325,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke */ public observe(): void { if (this._observer === null) { - const callback = (mutationList) => { + const callback = (mutationList: MutationRecord[]) => { mutationList.forEach((mutation) => { const removedNodes = Array.from(mutation.removedNodes); removedNodes.forEach((n) => { @@ -348,7 +348,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke this._forceEvaluation = false; this.activateIfNecessary(); - this._observer.disconnect(); + this._observer!.disconnect(); this._observer = null; } }); @@ -406,7 +406,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke } } - private getHighlightedText(searchText: string, caseSensitive: boolean, exactMatch: boolean) { + private getHighlightedText(searchText: string, caseSensitive?: boolean, exactMatch?: boolean) { this.appendDiv(); const stringValue = String(this.value); diff --git a/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.service.ts b/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.service.ts index ce96c3b7f89..a7450bf7c9d 100644 --- a/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.service.ts +++ b/projects/igniteui-angular/directives/src/directives/text-highlight/text-highlight.service.ts @@ -22,7 +22,7 @@ export class IgxTextHighlightService { /** * Clears any existing highlight. */ - public clearActiveHighlight(groupName) { + public clearActiveHighlight(groupName: string) { this.highlightGroupsMap.set(groupName, { index: -1 }); diff --git a/projects/igniteui-angular/directives/src/directives/toggle/toggle.directive.ts b/projects/igniteui-angular/directives/src/directives/toggle/toggle.directive.ts index f7159a52441..f1b9426da16 100644 --- a/projects/igniteui-angular/directives/src/directives/toggle/toggle.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/toggle/toggle.directive.ts @@ -157,7 +157,7 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { * ``` */ @Input() - public id: string; + public id!: string; /** * @hidden @@ -190,18 +190,18 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { return !this.collapsed; } - protected _overlayId: string; + protected _overlayId: string = ''; private _collapsed = true; protected destroy$ = new Subject(); - private _overlaySubFilter: [MonoTypeOperatorFunction, MonoTypeOperatorFunction] = [ + private _overlaySubFilter: [MonoTypeOperatorFunction, MonoTypeOperatorFunction] = [ filter(x => x.id === this._overlayId), takeUntil(this.destroy$) ]; - private _overlayOpenedSub: Subscription; - private _overlayClosingSub: Subscription; - private _overlayClosedSub: Subscription; - private _overlayContentAppendedSub: Subscription; + private _overlayOpenedSub!: Subscription; + private _overlayClosingSub!: Subscription; + private _overlayClosedSub!: Subscription; + private _overlayContentAppendedSub!: Subscription; /** * Opens the toggle. @@ -245,7 +245,7 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { this.unsubscribe(); this.overlayService.detach(this._overlayId); this._collapsed = true; - delete this._overlayId; + this._overlayId = ''; this.cdr.detectChanges(); return; } @@ -346,13 +346,13 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { this.destroy$.complete(); } - private overlayClosed = (e) => { + private overlayClosed = (e: OverlayEventArgs) => { this._collapsed = true; this.cdr.detectChanges(); this.unsubscribe(); this.overlayService.detach(this.overlayId); const args: ToggleViewEventArgs = { owner: this, id: this._overlayId, event: e.event }; - delete this._overlayId; + this._overlayId = ''; this.closed.emit(args); this.cdr.markForCheck(); }; @@ -376,7 +376,7 @@ export class IgxToggleDirective implements IToggleView, OnInit, OnDestroy { this._overlayClosingSub = this.overlayService .closing - .pipe(...this._overlaySubFilter) + .pipe(...this._overlaySubFilter as [MonoTypeOperatorFunction, MonoTypeOperatorFunction]) .subscribe((e: OverlayClosingEventArgs) => { const args: ToggleViewCancelableEventArgs = { cancel: false, event: e.event, owner: this, id: this._overlayId }; this.closing.emit(args); @@ -434,7 +434,7 @@ export class IgxToggleActionDirective implements OnInit { * ``` */ @Input() - public overlaySettings: OverlaySettings; + public overlaySettings!: OverlaySettings; /** * Determines where the toggle element overlay should be attached. @@ -450,7 +450,7 @@ export class IgxToggleActionDirective implements OnInit { * DOM tree position instead or use `container` property instead. */ @Input('igxToggleOutlet') - public outlet: IgxOverlayOutletDirective | ElementRef; + public outlet!: IgxOverlayOutletDirective | ElementRef; /** * @hidden @@ -467,13 +467,13 @@ export class IgxToggleActionDirective implements OnInit { */ public get target(): any { if (typeof this._target === 'string') { - return this.navigationService.get(this._target); + return this.navigationService!.get(this._target); } return this._target; } - protected _overlayDefaults: OverlaySettings; - protected _target: IToggleView | string; + protected _overlayDefaults!: OverlaySettings; + protected _target!: IToggleView | string; /** * @hidden diff --git a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-close-button.component.ts b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-close-button.component.ts index a80cea597ac..115cd6e7f45 100644 --- a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-close-button.component.ts +++ b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-close-button.component.ts @@ -16,7 +16,7 @@ import { CommonModule } from '@angular/common'; }) export class IgxTooltipCloseButtonComponent { @Input() - public customTemplate: TemplateRef; + public customTemplate!: TemplateRef; @Output() public clicked = new EventEmitter(); diff --git a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-target.directive.ts b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-target.directive.ts index 7c3615d58f7..70c3c8f5e97 100644 --- a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-target.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip-target.directive.ts @@ -10,7 +10,7 @@ import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { IBaseEventArgs } from 'igniteui-angular/core'; import { PositionSettings } from 'igniteui-angular/core'; -import { IgxToggleActionDirective } from '../toggle/toggle.directive'; +import { IgxToggleActionDirective, ToggleViewCancelableEventArgs } from '../toggle/toggle.directive'; import { IgxTooltipComponent } from './tooltip.component'; import { IgxTooltipDirective } from './tooltip.directive'; import { IgxTooltipCloseButtonComponent } from './tooltip-close-button.component'; @@ -276,7 +276,8 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen * @hidden */ @Input('igxTooltipTarget') - public override set target(target: any) { + public override set target(target: IgxTooltipDirective) { + // Guard against a sibling igxToggleAction on the same host assigning a non-tooltip target. See #14196. if (target instanceof IgxTooltipDirective) { this._target = target; } @@ -285,11 +286,11 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen /** * @hidden */ - public override get target(): any { + public override get target(): IgxTooltipDirective { if (typeof this._target === 'string') { - return this.navigationService.get(this._target); + return this.navigationService!.get(this._target) as IgxTooltipDirective; } - return this._target; + return this._target as IgxTooltipDirective; } /** @@ -375,7 +376,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen private _isForceClosed = false; private _hasArrow = false; private _closeButtonRef?: ComponentRef; - private _closeTemplate: TemplateRef; + private _closeTemplate!: TemplateRef; private _sticky = false; private _positionSettings: PositionSettings = TooltipPositionSettings; private _showTriggers = new Set(['pointerenter']); @@ -432,7 +433,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen this._overlayDefaults.closeOnOutsideClick = false; this._overlayDefaults.closeOnEscape = true; - this.target.closing.pipe(takeUntil(this._destroy$)).subscribe((event) => { + this.target.closing.pipe(takeUntil(this._destroy$)).subscribe((event: ToggleViewCancelableEventArgs) => { if (this.target.tooltipTarget !== this) { return; } @@ -666,7 +667,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen * Creates (if not already created) an instance of the tooltip close button, * and assigns it the provided custom template. */ - private _createCloseTemplate(template?: TemplateRef | undefined): void { + private _createCloseTemplate(template: TemplateRef): void { if (!this._closeButtonRef) { this._closeButtonRef = createComponent(IgxTooltipCloseButtonComponent, { environmentInjector: this._envInjector @@ -691,7 +692,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen this.target.role = "status" // Mark the tooltip directive as Dirty to ensure that // the CD refreshes the bindings - this.target.cdr?.markForCheck(); + this.target.markForCheck(); } } @@ -705,7 +706,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen this.target.role = "tooltip" // Mark the tooltip directive as Dirty to ensure that // the CD refreshes the bindings - this.target.cdr?.markForCheck(); + this.target.markForCheck(); } } diff --git a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.common.ts b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.common.ts index 6c69ad608e4..761b06485ef 100644 --- a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.common.ts +++ b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.common.ts @@ -73,7 +73,7 @@ export const TooltipPositionSettings: PositionSettings = { export class TooltipPositionStrategy extends AutoPositionStrategy { - private _placement: Placement; + private _placement!: Placement; constructor(settings?: PositionSettings) { if (settings) { @@ -112,7 +112,7 @@ export class TooltipPositionStrategy extends AutoPositionStrategy { public positionArrow(arrow: HTMLElement, arrowFit: ArrowFit): void { this.resetArrowPositionStyles(arrow); - const convert = (value: number) => { + const convert = (value: number | undefined) => { if (!value) { return ''; } @@ -122,7 +122,7 @@ export class TooltipPositionStrategy extends AutoPositionStrategy { Object.assign(arrow.style, { top: convert(arrowFit.top), left: convert(arrowFit.left), - [arrowFit.direction]: convert(-4), + [arrowFit.direction!]: convert(-4), }); } @@ -150,21 +150,21 @@ export class TooltipPositionStrategy extends AutoPositionStrategy { tooltipRect: Partial, positionProperty: 'top' | 'left' ): number { - const arrowSize = arrowRect.width > arrowRect.height - ? arrowRect.width - : arrowRect.height; + const arrowSize = arrowRect.width! > arrowRect.height! + ? arrowRect.width! + : arrowRect.height!; const tooltipSize = TooltipRegexes.vertical.test(this._placement) - ? tooltipRect.width - : tooltipRect.height; + ? tooltipRect.width! + : tooltipRect.height!; const direction = { top: 'horizontal', left: 'vertical', }[positionProperty]; - const center = `${direction}Center`; - const end = `${direction}End`; + const center = `${direction}Center` as keyof typeof TooltipRegexes; + const end = `${direction}End` as keyof typeof TooltipRegexes; if (TooltipRegexes[center].test(this._placement)) { const offset = tooltipSize / 2 - arrowSize / 2; @@ -223,7 +223,7 @@ export class TooltipPositionStrategy extends AutoPositionStrategy { * * @param settings Position settings for which to get the corresponding placement. */ - private getPlacementByPositionSettings(settings: PositionSettings): Placement { + private getPlacementByPositionSettings(settings: PositionSettings): Placement | undefined { const { horizontalDirection, horizontalStartPoint, verticalDirection, verticalStartPoint } = settings; const mapArray = Array.from(PositionsMap.entries()); @@ -252,7 +252,7 @@ export class TooltipPositionStrategy extends AutoPositionStrategy { left: 'right', }[direction]; - return opposite; + return opposite!; } } diff --git a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.component.ts b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.component.ts index 57e6c84c311..4b512382efe 100644 --- a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.component.ts +++ b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.component.ts @@ -11,7 +11,7 @@ import { IgxTooltipDirective } from './tooltip.directive'; export class IgxTooltipComponent { @ViewChild(IgxTooltipDirective, { static: true }) - public tooltip: IgxTooltipDirective; + public tooltip!: IgxTooltipDirective; - public content: string; + public content!: string; } \ No newline at end of file diff --git a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.directive.ts b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.directive.ts index a2238396300..da65b69b0c7 100644 --- a/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.directive.ts +++ b/projects/igniteui-angular/directives/src/directives/tooltip/tooltip.directive.ts @@ -61,7 +61,7 @@ export class IgxTooltipDirective extends IgxToggleDirective implements AfterView * ``` */ @Input() - public context; + public context: any; /** * Identifier for the tooltip. @@ -105,14 +105,14 @@ export class IgxTooltipDirective extends IgxToggleDirective implements AfterView /** * @hidden */ - public timeoutId; + public timeoutId: any; /** * @hidden */ - public tooltipTarget: IgxTooltipTargetDirective; + public tooltipTarget!: IgxTooltipTargetDirective; - private _arrowEl: HTMLElement; + private _arrowEl!: HTMLElement; private _role: 'tooltip' | 'status' = 'tooltip'; private _renderer = inject(Renderer2); private _platformUtil = inject(PlatformUtil); @@ -186,15 +186,19 @@ export class IgxTooltipDirective extends IgxToggleDirective implements AfterView if (info && info.closeAnimationPlayer) { info.closeAnimationPlayer.finish(); info.closeAnimationPlayer.reset(); - info.closeAnimationPlayer = null; + info.closeAnimationPlayer = null!; } else if (!this.collapsed) { - const animation = overlaySettings.positionStrategy.settings.closeAnimation; - overlaySettings.positionStrategy.settings.closeAnimation = null; + const animation = overlaySettings.positionStrategy!.settings.closeAnimation; + overlaySettings.positionStrategy!.settings.closeAnimation = null!; this.close(); - overlaySettings.positionStrategy.settings.closeAnimation = animation; + overlaySettings.positionStrategy!.settings.closeAnimation = animation; } } + public markForCheck() { + this.cdr.markForCheck(); + } + private _createArrow(): void { this._arrowEl = this._renderer.createElement('span'); this._renderer.setStyle(this._arrowEl, 'position', 'absolute'); @@ -204,6 +208,6 @@ export class IgxTooltipDirective extends IgxToggleDirective implements AfterView private _removeArrow(): void { this._arrowEl.remove(); - this._arrowEl = null; + this._arrowEl = null!; } } diff --git a/projects/igniteui-angular/directives/src/public_api.ts b/projects/igniteui-angular/directives/src/public_api.ts index 4deead82703..089dcc698e0 100644 --- a/projects/igniteui-angular/directives/src/public_api.ts +++ b/projects/igniteui-angular/directives/src/public_api.ts @@ -28,7 +28,6 @@ export * from './directives/mask/mask.directive'; // export { IgxRadioGroupDirective } from 'igniteui-angular/radio'; export * from './directives/ripple/ripple.directive'; export * from './directives/scroll-inertia/scroll_inertia.directive'; -export * from './directives/size/ig-size.directive'; export * from './directives/text-highlight/text-highlight.directive'; export * from './directives/text-selection/text-selection.directive'; export * from './directives/template-outlet/template_outlet.directive'; diff --git a/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts b/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts index b510ccfa156..420eb97e2bd 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/autocomplete/autocomplete.directive.ts @@ -113,7 +113,7 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective * ``` */ @Input('igxAutocompleteSettings') - public autocompleteSettings: AutocompleteOverlaySettings; + public autocompleteSettings!: AutocompleteOverlaySettings; /** @hidden @internal */ @HostBinding('attr.autocomplete') @@ -165,7 +165,7 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective private get settings(): OverlaySettings { const settings = Object.assign({}, this.defaultSettings, this.autocompleteSettings); if (!settings.target) { - const positionStrategyClone: IPositionStrategy = settings.positionStrategy.clone(); + const positionStrategyClone: IPositionStrategy = settings.positionStrategy!.clone(); settings.target = this.parentElement; settings.positionStrategy = positionStrategyClone; } @@ -202,15 +202,15 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective return 'list'; } - protected _composing: boolean; - protected id: string; + protected _composing!: boolean; + protected id!: string; protected get model() { return this.ngModel || this.formControl; } private _shouldBeOpen = false; private destroy$ = new Subject(); - private defaultSettings: OverlaySettings; + private defaultSettings!: OverlaySettings; /** @hidden @internal */ @HostListener('input') @@ -250,7 +250,7 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective } /** @hidden @internal */ - public override handleKeyDown(event) { + public override handleKeyDown(event: KeyboardEvent) { if (!this.collapsed && !this._composing) { switch (event.key.toLowerCase()) { case 'space': diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts index 37e509dd907..824a715e645 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-group.component.ts @@ -88,7 +88,7 @@ export class IgxDropDownGroupComponent { * ``` */ @Input() - public label: string; + public label!: string; private _id = NEXT_ID++; } diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts index 7d6746557e5..92c7e87f94c 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.base.ts @@ -180,7 +180,7 @@ export class IgxDropDownItemBaseDirective implements DoCheck { */ @Input({ transform: booleanAttribute }) @HostBinding('class.igx-drop-down__header') - public isHeader: boolean; + public isHeader!: boolean; /** * Sets/gets if the given item is disabled @@ -258,17 +258,16 @@ export class IgxDropDownItemBaseDirective implements DoCheck { */ protected _focused = false; protected _selected = false; - protected _index = null; + protected _index: number | null = null; protected _disabled = false; - protected _label = null; + protected _label: string | null = null; /** * @hidden * @internal */ @HostListener('click', ['$event']) - public clicked(event): void { // eslint-disable-line - } + public clicked(_event: MouseEvent): void { } /** * @hidden diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts index 0ea3d1fcf06..abce94f72c6 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-item.component.ts @@ -26,7 +26,7 @@ export class IgxDropDownItemComponent extends IgxDropDownItemBaseDirective { public override get focused(): boolean { let focusedState = this._focused; if (this.hasIndex) { - const focusedItem = this.selection.first_item(`${this.dropDown.id}-active`); + const focusedItem = this.selection!.first_item(`${this.dropDown.id}-active`); const focusedIndex = focusedItem ? focusedItem.index : -1; focusedState = this._index === focusedIndex; } @@ -58,7 +58,7 @@ export class IgxDropDownItemComponent extends IgxDropDownItemBaseDirective { */ public override get selected(): boolean { if (this.hasIndex) { - const item = this.selection.first_item(`${this.dropDown.id}`); + const item = this.selection!.first_item(`${this.dropDown.id}`); return item ? item.index === this._index && item.value === this.value : false; } return this._selected; @@ -88,7 +88,7 @@ export class IgxDropDownItemComponent extends IgxDropDownItemBaseDirective { } } - public override clicked(event): void { + public override clicked(event: MouseEvent): void { if (!this.isSelectable) { this.ensureItemFocus(); return; diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts index 1e1a9e0b298..172c4db0163 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down-navigation.directive.ts @@ -15,7 +15,7 @@ export class IgxDropDownItemNavigationDirective implements IDropDownNavigationDi public dropdown = inject(IGX_DROPDOWN_BASE, { self: true, optional: true }); - protected _target: IgxDropDownBaseDirective = null; + protected _target: IgxDropDownBaseDirective = null!; /** * Gets the target of the navigation directive; @@ -50,12 +50,12 @@ export class IgxDropDownItemNavigationDirective implements IDropDownNavigationDi */ @Input('igxDropDownItemNavigation') public set target(target: IgxDropDownBaseDirective) { - this._target = target ? target : this.dropdown; + this._target = target ? target : this.dropdown!; } @HostBinding('attr.aria-activedescendant') public get activeDescendant(): string { - return this._target?.activeDescendant; + return this._target?.activeDescendant!; } /** diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts index 79b5c2745e7..730d92f8fb5 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.base.ts @@ -48,7 +48,7 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit * ``` */ @Input() - public width: string; + public width!: string; /** * Gets/Sets the height of the drop down @@ -63,7 +63,7 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit * ``` */ @Input() - public height: string; + public height!: string; /** * Gets/Sets the drop down's id @@ -100,7 +100,7 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit */ @Input() @HostBinding('style.maxHeight') - public maxHeight = null; + public maxHeight: string = null!; /** * @hidden @internal @@ -180,13 +180,13 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit * @hidden * @internal */ - public children: QueryList; + public children!: QueryList; - protected _width; - protected _height; + protected _width: any; + protected _height: any; protected _focusedItem: any = null; protected _id = `igx-drop-down-${NEXT_ID++}`; - protected computedStyles; + protected computedStyles: any; /** * Gets if the dropdown is collapsed @@ -194,7 +194,7 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit public abstract readonly collapsed: boolean; public ngOnInit(): void { - this.computedStyles = this.document.defaultView.getComputedStyle(this.elementRef.nativeElement); + this.computedStyles = this.document.defaultView!.getComputedStyle(this.elementRef.nativeElement); } /** Keydown Handler */ @@ -202,7 +202,7 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit switch (key) { case DropDownActionKey.ENTER: case DropDownActionKey.SPACE: - this.selectItem(this.focusedItem, event); + this.selectItem(this.focusedItem!, event); break; case DropDownActionKey.ESCAPE: case DropDownActionKey.TAB: @@ -218,8 +218,8 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit */ public selectItem(newSelection?: IgxDropDownItemBaseDirective, event?: Event, emit = true) { // eslint-disable-line this.selectionChanging.emit({ - newSelection, - oldSelection: null, + newSelection: newSelection!, + oldSelection: null!, cancel: false }); } @@ -299,7 +299,7 @@ export abstract class IgxDropDownBaseDirective implements IDropDownList, OnInit protected navigate(direction: Navigate, currentIndex?: number) { let index = -1; if (this._focusedItem) { - index = currentIndex ? currentIndex : this.focusedItem.itemIndex; + index = currentIndex ? currentIndex : this.focusedItem!.itemIndex; } const newIndex = this.getNearestSiblingFocusableItemIndex(index, direction); this.navigateItem(newIndex); diff --git a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts index 111ad7c343d..5d7c1e23a7c 100644 --- a/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts +++ b/projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts @@ -65,7 +65,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID * @internal */ @ContentChildren(forwardRef(() => IgxDropDownItemComponent), { descendants: true }) - public override children: QueryList; + public override children!: QueryList; /** * Emitted before the dropdown is opened @@ -135,7 +135,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID * ``` */ @Input() - public labelledBy: string; + public labelledBy!: string; /** * Gets/sets the `role` attribute of the drop down. Default is 'listbox'. @@ -148,13 +148,13 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID public role = 'listbox'; @ContentChild(IgxForOfToken) - protected virtDir: IgxForOfToken; + protected virtDir!: IgxForOfToken; @ViewChild(IgxToggleDirective, { static: true }) - protected toggleDirective: IgxToggleDirective; + protected toggleDirective!: IgxToggleDirective; @ViewChild('scrollContainer', { static: true }) - protected scrollContainerRef: ElementRef; + protected scrollContainerRef!: ElementRef; /** * @hidden @internal @@ -220,7 +220,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID if (selectedItem) { return selectedItem; } - return null; + return null!; } /** @@ -241,12 +241,12 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID protected get collectionLength() { if (this.virtDir) { - return this.virtDir.totalItemCount || this.virtDir.igxForOf.length; + return this.virtDir.totalItemCount || this.virtDir.igxForOf!.length; } } protected destroy$ = new Subject(); - protected _scrollPosition: number; + protected _scrollPosition!: number; /** * Opens the dropdown @@ -310,7 +310,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID let newSelection: IgxDropDownItemBaseDirective; if (this.virtDir) { newSelection = { - value: this.virtDir.igxForOf[index], + value: this.virtDir.igxForOf![index], index } as IgxDropDownItemBaseDirective; } else { @@ -327,13 +327,13 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID */ public override navigateItem(index: number) { if (this.virtDir) { - if (index === -1 || index >= this.collectionLength) { + if (index === -1 || index >= this.collectionLength!) { return; } const direction = index > (this.focusedItem ? this.focusedItem.index : -1) ? Navigate.Down : Navigate.Up; const subRequired = this.isIndexOutOfBounds(index, direction); this.focusedItem = { - value: this.virtDir.igxForOf[index], + value: this.virtDir.igxForOf![index], index } as IgxDropDownItemBaseDirective; if (subRequired) { @@ -371,7 +371,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID // TODO: This logic _cannot_ be right, those are optional user-provided inputs that can be strings with units, refactor: const itemsInView = this.virtDir.igxForContainerSize / this.virtDir.igxForItemSize; targetScroll -= (itemsInView / 2 - 1) * this.virtDir.igxForItemSize; - this.virtDir.getScroll().scrollTop = targetScroll; + this.virtDir.getScroll()!.scrollTop = targetScroll; } /** @@ -505,7 +505,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID */ public override navigateLast() { if (this.virtDir) { - this.navigateItem(this.virtDir.totalItemCount ? this.virtDir.totalItemCount - 1 : this.virtDir.igxForOf.length - 1); + this.navigateItem(this.virtDir.totalItemCount ? this.virtDir.totalItemCount - 1 : this.virtDir.igxForOf!.length - 1); } else { super.navigateLast(); } @@ -545,7 +545,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID public override selectItem(newSelection?: IgxDropDownItemBaseDirective, event?: Event, emit = true) { const oldSelection = this.selectedItem; if (!newSelection) { - newSelection = this.focusedItem; + newSelection! = this.focusedItem!; } if (newSelection === null) { return; @@ -555,11 +555,11 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID } if (this.virtDir) { newSelection = { - value: newSelection.value, - index: newSelection.index + value: newSelection!.value, + index: newSelection!.index } as IgxDropDownItemBaseDirective; } - const args: ISelectionEventArgs = { oldSelection, newSelection, cancel: false, owner: this }; + const args: ISelectionEventArgs = { oldSelection, newSelection, cancel: false, owner: this }!; if (emit) { this.selectionChanging.emit(args); @@ -593,7 +593,7 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID */ public clearSelection() { const oldSelection = this.selectedItem; - const newSelection: IgxDropDownItemBaseDirective = null; + const newSelection: IgxDropDownItemBaseDirective = null!; const args: ISelectionEventArgs = { oldSelection, newSelection, cancel: false, owner: this }; this.selectionChanging.emit(args); if (this.selectedItem && !args.cancel) { @@ -649,9 +649,9 @@ export class IgxDropDownComponent extends IgxDropDownBaseDirective implements ID private isIndexOutOfBounds(index: number, direction: Navigate) { const virtState = this.virtDir.state; - const currentPosition = this.virtDir.getScroll().scrollTop; + const currentPosition = this.virtDir.getScroll()!.scrollTop; const itemPosition = this.virtDir.getScrollForIndex(index, direction === Navigate.Down); - const indexOutOfChunk = index < virtState.startIndex || index > virtState.chunkSize + virtState.startIndex; + const indexOutOfChunk = index < virtState.startIndex! || index > virtState.chunkSize! + virtState.startIndex!; const scrollNeeded = direction === Navigate.Down ? currentPosition < itemPosition : currentPosition > itemPosition; const subRequired = indexOutOfChunk || scrollNeeded; return subRequired; diff --git a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel-header.component.ts b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel-header.component.ts index 8cbd1d13889..b091008fa01 100644 --- a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel-header.component.ts +++ b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel-header.component.ts @@ -1,4 +1,4 @@ -import { Component, ChangeDetectorRef, ElementRef, HostBinding, HostListener, Input, EventEmitter, Output, ContentChild, ViewChild, booleanAttribute, inject, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectorRef, ElementRef, HostBinding, Input, EventEmitter, Output, ContentChild, ViewChild, booleanAttribute, inject, ChangeDetectionStrategy } from '@angular/core'; import { IgxExpansionPanelIconDirective } from './expansion-panel.directives'; import { IGX_EXPANSION_PANEL_COMPONENT, IgxExpansionPanelBase, IExpansionPanelCancelableEventArgs } from './expansion-panel.common'; import { IgxIconComponent } from 'igniteui-angular/icon'; @@ -18,6 +18,14 @@ export type ExpansionPanelHeaderIconPosition = (typeof ExpansionPanelHeaderIconP selector: 'igx-expansion-panel-header', templateUrl: 'expansion-panel-header.component.html', changeDetection: ChangeDetectionStrategy.Eager, + host: { + '(keydown.Enter)': 'onAction($any($event))', + '(keydown.Space)': 'onAction($any($event))', + '(keydown.Spacebar)': 'onAction($any($event))', + '(click)': 'onAction($event)', + '(keydown.alt.arrowdown)': 'openPanel($event)', + '(keydown.alt.arrowup)': 'closePanel($event)' + }, imports: [IgxIconComponent] }) export class IgxExpansionPanelHeaderComponent { @@ -31,7 +39,7 @@ export class IgxExpansionPanelHeaderComponent { */ public get iconRef(): ElementRef { const renderedTemplate = this.customIconRef ?? this.defaultIconRef; - return this.iconPosition !== ExpansionPanelHeaderIconPosition.NONE ? renderedTemplate : null; + return this.iconPosition !== ExpansionPanelHeaderIconPosition.NONE ? renderedTemplate : null!; } /** @@ -173,7 +181,7 @@ export class IgxExpansionPanelHeaderComponent { this._disabled = val; if (val) { // V.S. June 11th, 2021: #9696 TabIndex should be removed when panel is disabled - delete this.tabIndex; + this.tabIndex = undefined; } else { this.tabIndex = 0; } @@ -181,11 +189,11 @@ export class IgxExpansionPanelHeaderComponent { /** @hidden @internal */ @ContentChild(IgxExpansionPanelIconDirective, { read: ElementRef }) - private customIconRef: ElementRef; + private customIconRef!: ElementRef; /** @hidden @internal */ @ViewChild(IgxIconComponent, { read: ElementRef }) - private defaultIconRef: ElementRef; + private defaultIconRef!: ElementRef; /** * Sets/gets the `id` of the expansion panel header. @@ -198,7 +206,7 @@ export class IgxExpansionPanelHeaderComponent { public id = ''; /** @hidden @internal */ - public tabIndex = 0; + public tabIndex?: number = 0; // properties section private _iconTemplate = false; @@ -211,26 +219,21 @@ export class IgxExpansionPanelHeaderComponent { /** * @hidden */ - @HostListener('keydown.Enter', ['$event']) - @HostListener('keydown.Space', ['$event']) - @HostListener('keydown.Spacebar', ['$event']) - @HostListener('click', ['$event']) - public onAction(evt?: Event) { + public onAction(evt: KeyboardEvent | MouseEvent) { if (this.disabled) { - evt.stopPropagation(); + evt!.stopPropagation(); return; } - const eventArgs: IExpansionPanelCancelableEventArgs = { event: evt, owner: this.panel, cancel: false }; + const eventArgs: IExpansionPanelCancelableEventArgs = { event: evt!, owner: this.panel, cancel: false }; this.interaction.emit(eventArgs); if (eventArgs.cancel === true) { return; } this.panel.toggle(evt); - evt.preventDefault(); + evt!.preventDefault(); } /** @hidden @internal */ - @HostListener('keydown.alt.arrowdown', ['$event']) public openPanel(event: KeyboardEvent) { if (event.altKey) { const eventArgs: IExpansionPanelCancelableEventArgs = { event, owner: this.panel, cancel: false }; @@ -243,7 +246,6 @@ export class IgxExpansionPanelHeaderComponent { } /** @hidden @internal */ - @HostListener('keydown.alt.arrowup', ['$event']) public closePanel(event: KeyboardEvent) { if (event.altKey) { const eventArgs: IExpansionPanelCancelableEventArgs = { event, owner: this.panel, cancel: false }; diff --git a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.common.ts b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.common.ts index ee08acffd3e..a6c60b4ca5f 100644 --- a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.common.ts +++ b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.common.ts @@ -13,9 +13,9 @@ export interface IgxExpansionPanelBase { contentCollapsing: EventEmitter; contentExpanded: EventEmitter; contentExpanding: EventEmitter; - collapse(evt?: Event); - expand(evt?: Event); - toggle(evt?: Event); + collapse(evt?: Event): any; + expand(evt?: Event): any; + toggle(evt?: Event): any; } /** @hidden */ @@ -60,6 +60,6 @@ export abstract class HeaderContentBaseDirective { return element.nativeElement.textContent.trim(); } - return null; + return null!; }; } diff --git a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.component.ts b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.component.ts index 541150feaf5..d518a986464 100644 --- a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.component.ts +++ b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.component.ts @@ -209,13 +209,13 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements * @hidden */ @ContentChild(IgxExpansionPanelBodyComponent, { read: IgxExpansionPanelBodyComponent }) - public body: IgxExpansionPanelBodyComponent; + public body!: IgxExpansionPanelBodyComponent; /** * @hidden */ @ContentChild(IgxExpansionPanelHeaderComponent, { read: IgxExpansionPanelHeaderComponent }) - public header: IgxExpansionPanelHeaderComponent; + public header!: IgxExpansionPanelHeaderComponent; /** @hidden */ public ngAfterContentInit(): void { @@ -238,13 +238,13 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements * * ``` */ - public collapse(evt?: Event) { + public collapse(evt?: MouseEvent | KeyboardEvent) { // If expansion panel is already collapsed or is collapsing, do nothing if (this.collapsed || this.closeAnimationPlayer) { return; } - const args = { event: evt, panel: this, owner: this, cancel: false }; - this.contentCollapsing.emit(args); + const args = { event: evt!, panel: this, owner: this, cancel: false }; + this.contentCollapsing.emit(args!); if (args.cancel === true) { return; } @@ -252,7 +252,7 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements this.playCloseAnimation( this.body?.element, () => { - this.contentCollapsed.emit({ event: evt, owner: this }); + this.contentCollapsed.emit({ event: evt!, owner: this }); this.collapsed = true; this.collapsedChange.emit(true); this.cdr.markForCheck(); @@ -274,8 +274,8 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements if (!this.collapsed && !this.closeAnimationPlayer) { // Check if the panel is currently collapsing or already expanded return; } - const args = { event: evt, panel: this, owner: this, cancel: false }; - this.contentExpanding.emit(args); + const args = { event: evt!, panel: this, owner: this, cancel: false }; + this.contentExpanding.emit(args!); if (args.cancel === true) { return; } @@ -286,7 +286,7 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements this.playOpenAnimation( this.body?.element, () => { - this.contentExpanded.emit({ event: evt, owner: this }); + this.contentExpanded.emit({ event: evt!, owner: this }); } ); } @@ -301,7 +301,7 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements * * ``` */ - public toggle(evt?: Event) { + public toggle(evt?: MouseEvent | KeyboardEvent) { if (this.collapsed) { this.open(evt); } else { @@ -309,11 +309,11 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements } } - public open(evt?: Event) { + public open(evt?: MouseEvent | KeyboardEvent) { this.expand(evt); } - public close(evt?: Event) { + public close(evt?: MouseEvent | KeyboardEvent) { this.collapse(evt); } } diff --git a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.spec.ts b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.spec.ts index 8e5c22cb60c..6d79800a2bc 100644 --- a/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.spec.ts +++ b/projects/igniteui-angular/expansion-panel/src/expansion-panel/expansion-panel.spec.ts @@ -96,7 +96,7 @@ describe('igxExpansionPanel', () => { fixture.detectChanges(); const panel = fixture.componentInstance.panel; const header = fixture.componentInstance.header; - const mockEvent = new Event('click'); + const mockEvent = new MouseEvent('click'); expect(panel).toBeTruthy(); expect(header).toBeTruthy(); expect(header.disabled).toEqual(false); diff --git a/projects/igniteui-angular/expansion-panel/src/expansion-panel/toggle-animation-component.ts b/projects/igniteui-angular/expansion-panel/src/expansion-panel/toggle-animation-component.ts index 32dfd401d97..42799d29269 100644 --- a/projects/igniteui-angular/expansion-panel/src/expansion-panel/toggle-animation-component.ts +++ b/projects/igniteui-angular/expansion-panel/src/expansion-panel/toggle-animation-component.ts @@ -53,10 +53,10 @@ export abstract class ToggleAnimationPlayer implements ToggleAnimationOwner, OnD } /** @hidden @internal */ - public openAnimationPlayer: AnimationPlayer = null; + public openAnimationPlayer: AnimationPlayer = null!; /** @hidden @internal */ - public closeAnimationPlayer: AnimationPlayer = null; + public closeAnimationPlayer: AnimationPlayer = null!; protected destroy$: Subject = new Subject(); protected players: Map = new Map(); @@ -121,7 +121,7 @@ export abstract class ToggleAnimationPlayer implements ToggleAnimationOwner, OnD const targetEmitter = type === ANIMATION_TYPE.OPEN ? this.openAnimationStart : this.closeAnimationStart; targetEmitter.emit(); this.onDoneHandler(type); - return; + return undefined!; } const opposite = this.getPlayer(oppositeType); let oppositePosition = 1; @@ -144,7 +144,7 @@ export abstract class ToggleAnimationPlayer implements ToggleAnimationOwner, OnD return target; } - private onDoneHandler(type) { + private onDoneHandler(type: ANIMATION_TYPE) { const targetEmitter = type === ANIMATION_TYPE.OPEN ? this.openAnimationDone : this.closeAnimationDone; const targetCallback = type === ANIMATION_TYPE.OPEN ? this.onOpenedCallback : this.onClosedCallback; targetCallback(); @@ -170,7 +170,7 @@ export abstract class ToggleAnimationPlayer implements ToggleAnimationOwner, OnD if (this.closeAnimationPlayer != null) { this.closeAnimationPlayer.reset(); this.closeAnimationPlayer.destroy(); - this.closeAnimationPlayer = null; + this.closeAnimationPlayer = null!; } this.closeInterrupted = true; this.onClosedCallback = this._defaultClosedCallback; @@ -179,7 +179,7 @@ export abstract class ToggleAnimationPlayer implements ToggleAnimationOwner, OnD if (this.openAnimationPlayer != null) { this.openAnimationPlayer.reset(); this.openAnimationPlayer.destroy(); - this.openAnimationPlayer = null; + this.openAnimationPlayer = null!; } this.openInterrupted = true; this.onOpenedCallback = this._defaultOpenedCallback; @@ -196,7 +196,7 @@ export abstract class ToggleAnimationPlayer implements ToggleAnimationOwner, OnD case ANIMATION_TYPE.CLOSE: return this.closeAnimationPlayer; default: - return null; + return null!; } } } diff --git a/projects/igniteui-angular/grids/core/src/api.service.ts b/projects/igniteui-angular/grids/core/src/api.service.ts index 2342900448a..f2cc242265c 100644 --- a/projects/igniteui-angular/grids/core/src/api.service.ts +++ b/projects/igniteui-angular/grids/core/src/api.service.ts @@ -30,11 +30,11 @@ export class GridBaseAPIService implements GridServiceType { public crudService = inject(IgxGridCRUDService); public cms = inject(IgxColumnMovingService) - public grid: T; + public grid!: T; protected destroyMap: Map> = new Map>(); public get_column_by_name(name: string): ColumnType { - return this.grid.columns.find((col: ColumnType) => col.field === name); + return this.grid.columns.find((col: ColumnType) => col.field === name)!; } public get_summary_data(): any[] | null { @@ -46,17 +46,17 @@ export class GridBaseAPIService implements GridServiceType { if (!data) { if (grid.transactions.enabled) { data = DataUtil.mergeTransactions( - cloneArray(grid.data), + cloneArray(grid.data!), grid.transactions.getAggregatedChanges(true), grid.primaryKey, grid.dataCloneStrategy ); const deletedRows = grid.transactions.getTransactionLog().filter(t => t.type === TransactionType.DELETE).map(t => t.id); deletedRows.forEach(rowID => { - const tempData = grid.primaryKey ? data.map(rec => rec[grid.primaryKey]) : data; + const tempData = grid.primaryKey ? data!.map(rec => rec[grid.primaryKey]) : data!; const index = tempData.indexOf(rowID); if (index !== -1) { - data.splice(index, 1); + data!.splice(index, 1); } }); } else { @@ -88,18 +88,18 @@ export class GridBaseAPIService implements GridServiceType { public get_row_by_key(rowSelector: any): RowType { if (!this.grid) { - return null; + return null!; } const primaryKey = this.grid.primaryKey; if (primaryKey !== undefined && primaryKey !== null) { - return this.grid.dataRowList.find((row) => row.data[primaryKey] === rowSelector); + return this.grid.dataRowList.find((row: RowType) => row.data[primaryKey] === rowSelector); } else { - return this.grid.dataRowList.find((row) => row.data === rowSelector); + return this.grid.dataRowList.find((row: RowType) => row.data === rowSelector); } } public get_row_by_index(rowIndex: number): RowType { - return this.grid.rowList.find((row) => row.index === rowIndex); + return this.grid.rowList.find(row => row.index === rowIndex)!; } /** @@ -109,7 +109,7 @@ export class GridBaseAPIService implements GridServiceType { * @param dataCollection */ public get_rec_id_by_index(index: number, dataCollection?: any[]): any { - dataCollection = dataCollection || this.grid.data; + dataCollection = dataCollection || this.grid.data!; if (index >= 0 && index < dataCollection.length) { const rec = dataCollection[index]; return this.grid.primaryKey ? rec[this.grid.primaryKey] : rec; @@ -120,32 +120,34 @@ export class GridBaseAPIService implements GridServiceType { public get_cell_by_key(rowSelector: any, field: string): CellType { const row = this.get_row_by_key(rowSelector); if (row && row.cells) { - return row.cells.find((cell) => cell.column.field === field); + return row.cells.find((cell) => cell.column.field === field)!; } + return undefined!; } public get_cell_by_index(rowIndex: number, columnID: number | string): CellType { const row = this.get_row_by_index(rowIndex); const hasCells = row && row.cells; if (hasCells && typeof columnID === 'number') { - return row.cells.find((cell) => cell.column.index === columnID); + return row.cells!.find((cell) => cell.column.index === columnID)!; } if (hasCells && typeof columnID === 'string') { - return row.cells.find((cell) => cell.column.field === columnID); + return row.cells!.find((cell) => cell.column.field === columnID)!; } - + return undefined!; } public get_cell_by_visible_index(rowIndex: number, columnIndex: number): CellType { const row = this.get_row_by_index(rowIndex); if (row && row.cells) { - return row.cells.find((cell) => cell.visibleColumnIndex === columnIndex); + return row.cells.find((cell) => cell.visibleColumnIndex === columnIndex)!; } + return undefined!; } public update_cell(cell: IgxCell): IGridEditEventArgs { if (!cell) { - return; + return undefined!; } const args = cell.createCellEditEventArgs(true); if (!this.grid.crudService.row) { // should not recalculate summaries when there is row in edit mode @@ -162,7 +164,7 @@ export class GridBaseAPIService implements GridServiceType { const rowIndex = this.grid.pinnedRecords.indexOf(cell.rowData); if (rowIndex !== -1) { const previousRowId = cell.value; - const rowType = this.grid.getRowByIndex(cell.rowIndex); + const rowType = this.grid.getRowByIndex!(cell.rowIndex); this.unpin_row(previousRowId, rowType); this.pin_row(args.newValue, rowIndex, rowType); } @@ -308,7 +310,7 @@ export class GridBaseAPIService implements GridServiceType { } public get_filtered_data(): any[] { - return this.grid.filteredData; + return this.grid.filteredData!; } public addRowToData(rowData: any, _parentID?: any) { @@ -334,7 +336,7 @@ export class GridBaseAPIService implements GridServiceType { if (index !== -1) { if (grid.transactions.enabled) { const transaction: Transaction = { id: rowID, type: TransactionType.DELETE, newValue: null }; - grid.transactions.add(transaction, grid.data[index]); + grid.transactions.add(transaction, grid.data![index]); } else { (grid.data ?? (grid.data = [])).splice(index, 1); grid.summaryService.clearSummaryCache(); @@ -392,7 +394,7 @@ export class GridBaseAPIService implements GridServiceType { return record; } - public get_row_id(rowData) { + public get_row_id(rowData: any) { return this.grid.primaryKey ? rowData[this.grid.primaryKey] : rowData; } @@ -452,7 +454,7 @@ export class GridBaseAPIService implements GridServiceType { // this.crudService.endEdit(false); } - public get_rec_by_id(rowID) { + public get_rec_by_id(rowID: any) { return this.grid.primaryKey ? this.getRowData(rowID) : rowID; } @@ -463,11 +465,11 @@ export class GridBaseAPIService implements GridServiceType { * @param dataCollection */ public get_rec_index_by_id(pk: string | number, dataCollection?: any[]): number { - dataCollection = dataCollection || this.grid.data; + dataCollection = dataCollection || this.grid.data!; return this.grid.primaryKey ? dataCollection.findIndex(rec => rec[this.grid.primaryKey] === pk) : -1; } - public allow_expansion_state_change(rowID, expanded) { + public allow_expansion_state_change(rowID: any, expanded: boolean) { return this.grid.expansionStates.get(rowID) !== expanded; } @@ -545,7 +547,7 @@ export class GridBaseAPIService implements GridServiceType { }); } - public remove_grouping_expression(_fieldName) { + public remove_grouping_expression(_fieldName: string) { } public filterDataByExpressions(expressionsTree: IFilteringExpressionsTree): any[] { @@ -584,7 +586,7 @@ export class GridBaseAPIService implements GridServiceType { if (index === -1) { return; } - const eventArgs = this.get_pin_row_event_args(rowID, null , row, false); + const eventArgs = this.get_pin_row_event_args(rowID, undefined, row, false); grid.rowPinning.emit(eventArgs); if (eventArgs.cancel) { @@ -616,7 +618,7 @@ export class GridBaseAPIService implements GridServiceType { * @param rowCurrentValue Current value of the row as it is with applied previous transactions * @param rowNewValue New value of the row */ - protected updateData(grid, rowID, rowValueInDataSource: any, rowCurrentValue: any, rowNewValue: { [x: string]: any }) { + protected updateData(grid: GridType, rowID: any, rowValueInDataSource: any, rowCurrentValue: any, rowNewValue: { [x: string]: any }) { if (grid.transactions.enabled) { const transaction: Transaction = { id: rowID, @@ -632,7 +634,7 @@ export class GridBaseAPIService implements GridServiceType { protected update_row_in_array(value: any, _rowID: any, index: number) { const grid = this.grid; - grid.data[index] = value; + grid.data![index] = value; } protected getSortStrategyPerColumn(fieldName: string) { diff --git a/projects/igniteui-angular/grids/core/src/cell.component.html b/projects/igniteui-angular/grids/core/src/cell.component.html index 3b0269a40f6..7764bc012d8 100644 --- a/projects/igniteui-angular/grids/core/src/cell.component.html +++ b/projects/igniteui-angular/grids/core/src/cell.component.html @@ -179,14 +179,12 @@ [style.width.%]="100" mode="dropdown" [locale]="grid.locale" - [weekStart]="column.pipeArgs.weekStart" + [weekStart]="column.pipeArgs.weekStart!" [(value)]="editValue" [igxFocus]="true" [formControl]="formControl" - [inputFormat]=" - $safeNavigationMigration(column.editorOptions?.dateTimeFormat) - " - [displayFormat]="column.pipeArgs.format" + [inputFormat]="column.editorOptions?.dateTimeFormat!" + [displayFormat]="column.pipeArgs.format!" > @@ -197,10 +195,8 @@ [style.width.%]="100" mode="dropdown" [locale]="grid.locale" - [inputFormat]=" - $safeNavigationMigration(column.editorOptions?.dateTimeFormat) - " - [displayFormat]="column.pipeArgs.format" + [inputFormat]="column.editorOptions?.dateTimeFormat!" + [displayFormat]="column.pipeArgs.format!" [(value)]="editValue" [igxFocus]="true" [formControl]="formControl" @@ -216,11 +212,9 @@ [formControl]="formControl" igxInput [locale]="grid.locale" - [igxDateTimeEditor]=" - $safeNavigationMigration(column.editorOptions?.dateTimeFormat) - " + [igxDateTimeEditor]="column.editorOptions?.dateTimeFormat!" [defaultFormatType]="column.dataType" - [displayFormat]="column.pipeArgs.format" + [displayFormat]="column.pipeArgs.format!" [igxFocus]="true" /> @@ -299,7 +293,7 @@ @if (errors?.['minlength']) {
{{ - grid.resourceStrings.igx_grid_min_length_validation_error + grid.resourceStrings.igx_grid_min_length_validation_error! | igxStringReplace: '{0}' : errors.minlength.requiredLength }}
@@ -307,7 +301,7 @@ @if (errors?.['maxlength']) {
{{ - grid.resourceStrings.igx_grid_max_length_validation_error + grid.resourceStrings.igx_grid_max_length_validation_error! | igxStringReplace: '{0}' : errors.maxlength.requiredLength }}
@@ -315,7 +309,7 @@ @if (errors?.['min']) {
{{ - grid.resourceStrings.igx_grid_min_validation_error + grid.resourceStrings.igx_grid_min_validation_error! | igxStringReplace: '{0}' : errors.min.min }}
@@ -323,7 +317,7 @@ @if (errors?.['max']) {
{{ - grid.resourceStrings.igx_grid_max_validation_error + grid.resourceStrings.igx_grid_max_validation_error! | igxStringReplace: '{0}' : errors.max.max }}
diff --git a/projects/igniteui-angular/grids/core/src/cell.component.ts b/projects/igniteui-angular/grids/core/src/cell.component.ts index f53956550f4..a63b1f3706c 100644 --- a/projects/igniteui-angular/grids/core/src/cell.component.ts +++ b/projects/igniteui-angular/grids/core/src/cell.component.ts @@ -36,15 +36,15 @@ import { IgxNumberFormatterPipe, IgxDateFormatterPipe, IgxCurrencyFormatterPipe, - IgxPercentFormatterPipe + IgxPercentFormatterPipe, + ISelectionNode } from 'igniteui-angular/core'; import { IgxGridSelectionService } from './selection/selection.service'; import { GridSelectionMode } from './common/enums'; import { CellType, IgxCellTemplateContext, IGX_GRID_BASE, RowType } from './common/grid.interface'; import { IgxRowDirective } from './row.directive'; -import { ISearchInfo } from './common/events'; +import { IGridEditEventArgs, ISearchInfo } from './common/events'; import { IgxGridCell } from './grid-public-cell'; -import { ISelectionNode } from './common/types'; import { IgxIconComponent } from 'igniteui-angular/icon'; import { IgxGridCellImageAltPipe, IgxStringReplacePipe, IgxColumnFormatterPipe } from './common/pipes'; import { @@ -61,6 +61,7 @@ import { IgxInputDirective, IgxInputGroupComponent, IgxPrefixDirective, IgxSuffi import { IgxCheckboxComponent } from 'igniteui-angular/checkbox'; import { IgxDatePickerComponent } from 'igniteui-angular/date-picker'; import { IgxTimePickerComponent } from 'igniteui-angular/time-picker'; +import { IgxCell } from './common/crud.service'; /** * Providing reference to grid cell: @@ -131,21 +132,21 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * @internal */ @ViewChildren('error', { read: IgxTooltipDirective }) - public errorTooltip: QueryList; + public errorTooltip!: QueryList; /** * @hidden * @internal */ @ViewChild('errorIcon', { read: IgxIconComponent, static: false }) - public errorIcon: IgxIconComponent; + public errorIcon!: IgxIconComponent; /** * Gets the default error template. * @hidden @internal */ @ViewChild('defaultError', { read: TemplateRef, static: true }) - public defaultErrorTemplate: TemplateRef; + public defaultErrorTemplate!: TemplateRef; /** * Gets the column of the cell. @@ -156,27 +157,27 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * @memberof IgxGridCellComponent */ @Input() - public column: ColumnType; + public column!: ColumnType; /** * @hidden * @internal */ @Input() - public isPlaceholder: boolean; + public isPlaceholder!: boolean; /** Gets whether this cell is a merged cell. */ @Input() - public isMerged: boolean; + public isMerged!: boolean; /** * @hidden * @internal */ protected get formGroup(): FormGroup { - return this.grid.validation.getFormGroup(this.intRow.key); + return this.grid.validation.getFormGroup(this.intRow.key)!; } /** @@ -184,7 +185,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * @internal */ @Input() - public intRow: IgxRowDirective; + public intRow!: IgxRowDirective; /** * Gets the row of the cell. @@ -196,7 +197,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT */ @Input() public get row(): RowType { - return this.grid.createRow(this.intRow.index); + return this.grid.createRow!(this.intRow.index); } /** @@ -240,13 +241,13 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * @memberof IgxGridCellComponent */ @Input() - public cellTemplate: TemplateRef; + public cellTemplate!: TemplateRef; @Input() - public cellValidationErrorTemplate: TemplateRef; + public cellValidationErrorTemplate!: TemplateRef; @Input() - public pinnedIndicator: TemplateRef; + public pinnedIndicator!: TemplateRef; /** * Sets/gets the cell value. @@ -271,7 +272,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * @memberof IgxGridCellComponent */ @Input() - public formatter: (value: any, rowData?: any, columnData?: any) => any; + public formatter?: (value: any, rowData?: any, columnData?: any) => any; /** * Gets the cell template context object. @@ -693,7 +694,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT */ public set editValue(value) { if (this.grid.crudService.cellInEditMode) { - this.grid.crudService.cell.editValue = value; + (this.grid.crudService.cell as IgxCell).editValue = value; } } @@ -708,7 +709,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT */ public get editValue() { if (this.grid.crudService.cellInEditMode) { - return this.grid.crudService.cell.editValue; + return (this.grid.crudService.cell as IgxCell).editValue; } } @@ -745,19 +746,19 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT } @ViewChild('defaultCell', { read: TemplateRef, static: true }) - protected defaultCellTemplate: TemplateRef; + protected defaultCellTemplate!: TemplateRef; @ViewChild('emptyCell', { read: TemplateRef, static: true }) - protected emptyCellTemplate: TemplateRef; + protected emptyCellTemplate!: TemplateRef; @ViewChild('defaultPinnedIndicator', { read: TemplateRef, static: true }) - protected defaultPinnedIndicator: TemplateRef; + protected defaultPinnedIndicator!: TemplateRef; @ViewChild('inlineEditor', { read: TemplateRef, static: true }) - protected inlineEditorTemplate: TemplateRef; + protected inlineEditorTemplate!: TemplateRef; @ViewChild('addRowCell', { read: TemplateRef, static: true }) - protected addRowCellTemplate: TemplateRef; + protected addRowCellTemplate!: TemplateRef; @ViewChild(IgxTextHighlightDirective, { read: IgxTextHighlightDirective }) protected set highlight(value: IgxTextHighlightDirective) { @@ -778,14 +779,14 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT protected get selectionNode(): ISelectionNode { return { row: this.rowIndex, - column: this.column.columnLayoutChild ? this.column.parent.visibleIndex : this.visibleColumnIndex, + column: this.column.columnLayoutChild ? this.column.parent!.visibleIndex : this.visibleColumnIndex, layout: this.column.columnLayoutChild ? { rowStart: this.column.rowStart, colStart: this.column.colStart, rowEnd: this.column.rowEnd, colEnd: this.column.colEnd, columnVisibleIndex: this.visibleColumnIndex - } : null + } : null! }; } @@ -837,8 +838,8 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT return this.grid.i18nFormatter.getCurrencySymbol(this.currencyCode, this.grid.locale); } - protected _lastSearchInfo: ISearchInfo; - private _highlight: IgxTextHighlightDirective; + protected _lastSearchInfo!: ISearchInfo; + private _highlight!: IgxTextHighlightDirective; private _cellSelection: GridSelectionMode = GridSelectionMode.multiple; private _vIndex = -1; @@ -849,7 +850,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT @HostListener('dblclick', ['$event']) public onDoubleClick = (event: MouseEvent) => { if (this.editable && !this.editMode && !this.intRow.deleted && !this.grid.crudService.rowEditingBlocked) { - this.grid.crudService.enterEditMode(this, event as Event); + this.grid.crudService.enterEditMode(this, event); } this.grid.doubleClick.emit({ @@ -968,8 +969,8 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT private resizeAndRepositionOverlayById(overlayId: string, newSize: number) { const overlay = this.overlayService.getOverlayById(overlayId); if (!overlay) return; - overlay.initialSize.width = newSize; - overlay.elementRef.nativeElement.parentElement.style.width = newSize + 'px'; + overlay.initialSize!.width = newSize; + overlay.elementRef!.nativeElement.parentElement.style.width = newSize + 'px'; this.overlayService.reposition(overlayId); } @@ -986,7 +987,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT } if (this.editable && value) { if (this.grid.crudService.cellInEditMode) { - this.grid.gridAPI.update_cell(this.grid.crudService.cell); + this.grid.gridAPI.update_cell(this.grid.crudService.cell as IgxCell); this.grid.crudService.endCellEdit(); } this.grid.crudService.enterEditMode(this); @@ -1032,9 +1033,9 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT const scrollOffset = this.grid.verticalScrollContainer.scrollPosition + (event.y - this.grid.tbody.nativeElement.getBoundingClientRect().y); const targetRowIndex = this.grid.verticalScrollContainer.getIndexAtScroll(scrollOffset); if (targetRowIndex != this.rowIndex) { - const row = this.grid.rowList.toArray().find(x => x.index === targetRowIndex); - const actualTarget = row.cells.find(x => x.column === this.column); - actualTarget.pointerdown(event); + const row = this.grid.rowList.find((x) => x.index === targetRowIndex); + const actualTarget = row?.cells?.find((x) => x.column === this.column); + actualTarget?.pointerdown!(event); return; } } @@ -1117,7 +1118,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT if (this.selectionService.primaryButton) { const currentActive = this.selectionService.activeElement; - if (this.cellSelectionMode === GridSelectionMode.single && (event as any)?.ctrlKey && this.selected) { + if (this.cellSelectionMode === GridSelectionMode.single && (event as KeyboardEvent)?.ctrlKey && this.selected) { this.selectionService.activeElement = null; shouldEmitSelection = true; } else { @@ -1154,7 +1155,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT } this.selectionService.primaryButton = true; if (this.cellSelectionMode === GridSelectionMode.multiple && this.selectionService.activeElement) { - if (this.selectionService.isInMap(this.selectionService.activeElement) && (event as any)?.ctrlKey && !(event as any)?.shiftKey) { + if (this.selectionService.isInMap(this.selectionService.activeElement) && (event as KeyboardEvent)?.ctrlKey && !(event as KeyboardEvent)?.shiftKey) { this.selectionService.remove(this.selectionService.activeElement); shouldEmitSelection = true; } else { @@ -1216,7 +1217,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * @hidden * @internal */ - private _updateCRUDStatus(event?: Event) { + private _updateCRUDStatus(event?: FocusEvent | KeyboardEvent) { if (this.editMode) { return; } @@ -1228,7 +1229,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT if (this.editable && editMode && !this.intRow.deleted) { if (editableCell) { - editableArgs = this.grid.crudService.updateCell(false, event); + editableArgs = this.grid.crudService.updateCell(false, event) as IGridEditEventArgs; /* This check is related with the following issue #6517: * when edit cell that belongs to a column which is sorted and press tab, @@ -1237,7 +1238,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * Also we need to keep the notifyChanges below, because of the current * change detection cycle when we have editing with enabled transactions */ - if (this.grid.sortingExpressions.length && this.grid.sortingExpressions.indexOf(editableCell.column.field)) { + if (this.grid.sortingExpressions.length && this.grid.sortingExpressions.indexOf(editableCell.column.field as any) !== -1) { this.grid.cdr.detectChanges(); } @@ -1260,7 +1261,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT } } - private addPointerListeners(selection) { + private addPointerListeners(selection: GridSelectionMode) { if (selection !== GridSelectionMode.multiple) { return; } @@ -1269,7 +1270,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT this.nativeElement.addEventListener('focusout', this.focusout); } - private removePointerListeners(selection) { + private removePointerListeners(selection: GridSelectionMode) { if (selection !== GridSelectionMode.multiple) { return; } @@ -1279,7 +1280,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT } private getCellType(useRow?: boolean): CellType { - const rowID = useRow ? this.grid.createRow(this.intRow.index, this.intRow.data) : this.intRow.index; + const rowID = useRow ? this.grid.createRow!(this.intRow.index, this.intRow.data) : this.intRow.index; return new IgxGridCell(this.grid, rowID, this.column); } } diff --git a/projects/igniteui-angular/grids/core/src/column-actions/column-actions.component.ts b/projects/igniteui-angular/grids/core/src/column-actions/column-actions.component.ts index fc4f1e959e5..0cc63749cfc 100644 --- a/projects/igniteui-angular/grids/core/src/column-actions/column-actions.component.ts +++ b/projects/igniteui-angular/grids/core/src/column-actions/column-actions.component.ts @@ -35,7 +35,7 @@ export class IgxColumnActionsComponent implements DoCheck { * ``` */ @Input() - public grid: GridType; + public grid!: GridType; /** * Gets/sets the indentation of columns in the column list based on their hierarchy level. * @@ -89,7 +89,7 @@ export class IgxColumnActionsComponent implements DoCheck { * ``` */ @ViewChildren(IgxCheckboxComponent) - public columnItems: QueryList; + public columnItems!: QueryList; /** * Gets/sets the title of the column actions component. * @@ -129,7 +129,7 @@ export class IgxColumnActionsComponent implements DoCheck { /** * @hidden @internal */ - public actionsDirective: IgxColumnActionsBaseDirective; + public actionsDirective!: IgxColumnActionsBaseDirective; protected _differ: IterableDiffer | null = null; @@ -151,12 +151,12 @@ export class IgxColumnActionsComponent implements DoCheck { /** * @hidden @internal */ - private _uncheckAllText: string; + private _uncheckAllText!: string; /** * @hidden @internal */ - private _checkAllText: string; + private _checkAllText!: string; /** * @hidden @internal @@ -339,7 +339,7 @@ export class IgxColumnActionsComponent implements DoCheck { /** * @hidden @internal */ - public trackChanges = (index, col) => col.field + '_' + this.actionsDirective.actionEnabledColumnsFilter(col, index, []); + public trackChanges = (index: number, col: ColumnType) => col.field + '_' + this.actionsDirective.actionEnabledColumnsFilter(col, index, []); /** * @hidden @internal @@ -430,7 +430,7 @@ export class IgxFilterActionColumnsPipe implements PipeTransform { } let copy = collection.slice(0); if (filterCriteria && filterCriteria.length > 0) { - const filterFunc = (c) => { + const filterFunc = (c: ColumnType): boolean => { const filterText = c.header || c.field; if (!filterText) { return false; diff --git a/projects/igniteui-angular/grids/core/src/column-actions/column-hiding.directive.ts b/projects/igniteui-angular/grids/core/src/column-actions/column-hiding.directive.ts index 2492480ee71..f4f1b09ebb8 100644 --- a/projects/igniteui-angular/grids/core/src/column-actions/column-hiding.directive.ts +++ b/projects/igniteui-angular/grids/core/src/column-actions/column-hiding.directive.ts @@ -49,7 +49,7 @@ export class IgxColumnHidingDirective extends IgxColumnActionsBaseDirective { /** * @hidden @internal */ - public actionEnabledColumnsFilter = c => !c.disableHiding; + public actionEnabledColumnsFilter = (c: ColumnType) => !c.disableHiding; /** * @hidden @internal diff --git a/projects/igniteui-angular/grids/core/src/columns/column-group.component.ts b/projects/igniteui-angular/grids/core/src/columns/column-group.component.ts index 669c4ee995b..8501cbc3fae 100644 --- a/projects/igniteui-angular/grids/core/src/columns/column-group.component.ts +++ b/projects/igniteui-angular/grids/core/src/columns/column-group.component.ts @@ -198,7 +198,7 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After * @memberof IgxColumnGroupComponent */ @Input() - public override collapsibleIndicatorTemplate: TemplateRef; + public override collapsibleIndicatorTemplate!: TemplateRef; /** * @hidden @@ -387,7 +387,7 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After if (val.hidden) { return acc; } - return acc + parseFloat(val.calcWidth); + return acc + parseFloat(val.calcWidth?.toString() || val.defaultWidth); }, 0)}`; return width + 'px'; } diff --git a/projects/igniteui-angular/grids/core/src/columns/column-layout.component.ts b/projects/igniteui-angular/grids/core/src/columns/column-layout.component.ts index 86781e45269..4bc6ab6deaf 100644 --- a/projects/igniteui-angular/grids/core/src/columns/column-layout.component.ts +++ b/projects/igniteui-angular/grids/core/src/columns/column-layout.component.ts @@ -32,7 +32,7 @@ import { IgxColumnGroupComponent } from './column-group.component'; }) export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements AfterContentInit { /** @hidden @internal **/ - public childrenVisibleIndexes = []; + public childrenVisibleIndexes: { column: IgxColumnComponent; index: number }[] = []; /** * Gets the width of the column layout. * ```typescript @@ -56,15 +56,15 @@ export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements /** * @hidden */ - public override getCalcWidth(): any { + public override getCalcWidth(): string | number | null { let borderWidth = 0; if (this.headerGroup && this.headerGroup.hasLastPinnedChildColumn) { - const headerStyles = this.grid.document.defaultView.getComputedStyle(this.headerGroup.nativeElement.children[0]); + const headerStyles = this.grid.document.defaultView!.getComputedStyle(this.headerGroup.nativeElement.children[0]); borderWidth = parseFloat(headerStyles.borderRightWidth); } - return super.getCalcWidth() + borderWidth; + return super.getCalcWidth() as number + borderWidth; } /** @@ -121,7 +121,7 @@ export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements if (!this._hidden && !columns.find(c => c.field === this.field)) { this.grid.resetColumnCollections(); } - this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes()); + this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes!()); } } @@ -157,7 +157,7 @@ export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements : []; const orderedCols = columns .filter(x => !x.columnGroup && !x.hidden) - .sort((a, b) => a.rowStart - b.rowStart || columns.indexOf(a.parent) - columns.indexOf(b.parent) || a.colStart - b.colStart); + .sort((a, b) => a.rowStart - b.rowStart || columns.indexOf(a.parent!) - columns.indexOf(b.parent!) || a.colStart - b.colStart); this.children.forEach(child => { const rs = child.rowStart || 1; let vIndex = 0; diff --git a/projects/igniteui-angular/grids/core/src/columns/column.component.ts b/projects/igniteui-angular/grids/core/src/columns/column.component.ts index 668f7d32222..953ca1debca 100644 --- a/projects/igniteui-angular/grids/core/src/columns/column.component.ts +++ b/projects/igniteui-angular/grids/core/src/columns/column.component.ts @@ -8,9 +8,6 @@ import { CellType, GridType, IgxCellTemplateContext, IgxColumnTemplateContext, I import { IgxGridHeaderComponent } from '../headers/grid-header.component'; import { IgxGridFilteringCellComponent } from '../filtering/base/grid-filtering-cell.component'; import { IgxGridHeaderGroupComponent } from '../headers/grid-header-group.component'; -import { - IgxSummaryOperand, IgxNumberSummaryOperand, IgxDateSummaryOperand, IgxTimeSummaryOperand -} from '../summaries/grid-summary'; import { IgxCellTemplateDirective, IgxCellHeaderTemplateDirective, @@ -24,7 +21,34 @@ import { DropPosition } from '../moving/moving.service'; import { IColumnVisibilityChangingEventArgs, IPinColumnCancellableEventArgs, IPinColumnEventArgs } from '../common/events'; import { IgxGridCell } from '../grid-public-cell'; import { NG_VALIDATORS, Validator } from '@angular/forms'; -import { ColumnPinningPosition, ColumnType, DefaultSortingStrategy, ExpressionsTreeUtil, FilteringExpressionsTree, GridColumnDataType, IColumnEditorOptions, IColumnPipeArgs, IgxBooleanFilteringOperand, IgxDateFilteringOperand, IgxDateTimeFilteringOperand, IgxFilteringOperand, IgxNumberFilteringOperand, IgxStringFilteringOperand, IgxSummaryResult, IgxTimeFilteringOperand, isConstructor, ISortingStrategy, MRLColumnSizeInfo, MRLResizeColumnInfo, PlatformUtil, ɵSize } from 'igniteui-angular/core'; +import { + ColumnPinningPosition, + ColumnType, + DefaultSortingStrategy, + ExpressionsTreeUtil, + FilteringExpressionsTree, + GridColumnDataType, + IColumnEditorOptions, + IColumnPipeArgs, + IgxBooleanFilteringOperand, + IgxDateFilteringOperand, + IgxDateSummaryOperand, + IgxDateTimeFilteringOperand, + IgxFilteringOperand, + IgxNumberFilteringOperand, + IgxNumberSummaryOperand, + IgxStringFilteringOperand, + IgxSummaryOperand, + IgxSummaryResult, + IgxTimeFilteringOperand, + IgxTimeSummaryOperand, + isConstructor, + ISortingStrategy, + MRLColumnSizeInfo, + MRLResizeColumnInfo, + PlatformUtil, + ɵSize +} from 'igniteui-angular/core'; import type { IgxColumnLayoutComponent } from './column-layout.component'; const DEFAULT_DATE_FORMAT = 'mediumDate'; @@ -112,7 +136,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden @internal */ - public validators: Validator[] = this._validators; + public validators: Validator[] = this._validators!; /** * Sets/gets the `header` value. @@ -360,8 +384,8 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy if (this._hidden !== value) { this._hidden = value; this.hiddenChange.emit(this._hidden); - if (this.columnLayoutChild && this.parent.hidden !== value) { - this.parent.hidden = value; + if (this.columnLayoutChild && this.parent!.hidden !== value) { + this.parent!.hidden = value; return; } if (this.grid) { @@ -526,7 +550,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy } /** @hidden @internal **/ - public autoSize: number; + public autoSize!: number; /** * Sets/gets the maximum `width` of the column. @@ -707,7 +731,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy @notifyChanges() @WatchColumnChanges() @Input() - public formatter: (value: any, rowData?: any) => any; + public formatter?: (value: any, rowData?: any) => any; /* blazorAlternateType: SummaryValueFormatterEventHandler */ /* blazorOnlyScript */ @@ -740,7 +764,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy @notifyChanges() @WatchColumnChanges() @Input() - public summaryFormatter: (summary: IgxSummaryResult, summaryOperand: IgxSummaryOperand) => any; + public summaryFormatter?: (summary: IgxSummaryResult, summaryOperand: IgxSummaryOperand) => any; /** * Sets/gets whether the column filtering should be case sensitive. @@ -805,7 +829,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** @hidden */ @Input() - public collapsibleIndicatorTemplate: TemplateRef; + public collapsibleIndicatorTemplate?: TemplateRef; /** * Row index where the current field should end. @@ -819,7 +843,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @memberof IgxColumnComponent */ @Input() - public rowEnd: number; + public rowEnd!: number; /** * Column index where the current field should end. @@ -833,7 +857,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @memberof IgxColumnComponent */ @Input() - public colEnd: number; + public colEnd!: number; /** * Row index from which the field is starting. @@ -846,7 +870,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @memberof IgxColumnComponent */ @Input() - public rowStart: number; + public rowStart!: number; /** * Column index from which the field is starting. @@ -859,7 +883,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @memberof IgxColumnComponent */ @Input() - public colStart: number; + public colStart!: number; /** * Sets/gets custom properties provided in additional template context. @@ -904,47 +928,47 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @hidden */ @ContentChild(IgxFilterCellTemplateDirective, { read: IgxFilterCellTemplateDirective }) - public filterCellTemplateDirective: IgxFilterCellTemplateDirective; + public filterCellTemplateDirective?: IgxFilterCellTemplateDirective; /** * @hidden */ @ContentChild(IgxSummaryTemplateDirective, { read: IgxSummaryTemplateDirective }) - protected summaryTemplateDirective: IgxSummaryTemplateDirective; + protected summaryTemplateDirective?: IgxSummaryTemplateDirective; /** * @hidden * @see {@link bodyTemplate} */ @ContentChild(IgxCellTemplateDirective, { read: IgxCellTemplateDirective }) - protected cellTemplate: IgxCellTemplateDirective; + protected cellTemplate?: IgxCellTemplateDirective; /** * @hidden */ @ContentChild(IgxCellValidationErrorDirective, { read: IgxCellValidationErrorDirective }) - protected cellValidationErrorTemplate: IgxCellValidationErrorDirective; + protected cellValidationErrorTemplate?: IgxCellValidationErrorDirective; /** * @hidden */ @ContentChildren(IgxCellHeaderTemplateDirective, { read: IgxCellHeaderTemplateDirective, descendants: false }) - protected headTemplate: QueryList; + protected headTemplate?: QueryList; /** * @hidden */ @ContentChild(IgxCellEditorTemplateDirective, { read: IgxCellEditorTemplateDirective }) - protected editorTemplate: IgxCellEditorTemplateDirective; + protected editorTemplate?: IgxCellEditorTemplateDirective; /** * @hidden */ @ContentChild(IgxCollapsibleIndicatorTemplateDirective, { read: IgxCollapsibleIndicatorTemplateDirective, static: false }) - protected collapseIndicatorTemplate: IgxCollapsibleIndicatorTemplateDirective; + protected collapseIndicatorTemplate?: IgxCollapsibleIndicatorTemplateDirective; /** * @hidden */ - public get calcWidth(): any { + public get calcWidth(): string | number | null { return this.getCalcWidth(); } /** @hidden @internal **/ - public calcPixelWidth: number; + public calcPixelWidth!: number; /** * @hidden @@ -1052,7 +1076,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy @Input() public get pinningPosition(): ColumnPinningPosition { const userSet = this._pinningPosition !== null && this._pinningPosition !== undefined; - return userSet ? this._pinningPosition : this.grid.pinning.columns; + return userSet ? this._pinningPosition : this.grid.pinning.columns!; } /** @@ -1505,7 +1529,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy const cell = new IgxGridCell(this.grid as any, index, this); return cell; } - }).filter(cell => cell); + }).filter(cell => cell) as CellType[]; } @@ -1514,11 +1538,11 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy */ public get _cells(): CellType[] { return this.grid.rowList.filter((row) => row instanceof IgxRowDirective) - .map((row) => { + .map((row: any) => { if (row._cells) { - return row._cells.filter((cell) => cell.columnIndex === this.index); + return row._cells.filter((cell: any) => cell.columnIndex === this.index); } - }).reduce((a, b) => a.concat(b), []); + }).reduce((a: any, b: any) => a.concat(b), []); } /** @@ -1544,7 +1568,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy } if (this.columnLayoutChild) { // TODO: Refactor/redo/remove this - return (this.parent as IgxColumnLayoutComponent).childrenVisibleIndexes.find(x => x.column === this).index; + return (this.parent as IgxColumnLayoutComponent).childrenVisibleIndexes.find(x => x.column === this)!.index; } if (!this.pinned) { @@ -1597,7 +1621,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @memberof IgxColumnComponent */ public get columnLayoutChild(): boolean { - return this.parent && this.parent.columnLayout; + return this.parent != null && this.parent.columnLayout; } /** @@ -1757,17 +1781,17 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - public defaultWidth: string; + public defaultWidth!: string; /** * @hidden */ - public widthSetByUser: boolean; + public widthSetByUser!: boolean; /** * @hidden */ - public hasNestedPath: boolean; + public hasNestedPath!: boolean; /** * @hidden @@ -1817,7 +1841,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * * @deprecated in version 18.1.0. Use the `childColumns` property instead. */ - public children: QueryList; + public children!: QueryList; /** * @hidden */ @@ -1834,7 +1858,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy protected _applySelectableClass = false; protected _vIndex = NaN; - protected _pinningPosition = null; + protected _pinningPosition: ColumnPinningPosition = null!; /** * @hidden */ @@ -1842,27 +1866,27 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _bodyTemplate: TemplateRef; + protected _bodyTemplate!: TemplateRef; /** * @hidden */ - protected _errorTemplate: TemplateRef; + protected _errorTemplate!: TemplateRef; /** * @hidden */ - protected _headerTemplate: TemplateRef; + protected _headerTemplate!: TemplateRef; /** * @hidden */ - protected _summaryTemplate: TemplateRef; + protected _summaryTemplate!: TemplateRef; /** * @hidden */ - protected _inlineEditorTemplate: TemplateRef; + protected _inlineEditorTemplate!: TemplateRef; /** * @hidden */ - protected _filterCellTemplate: TemplateRef; + protected _filterCellTemplate!: TemplateRef; /** * @hidden */ @@ -1874,7 +1898,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _filters = null; + protected _filters: IgxFilteringOperand = null!; /** * @hidden */ @@ -1882,9 +1906,9 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _groupingComparer: (a: any, b: any, currRec?: any, groupRec?: any) => number; + protected _groupingComparer!: (a: any, b: any, currRec?: any, groupRec?: any) => number; - protected _mergingComparer: (prevRecord: any, record: any, field: string) => boolean; + protected _mergingComparer!: (prevRecord: any, record: any, field: string) => boolean; /** * @hidden */ @@ -1892,7 +1916,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _index: number; + protected _index!: number; /** * @hidden */ @@ -1900,7 +1924,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _width: string; + protected _width!: string; /** * @hidden */ @@ -1908,7 +1932,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _maxWidth; + protected _maxWidth!: string; /** * @hidden */ @@ -1916,7 +1940,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _editable: boolean; + protected _editable!: boolean; /** * @hidden */ @@ -1928,7 +1952,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - protected _visibleWhenCollapsed; + protected _visibleWhenCollapsed!: boolean; /** * @hidden */ @@ -1948,8 +1972,8 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return this.field !== undefined && this.grid !== undefined && this.field === this.grid.primaryKey; } - private _field: string; - private _calcWidth = null; + private _field!: string; + private _calcWidth: string | number | null = null; private _columnPipeArgs: IColumnPipeArgs = { digitsInfo: DEFAULT_DIGITS_INFO }; private _editorOptions: IColumnEditorOptions = { }; @@ -2081,7 +2105,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy columnSizes[col.colStart - 1] = { ref: col, width: col.width === 'fit-content' ? col.autoSize : - col.widthSetByUser || this.grid.columnWidthSetByUser ? parseFloat(col.calcWidth) : null, + col.widthSetByUser || this.grid.columnWidthSetByUser ? parseFloat(col.calcWidth?.toString() || col.defaultWidth) : null!, colSpan: col.gridColumnSpan, colEnd: col.colStart + col.gridColumnSpan, widthSetByUser: col.widthSetByUser @@ -2110,7 +2134,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy columnSizes[col.colStart - 1] = { ref: col, width: col.width === 'fit-content' ? col.autoSize : - col.widthSetByUser || this.grid.columnWidthSetByUser ? parseFloat(col.calcWidth) : null, + col.widthSetByUser || this.grid.columnWidthSetByUser ? parseFloat(col.calcWidth?.toString() || col.defaultWidth) : null!, colSpan: col.gridColumnSpan, colEnd: col.colStart + col.gridColumnSpan, widthSetByUser: col.widthSetByUser @@ -2124,7 +2148,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy columnSizes[i] = { ref: col, width: col.width === 'fit-content' ? col.autoSize : - col.widthSetByUser || this.grid.columnWidthSetByUser ? parseFloat(col.calcWidth) : null, + col.widthSetByUser || this.grid.columnWidthSetByUser ? parseFloat(col.calcWidth?.toString() || col.defaultWidth) : null!, colSpan: col.gridColumnSpan, colEnd: col.colStart + col.gridColumnSpan, widthSetByUser: col.widthSetByUser @@ -2202,7 +2226,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return [{ target: this, spanUsed: 1 }]; } - const columnSized = this.getInitialChildColumnSizes(this.parent.children as QueryList); + const columnSized = this.getInitialChildColumnSizes(this.parent!.children as QueryList); const targets: MRLResizeColumnInfo[] = []; const colEnd = this.colEnd ? this.colEnd : this.colStart + 1; @@ -2240,13 +2264,13 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy public pin(index?: number, pinningPosition?: ColumnPinningPosition): boolean { // TODO: Probably should the return type of the old functions // should be moved as a event parameter. - const grid = (this.grid as any); + const grid = this.grid; if (this._pinned) { return false; } if (this.parent && !this.parent.pinned) { - return this.topLevelParent.pin(index, pinningPosition); + return this.topLevelParent!.pin(index, pinningPosition); } const targetPinPosition = pinningPosition !== null && pinningPosition !== undefined ? pinningPosition : this.pinningPosition; const pinningVisibleCollection = targetPinPosition === ColumnPinningPosition.Start ? @@ -2254,7 +2278,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy const pinningCollection = targetPinPosition === ColumnPinningPosition.Start ? grid._pinnedStartColumns : grid._pinnedEndColumns; const hasIndex = index !== undefined && index !== null; - if (hasIndex && (index < 0 || index > pinningVisibleCollection.length)) { + if (hasIndex && (index! < 0 || index! > pinningVisibleCollection.length)) { return false; } @@ -2262,13 +2286,13 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return false; } - const rootPinnedCols = pinningCollection.filter((c) => c.level === 0); - index = hasIndex ? index : rootPinnedCols.length; - const args: IPinColumnCancellableEventArgs = { column: this, insertAtIndex: index, isPinned: false, cancel: false }; + const rootPinnedCols = pinningCollection.filter((c: any) => c.level === 0); + index = hasIndex ? index! : rootPinnedCols.length; + const args: IPinColumnCancellableEventArgs = { column: this, insertAtIndex: index!, isPinned: false, cancel: false }; this.grid.columnPin.emit(args); if (args.cancel) { - return; + return undefined!; } this.grid.crudService.endEdit(false); @@ -2293,10 +2317,10 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy if (this.level === 0) { rootPinnedCols.splice(args.insertAtIndex, 0, this); } - let allPinned = []; + let allPinned: any[] = []; // FIX: this is duplicated on every step in the hierarchy.... // re-create hierarchy - rootPinnedCols.forEach(group => { + rootPinnedCols.forEach((group: any) => { allPinned.push(group); allPinned = allPinned.concat(group.allChildren); }); @@ -2320,17 +2344,17 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy } if (this.columnGroup) { - this.allChildren.forEach(child => child.pin(null, targetPinPosition)); + this.allChildren.forEach(child => child.pin(null!, targetPinPosition)); grid.reinitPinStates(); } grid.resetCaches(); grid.notifyChanges(); if (this.columnLayoutChild) { - this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes()); + this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes!()); } this.grid.filteringService.refreshExpressions(); - const eventArgs: IPinColumnEventArgs = { column: this, insertAtIndex: index, isPinned: true }; + const eventArgs: IPinColumnEventArgs = { column: this, insertAtIndex: index!, isPinned: true }; this.grid.columnPinned.emit(eventArgs); return true; } @@ -2354,27 +2378,27 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy } if (this.parent && this.parent.pinned) { - return this.topLevelParent.unpin(index); + return this.topLevelParent!.unpin(index); } const hasIndex = index !== undefined && index !== null; - if (hasIndex && (index < 0 || index > grid._unpinnedColumns.length)) { + if (hasIndex && (index! < 0 || index! > grid._unpinnedColumns.length)) { return false; } // estimate the exact index at which column will be inserted // takes into account initial unpinned index of the column if (!hasIndex) { - const indices = grid._unpinnedColumns.map(col => col.index); + const indices = grid._unpinnedColumns.map((col: any) => col.index); indices.push(this.index); - indices.sort((a, b) => a - b); + indices.sort((a: any, b: any) => a - b); index = indices.indexOf(this.index); } - const args: IPinColumnCancellableEventArgs = { column: this, insertAtIndex: index, isPinned: true, cancel: false }; + const args: IPinColumnCancellableEventArgs = { column: this, insertAtIndex: index!, isPinned: true, cancel: false }; this.grid.columnPin.emit(args); if (args.cancel) { - return; + return undefined!; } this.grid.crudService.endEdit(false); @@ -2412,11 +2436,11 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy grid.notifyChanges(); if (this.columnLayoutChild) { - this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes()); + this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes!()); } this.grid.filteringService.refreshExpressions(); - this.grid.columnPinned.emit({ column: this, insertAtIndex: index, isPinned: false }); + this.grid.columnPinned.emit({ column: this, insertAtIndex: index!, isPinned: false }); return true; } @@ -2579,7 +2603,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy /** * @hidden */ - public getCalcWidth(): any { + public getCalcWidth(): string | number | null { if (this._calcWidth && !isNaN(this.calcPixelWidth)) { return this._calcWidth; } @@ -2612,11 +2636,11 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy const largest = new Map(); if (this._cells.length > 0) { - const cellsContentWidths = []; - this._cells.forEach((cell) => cellsContentWidths.push(cell.calculateSizeToFit(range))); + const cellsContentWidths: number[] = []; + this._cells.forEach((cell) => cellsContentWidths.push(cell.calculateSizeToFit!(range))); const index = cellsContentWidths.indexOf(Math.max(...cellsContentWidths)); - const cellStyle = this.grid.document.defaultView.getComputedStyle(this._cells[index].nativeElement); + const cellStyle = this.grid.document.defaultView!.getComputedStyle(this._cells[index].nativeElement!); const cellPadding = parseFloat(cellStyle.paddingLeft) + parseFloat(cellStyle.paddingRight) + parseFloat(cellStyle.borderLeftWidth) + parseFloat(cellStyle.borderRightWidth); @@ -2629,7 +2653,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy } const largestCell = Math.max(...Array.from(largest.keys())); - const width = Math.ceil(largestCell + largest.get(largestCell)); + const width = Math.ceil(largestCell + largest.get(largestCell)!); if (Number.isNaN(width)) { return this.width; @@ -2676,7 +2700,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @hidden * @internal */ - public getConstrainedSizePx(newSize) { + public getConstrainedSizePx(newSize: number) { if (this.maxWidth && newSize >= this.maxWidthPx) { this.widthConstrained = true; return this.maxWidthPx; @@ -2719,7 +2743,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy const currentCalcWidth = parseFloat(possibleColumnWidth); this._calcWidth = this.getConstrainedSizePx(currentCalcWidth); } - this.calcPixelWidth = parseFloat(this._calcWidth); + this.calcPixelWidth = parseFloat(this._calcWidth.toString()); } /** diff --git a/projects/igniteui-angular/grids/core/src/common/crud.service.ts b/projects/igniteui-angular/grids/core/src/common/crud.service.ts index dd7cc855143..d14edfd780f 100644 --- a/projects/igniteui-angular/grids/core/src/common/crud.service.ts +++ b/projects/igniteui-angular/grids/core/src/common/crud.service.ts @@ -4,7 +4,7 @@ import { IGridEditDoneEventArgs, IGridEditEventArgs, IRowDataCancelableEventArgs import { GridType, RowType } from './grid.interface'; import { Subject } from 'rxjs'; import { FormGroup } from '@angular/forms'; -import { copyDescriptors, DateTimeUtil, isDate, isEqual } from 'igniteui-angular/core'; +import { ColumnType, copyDescriptors, DateTimeUtil, isDate, isEqual } from 'igniteui-angular/core'; export class IgxEditRow { public transactionState: any; @@ -122,9 +122,9 @@ export class IgxCell { public pendingValue: any; constructor( - public id, + public id: any, public rowIndex: number, - public column, + public column: ColumnType, public value: any, public _editValue: any, public rowData: any, @@ -144,8 +144,8 @@ export class IgxCell { if (this.grid.validationTrigger === 'change') { // in case trigger is change, mark as touched. - formControl.setValue(value); - formControl.markAsTouched(); + formControl!.setValue(value); + formControl!.markAsTouched(); } else { this.pendingValue = value; } @@ -205,12 +205,12 @@ export class IgxCell { } export class IgxCellCrudState { - public grid: GridType; + public grid!: GridType; public cell: IgxCell | null = null; public row: IgxEditRow | null = null; public isInCompositionMode = false; - public createCell(cell): IgxCell { + public createCell(cell: any): IgxCell { return this.cell = new IgxCell(cell.cellID || cell.id, cell.row.index, cell.column, cell.value, cell.value, cell.row.data, cell.grid); } @@ -219,13 +219,13 @@ export class IgxCellCrudState { return this.row = new IgxEditRow(cell.id.rowID, cell.rowIndex, cell.rowData, cell.grid); } - public sameRow(rowID): boolean { - return this.row && this.row.id === rowID; + public sameRow(rowID: any): boolean { + return !!(this.row && this.row.id === rowID); } public sameCell(cell: IgxCell): boolean { - return (this.cell.id.rowID === cell.id.rowID && - this.cell.id.columnID === cell.id.columnID); + return (this.cell!.id.rowID === cell.id.rowID && + this.cell!.id.columnID === cell.id.columnID); } public get cellInEditMode(): boolean { @@ -233,7 +233,7 @@ export class IgxCellCrudState { } public beginCellEdit(event?: Event) { - const args = this.cell.createCellEditEventArgs(false, event); + const args = this.cell!.createCellEditEventArgs(false, event); this.grid.cellEditEnter.emit(args); if (args.cancel) { @@ -243,14 +243,14 @@ export class IgxCellCrudState { } public cellEdit(event?: Event) { - const args = this.cell.createCellEditEventArgs(true, event); + const args = this.cell!.createCellEditEventArgs(true, event); this.grid.cellEdit.emit(args); return args; } - public updateCell(exit: boolean, event?: Event): IGridEditEventArgs { + public updateCell(exit: boolean, event?: Event): IGridEditEventArgs | IGridEditDoneEventArgs | undefined { if (!this.cell) { - return; + return undefined!; } // this is needed when we are not using ngModel to update the editValue // so that the change event of the inlineEditorTemplate is hit before @@ -268,15 +268,15 @@ export class IgxCellCrudState { const formControl = this.grid.validation.getFormControl(this.cell.id.rowID, this.cell.column.field); if (this.grid.validationTrigger === 'blur' && this.cell.pendingValue !== undefined) { // in case trigger is blur, update value if there's a pending one and mark as touched. - formControl.setValue(this.cell.pendingValue); - formControl.markAsTouched(); + formControl!.setValue(this.cell.pendingValue); + formControl!.markAsTouched(); } if (this.grid.validationTrigger === 'blur') { this.grid.tbody.nativeElement.focus({ preventScroll: true }); } - let doneArgs; + let doneArgs: IGridEditDoneEventArgs; if (this.cell.column.dataType === 'date' && !isDate(this.cell.value)) { if (isEqual(DateTimeUtil.parseIsoDate(this.cell.value), this.cell.editValue)) { doneArgs = this.exitCellEdit(event); @@ -305,12 +305,12 @@ export class IgxCellCrudState { return { ...args, ...doneArgs }; } - public cellEditDone(event, addRow: boolean): IGridEditDoneEventArgs { - const newValue = this.cell.castToNumber(this.cell.editValue); - const doneArgs = this.cell.createCellEditDoneEventArgs(newValue, event); + public cellEditDone(event: Event | undefined, addRow: boolean): IGridEditDoneEventArgs { + const newValue = this.cell!.castToNumber(this.cell!.editValue); + const doneArgs = this.cell!.createCellEditDoneEventArgs(newValue, event); this.grid.cellEditDone.emit(doneArgs); if (addRow) { - doneArgs.rowData = this.row.data; + doneArgs.rowData = this.row!.data; } return doneArgs; } @@ -318,7 +318,7 @@ export class IgxCellCrudState { /** Exit cell edit mode */ public exitCellEdit(event?: Event): IGridEditDoneEventArgs { if (!this.cell) { - return; + return undefined!; } const newValue = this.cell.castToNumber(this.cell.editValue); const args = this.cell?.createCellEditDoneEventArgs(newValue, event); @@ -357,9 +357,9 @@ export class IgxRowCrudState extends IgxCellCrudState { return this.grid.primaryKey; } - public get rowInEditMode(): RowType { + public get rowInEditMode(): RowType | undefined { const editRowState = this.row; - return editRowState !== null ? this.grid.rowList.find(e => e.key === editRowState.id) : null; + return editRowState !== null ? this.grid.rowList.find(e => e.key === editRowState.id) : undefined; } public get rowEditing(): boolean { @@ -382,11 +382,11 @@ export class IgxRowCrudState extends IgxCellCrudState { public beginRowEdit(event?: Event) { if (!this.row || this.row.isAddRow) { if (!this.row) { - this.createRow(this.cell); + this.createRow(this.cell!); } if (!this._rowEditingStarted) { - const rowArgs = this.row.createRowEditEventArgs(false, event); + const rowArgs = this.row!.createRowEditEventArgs(false, event); this.grid.rowEditEnter.emit(rowArgs); if (rowArgs.cancel) { @@ -397,14 +397,14 @@ export class IgxRowCrudState extends IgxCellCrudState { this._rowEditingStarted = true; } - this.row.transactionState = this.grid.transactions.getAggregatedValue(this.row.id, true); + this.row!.transactionState = this.grid.transactions.getAggregatedValue(this.row!.id, true); this.grid.transactions.startPending(); - this.grid.openRowOverlay(this.row.id); + this.grid.openRowOverlay(this.row!.id); } } public rowEdit(event: Event): IGridEditEventArgs { - const args = this.row.createRowEditEventArgs(true, event); + const args = this.row!.createRowEditEventArgs(true, event); this.grid.rowEdit.emit(args); return args; } @@ -420,7 +420,7 @@ export class IgxRowCrudState extends IgxCellCrudState { if (commit) { this.row.newData = this.grid.transactions.getAggregatedValue(this.row.id, true); this.updateRowEditData(this.row, this.row.newData); - args = this.rowEdit(event); + args = this.rowEdit(event!); if (args.cancel) { return args; } @@ -435,24 +435,24 @@ export class IgxRowCrudState extends IgxCellCrudState { * @hidden @internal */ public endRowTransaction(commit: boolean, event?: Event): IGridEditEventArgs | IRowDataCancelableEventArgs { - this.row.newData = this.grid.transactions.getAggregatedValue(this.row.id, true); - let rowEditArgs = this.row.createRowEditEventArgs(true, event); + this.row!.newData = this.grid.transactions.getAggregatedValue(this.row!.id, true); + let rowEditArgs = this.row!.createRowEditEventArgs(true, event); let nonCancelableArgs; if (!commit) { this.grid.transactions.endPending(false); const isAddRow = this.row && this.row.isAddRow; - const id = this.row ? this.row.id : this.cell.id.rowID; + const id = this.row ? this.row.id : this.cell!.id.rowID; if (isAddRow) { this.grid.validation.clear(id); } else { this.grid.validation.update(id, rowEditArgs.oldValue); } - } else if (!this.row.isAddRow) { - rowEditArgs = this.grid.gridAPI.update_row(this.row, this.row.newData, event); - nonCancelableArgs = this.rowEditDone(rowEditArgs.oldValue, event); + } else if (!this.row!.isAddRow) { + rowEditArgs = this.grid.gridAPI.update_row(this.row!, this.row!.newData, event); + nonCancelableArgs = this.rowEditDone(rowEditArgs.oldValue, event!); } else { - const rowAddArgs = this.row.createRowDataEventArgs(event); + const rowAddArgs = this.row!.createRowDataEventArgs(event); this.grid.rowAdd.emit(rowAddArgs); if (rowAddArgs.cancel) { return rowAddArgs; @@ -461,10 +461,10 @@ export class IgxRowCrudState extends IgxCellCrudState { this.grid.transactions.endPending(false); const parentId = this.getParentRowId(); - this.grid.gridAPI.addRowToData(this.row.newData ?? this.row.data, parentId); + this.grid.gridAPI.addRowToData(this.row!.newData ?? this.row!.data, parentId); this.grid.triggerPipes(); - nonCancelableArgs = this.rowEditDone(null, event); + nonCancelableArgs = this.rowEditDone(null, event!); } nonCancelableArgs = this.exitRowEdit(rowEditArgs.oldValue, event); @@ -472,16 +472,16 @@ export class IgxRowCrudState extends IgxCellCrudState { return { ...nonCancelableArgs, ...rowEditArgs }; } - public rowEditDone(cachedRowData, event: Event) { - const doneArgs = this.row.createRowEditDoneEventArgs(cachedRowData, event); + public rowEditDone(cachedRowData: any, event: Event) { + const doneArgs = this.row!.createRowEditDoneEventArgs(cachedRowData, event); this.grid.rowEditDone.emit(doneArgs); return doneArgs; } /** Exit row edit mode */ - public exitRowEdit(cachedRowData, event?: Event): IGridEditDoneEventArgs { - const nonCancelableArgs = this.row.createRowEditDoneEventArgs(cachedRowData, event); + public exitRowEdit(cachedRowData: any, event?: Event): IGridEditDoneEventArgs { + const nonCancelableArgs = this.row!.createRowEditDoneEventArgs(cachedRowData, event); this.grid.rowEditExit.emit(nonCancelableArgs); this.grid.closeRowEditingOverlay(); @@ -509,7 +509,7 @@ export class IgxRowCrudState extends IgxCellCrudState { const grid = this.grid; const rowInEditMode = grid.gridAPI.crudService.row; - row.newData = value ?? rowInEditMode.transactionState; + row.newData = value ?? rowInEditMode?.transactionState; if (rowInEditMode && row.id === rowInEditMode.id) { @@ -528,7 +528,7 @@ export class IgxRowCrudState extends IgxCellCrudState { } export class IgxRowAddCrudState extends IgxRowCrudState { - public addRowParent: IgxAddRowParent = null; + public addRowParent: IgxAddRowParent = null!; /** * @hidden @internal @@ -555,7 +555,7 @@ export class IgxRowAddCrudState extends IgxRowCrudState { rowID: rowId, rowKey: rowId, index: isInPinnedArea ? pinIndex : unpinIndex, - asChild: newRowAsChild, + asChild: newRowAsChild!, isPinned: isInPinnedArea }; } @@ -571,7 +571,7 @@ export class IgxRowAddCrudState extends IgxRowCrudState { const pinnedIndex = this.grid.pinnedRecords.findIndex(x => x[this.primaryKey] === rowData[this.primaryKey]); // A check whether the row is in the current view const viewIndex = pinnedIndex !== -1 ? pinnedIndex : this._findRecordIndexInView(rowData); - const dataIndex = this.grid.filteredSortedData.findIndex(data => data[this.primaryKey] === rowData[this.primaryKey]); + const dataIndex = this.grid.filteredSortedData!.findIndex(data => data[this.primaryKey] === rowData[this.primaryKey]); const isInView = viewIndex !== -1 && !this.grid.navigation.shouldPerformVerticalScroll(viewIndex, 0); const showIndex = isInView ? -1 : dataIndex; this.grid.showSnackbarFor(showIndex); @@ -605,7 +605,7 @@ export class IgxRowAddCrudState extends IgxRowCrudState { * @hidden @internal */ public endAddRow() { - this.addRowParent = null; + this.addRowParent = null!; this.grid.triggerPipes(); } @@ -614,7 +614,7 @@ export class IgxRowAddCrudState extends IgxRowCrudState { * @internal * TODO: consider changing modifier */ - public _findRecordIndexInView(rec) { + public _findRecordIndexInView(rec: any) { return this.grid.dataView.findIndex(data => data[this.primaryKey] === rec[this.primaryKey]); } @@ -631,7 +631,7 @@ export class IgxRowAddCrudState extends IgxRowCrudState { @Injectable() export class IgxGridCRUDService extends IgxRowAddCrudState { - public enterEditMode(cell, event?: Event) { + public enterEditMode(cell: any, event?: FocusEvent | MouseEvent | KeyboardEvent) { if (this.isInCompositionMode) { return; } @@ -682,7 +682,7 @@ export class IgxGridCRUDService extends IgxRowAddCrudState { * @param asChild Specifies if the new row should be added as a child to a tree row. * @param event Base event that triggered the add row mode. */ - public enterAddRowMode(parentRow: RowType, asChild?: boolean, event?: Event) { + public enterAddRowMode(parentRow: RowType | null, asChild?: boolean, event?: MouseEvent | KeyboardEvent) { if (!this.rowEditing && (this.grid.primaryKey === undefined || this.grid.primaryKey === null)) { console.warn('The grid must use row edit mode to perform row adding! Please set rowEditable to true.'); return; @@ -699,26 +699,26 @@ export class IgxGridCRUDService extends IgxRowAddCrudState { this.grid.transactions.startPending(); if (this.addRowParent.isPinned) { // If parent is pinned, add the new row to pinned records - (this.grid as any)._pinnedRecordIDs.splice(this.row.index, 0, this.row.id); + (this.grid as any)._pinnedRecordIDs.splice(this.row!.index, 0, this.row!.id); } this.grid.triggerPipes(); this.grid.notifyChanges(true); - this.grid.navigateTo(this.row.index, -1); + this.grid.navigateTo(this.row!.index, -1); // when selecting the dummy row we need to adjust for top pinned rows const indexAdjust = this.grid.isRowPinningToTop ? (!this.addRowParent.isPinned ? this.grid.pinnedRows.length : 0) : (!this.addRowParent.isPinned ? 0 : this.grid.unpinnedRecords.length); // TODO: Type this without shoving a bunch of internal properties in the row type - const dummyRow = this.grid.gridAPI.get_row_by_index(this.row.index + indexAdjust) as any; + const dummyRow = this.grid.gridAPI.get_row_by_index(this.row!.index + indexAdjust) as any; dummyRow.triggerAddAnimation(); dummyRow.cdr.detectChanges(); dummyRow.addAnimationEnd.pipe(first()).subscribe(() => { - const cell = dummyRow.cells.find(c => c.editable); + const cell = dummyRow.cells.find((c: any) => c.editable); if (cell) { - this.grid.gridAPI.update_cell(this.cell); + this.grid.gridAPI.update_cell(this.cell!); this.enterEditMode(cell, event); cell.activate(); } @@ -737,16 +737,16 @@ export class IgxGridCRUDService extends IgxRowAddCrudState { * @param commit */ // TODO: Implement the same representation of the method without evt emission. - public endEdit(commit = true, event?: Event): boolean { + public endEdit(commit = true, event?: FocusEvent | MouseEvent | KeyboardEvent): boolean { if (!this.row && !this.cell) { - return; + return undefined!; } - let args; + let args: IGridEditEventArgs; if (commit) { - args = this.updateCell(true, event); + args = this.updateCell(true, event) as IGridEditEventArgs; if (args && args.cancel) { - return args.cancel; + return true; } } else { // needede because this.cell is null after exitCellEdit diff --git a/projects/igniteui-angular/grids/core/src/common/grid.interface.ts b/projects/igniteui-angular/grids/core/src/common/grid.interface.ts index 68741808763..38f191adbb2 100644 --- a/projects/igniteui-angular/grids/core/src/common/grid.interface.ts +++ b/projects/igniteui-angular/grids/core/src/common/grid.interface.ts @@ -11,16 +11,20 @@ import { IGridContextMenuEventArgs } from '../common/events'; import { ChangeDetectorRef, ElementRef, EventEmitter, InjectionToken, QueryList, TemplateRef, ViewContainerRef } from '@angular/core'; -import { IgxCell, IgxEditRow } from './crud.service'; -import { GridSelectionRange } from './types'; +import { IgxCell, IgxEditRow, IgxGridCRUDService } from './crud.service'; import { DropPosition, IgxColumnMovingService } from '../moving/moving.service'; import { Observable, Subject } from 'rxjs'; -import { ColumnPinningPosition, ColumnType, FilteringExpressionsTree, FilteringLogic, GridColumnDataType, GridSummaryCalculationMode, GridTypeBase, IDataCloneStrategy, IFilteringExpressionsTree, IFilteringStrategy, IGridGroupingStrategy, IGridMergeStrategy, IGridResourceStrings, IGridSortingStrategy, IGroupByExpandState, IGroupByRecord, IGroupingExpression, IgxSummaryResult, IPathSegment, ISortingExpression, ISortingOptions, ITreeGridRecord, OverlaySettings, ɵSize, SortingDirection, State, Transaction, TransactionService, type IgxOverlayOutletDirective } from 'igniteui-angular/core'; +import { ColumnPinningPosition, ColumnType, FilteringExpressionsTree, FilteringLogic, GridColumnDataType, GridSelectionRange, GridSummaryCalculationMode, GridTypeBase, IDataCloneStrategy, IFilteringExpressionsTree, IFilteringStrategy, IGridGroupingStrategy, IGridMergeStrategy, IGridResourceStrings, IGridSortingStrategy, IGroupByExpandState, IGroupByRecord, IGroupingExpression, IgxSummaryResult, IPathSegment, ISortingExpression, ISortingOptions, ITreeGridRecord, OverlaySettings, ɵSize, SortingDirection, State, Transaction, TransactionService, type IgxOverlayOutletDirective } from 'igniteui-angular/core'; import { FormControl, FormGroup, ValidationErrors } from '@angular/forms'; import type { IForOfState, IgxGridForOfDirective, IgxToggleDirective } from 'igniteui-angular/directives'; import type { IgxPaginatorComponent } from 'igniteui-angular/paginator'; -import { IgxGridValidationService } from '../grid-validation.service'; +import { IgxSummaryRowComponent } from '../summaries/summary-row.component'; import { IDimensionsChange, IPivotConfiguration, IPivotDimension, IPivotKeys, IPivotUISettings, IPivotValue, IValuesChange, PivotDimensionType } from '../pivot-grid.interface'; +import { IgxGroupByAreaDirective } from '../grouping/group-by-area.directive'; +import { IgxGridSelectionService } from '../selection/selection.service'; +import { IgxGridValidationService } from '../grid-validation.service'; +import { IgxSummaryCellComponent } from '../summaries/summary-cell.component'; +import { IgxFilteringService } from '../filtering/grid-filtering.service'; export const IGX_GRID_BASE = /*@__PURE__*/new InjectionToken('IgxGridBaseToken'); export const IGX_GRID_SERVICE_BASE = /*@__PURE__*/new InjectionToken('IgxGridServiceBaseToken'); @@ -91,7 +95,7 @@ export interface CellType { * A method to activate the cell. * It takes a focus or keyboard event as an argument */ - activate?(event: FocusEvent | KeyboardEvent): void; + activate?(event?: FocusEvent | KeyboardEvent | MouseEvent): void; /* blazorSuppress */ /** * Optional @@ -106,6 +110,13 @@ export interface CellType { * It takes a mouse event as an argument */ onClick?(event: MouseEvent): void; + /* blazorSuppress */ + /** + * Optional + * A method to handle click events on the cell + * It takes a mouse event as an argument + */ + pointerdown?(event: PointerEvent): void; } /** @@ -124,8 +135,8 @@ export interface HeaderType { selectable: boolean; /** Indicates whether the cell is currently selected */ selected: boolean; - /** Indicates whether the column header is a title cell. */ - title: boolean; + /** Represents the header title */ + title: string; /** Represents the sorting direction of the column (ascending, descending or none). */ sortDirection: SortingDirection; } @@ -152,6 +163,7 @@ export interface RowType { * A map of column field names to the summary results for the row. */ summaries?: Map; + summaryCells?: QueryList | IgxSummaryCellComponent[]; groupRow?: IGroupByRecord; key?: any; readonly validation?: IGridValidationState; @@ -331,7 +343,7 @@ export interface GridServiceType { /** The reference to the parent `GridType` that contains the service. */ grid: GridType; /** Represents the type of the CRUD service (Create, Read, Update, Delete) operations on the grid data. */ - crudService: any; + crudService: IgxGridCRUDService; /** A service responsible for handling column moving within the grid. It contains a reference to the column, its icon, and indicator for cancellation. */ cms: IgxColumnMovingService; @@ -368,7 +380,7 @@ export interface GridServiceType { * Represents a method declaration for retrieving the cell object associated with a specific row and column using their indexes. * It counts only the indexes of the visible columns and rows */ - get_cell_by_visible_index(rowIndex: number, columnIndex: number); + get_cell_by_visible_index(rowIndex: number, columnIndex: number): CellType; /** Represents a method declaration that sets the expansion state of a group row (used for tree grids) * It takes the value for the expansion as a parameter (expanded or collapsed) */ @@ -484,7 +496,7 @@ export interface GridType extends IGridDataBindable { /** @hidden @internal */ theadRow: any; /** @hidden @internal */ - groupArea: any; + groupArea: IgxGroupByAreaDirective; /** @hidden @internal */ filterCellList: any[]; /** @hidden @internal */ @@ -501,7 +513,7 @@ export interface GridType extends IGridDataBindable { /** @hidden @internal */ paginatorList?: QueryList; /** @hidden @internal */ - crudService: any; + crudService: IgxGridCRUDService; /** @hidden @internal */ summaryService: any; /** @hidden @internal */ @@ -514,10 +526,10 @@ export interface GridType extends IGridDataBindable { // TYPE /** @hidden @internal */ /** The service handling selection in the grid. Selecting, deselecting elements */ - selectionService: any; + selectionService: IgxGridSelectionService; navigation: any; /** @hidden @internal */ - filteringService: any; + filteringService: IgxFilteringService; /** * @deprecated in version 21.2.0. Overlays now use the HTML Popover API and no longer move to the document * body by default, so using outlet is also no longer needed - just define the overlay in the intended @@ -659,7 +671,7 @@ export interface GridType extends IGridDataBindable { tbody: any; verticalScrollContainer: any; dataRowList: any; - rowList: any; + rowList: QueryList; /** An unmodifiable list, containing all the columns of the grid. */ columnList: QueryList; columns: ColumnType[]; @@ -680,7 +692,7 @@ export interface GridType extends IGridDataBindable { headerGroups: any[]; /** @hidden @internal */ headerGroupsList: any[]; - summariesRowList: any; + summariesRowList: QueryList; /** @hidden @internal */ headerContainer: any; /** Indicates whether cells are selectable in the grid */ @@ -745,7 +757,7 @@ export interface GridType extends IGridDataBindable { /* blazorCSSuppress */ /** Property, that provides a callback for loading unique column values on demand. * If this property is provided, the unique values it generates will be used by the Excel Style Filtering */ - uniqueColumnValuesStrategy: (column: ColumnType, tree: FilteringExpressionsTree, done: (values: any[]) => void) => void; + uniqueColumnValuesStrategy?: (column: ColumnType, tree: FilteringExpressionsTree, done: (values: any[]) => void) => void; /* blazorSuppress */ /** Property, that gets the header cell inner width for auto-sizing. */ getHeaderCellWidth: (element: HTMLElement) => ISizeInfo; @@ -921,7 +933,7 @@ export interface GridType extends IGridDataBindable { openRowOverlay(id: any): void; openAdvancedFilteringDialog(overlaySettings?: OverlaySettings): void; showSnackbarFor(index: number): void; - getColumnByName(name: string): any; + getColumnByName(name: string): ColumnType; getColumnByVisibleIndex(index: number): ColumnType; getHeaderGroupWidth(column: ColumnType): string; getRowByKey?(key: any): RowType; @@ -945,7 +957,7 @@ export interface GridType extends IGridDataBindable { isGhostRecord(rec: any): boolean; isTreeRow?(rec: any): boolean; isChildGridRecord?(rec: any): boolean; - getChildGrids?(inDepth?: boolean): any[]; + getChildGrids?(inDepth?: boolean): GridType[]; isHierarchicalRecord?(record: any): boolean; columnToVisibleIndex(key: string | number): number; moveColumn(column: ColumnType, target: ColumnType, pos: DropPosition): void; @@ -973,7 +985,7 @@ export interface GridType extends IGridDataBindable { notifyChanges(repaint?: boolean): void; resetColumnCollections(): void; triggerPipes(): void; - repositionRowEditingOverlay(row: RowType): void; + repositionRowEditingOverlay(row?: RowType): void; closeRowEditingOverlay(): void; reflow(): void; @@ -1069,17 +1081,17 @@ export interface PivotGridType extends GridType { * Represents a method declaration for moving dimension from its currently collection to the specified target collection * by type (Row, Column or Filter) at specified index or at the collection's end */ - moveDimension(dimension: IPivotDimension, targetCollectionType: PivotDimensionType, index?: number); - getDimensionsByType(dimension: PivotDimensionType); + moveDimension(dimension: IPivotDimension, targetCollectionType: PivotDimensionType, index?: number): void; + getDimensionsByType(dimension: PivotDimensionType): IPivotDimension[] | null; /** Toggles the dimension's enabled state on or off. The dimension remains in its current collection */ - toggleDimension(dimension: IPivotDimension); + toggleDimension(dimension: IPivotDimension): void; /** Sort the dimension and its children in the provided direction (ascending, descending or none). */ - sortDimension(dimension: IPivotDimension, sortDirection: SortingDirection); + sortDimension(dimension: IPivotDimension, sortDirection: SortingDirection): void; /** Toggles the value's enabled state on or off. The value remains in its current collection. */ - toggleValue(value: IPivotValue); + toggleValue(value: IPivotValue): void; /** Move value from its currently at specified index or at the end. * If the parameter is not set, it will add it to the end of the collection. */ - moveValue(value: IPivotValue, index?: number); + moveValue(value: IPivotValue, index?: number): void; rowDimensionWidth(dim: IPivotDimension): string; rowDimensionWidthToPixels(dim: IPivotDimension): number; /** Emits an event when the dimensions in the pivot grid change. */ @@ -1138,7 +1150,7 @@ export interface IgxGridEmptyTemplateContext { export interface IgxGridRowEditTemplateContext { $implicit: undefined, rowChangesCount: number, - endEdit: (commit: boolean, event?: Event) => void + endEdit: (commit: boolean, event?: FocusEvent | MouseEvent | KeyboardEvent) => void } export interface IgxGridRowEditTextTemplateContext { @@ -1148,7 +1160,7 @@ export interface IgxGridRowEditTextTemplateContext { export interface IgxGridRowEditActionsTemplateContext { /* blazorCSSuppress */ /* blazorAlternateType: RowEditActionsImplicit */ - $implicit: (commit: boolean, event?: Event) => void + $implicit: (commit: boolean, event?: FocusEvent | MouseEvent | KeyboardEvent) => void } export interface IgxGridHeaderTemplateContext { diff --git a/projects/igniteui-angular/grids/core/src/common/pipes.ts b/projects/igniteui-angular/grids/core/src/common/pipes.ts index 219e1f1a032..096007c67b3 100644 --- a/projects/igniteui-angular/grids/core/src/common/pipes.ts +++ b/projects/igniteui-angular/grids/core/src/common/pipes.ts @@ -1,9 +1,8 @@ import { Pipe, PipeTransform, inject } from '@angular/core'; import { GridType, IGX_GRID_BASE, RowType } from './grid.interface'; import { IgxAddRow } from './crud.service'; -import { IgxSummaryOperand } from '../summaries/grid-summary'; import { IgxGridRow } from '../grid-public-row'; -import { cloneArray, columnFieldPath, DataUtil, IgxSummaryResult, resolveNestedPath } from 'igniteui-angular/core'; +import { cloneArray, columnFieldPath, DataUtil, IgxSummaryOperand, IgxSummaryResult, resolveNestedPath } from 'igniteui-angular/core'; interface GridStyleCSSProperty { [prop: string]: any; @@ -52,7 +51,7 @@ export class IgxGridCellStylesPipe implements PipeTransform { public transform(styles: GridStyleCSSProperty, _: any, data: any, field: string, index: number, __: number): GridStyleCSSProperty { - const css = {}; + const css: GridStyleCSSProperty = {}; if (!styles) { return css; } @@ -166,7 +165,7 @@ export class IgxGridRowStylesPipe implements PipeTransform { public transform(styles: GridStyleCSSProperty, rowData: any, index: number, __: number): GridStyleCSSProperty { - const css = {}; + const css: GridStyleCSSProperty = {}; if (!styles) { return css; } @@ -278,7 +277,7 @@ export class IgxGridPaginatorOptionsPipe implements PipeTransform { standalone: true }) export class IgxHasVisibleColumnsPipe implements PipeTransform { - public transform(values: any[], hasVisibleColumns) { + public transform(values: any[], hasVisibleColumns: boolean) { if (!(values && values.length)) { return values; } @@ -289,9 +288,9 @@ export class IgxHasVisibleColumnsPipe implements PipeTransform { /** @hidden @internal */ function buildDataView(): MethodDecorator { - return function (_target: unknown, _propertyKey: string, descriptor: PropertyDescriptor) { + return function (_target: unknown, _propertyKey: string | symbol, descriptor: PropertyDescriptor) { const original = descriptor.value; - descriptor.value = function (...args: unknown[]) { + descriptor.value = function (this: any, ...args: unknown[]) { const result = original.apply(this, args); this.grid.buildDataView(); return result; diff --git a/projects/igniteui-angular/grids/core/src/common/pivot-strategy.ts b/projects/igniteui-angular/grids/core/src/common/pivot-strategy.ts index 05691d48989..9405f434f44 100644 --- a/projects/igniteui-angular/grids/core/src/common/pivot-strategy.ts +++ b/projects/igniteui-angular/grids/core/src/common/pivot-strategy.ts @@ -9,7 +9,7 @@ import { PivotUtil } from '../pivot-util'; /* csSuppress */ export class NoopPivotDimensionsStrategy implements IPivotDimensionStrategy { - private static _instance: NoopPivotDimensionsStrategy = null; + private static _instance: NoopPivotDimensionsStrategy = null!; public static instance(): NoopPivotDimensionsStrategy { return this._instance || (this._instance = new NoopPivotDimensionsStrategy()); @@ -22,7 +22,7 @@ export class NoopPivotDimensionsStrategy implements IPivotDimensionStrategy { export class PivotRowDimensionsStrategy implements IPivotDimensionStrategy { - private static _instance: PivotRowDimensionsStrategy = null; + private static _instance: PivotRowDimensionsStrategy = null!; public static instance() { return this._instance || (this._instance = new PivotRowDimensionsStrategy()); @@ -36,7 +36,7 @@ export class PivotRowDimensionsStrategy implements IPivotDimensionStrategy { pivotKeys: IPivotKeys = DEFAULT_PIVOT_KEYS ): IPivotGridRecord[] { let hierarchies; - let data: IPivotGridRecord[]; + let data!: IPivotGridRecord[]; const prevRowDims = []; const currRows = cloneArray(rows, true); PivotUtil.assignLevels(currRows); @@ -64,7 +64,7 @@ export class PivotRowDimensionsStrategy implements IPivotDimensionStrategy { } export class PivotColumnDimensionsStrategy implements IPivotDimensionStrategy { - private static _instance: PivotRowDimensionsStrategy = null; + private static _instance: PivotRowDimensionsStrategy = null!; public static instance() { return this._instance || (this._instance = new PivotColumnDimensionsStrategy()); @@ -81,7 +81,7 @@ export class PivotColumnDimensionsStrategy implements IPivotDimensionStrategy { return res; } - private processHierarchy(collection: IPivotGridRecord[], columns: IPivotDimension[], values, pivotKeys, cloneStrategy) { + private processHierarchy(collection: IPivotGridRecord[], columns: IPivotDimension[], values: IPivotValue[], pivotKeys: IPivotKeys, cloneStrategy: IDataCloneStrategy) { const result: IPivotGridRecord[] = []; collection.forEach(rec => { // apply aggregations based on the created groups and generate column fields based on the hierarchies @@ -91,7 +91,7 @@ export class PivotColumnDimensionsStrategy implements IPivotDimensionStrategy { return result; } - private groupColumns(rec: IPivotGridRecord, columns, values, pivotKeys, cloneStrategy) { + private groupColumns(rec: IPivotGridRecord, columns: IPivotDimension[], values: IPivotValue[], pivotKeys: IPivotKeys, cloneStrategy: IDataCloneStrategy) { const children = rec.children; if (children && children.size > 0) { children.forEach((childRecs) => { @@ -105,14 +105,14 @@ export class PivotColumnDimensionsStrategy implements IPivotDimensionStrategy { this.applyAggregates(rec, columns, values, pivotKeys, cloneStrategy); } - private applyAggregates(rec, columns, values, pivotKeys, cloneStrategy) { - const leafRecords = this.getLeafs(rec.records, pivotKeys); + private applyAggregates(rec: IPivotGridRecord, columns: IPivotDimension[], values: IPivotValue[], pivotKeys: IPivotKeys, cloneStrategy: IDataCloneStrategy) { + const leafRecords = this.getLeafs(rec.records!, pivotKeys); const hierarchy = PivotUtil.getFieldsHierarchy(leafRecords, columns, PivotDimensionType.Column, pivotKeys, cloneStrategy); PivotUtil.applyAggregations(rec, hierarchy, values, pivotKeys) } - private getLeafs(records, pivotKeys) { - let leafs = []; + private getLeafs(records: any[], pivotKeys: IPivotKeys): any[] { + let leafs: any[] = []; for (const rec of records) { if (rec[pivotKeys.records]) { leafs = leafs.concat(this.getLeafs(rec[pivotKeys.records], pivotKeys)); @@ -138,18 +138,21 @@ export class DimensionValuesFilteringStrategy extends FilteringStrategy { protected override getFieldValue(rec: any, fieldName: string, _isDate = false, _isTime = false, grid?: PivotGridType): any { - const allDimensions = grid.allDimensions; + const allDimensions = grid!.allDimensions; const enabledDimensions = allDimensions.filter(x => x && x.enabled); - const dim :IPivotDimension = PivotUtil.flatten(enabledDimensions).find(x => x.memberName === fieldName); + const dim = PivotUtil.flatten(enabledDimensions).find(x => x.memberName === fieldName); + if (!dim) { + return undefined; + } const value = dim.childLevel ? this._getDimensionValueHierarchy(dim, rec).map(x => `[` + x +`]`).join('.') : PivotUtil.extractValueFromDimension(dim, rec); return value; } public override getFilterItems(column: ColumnType, tree: IFilteringExpressionsTree): Promise { - const grid = (column.grid as any); - const enabledDimensions = grid.allDimensions.filter(x => x && x.enabled); + const grid = column.grid; + const enabledDimensions = grid.allDimensions.filter((x: any) => x && x.enabled); const data = column.grid.gridAPI.filterDataByExpressions(tree); - const dim = enabledDimensions.find(x => x.memberName === column.field); + const dim = enabledDimensions.find((x: any) => x.memberName === column.field); const allValuesHierarchy = PivotUtil.getFieldsHierarchy( data, [dim], @@ -167,7 +170,7 @@ export class DimensionValuesFilteringStrategy extends FilteringStrategy { hierarchy.forEach((value) => { const val = value.value; const path = val.split(pivotKeys.columnDimensionSeparator); - const hierarchicalValue = path.length > 1 ? path.map(x => `[` + x +`]`).join('.') : val; + const hierarchicalValue = path.length > 1 ? path.map((x: string) => `[` + x +`]`).join('.') : val; const text = path[path.length -1]; items.push({ value: hierarchicalValue, diff --git a/projects/igniteui-angular/grids/core/src/common/public_api.ts b/projects/igniteui-angular/grids/core/src/common/public_api.ts index e7ce68a19e5..7bc0b6343d7 100644 --- a/projects/igniteui-angular/grids/core/src/common/public_api.ts +++ b/projects/igniteui-angular/grids/core/src/common/public_api.ts @@ -1,7 +1,6 @@ export * from './enums'; export * from './events'; export * from './grid.interface'; -export * from './types'; export * from './random'; export * from './pipes'; export * from './crud.service'; diff --git a/projects/igniteui-angular/grids/core/src/common/types.ts b/projects/igniteui-angular/grids/core/src/common/types.ts deleted file mode 100644 index 8d566c654ac..00000000000 --- a/projects/igniteui-angular/grids/core/src/common/types.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { InjectionToken } from '@angular/core'; -import { State, Transaction, TransactionService } from 'igniteui-angular/core'; - -/* tsPlainInterface */ -/* marshalByValue */ -/** - * Represents a range selection between certain rows and columns of the grid. - * Range selection can be made either through drag selection or through keyboard selection. - */ -export interface GridSelectionRange { - /** The index of the starting row of the selection range. */ - rowStart: number; - /** The index of the ending row of the selection range. */ - rowEnd: number; - /* blazorAlternateType: double */ - /** - * The identifier or index of the starting column of the selection range. - * It can be either a string representing the column's field name or a numeric index. - */ - columnStart: string | number; - /* blazorAlternateType: double */ - /** - * The identifier or index of the ending column of the selection range. - * It can be either a string representing the column's field name or a numeric index. - */ - columnEnd: string | number; -} - -/** - * Represents a single selected cell or node in a grid. - */ -export interface ISelectionNode { - /** - * The index of the selected row. - */ - row: number; - /** - * The index of the selected column. - */ - column: number; - /** - * (Optional) - * Additional layout information for multi-row selection nodes. - */ - layout?: IMultiRowLayoutNode; - /** - * (Optional) - * Indicates if the selected node is a summary row. - * This property is true if the selected row is a summary row; otherwise, it is false. - */ - isSummaryRow?: boolean; -} - -export interface IMultiRowLayoutNode { - rowStart: number; - colStart: number; - rowEnd: number; - colEnd: number; - columnVisibleIndex: number; -} - -/** - * Represents the state of the keyboard when selecting. - */ -export interface ISelectionKeyboardState { - /** The selected node in the grid, if any. Can be null if no node is selected. */ - node: null | ISelectionNode; - /** Indicates whether the Shift key is currently pressed during the selection. */ - shift: boolean; - /** The range of the selected cells in the grid. Can be null when resetting the selection. */ - range: GridSelectionRange; - /** Indicates whether the selection is currently active (being performed). `False` when resetting the selection. */ - active: boolean; -} - -/** - * Represents the state of the grid selection using pointer interactions (mouse). - * Extends ISelectionKeyboardState to include pointer-specific properties. - */ -export interface ISelectionPointerState extends ISelectionKeyboardState { - /** Indicates whether the Ctrl key is currently pressed during the selection. */ - ctrl: boolean; - /** Indicates whether the primary pointer button is pressed during the selection (clicked). */ - primaryButton: boolean; -} - -/** - * Represents the state of the columns in the grid. - */ -export interface IColumnSelectionState { - /** Represents the field name of the selected column, if any. Can be null if no column is selected. */ - field: null | string; - /** An array of strings representing the ranges of selected columns in the grid. */ - range: string[]; -} - -/** - * Represents the overall state of grid selection, combining both keyboard and pointer interaction states. - * It can be either an ISelectionKeyboardState or an ISelectionPointerState. - */ -export type SelectionState = ISelectionKeyboardState | ISelectionPointerState; - -/** - * Injection token for accessing the grid transaction object. - * This allows injecting the grid transaction object into components or services. - */ -export const IgxGridTransaction = /*@__PURE__*/new InjectionToken>('IgxGridTransaction'); diff --git a/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.html b/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.html index b5270a643b6..cf28e93a681 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.html +++ b/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.html @@ -11,7 +11,7 @@ [resourceStrings]="queryBuilderResourceStrings" [expressionTree]="this.grid.advancedFilteringExpressionsTree"> diff --git a/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.ts b/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.ts index 03149f94305..455949c93ab 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/advanced-filtering/advanced-filtering-dialog.component.ts @@ -3,7 +3,7 @@ import { Subject } from 'rxjs'; import { IActiveNode } from '../../grid-navigation.service'; import { GridType } from '../../common/grid.interface'; import { NgClass } from '@angular/common'; -import { IDragStartEventArgs, IgxButtonDirective, IgxDragDirective, IgxDragHandleDirective } from 'igniteui-angular/directives'; +import { IDragMoveEventArgs, IDragStartEventArgs, IgxButtonDirective, IgxDragDirective, IgxDragHandleDirective } from 'igniteui-angular/directives'; import { IgxQueryBuilderComponent, IgxQueryBuilderHeaderComponent } from 'igniteui-angular/query-builder'; import { EntityType, @@ -43,7 +43,7 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { * @hidden @internal */ @ViewChild('queryBuilder', { read: IgxQueryBuilderComponent }) - public queryBuilder: IgxQueryBuilderComponent; + public queryBuilder!: IgxQueryBuilderComponent; /** * @hidden @internal @@ -64,12 +64,12 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { /** * @hidden @internal */ - public queryBuilderResourceStrings: IQueryBuilderResourceStrings; + public queryBuilderResourceStrings!: IQueryBuilderResourceStrings; private destroy$ = new Subject(); - private _overlayComponentId: string; - private _overlayService: IgxOverlayService; - private _grid: GridType; + private _overlayComponentId!: string; + private _overlayService!: IgxOverlayService; + private _grid!: GridType; constructor() { onResourceChangeHandle(this.destroy$, () => { @@ -126,7 +126,7 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { /** * @hidden @internal */ - public onDragMove(e) { + public onDragMove(e: IDragMoveEventArgs) { const deltaX = e.nextPageX - e.pageX; const deltaY = e.nextPageY - e.pageY; e.cancel = true; @@ -158,9 +158,9 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { /** * @hidden @internal */ - public onClearButtonClick(event?: Event) { + public onClearButtonClick(event?: MouseEvent) { this.grid.crudService.endEdit(false, event); - this.queryBuilder.expressionTree = this.grid.advancedFilteringExpressionsTree = null; + this.queryBuilder.expressionTree = this.grid.advancedFilteringExpressionsTree = null!; } /** @@ -179,7 +179,7 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { /** * @hidden @internal */ - public applyChanges(event?: Event) { + public applyChanges(event?: MouseEvent) { this.grid.crudService.endEdit(false, event); this.queryBuilder.exitOperandEdit(); this.grid.advancedFilteringExpressionsTree = this.queryBuilder.expressionTree as IFilteringExpressionsTree; @@ -195,7 +195,7 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { /** * @hidden @internal */ - public onApplyButtonClick(event?: Event) { + public onApplyButtonClick(event?: MouseEvent) { this.applyChanges(event); this.closeDialog(); } @@ -211,7 +211,7 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { } else { const entities: EntityType[] = [ { - name: null, + name: null!, fields: this.filterableFields.map(f => ({ field: f.field, dataType: f.dataType, @@ -243,10 +243,10 @@ export class IgxAdvancedFilteringDialogComponent implements OnDestroy { const affix = prop.replace(reg, ''); const filterProp = `igx_query_builder_filter_${affix}`; const generalProp = `igx_query_builder_${affix}` - if (queryBuilderRS[filterProp] !== undefined) { - queryBuilderRS[filterProp] = gridRS[prop]; - } else if (queryBuilderRS[generalProp] !== undefined) { - queryBuilderRS[generalProp] = gridRS[prop]; + if ((queryBuilderRS as any)[filterProp] !== undefined) { + (queryBuilderRS as any)[filterProp] = (gridRS as any)[prop]; + } else if ((queryBuilderRS as any)[generalProp] !== undefined) { + (queryBuilderRS as any)[generalProp] = (gridRS as any)[prop]; } }); diff --git a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.html b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.html index 3fb62f3b3b1..9f7883b581c 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.html +++ b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.html @@ -25,7 +25,7 @@ (remove)="onChipRemoved($event, item)"> + [name]="item.expression.condition!.iconName"> {{filteringService.getChipLabel(item.expression)}} diff --git a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.ts b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.ts index 07c5311afb5..a62a3c57536 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-cell.component.ts @@ -30,28 +30,28 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC public filteringService = inject(IgxFilteringService); @Input() - public column: ColumnType; + public column!: ColumnType; @ViewChild('emptyFilter', { read: TemplateRef, static: true }) - protected emptyFilter: TemplateRef; + protected emptyFilter!: TemplateRef; @ViewChild('defaultFilter', { read: TemplateRef, static: true }) - protected defaultFilter: TemplateRef; + protected defaultFilter!: TemplateRef; @ViewChild('complexFilter', { read: TemplateRef, static: true }) - protected complexFilter: TemplateRef; + protected complexFilter!: TemplateRef; @ViewChild('chipsArea', { read: IgxChipsAreaComponent }) - protected chipsArea: IgxChipsAreaComponent; + protected chipsArea!: IgxChipsAreaComponent; @ViewChild('moreIcon', { read: ElementRef }) - protected moreIcon: ElementRef; + protected moreIcon!: ElementRef; @ViewChild('ghostChip', { read: IgxChipComponent }) - protected ghostChip: IgxChipComponent; + protected ghostChip!: IgxChipComponent; @ViewChild('complexChip', { read: IgxChipComponent }) - protected complexChip: IgxChipComponent; + protected complexChip!: IgxChipComponent; @HostBinding('class') @@ -61,7 +61,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC 'igx-grid__filtering-cell'; } - public expressionsList: ExpressionUI[]; + public expressionsList!: ExpressionUI[]; public moreFiltersCount = 0; @HostBinding('class.igx-grid-th--pinned') @@ -118,7 +118,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC public get template(): TemplateRef { if (!this.column.filterable) { - return null; + return null!; } if (this.column.filterCellTemplate) { return this.column.filterCellTemplate; @@ -159,7 +159,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC this.filteringService.grid.navigation.performHorizontalScrollToCell(this.column.visibleIndex); this.filteringService.filteredColumn = this.column; this.filteringService.isFilterRowVisible = true; - this.filteringService.selectedExpression = expression; + this.filteringService.selectedExpression = expression!; } /** @@ -206,7 +206,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC } private isMoreIconHidden(): boolean { - return this.filteringService.columnToMoreIconHidden.get(this.column.field); + return this.filteringService.columnToMoreIconHidden.get(this.column.field)!; } private updateVisibleFilters() { diff --git a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.html b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.html index cc5c8ef6274..758413dcd82 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.html +++ b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.html @@ -91,12 +91,12 @@ #picker [(value)]="value" [locale]="filteringService.grid.locale" - (click)="expression.condition.isUnary ? null : picker.open()" + (click)="expression.condition!.isUnary ? null : picker.open()" type="box" - [displayFormat]="column.pipeArgs.format" - [formatter]="column.formatter" + [displayFormat]="column.pipeArgs.format!" + [formatter]="column.formatter!" [placeholder]="placeholder" - [weekStart]="column.pipeArgs.weekStart" + [weekStart]="column.pipeArgs.weekStart!" (keydown)="onInputKeyDown($event)" (focusout)="onInputGroupFocusout()" (closed)="focusEditElement()" @@ -110,7 +110,7 @@ > @if (value) { @@ -143,19 +143,17 @@ @if (value) { @@ -217,10 +215,8 @@ tabindex="0" [placeholder]="placeholder" [locale]="filteringService.grid.locale" - [displayFormat]="column.pipeArgs.format" - [igxDateTimeEditor]=" - $safeNavigationMigration(column.editorOptions?.dateTimeFormat) - " + [displayFormat]="column.pipeArgs.format!" + [igxDateTimeEditor]="column.editorOptions.dateTimeFormat!" defaultFormatType="dateTime" [value]="value" (valueChange)="onInput($event)" @@ -294,7 +290,7 @@ {{ filteringService.getChipLabel(item.expression) }} diff --git a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.ts b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.ts index 26477ee2e97..e3ba994642c 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/base/grid-filtering-row.component.ts @@ -111,7 +111,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe this.expression.searchVal = null; this._value = null; const index = this.expressionsList.findIndex(item => item.expression === this.expression); - if (index === 0 && this.expressionsList.length === 1 && !this.expression.condition.isUnary) { + if (index === 0 && this.expressionsList.length === 1 && !this.expression.condition!.isUnary) { this.filteringService.clearFilter(this.column.field); } } else { @@ -141,54 +141,54 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe public defaultCSSClass = true; @ViewChild('defaultFilterUI', { read: TemplateRef, static: true }) - protected defaultFilterUI: TemplateRef; + protected defaultFilterUI!: TemplateRef; @ViewChild('defaultDateUI', { read: TemplateRef, static: true }) - protected defaultDateUI: TemplateRef; + protected defaultDateUI!: TemplateRef; @ViewChild('defaultTimeUI', { read: TemplateRef, static: true }) - protected defaultTimeUI: TemplateRef; + protected defaultTimeUI!: TemplateRef; @ViewChild('defaultDateTimeUI', { read: TemplateRef, static: true }) - protected defaultDateTimeUI: TemplateRef; + protected defaultDateTimeUI!: TemplateRef; @ViewChild('input', { read: ElementRef }) - protected input: ElementRef; + protected input!: ElementRef; @ViewChild('inputGroupConditions', { read: IgxDropDownComponent, static: true }) - protected dropDownConditions: IgxDropDownComponent; + protected dropDownConditions!: IgxDropDownComponent; @ViewChild('chipsArea', { read: IgxChipsAreaComponent, static: true }) - protected chipsArea: IgxChipsAreaComponent; + protected chipsArea!: IgxChipsAreaComponent; @ViewChildren('operators', { read: IgxDropDownComponent }) - protected dropDownOperators: QueryList; + protected dropDownOperators!: QueryList; @ViewChild('inputGroup', { read: ElementRef }) - protected inputGroup: ElementRef; + protected inputGroup!: ElementRef; @ViewChild('picker') - protected picker: IgxDatePickerComponent | IgxTimePickerComponent; + protected picker!: IgxDatePickerComponent | IgxTimePickerComponent; @ViewChild('inputGroupPrefix', { read: ElementRef }) - protected inputGroupPrefix: ElementRef; + protected inputGroupPrefix!: ElementRef; @ViewChild('container', { static: true }) - protected container: ElementRef; + protected container!: ElementRef; @ViewChild('operand') - protected operand: ElementRef; + protected operand!: ElementRef; @ViewChild('closeButton', { static: true }) - protected closeButton: ElementRef; + protected closeButton!: ElementRef; public get nativeElement() { return this.ref.nativeElement; } - public showArrows: boolean; - public expression: IFilteringExpression; - public expressionsList: Array; + public showArrows!: boolean; + public expression!: IFilteringExpression; + public expressionsList!: Array; private _positionSettings = { horizontalStartPoint: HorizontalAlignment.Left, @@ -209,9 +209,9 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe positionStrategy: new ConnectedPositioningStrategy(this._positionSettings) }; - private chipsAreaWidth: number; + private chipsAreaWidth!: number; private chipAreaScrollOffset = 0; - private _column = null; + private _column: ColumnType = null!; private isKeyPressed = false; private isComposing = false; private _cancelChipClick = false; @@ -220,7 +220,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe /** switch to icon buttons when width is below 432px */ private readonly NARROW_WIDTH_THRESHOLD = 432; - private inputSubject: Subject = new Subject(); + private inputSubject: Subject = new Subject(); private $destroyer = new Subject(); private readonly DEBOUNCE_TIME = inject(INPUT_DEBOUNCE_TIME); @@ -290,7 +290,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe } public get conditions(): any { - return this.column.filters.conditionList(); + return this.column.filters!.conditionList(); } public get isUnaryCondition(): boolean { @@ -305,11 +305,11 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe if (this.expression.condition && this.expression.condition.isUnary) { return this.filteringService.getChipLabel(this.expression); } else if (this.column.dataType === GridColumnDataType.Date) { - return this.filteringService.grid.resourceStrings.igx_grid_filter_row_date_placeholder; + return this.filteringService.grid.resourceStrings.igx_grid_filter_row_date_placeholder!; } else if (this.column.dataType === GridColumnDataType.Boolean) { - return this.filteringService.grid.resourceStrings.igx_grid_filter_row_boolean_placeholder; + return this.filteringService.grid.resourceStrings.igx_grid_filter_row_boolean_placeholder!; } else { - return this.filteringService.grid.resourceStrings.igx_grid_filter_row_placeholder; + return this.filteringService.grid.resourceStrings.igx_grid_filter_row_placeholder!; } } @@ -362,22 +362,25 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe /** * Event handler for input on the input. */ - public onInput(eventArgs) { + public onInput(eventArgs: InputEvent | Date) { this.inputSubject.next(eventArgs); } - private handleInputChange(eventArgs) { + private handleInputChange(eventArgs: InputEvent | Date) { if (!eventArgs) { return; } - // The 'iskeyPressed' flag is needed for a case in IE, because the input event is fired on focus and for some reason, - // when you have a japanese character as a placeholder, on init the value here is empty string . - const target = eventArgs.target; + // DateTime editors are bound to igxDateTimeEditor's (valueChange), which emits the + // parsed Date rather than a DOM InputEvent. if (this.column.dataType === GridColumnDataType.DateTime) { this.value = eventArgs; return; } + + // The 'iskeyPressed' flag is needed for a case in IE, because the input event is fired on focus and for some reason, + // when you have a japanese character as a placeholder, on init the value here is empty string . + const target = (eventArgs as InputEvent).target as HTMLInputElement; if (this.platform.isEdge && target.type !== 'number' || this.isKeyPressed || target.value || target.checkValidity()) { this.value = target.value; @@ -412,14 +415,14 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe * Returns the filtering operation condition for a given value. */ public getCondition(value: string): IFilteringOperation { - return this.column.filters.condition(value); + return this.column.filters!.condition(value); } /** * Returns the translated condition name for a given value. */ public translateCondition(value: string): string { - return this.filteringService.grid.resourceStrings[`igx_grid_filter_${this.getCondition(value).name}`] || value; + return (this.filteringService.grid.resourceStrings as any)[`igx_grid_filter_${this.getCondition(value).name}`] || value; } /** @@ -429,7 +432,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe if (this.column.dataType === GridColumnDataType.Boolean && this.expression.condition === null) { return this.getCondition(this.conditions[0]).iconName; } else { - return this.expression.condition.iconName; + return this.expression.condition!.iconName; } } @@ -469,7 +472,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe let indexToDeselect = -1; for (let index = 0; index < this.expressionsList.length; index++) { const expression = this.expressionsList[index].expression; - if (expression.searchVal === null && !expression.condition.isUnary) { + if (expression.searchVal === null && !expression.condition!.isUnary) { indexToDeselect = index; } } @@ -556,12 +559,12 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe public close() { if (this.expressionsList.length === 1 && this.expressionsList[0].expression.searchVal === null && - this.expressionsList[0].expression.condition.isUnary === false) { + this.expressionsList[0].expression.condition!.isUnary === false) { this.filteringService.getExpressions(this.column.field).pop(); this.filter(); } else { - const condToRemove = this.expressionsList.filter(ex => ex.expression.searchVal === null && !ex.expression.condition.isUnary); + const condToRemove = this.expressionsList.filter(ex => ex.expression.searchVal === null && !ex.expression.condition!.isUnary); if (condToRemove && condToRemove.length > 0) { condToRemove.forEach(c => this.filteringService.removeExpression(this.column.field, this.expressionsList.indexOf(c))); this.filter(); @@ -570,8 +573,8 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe this.filteringService.isFilterRowVisible = false; this.filteringService.updateFilteringCell(this.column); - this.filteringService.filteredColumn = null; - this.filteringService.selectedExpression = null; + this.filteringService.filteredColumn = null!; + this.filteringService.selectedExpression = null!; this.filteringService.grid.theadRow.nativeElement.focus(); this.chipAreaScrollOffset = 0; @@ -604,7 +607,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe /** * Opens the logic operators dropdown. */ - public toggleOperatorsDropDown(eventArgs, index) { + public toggleOperatorsDropDown(eventArgs: any, index: number) { this._operatorsOverlaySettings.target = eventArgs.target.parentElement; this._operatorsOverlaySettings.excludeFromOutsideClick = [eventArgs.target.parentElement as HTMLElement]; this.dropDownOperators.toArray()[index].toggle(this._operatorsOverlaySettings); @@ -613,7 +616,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe /** * Event handler for change event in conditions dropdown. */ - public onConditionsChanged(eventArgs) { + public onConditionsChanged(eventArgs: ISelectionEventArgs) { const value = (eventArgs.newSelection as IgxDropDownItemComponent).value; this.expression.condition = this.getCondition(value); this.expression.conditionName = value; @@ -631,13 +634,13 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe } - public onChipPointerdown(_args, chip: IgxChipComponent) { + public onChipPointerdown(_args: any, chip: IgxChipComponent) { const activeElement = this.column?.grid.document.activeElement; this._cancelChipClick = chip.selected && activeElement && this.editorFocused(activeElement); } - public onChipClick(_args, item: ExpressionUI) { + public onChipClick(_args: any, item: ExpressionUI) { if (this._cancelChipClick) { this._cancelChipClick = false; return; @@ -782,7 +785,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe private addExpression(isSelected: boolean) { const exprUI = new ExpressionUI(); exprUI.expression = this.expression; - exprUI.beforeOperator = this.expressionsList.length > 0 ? FilteringLogic.And : null; + exprUI.beforeOperator = this.expressionsList.length > 0 ? FilteringLogic.And : null!; exprUI.isSelected = isSelected; this.expressionsList.push(exprUI); @@ -826,7 +829,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe } if (this.column.dataType === GridColumnDataType.Date && this.input) { - this.input.nativeElement.value = null; + this.input.nativeElement.value = null!; } this.showHideArrowButtons(); diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/base-filtering.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/base-filtering.component.ts index df20c0571a0..c8d269d0b76 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/base-filtering.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/base-filtering.component.ts @@ -1,6 +1,7 @@ import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, inject } from '@angular/core'; import { ExpressionUI, FilterListItem } from './common'; import { IgxOverlayService, PlatformUtil } from 'igniteui-angular/core'; +import { GridType } from '../../common/grid.interface'; @@ -12,7 +13,7 @@ export abstract class BaseFilteringComponent { public abstract column: any; - public abstract get grid(): any; + public abstract get grid(): GridType; public abstract overlayComponentId: string; public abstract mainDropdown: ElementRef; @@ -32,7 +33,7 @@ export abstract class BaseFilteringComponent { public abstract detectChanges(): void; public abstract hide(): void; public abstract closeDropdown(): void; - public abstract onSelect(): void; + public abstract onSelect(event?: MouseEvent): void; public abstract onPin(): void; public abstract onHideToggle(): void; public abstract cancel(): void; diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/common.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/common.ts index 1eeb325b252..c23abd67fb3 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/common.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/common.ts @@ -7,9 +7,9 @@ import { getUUID } from '../../common/random'; export class FilterListItem { public value: any; public label: any; - public isSelected: boolean; - public indeterminate: boolean; - public isFiltered: boolean; + public isSelected!: boolean; + public indeterminate!: boolean; + public isFiltered!: boolean; public isSpecial = false; public isBlanks = false; public children?: Array; @@ -21,9 +21,9 @@ export class FilterListItem { */ export class ExpressionUI { public expressionId: string; - public expression: IFilteringExpression; - public beforeOperator: FilteringLogic; - public afterOperator: FilteringLogic; + public expression!: IFilteringExpression; + public beforeOperator!: FilteringLogic; + public afterOperator!: FilteringLogic; public isSelected = false; public isVisible = true; @@ -37,9 +37,9 @@ export class ExpressionUI { * @hidden @internal */ export class ActiveElement { - public index: number; - public id: string; - public checked: boolean; + public index!: number; + public id!: string; + public checked!: boolean; } export function generateExpressionsList(expressions: IFilteringExpressionsTree | IFilteringExpression, @@ -49,7 +49,7 @@ export function generateExpressionsList(expressions: IFilteringExpressionsTree | // The beforeOperator of the first expression and the afterOperator of the last expression should be null if (expressionsUIs.length) { - expressionsUIs[expressionsUIs.length - 1].afterOperator = null; + expressionsUIs[expressionsUIs.length - 1].afterOperator = null!; } } diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-conditional-filter.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-conditional-filter.component.ts index 4397504c167..01b760ca0c3 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-conditional-filter.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-conditional-filter.component.ts @@ -27,7 +27,7 @@ export class IgxExcelStyleConditionalFilterComponent implements OnDestroy { * @hidden @internal */ @ViewChild('subMenu', { read: IgxDropDownComponent }) - public subMenu: IgxDropDownComponent; + public subMenu!: IgxDropDownComponent; protected get filterNumber() { return this.esf.expressionsList.filter(e => e.expression.condition).length; @@ -79,9 +79,9 @@ export class IgxExcelStyleConditionalFilterComponent implements OnDestroy { /** * @hidden @internal */ - public onTextFilterClick(eventArgs) { + public onTextFilterClick(eventArgs: MouseEvent | KeyboardEvent) { if (this.shouldOpenSubMenu) { - this._subMenuOverlaySettings.target = eventArgs.currentTarget; + this._subMenuOverlaySettings.target = eventArgs.currentTarget as HTMLElement; const gridRect = this.esf.grid.nativeElement.getBoundingClientRect(); const dropdownRect = this.esf.mainDropdown.nativeElement.getBoundingClientRect(); @@ -91,11 +91,11 @@ export class IgxExcelStyleConditionalFilterComponent implements OnDestroy { x += window.pageXOffset; x1 += window.pageXOffset; if (Math.abs(x - x1) < 200) { - this._subMenuOverlaySettings.positionStrategy.settings.horizontalDirection = HorizontalAlignment.Left; - this._subMenuOverlaySettings.positionStrategy.settings.horizontalStartPoint = HorizontalAlignment.Left; + this._subMenuOverlaySettings.positionStrategy!.settings.horizontalDirection = HorizontalAlignment.Left; + this._subMenuOverlaySettings.positionStrategy!.settings.horizontalStartPoint = HorizontalAlignment.Left; } else { - this._subMenuOverlaySettings.positionStrategy.settings.horizontalDirection = HorizontalAlignment.Right; - this._subMenuOverlaySettings.positionStrategy.settings.horizontalStartPoint = HorizontalAlignment.Right; + this._subMenuOverlaySettings.positionStrategy!.settings.horizontalDirection = HorizontalAlignment.Right; + this._subMenuOverlaySettings.positionStrategy!.settings.horizontalStartPoint = HorizontalAlignment.Right; } this.subMenu.open(this._subMenuOverlaySettings); @@ -115,14 +115,14 @@ export class IgxExcelStyleConditionalFilterComponent implements OnDestroy { if (expressions.length < 1) { return false; } - return expressions.length === 1 ? expressions[0].expression.condition.name === condition : condition === 'custom'; + return expressions.length === 1 ? expressions[0].expression.condition!.name === condition : condition === 'custom'; } /** * @hidden @internal */ public translateCondition(value: string): string { - return this.esf.grid.resourceStrings[`igx_grid_filter_${this.getCondition(value).name}`] || value; + return (this.esf.grid.resourceStrings as any)[`igx_grid_filter_${this.getCondition(value).name}`] || value; } /** @@ -180,9 +180,9 @@ export class IgxExcelStyleConditionalFilterComponent implements OnDestroy { */ public showCustomFilterItem(): boolean { const exprTree = this.esf.column.filteringExpressionsTree; - return exprTree && exprTree.filteringOperands && exprTree.filteringOperands.length && + return (exprTree && exprTree.filteringOperands && exprTree.filteringOperands.length && !((exprTree.filteringOperands[0] as IFilteringExpression).condition && - (exprTree.filteringOperands[0] as IFilteringExpression).condition.name === 'in'); + (exprTree.filteringOperands[0] as IFilteringExpression).condition!.name === 'in')) as boolean; } /** diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-custom-dialog.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-custom-dialog.component.ts index 460c276a6a4..f584936a458 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-custom-dialog.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-custom-dialog.component.ts @@ -38,7 +38,7 @@ export class IgxExcelStyleCustomDialogComponent { this.overlayService.closed.pipe(takeUntilDestroyed()).subscribe((args) => { if (args.id === this.overlayComponentId) { this.overlayService.detach(this.overlayComponentId); - this.overlayComponentId = null; + this.overlayComponentId = null!; } }); } @@ -47,31 +47,31 @@ export class IgxExcelStyleCustomDialogComponent { public expressionsList = new Array(); @Input() - public column: ColumnType; + public column!: ColumnType; @Input() - public selectedOperator: string; + public selectedOperator!: string; @Input() - public filteringService: IgxFilteringService; + public filteringService!: IgxFilteringService; @Input() - public overlayComponentId: string; + public overlayComponentId!: string; @ViewChild('defaultExpressionTemplate', { read: TemplateRef }) - protected defaultExpressionTemplate: TemplateRef; + protected defaultExpressionTemplate!: TemplateRef; @ViewChild('dateExpressionTemplate', { read: TemplateRef }) - protected dateExpressionTemplate: TemplateRef; + protected dateExpressionTemplate!: TemplateRef; @ViewChild('expressionsContainer', { static: true }) - protected expressionsContainer: ElementRef; + protected expressionsContainer!: ElementRef; @ViewChildren(IgxExcelStyleDefaultExpressionComponent) - private expressionComponents: QueryList; + private expressionComponents!: QueryList; @ViewChildren(IgxExcelStyleDateExpressionComponent) - private expressionDateComponents: QueryList; + private expressionDateComponents!: QueryList; public get template(): TemplateRef { if (this.column.dataType === GridColumnDataType.Date) { @@ -99,7 +99,7 @@ export class IgxExcelStyleCustomDialogComponent { public onClearButtonClick() { this.filteringService.clearFilter(this.column.field); - this.selectedOperator = null; + this.selectedOperator = null!; this.createInitialExpressionUIElement(); this.cdr.detectChanges(); } @@ -108,7 +108,7 @@ export class IgxExcelStyleCustomDialogComponent { if (this.overlayComponentId) { this.overlayService.hide(this.overlayComponentId); this.overlayService.detach(this.overlayComponentId); - this.overlayComponentId = null; + this.overlayComponentId = null!; } } @@ -123,8 +123,8 @@ export class IgxExcelStyleCustomDialogComponent { (element.expression.searchVal || element.expression.searchVal === 0 || element.expression.condition.isUnary)); if (this.expressionsList.length > 0) { - this.expressionsList[0].beforeOperator = null; - this.expressionsList[this.expressionsList.length - 1].afterOperator = null; + this.expressionsList[0].beforeOperator = null!; + this.expressionsList[this.expressionsList.length - 1].afterOperator = null!; } this.filteringService.filterInternal(this.column.field, this.expressionsList); @@ -154,13 +154,13 @@ export class IgxExcelStyleCustomDialogComponent { const indexToRemove = this.expressionsList.indexOf(event); if (indexToRemove === 0 && this.expressionsList.length > 1) { - this.expressionsList[1].beforeOperator = null; + this.expressionsList[1].beforeOperator = null!; } else if (indexToRemove === this.expressionsList.length - 1) { - this.expressionsList[indexToRemove - 1].afterOperator = null; + this.expressionsList[indexToRemove - 1].afterOperator = null!; } else { this.expressionsList[indexToRemove - 1].afterOperator = this.expressionsList[indexToRemove + 1].beforeOperator; - this.expressionsList[0].beforeOperator = null; - this.expressionsList[this.expressionsList.length - 1].afterOperator = null; + this.expressionsList[0].beforeOperator = null!; + this.expressionsList[this.expressionsList.length - 1].afterOperator = null!; } this.expressionsList.splice(indexToRemove, 1); @@ -216,7 +216,7 @@ export class IgxExcelStyleCustomDialogComponent { private createInitialExpressionUIElement() { let firstExprUI = new ExpressionUI(); if (this.expressionsList.length == 1 && this.expressionsList[0].expression.condition?.name === this.selectedOperator) { - firstExprUI = this.expressionsList.pop(); + firstExprUI = this.expressionsList.pop()!; } else { this.expressionsList = []; const cond = this.createCondition(this.selectedOperator); diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.html b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.html index ca089163961..4d8a848f19f 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.html +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.html @@ -36,11 +36,11 @@ [locale]="grid.locale" (click)="picker.open()" [placeholder]="inputDatePlaceholder" - [formatter]="column.formatter" - [disabled]=" + [formatter]="column.formatter!" + [disabled]="!!( expressionUI.expression.condition && expressionUI.expression.condition.isUnary - " + )" type="box" > @@ -56,15 +56,13 @@ [locale]="grid.locale" (click)="picker.open()" [placeholder]="inputTimePlaceholder" - [displayFormat]="column.pipeArgs.format" - [inputFormat]=" - $safeNavigationMigration(column.editorOptions?.dateTimeFormat) - " - [formatter]="column.formatter" - [disabled]=" + [displayFormat]="column.pipeArgs.format!" + [inputFormat]="column.editorOptions?.dateTimeFormat!" + [formatter]="column.formatter!" + [disabled]="!!( expressionUI.expression.condition && expressionUI.expression.condition.isUnary - " + )" type="box" > @@ -81,16 +79,14 @@ tabindex="0" [placeholder]="inputDatePlaceholder" [locale]="column.grid.locale" - [igxDateTimeEditor]=" - $safeNavigationMigration(column.editorOptions?.dateTimeFormat) - " + [igxDateTimeEditor]="column.editorOptions?.dateTimeFormat!" [defaultFormatType]="column.dataType" - [displayFormat]="column.pipeArgs.format" + [displayFormat]="column.pipeArgs.format!" [(ngModel)]="searchVal" - [disabled]=" + [disabled]="!!( expressionUI.expression.condition && expressionUI.expression.condition.isUnary - " + )" /> } diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.ts index b0ff9b25844..9a534786e0a 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-date-expression.component.ts @@ -23,10 +23,10 @@ export class IgxExcelStyleDateExpressionComponent extends IgxExcelStyleDefaultEx protected i18nFormatter = inject(I18N_FORMATTER); @ViewChild('input', { read: IgxInputDirective, static: false }) - private input: IgxInputDirective; + private input!: IgxInputDirective; @ViewChild('picker') - private picker: IgxDatePickerComponent | IgxTimePickerComponent; + private picker!: IgxDatePickerComponent | IgxTimePickerComponent; @Input() public get searchVal(): any { diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.html b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.html index 17fe6814d78..b37b4f029de 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.html +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.html @@ -28,7 +28,7 @@ [type]="type" tabindex="0" [placeholder]="inputValuePlaceholder" - [disabled]="expressionUI.expression.condition && expressionUI.expression.condition.isUnary" + [disabled]="!!(expressionUI.expression.condition && expressionUI.expression.condition.isUnary)" autocomplete="off" [(ngModel)]="expressionUI.expression.searchVal" (blur)="updateSearchValueOnBlur($event)" diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.ts index a93ede71e8f..5748b6ee101 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-default-expression.component.ts @@ -7,6 +7,7 @@ import { IgxInputDirective, IgxInputGroupComponent, IgxPrefixDirective, IgxSuffi import { IgxIconComponent } from 'igniteui-angular/icon'; import { IgxButtonDirective, IgxIconButtonDirective } from 'igniteui-angular/directives'; import { IgxButtonGroupComponent } from 'igniteui-angular/button-group'; +import { ISelectionEventArgs } from 'igniteui-angular/drop-down'; /** * @hidden @@ -30,13 +31,13 @@ export class IgxExcelStyleDefaultExpressionComponent implements AfterViewInit { protected platform = inject(PlatformUtil); @Input() - public column: ColumnType; + public column!: ColumnType; @Input() - public expressionUI: ExpressionUI; + public expressionUI!: ExpressionUI; @Input() - public expressionsList: Array; + public expressionsList!: Array; @Input() public grid: any; @@ -48,16 +49,16 @@ export class IgxExcelStyleDefaultExpressionComponent implements AfterViewInit { public logicOperatorChanged = new EventEmitter(); @ViewChild('overlayOutlet', { read: IgxOverlayOutletDirective, static: true }) - public overlayOutlet: IgxOverlayOutletDirective; + public overlayOutlet!: IgxOverlayOutletDirective; @ViewChild('dropdownConditions', { read: IgxSelectComponent, static: true }) - protected dropdownConditions: IgxSelectComponent; + protected dropdownConditions!: IgxSelectComponent; @ViewChild('logicOperatorButtonGroup', { read: IgxButtonGroupComponent }) - protected logicOperatorButtonGroup: IgxButtonGroupComponent; + protected logicOperatorButtonGroup!: IgxButtonGroupComponent; @ViewChild('inputValues', { read: IgxInputDirective, static: true }) - protected inputValuesDirective: IgxInputDirective; + protected inputValuesDirective!: IgxInputDirective; public dropDownOverlaySettings: OverlaySettings = { scrollStrategy: new AbsoluteScrollStrategy(), @@ -93,7 +94,7 @@ export class IgxExcelStyleDefaultExpressionComponent implements AfterViewInit { } public get conditions() { - return this.column.filters.conditionList(); + return this.column.filters!.conditionList(); } protected get inputValuesElement() { @@ -128,11 +129,11 @@ export class IgxExcelStyleDefaultExpressionComponent implements AfterViewInit { } public isConditionSelected(conditionName: string): boolean { - return this.expressionUI.expression.condition && this.expressionUI.expression.condition.name === conditionName; + return (this.expressionUI.expression.condition && this.expressionUI.expression.condition.name === conditionName) as boolean; } - public onConditionsChanged(eventArgs: any) { - const value = (eventArgs.newSelection as IgxSelectComponent).value; + public onConditionsChanged(eventArgs: ISelectionEventArgs) { + const value = eventArgs.newSelection.value; this.expressionUI.expression.condition = this.getCondition(value); this.expressionUI.expression.conditionName = value; @@ -142,18 +143,19 @@ export class IgxExcelStyleDefaultExpressionComponent implements AfterViewInit { } public getCondition(value: string): IFilteringOperation { - return this.column.filters.condition(value); + return this.column.filters!.condition(value); } public getConditionFriendlyName(name: string): string { return this.grid.resourceStrings[`igx_grid_filter_${name}`] || name; } - public updateSearchValueOnBlur(eventArgs) { - this.expressionUI.expression.searchVal = DataUtil.parseValue(this.column.dataType, eventArgs.target.value); + public updateSearchValueOnBlur(eventArgs: FocusEvent) { + const target = eventArgs.target as HTMLInputElement; + this.expressionUI.expression.searchVal = DataUtil.parseValue(this.column.dataType, target.value); } - public onLogicOperatorButtonClicked(eventArgs, buttonIndex: number) { + public onLogicOperatorButtonClicked(eventArgs: MouseEvent, buttonIndex: number) { if (this.logicOperatorButtonGroup.selectedButtons.length === 0) { eventArgs.stopPropagation(); this.logicOperatorButtonGroup.selectButton(buttonIndex); @@ -179,7 +181,7 @@ export class IgxExcelStyleDefaultExpressionComponent implements AfterViewInit { this.expressionRemoved.emit(this.expressionUI); } - public onOutletPointerDown(event) { + public onOutletPointerDown(event: PointerEvent) { event.preventDefault(); } } diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-filtering.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-filtering.component.ts index 166248f9aa4..372de7e6998 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-filtering.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-filtering.component.ts @@ -32,7 +32,7 @@ import { IgxExcelStylePinningComponent } from './excel-style-pinning.component'; import { IgxExcelStyleMovingComponent } from './excel-style-moving.component'; import { IgxExcelStyleSortingComponent } from './excel-style-sorting.component'; import { IgxExcelStyleHeaderComponent } from './excel-style-header.component'; -import { ColumnType, FilteringExpressionsTree, GridColumnDataType, GridTypeBase, IFilteringExpressionsTree, IgxFilterItem, IgxOverlayService, isTree, SortingDirection } from 'igniteui-angular/core'; +import { ColumnType, FilteringExpressionsTree, GridColumnDataType, IFilteringExpressionsTree, IgxFilterItem, IgxOverlayService, isTree, SortingDirection } from 'igniteui-angular/core'; @Directive({ selector: '[igxExcelStyleColumnOperations],igx-excel-style-column-operations', @@ -129,31 +129,31 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent public filterCleared = new EventEmitter(); @ViewChild('mainDropdown', { read: ElementRef }) - public mainDropdown: ElementRef; + public mainDropdown!: ElementRef; /** * @hidden @internal */ @ContentChild(IgxExcelStyleColumnOperationsTemplateDirective, { read: IgxExcelStyleColumnOperationsTemplateDirective }) - public excelColumnOperationsDirective: IgxExcelStyleColumnOperationsTemplateDirective; + public excelColumnOperationsDirective!: IgxExcelStyleColumnOperationsTemplateDirective; /** * @hidden @internal */ @ContentChild(IgxExcelStyleFilterOperationsTemplateDirective, { read: IgxExcelStyleFilterOperationsTemplateDirective }) - public excelFilterOperationsDirective: IgxExcelStyleFilterOperationsTemplateDirective; + public excelFilterOperationsDirective!: IgxExcelStyleFilterOperationsTemplateDirective; /** * @hidden @internal */ @ViewChild('defaultExcelColumnOperations', { read: TemplateRef, static: true }) - protected defaultExcelColumnOperations: TemplateRef; + protected defaultExcelColumnOperations!: TemplateRef; /** * @hidden @internal */ @ViewChild('defaultExcelFilterOperations', { read: TemplateRef, static: true }) - protected defaultExcelFilterOperations: TemplateRef; + protected defaultExcelFilterOperations!: TemplateRef; /** * Sets the column. @@ -192,17 +192,17 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent /** * @hidden @internal */ - public overlayService: IgxOverlayService; + public overlayService!: IgxOverlayService; /** * @hidden @internal */ - public overlayComponentId: string; + public overlayComponentId!: string; /** * @hidden @internal */ public isHierarchical = false; - private _minHeight; + private _minHeight: any; /** * Gets the minimum height. @@ -222,6 +222,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent if (this._minHeight || this._minHeight === 0) { return this._minHeight; } + return undefined!; } /** @@ -232,14 +233,14 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent } - private _maxHeight: string; + private _maxHeight!: string; private containsNullOrEmpty = false; private selectAllSelected = true; private selectAllIndeterminate = false; private filterValues = new Set(); - private _column: ColumnType; - private subscriptions: Subscription; - private _originalDisplay: string; + private _column!: ColumnType; + private subscriptions!: Subscription; + private _originalDisplay!: string; /** * Gets the maximum height. @@ -260,6 +261,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent if (this._maxHeight) { return this._maxHeight; } + return undefined!; } /** @@ -272,8 +274,8 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent /** * @hidden @internal */ - public get grid(): GridTypeBase { - return this.column?.grid ?? this.gridAPI; + public get grid(): GridType { + return this.column?.grid as GridType ?? this.gridAPI; } /** @@ -281,14 +283,14 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent */ public ngOnDestroy(): void { this.subscriptions?.unsubscribe(); - delete this.overlayComponentId; + this.overlayComponentId = ''; } /** * @hidden @internal */ public ngAfterViewInit(): void { - this.computedStyles = this.document.defaultView.getComputedStyle(this.element.nativeElement); + this.computedStyles = this.document.defaultView!.getComputedStyle(this.element.nativeElement); } @@ -328,11 +330,11 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent /** * @hidden @internal */ - public onSelect() { + public onSelect(event?: MouseEvent) { if (!this.column.selected) { - this.grid.selectionService.selectColumn(this.column.field, this.grid.columnSelection === GridSelectionMode.single); + this.grid.selectionService.selectColumn(this.column.field, this.grid.columnSelection === GridSelectionMode.single, false, event); } else { - this.grid.selectionService.deselectColumn(this.column.field); + this.grid.selectionService.deselectColumn(this.column.field, event); } this.grid.notifyChanges(); } @@ -368,7 +370,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent public closeDropdown() { if (this.overlayComponentId) { this.overlayService.hide(this.overlayComponentId); - this.overlayComponentId = null; + this.overlayComponentId = null!; } } @@ -398,7 +400,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent this.cdr.detectChanges(); } - protected computedStyles; + protected computedStyles!: CSSStyleDeclaration; protected get size(): string { return this.computedStyles?.getPropertyValue('--component-size'); @@ -440,23 +442,23 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent private areExpressionsSelectable() { if (this.expressionsList.length === 1 && - (this.expressionsList[0].expression.condition.name === 'equals' || - this.expressionsList[0].expression.condition.name === 'at' || - this.expressionsList[0].expression.condition.name === 'true' || - this.expressionsList[0].expression.condition.name === 'false' || - this.expressionsList[0].expression.condition.name === 'empty' || - this.expressionsList[0].expression.condition.name === 'in')) { + (this.expressionsList[0].expression.condition!.name === 'equals' || + this.expressionsList[0].expression.condition!.name === 'at' || + this.expressionsList[0].expression.condition!.name === 'true' || + this.expressionsList[0].expression.condition!.name === 'false' || + this.expressionsList[0].expression.condition!.name === 'empty' || + this.expressionsList[0].expression.condition!.name === 'in')) { return true; } const selectableExpressionsCount = this.expressionsList.filter(exp => (exp.beforeOperator === 1 || exp.afterOperator === 1) && - (exp.expression.condition.name === 'equals' || - exp.expression.condition.name === 'at' || - exp.expression.condition.name === 'true' || - exp.expression.condition.name === 'false' || - exp.expression.condition.name === 'empty' || - exp.expression.condition.name === 'in')).length; + (exp.expression.condition!.name === 'equals' || + exp.expression.condition!.name === 'at' || + exp.expression.condition!.name === 'true' || + exp.expression.condition!.name === 'false' || + exp.expression.condition!.name === 'empty' || + exp.expression.condition!.name === 'in')).length; return selectableExpressionsCount === this.expressionsList.length; } @@ -476,7 +478,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent const expressionsTree: FilteringExpressionsTree = this.getColumnFilterExpressionsTree(); const prevColumn = this.column; - this.grid.uniqueColumnValuesStrategy(this.column, expressionsTree, (values: any[]) => { + this.grid.uniqueColumnValuesStrategy?.(this.column, expressionsTree, (values: any[]) => { if (!this.column || this.column !== prevColumn) { return; } @@ -509,7 +511,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent const expressionsTree = this.getColumnFilterExpressionsTree(); const promise = this.grid.filterStrategy.getFilterItems(this.column, expressionsTree); - promise.then((items) => { + promise.then((items: IgxFilterItem[]) => { this.isHierarchical = items.length > 0 && items.some(i => i.children && i.children.length > 0); this.uniqueValues = items; this.renderValues(); @@ -579,7 +581,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent private getColumnFilterExpressionsTree() { const gridExpressionsTree: IFilteringExpressionsTree = this.grid.filteringExpressionsTree; - const expressionsTree = new FilteringExpressionsTree(gridExpressionsTree.operator, gridExpressionsTree.fieldName); + const expressionsTree = new FilteringExpressionsTree(gridExpressionsTree.operator, gridExpressionsTree.fieldName!); for (const operand of gridExpressionsTree.filteringOperands) { if (isTree(operand)) { @@ -602,11 +604,11 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent const filterListItem = new FilterListItem(); if (value !== undefined && value !== null && value !== '') { if (this.column.filteringExpressionsTree) { - if (value === true && this.expressionsList.find(exp => exp.expression.condition.name === 'true')) { + if (value === true && this.expressionsList.find(exp => exp.expression.condition!.name === 'true')) { filterListItem.isSelected = true; filterListItem.isFiltered = true; this.selectAllIndeterminate = true; - } else if (value === false && this.expressionsList.find(exp => exp.expression.condition.name === 'false')) { + } else if (value === false && this.expressionsList.find(exp => exp.expression.condition!.name === 'false')) { filterListItem.isSelected = true; filterListItem.isFiltered = true; this.selectAllIndeterminate = true; @@ -639,7 +641,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent } private generateFilterListItems(values: IgxFilterItem[], shouldUpdateSelection: boolean, parent?: FilterListItem) { - const filterListItems = []; + const filterListItems: FilterListItem[] = []; values?.forEach(element => { const value = element.value; const hasValue = value !== undefined && value !== null && value !== ''; @@ -690,7 +692,7 @@ export class IgxGridExcelStyleFilteringComponent extends BaseFilteringComponent this.listData.unshift(selectAll); } - private generateBlanksItem(shouldUpdateSelection) { + private generateBlanksItem(shouldUpdateSelection: boolean) { const blanks = new FilterListItem(); if (this.column.filteringExpressionsTree) { if (shouldUpdateSelection) { diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-header.component.html b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-header.component.html index 7aa8df61600..f02b22f7861 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-header.component.html +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-header.component.html @@ -6,7 +6,7 @@

{{ esf.column.header || esf.column.field }}

@@ -95,11 +96,9 @@ diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts index 18649187a00..c071db52af3 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts @@ -57,46 +57,46 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { * @hidden @internal */ @ViewChild('input', { read: IgxInputDirective, static: true }) - public searchInput: IgxInputDirective; + public searchInput!: IgxInputDirective; @ViewChild('cancelButton', { read: IgxButtonDirective, static: true }) - protected cancelButton: IgxButtonDirective; + protected cancelButton!: IgxButtonDirective; /** * @hidden @internal */ @ViewChild('list', { read: IgxListComponent, static: false }) - public list: IgxListComponent; + public list!: IgxListComponent; /** * @hidden @internal */ @ViewChild('selectAllCheckbox', { read: IgxCheckboxComponent, static: false }) - public selectAllCheckbox: IgxCheckboxComponent; + public selectAllCheckbox!: IgxCheckboxComponent; /** * @hidden @internal */ @ViewChild('addToCurrentFilterCheckbox', { read: IgxCheckboxComponent, static: false }) - public addToCurrentFilterCheckbox: IgxCheckboxComponent; + public addToCurrentFilterCheckbox!: IgxCheckboxComponent; /** * @hidden @internal */ @ViewChild('tree', { read: IgxTreeComponent, static: false }) - public tree: IgxTreeComponent; + public tree!: IgxTreeComponent; /** * @hidden @internal */ @ViewChild(IgxForOfDirective) - protected virtDir: IgxForOfDirective; + protected virtDir!: IgxForOfDirective; /** * @hidden @internal */ @ViewChild('defaultExcelStyleLoadingValuesTemplate', { read: TemplateRef }) - protected defaultExcelStyleLoadingValuesTemplate: TemplateRef; + protected defaultExcelStyleLoadingValuesTemplate!: TemplateRef; /** * @hidden @internal @@ -170,7 +170,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { /** * @hidden @internal */ - public matchesCount: number; + public matchesCount = 0; /** * @hidden @internal @@ -187,10 +187,10 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { private _id = `igx-excel-style-search-${NEXT_ID++}`; private _isLoading = true; - private _addToCurrentFilterItem: FilterListItem; - private _selectAllItem: FilterListItem; - private _hierarchicalSelectedItems: FilterListItem[]; - private _focusedItem: ActiveElement = null; + private _addToCurrentFilterItem!: FilterListItem; + private _selectAllItem!: FilterListItem; + private _hierarchicalSelectedItems!: FilterListItem[]; + private _focusedItem: ActiveElement = null!; private destroy$ = new Subject(); constructor() { @@ -601,7 +601,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { blanksItem = selectedItems[blanksItemIndex]; selectedItems.splice(blanksItemIndex, 1); } - let searchVal; + let searchVal: any; switch (this.esf.column.dataType) { case GridColumnDataType.Date: searchVal = new Set(selectedItems.map(d => d.value.toDateString())); @@ -617,7 +617,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { const selectedValues = new Set(selectedItems.map(item => item.value.toLowerCase())); searchVal = new Set(); - this.esf.grid.data.forEach(item => { + this.esf.grid.data?.forEach((item: any) => { const fieldPaths = columnFieldPath(this.esf.column.field) const itemValue = resolveNestedPath(item, fieldPaths); if (typeof itemValue === "string" && selectedValues.has(itemValue.toLowerCase())) { @@ -697,19 +697,19 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { } protected onFocus() { - const firstIndexInView = this.virtDir.state.startIndex; - if (this.virtDir.igxForOf.length > 0) { + const firstIndexInView = this.virtDir.state.startIndex!; + if (this.virtDir.igxForOf!.length > 0) { this.focusedItem = { id: this.getItemId(firstIndexInView), index: firstIndexInView, - checked: this.virtDir.igxForOf[firstIndexInView].isSelected + checked: this.virtDir.igxForOf![firstIndexInView].isSelected }; } this.setActiveDescendant(); } protected onFocusOut() { - this.focusedItem = null; + this.focusedItem = null!; this.setActiveDescendant(); } @@ -741,8 +741,8 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { element.isSelected = true; this.hierarchicalSelectAllChildren(element); this._hierarchicalSelectedItems.push(element); - } else if (element.children.length > 0) { - element.children = this.hierarchicalSelectMatches(element.children, searchVal); + } else if (element.children!.length > 0) { + element.children = this.hierarchicalSelectMatches(element.children!, searchVal); if (element.children.length > 0) { element.isSelected = true; if (node) { @@ -756,7 +756,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { } private hierarchicalSelectAllChildren(element: FilterListItem) { - element.children.forEach(child => { + element.children!.forEach(child => { child.indeterminate = false; child.isSelected = true; this._hierarchicalSelectedItems.push(child); @@ -843,7 +843,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { } private onArrowDownKeyDown() { - const lastIndex = this.virtDir.igxForOf.length - 1; + const lastIndex = this.virtDir.igxForOf!.length - 1; if (this.focusedItem && this.focusedItem.index === lastIndex) { // on ArrowDown the focus stays on the same element if it is the last focused return; @@ -859,7 +859,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { } private onEndKeyDown() { - this.navigateItem(this.virtDir.igxForOf.length - 1); + this.navigateItem(this.virtDir.igxForOf!.length - 1); this.setActiveDescendant(); } @@ -875,7 +875,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { } private navigateItem(index: number) { - if (index === -1 || index >= this.virtDir.igxForOf.length) { + if (index === -1 || index >= this.virtDir.igxForOf!.length) { return; } const direction = index > (this.focusedItem ? this.focusedItem.index : -1) ? Navigate.Down : Navigate.Up; @@ -883,7 +883,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { this.focusedItem = { id: this.getItemId(index), index: index, - checked: this.virtDir.igxForOf[index].isSelected + checked: this.virtDir.igxForOf![index].isSelected }; if (scrollRequired) { this.virtDir.scrollTo(index); @@ -894,7 +894,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { const virtState = this.virtDir.state; const currentPosition = this.virtDir.getScroll().scrollTop; const itemPosition = this.virtDir.getScrollForIndex(index, direction === Navigate.Down); - const indexOutOfChunk = index < virtState.startIndex || index > virtState.chunkSize + virtState.startIndex; + const indexOutOfChunk = index < virtState.startIndex! || index > virtState.chunkSize! + virtState.startIndex!; const scrollNeeded = direction === Navigate.Down ? currentPosition < itemPosition : currentPosition > itemPosition; const subRequired = indexOutOfChunk || scrollNeeded; return subRequired; diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-selecting.component.html b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-selecting.component.html index 34b3b651719..e9cb32b96a0 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-selecting.component.html +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-selecting.component.html @@ -2,7 +2,7 @@
{{esf.grid.resourceStrings.igx_grid_excel_select }} diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-sorting.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-sorting.component.ts index 18fa073feab..2b734c043fd 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-sorting.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-sorting.component.ts @@ -29,7 +29,7 @@ export class IgxExcelStyleSortingComponent implements OnDestroy { * @hidden @internal */ @ViewChild('sortButtonGroup', { read: IgxButtonGroupComponent }) - public sortButtonGroup: IgxButtonGroupComponent; + public sortButtonGroup!: IgxButtonGroupComponent; private destroy$ = new Subject(); @@ -47,7 +47,7 @@ export class IgxExcelStyleSortingComponent implements OnDestroy { /** * @hidden @internal */ - public onSortButtonClicked(sortDirection) { + public onSortButtonClicked(sortDirection: number) { if (this.sortButtonGroup.buttons.filter(b => b.selected).length === 0) { if (this.esf.grid.isColumnGrouped(this.esf.column.field)) { this.sortButtonGroup.selectButton(sortDirection - 1); diff --git a/projects/igniteui-angular/grids/core/src/filtering/grid-filtering.service.ts b/projects/igniteui-angular/grids/core/src/filtering/grid-filtering.service.ts index a196db3474a..06b640d4bac 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/grid-filtering.service.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/grid-filtering.service.ts @@ -22,11 +22,11 @@ export class IgxFilteringService implements OnDestroy { protected _overlayService = inject(IgxOverlayService); public isFilterRowVisible = false; - public filteredColumn: ColumnType = null; - public selectedExpression: IFilteringExpression = null; + public filteredColumn: ColumnType = null!; + public selectedExpression: IFilteringExpression = null!; public columnToMoreIconHidden = new Map(); public activeFilterCell = 0; - public grid: GridType; + public grid!: GridType; private columnsWithComplexFilter = new Set(); private areEventsSubscribed = false; @@ -41,11 +41,11 @@ export class IgxFilteringService implements OnDestroy { positionStrategy: new ExcelStylePositionStrategy({ verticalStartPoint: VerticalAlignment.Bottom, openAnimation: useAnimation(fadeIn, { params: { duration: '250ms' } }), - closeAnimation: null + closeAnimation: null! }), scrollStrategy: new AbsoluteScrollStrategy() }; - protected lastActiveNode; + protected lastActiveNode: any; public ngOnDestroy(): void { this.destroy$.next(true); @@ -108,7 +108,7 @@ export class IgxFilteringService implements OnDestroy { this.grid.parentVirtDir.chunkLoad.pipe(takeUntil(this.destroy$)).subscribe((eventArgs: IForOfState) => { if (eventArgs.startIndex !== this.columnStartIndex) { - this.columnStartIndex = eventArgs.startIndex; + this.columnStartIndex = eventArgs.startIndex!; this.grid.filterCellList.forEach((filterCell) => { filterCell.updateFilterCellArea(); }); @@ -137,14 +137,14 @@ export class IgxFilteringService implements OnDestroy { /** * Internal method to create expressionsTree and filter grid used in both filter modes. */ - public filterInternal(field: string, expressions: FilteringExpressionsTree | Array = null): void { + public filterInternal(field: string, expressions: FilteringExpressionsTree | Array = null!): void { this.isFiltering = true; let expressionsTree; if (expressions && 'operator' in expressions) { expressionsTree = expressions; } else { - expressionsTree = this.createSimpleFilteringTree(field, expressions); + expressionsTree = this.createSimpleFilteringTree(field, expressions as ExpressionUI[]); } if (expressionsTree.filteringOperands.length === 0) { @@ -195,7 +195,7 @@ export class IgxFilteringService implements OnDestroy { } else if (isTree(expressionsTreeForColumn)) { this.filter_internal(field, value, expressionsTreeForColumn, filteringIgnoreCase); } else { - this.filter_internal(field, value, expressionsTreeForColumn.condition, filteringIgnoreCase); + this.filter_internal(field, value, expressionsTreeForColumn.condition!, filteringIgnoreCase); } } const doneEventArgs = ExpressionsTreeUtil.find(this.grid.filteringExpressionsTree, field) as FilteringExpressionsTree; @@ -203,7 +203,7 @@ export class IgxFilteringService implements OnDestroy { requestAnimationFrame(() => this.grid.filteringDone.emit(doneEventArgs)); } - public filter_global(term, condition, ignoreCase) { + public filter_global(term: any, condition: any, ignoreCase: any) { if (!condition) { return; } @@ -232,7 +232,7 @@ export class IgxFilteringService implements OnDestroy { } } - const emptyFilter = new FilteringExpressionsTree(null, field); + const emptyFilter = new FilteringExpressionsTree(null!, field); const onFilteringEventArgs: IFilteringEventArgs = { owner: this.grid, filteringExpressions: emptyFilter, @@ -283,13 +283,13 @@ export class IgxFilteringService implements OnDestroy { * Filters all the column in the grid with the same condition. * @deprecated in version 19.0.0. */ - public filterGlobal(value: any, condition, ignoreCase?) { + public filterGlobal(value: any, condition: IFilteringOperation, ignoreCase?: boolean) { if (!condition) { return; } const filteringTree = this.grid.filteringExpressionsTree; - const newFilteringTree = new FilteringExpressionsTree(filteringTree.operator, filteringTree.fieldName); + const newFilteringTree = new FilteringExpressionsTree(filteringTree.operator, filteringTree.fieldName!); for (const column of this.grid.columns) { this.prepare_filtering_expression(newFilteringTree, column.field, value, condition, @@ -336,7 +336,7 @@ export class IgxFilteringService implements OnDestroy { return expressionUIs; } - return this.columnToExpressionsMap.get(columnId); + return this.columnToExpressionsMap.get(columnId)!; } /** @@ -373,13 +373,13 @@ export class IgxFilteringService implements OnDestroy { const expressionsList = this.getExpressions(columnId); if (indexToRemove === 0 && expressionsList.length > 1) { - expressionsList[1].beforeOperator = null; + expressionsList[1].beforeOperator = null!; } else if (indexToRemove === expressionsList.length - 1) { - expressionsList[indexToRemove - 1].afterOperator = null; + expressionsList[indexToRemove - 1].afterOperator = null!; } else { expressionsList[indexToRemove - 1].afterOperator = expressionsList[indexToRemove + 1].beforeOperator; - expressionsList[0].beforeOperator = null; - expressionsList[expressionsList.length - 1].afterOperator = null; + expressionsList[0].beforeOperator = null!; + expressionsList[expressionsList.length - 1].afterOperator = null!; } expressionsList.splice(indexToRemove, 1); @@ -388,13 +388,13 @@ export class IgxFilteringService implements OnDestroy { /** * Generate filtering tree for a given column from existing ExpressionUIs. */ - public createSimpleFilteringTree(columnId: string, expressionUIList = null): FilteringExpressionsTree { + public createSimpleFilteringTree(columnId: string, expressionUIList: ExpressionUI[] = null!): FilteringExpressionsTree { const expressionsList = expressionUIList ? expressionUIList : this.getExpressions(columnId); const expressionsTree = new FilteringExpressionsTree(FilteringLogic.Or, columnId); - let currAndBranch: FilteringExpressionsTree; + let currAndBranch!: FilteringExpressionsTree; for (const currExpressionUI of expressionsList) { - if (!currExpressionUI.expression.condition.isUnary && currExpressionUI.expression.searchVal === null) { + if (!currExpressionUI.expression.condition!.isUnary && currExpressionUI.expression.searchVal === null) { if (currExpressionUI.afterOperator === FilteringLogic.And && !currAndBranch) { currAndBranch = new FilteringExpressionsTree(FilteringLogic.And, columnId); expressionsTree.filteringOperands.push(currAndBranch); @@ -414,7 +414,7 @@ export class IgxFilteringService implements OnDestroy { currAndBranch.filteringOperands.push(currExpressionUI.expression); } else { expressionsTree.filteringOperands.push(currExpressionUI.expression); - currAndBranch = null; + currAndBranch = null!; } } @@ -453,8 +453,8 @@ export class IgxFilteringService implements OnDestroy { * Generate the label of a chip from a given filtering expression. */ public getChipLabel(expression: IFilteringExpression): any { - if (expression.condition.isUnary) { - return this.grid.resourceStrings[`igx_grid_filter_${expression.condition.name}`] || expression.condition.name; + if (expression.condition!.isUnary) { + return (this.grid.resourceStrings as any)[`igx_grid_filter_${expression.condition!.name}`] || expression.condition!.name; } else if (expression.searchVal instanceof Date) { const column = this.grid.getColumnByName(expression.fieldName); const formatter = column.formatter; @@ -501,7 +501,7 @@ export class IgxFilteringService implements OnDestroy { return true; } - protected filter_internal(fieldName: string, term, conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree, + protected filter_internal(fieldName: string, term: any, conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree, ignoreCase: boolean) { const filteringTree = this.grid.filteringExpressionsTree; this.grid.crudService.endEdit(false); @@ -519,7 +519,7 @@ export class IgxFilteringService implements OnDestroy { protected prepare_filtering_expression( filteringState: IFilteringExpressionsTree, fieldName: string, - searchVal, + searchVal: any, conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree, ignoreCase: boolean, insertAtIndex = -1, @@ -533,7 +533,7 @@ export class IgxFilteringService implements OnDestroy { let newExpressionsTree = filteringState as FilteringExpressionsTree; if (createNewTree) { - newExpressionsTree = new FilteringExpressionsTree(filteringState.operator, filteringState.fieldName); + newExpressionsTree = new FilteringExpressionsTree(filteringState.operator, filteringState.fieldName!); newExpressionsTree.filteringOperands = [...filteringState.filteringOperands]; } @@ -583,7 +583,7 @@ export class IgxFilteringService implements OnDestroy { let count = 0; let operand; for (let i = 0; i < expressions.filteringOperands.length; i++) { - operand = expressions[i]; + operand = expressions.filteringOperands[i]; if (operand && isTree(operand)) { if (operand.operator === FilteringLogic.And) { count++; diff --git a/projects/igniteui-angular/grids/core/src/grid-actions/grid-action-button.component.ts b/projects/igniteui-angular/grids/core/src/grid-actions/grid-action-button.component.ts index 5a2734cf640..d767dd1c39d 100644 --- a/projects/igniteui-angular/grids/core/src/grid-actions/grid-action-button.component.ts +++ b/projects/igniteui-angular/grids/core/src/grid-actions/grid-action-button.component.ts @@ -16,7 +16,7 @@ export class IgxGridActionButtonComponent { /* blazorSuppress */ @ViewChild('container') - public container: ElementRef; + public container!: ElementRef; /* blazorSuppress */ /** @@ -28,7 +28,7 @@ export class IgxGridActionButtonComponent { * ``` */ @Output() - public actionClick = new EventEmitter(); + public actionClick = new EventEmitter(); /** * Reference to the current template. @@ -37,7 +37,7 @@ export class IgxGridActionButtonComponent { * @internal */ @ViewChild('menuItemTemplate') - public templateRef: TemplateRef; + public templateRef!: TemplateRef; /** * Whether button action is rendered in menu and should container text label. @@ -49,13 +49,13 @@ export class IgxGridActionButtonComponent { * Name of the icon to display in the button. */ @Input() - public iconName: string; + public iconName!: string; /** * Additional Menu item container element classes. */ @Input() - public classNames: string; + public classNames!: string; /** @hidden @internal */ public get containerClass(): string { @@ -66,26 +66,26 @@ export class IgxGridActionButtonComponent { * The name of the icon set. Used in case the icon is from a different icon set. */ @Input() - public iconSet: string; + public iconSet!: string; /** * The text of the label. */ @Input() - public labelText: string; + public labelText!: string; /** * @hidden * @internal */ - public handleClick(event) { + public handleClick(event: MouseEvent) { this.actionClick.emit(event); } /** * @hidden @internal */ - public preventEvent(event) { + public preventEvent(event: Event) { if (event) { event.stopPropagation(); event.preventDefault(); diff --git a/projects/igniteui-angular/grids/core/src/grid-actions/grid-actions-base.directive.ts b/projects/igniteui-angular/grids/core/src/grid-actions/grid-actions-base.directive.ts index c3bbb0b3e47..3ef8edd54db 100644 --- a/projects/igniteui-angular/grids/core/src/grid-actions/grid-actions-base.directive.ts +++ b/projects/igniteui-angular/grids/core/src/grid-actions/grid-actions-base.directive.ts @@ -19,7 +19,7 @@ export class IgxGridActionsBaseDirective implements AfterViewInit { /** @hidden @internal **/ @ViewChildren(IgxGridActionButtonComponent) - public buttons: QueryList; + public buttons!: QueryList; /** * Gets/Sets if the action buttons will be rendered as menu items. When in menu, items will be rendered with text label. @@ -34,7 +34,7 @@ export class IgxGridActionsBaseDirective implements AfterViewInit { public asMenuItems = false; /** @hidden @internal **/ - public strip: IgxActionStripToken; + public strip!: IgxActionStripToken; /** * @hidden @@ -73,7 +73,7 @@ export class IgxGridActionsBaseDirective implements AfterViewInit { * @internal * @param context */ - protected isRow(context): context is IgxRowDirective { + protected isRow(context: any): context is IgxRowDirective { return context && context instanceof IgxRowDirective; } } diff --git a/projects/igniteui-angular/grids/core/src/grid-actions/grid-editing-actions.component.ts b/projects/igniteui-angular/grids/core/src/grid-actions/grid-editing-actions.component.ts index d9ec410458b..e118d35c8d1 100644 --- a/projects/igniteui-angular/grids/core/src/grid-actions/grid-editing-actions.component.ts +++ b/projects/igniteui-angular/grids/core/src/grid-actions/grid-editing-actions.component.ts @@ -67,7 +67,7 @@ export class IgxGridEditingActionsComponent extends IgxGridActionsBaseDirective */ public get disabled(): boolean { if (!this.isRow(this.strip.context)) { - return; + return undefined!; } return this.strip.context.disabled; } @@ -110,7 +110,7 @@ export class IgxGridEditingActionsComponent extends IgxGridActionsBaseDirective * this.gridEditingActions.startEdit(); * ``` */ - public startEdit(event?): void { + public startEdit(event?: MouseEvent): void { if (event) { event.stopPropagation(); } @@ -130,14 +130,14 @@ export class IgxGridEditingActionsComponent extends IgxGridActionsBaseDirective if (grid.rowList.filter(r => r === row).length !== 0) { grid.gridAPI.crudService.enterEditMode(firstEditable, event); if (!grid.gridAPI.crudService.nonEditable) { - firstEditable.activate(event); + firstEditable.activate!(event); } } this.strip.hide(); } /** @hidden @internal **/ - public deleteRowHandler(event?): void { + public deleteRowHandler(event?: MouseEvent): void { if (event) { event.stopPropagation(); } @@ -152,7 +152,7 @@ export class IgxGridEditingActionsComponent extends IgxGridActionsBaseDirective } /** @hidden @internal **/ - public addRowHandler(event?, asChild?: boolean): void { + public addRowHandler(event?: MouseEvent, asChild?: boolean): void { if (event) { event.stopPropagation(); } diff --git a/projects/igniteui-angular/grids/core/src/grid-actions/grid-pinning-actions.component.ts b/projects/igniteui-angular/grids/core/src/grid-actions/grid-pinning-actions.component.ts index 839ecc875c9..c1b138d67cd 100644 --- a/projects/igniteui-angular/grids/core/src/grid-actions/grid-pinning-actions.component.ts +++ b/projects/igniteui-angular/grids/core/src/grid-actions/grid-pinning-actions.component.ts @@ -41,7 +41,7 @@ export class IgxGridPinningActionsComponent extends IgxGridActionsBaseDirective */ public get pinned(): boolean { if (!this.isRow(this.strip.context)) { - return; + return undefined!; } const context = this.strip.context; if (context && !this.iconsRendered) { @@ -59,7 +59,7 @@ export class IgxGridPinningActionsComponent extends IgxGridActionsBaseDirective */ public get inPinnedArea(): boolean { if (!this.isRow(this.strip.context)) { - return; + return undefined!; } const context = this.strip.context; return this.pinned && !context.disabled; @@ -73,7 +73,7 @@ export class IgxGridPinningActionsComponent extends IgxGridActionsBaseDirective */ public get pinnedTop(): boolean { if (!this.isRow(this.strip.context)) { - return; + return undefined!; } return this.strip.context.grid.isRowPinningToTop; } @@ -86,7 +86,7 @@ export class IgxGridPinningActionsComponent extends IgxGridActionsBaseDirective * this.gridPinningActions.pin(); * ``` */ - public pin(event?): void { + public pin(event?: MouseEvent): void { if (event) { event.stopPropagation(); } @@ -107,7 +107,7 @@ export class IgxGridPinningActionsComponent extends IgxGridActionsBaseDirective * this.gridPinningActions.unpin(); * ``` */ - public unpin(event?): void { + public unpin(event?: MouseEvent): void { if (event) { event.stopPropagation(); } @@ -120,7 +120,7 @@ export class IgxGridPinningActionsComponent extends IgxGridActionsBaseDirective this.strip.hide(); } - public scrollToRow(event) { + public scrollToRow(event: MouseEvent): void { if (event) { event.stopPropagation(); } diff --git a/projects/igniteui-angular/grids/core/src/grid-mrl-navigation.service.ts b/projects/igniteui-angular/grids/core/src/grid-mrl-navigation.service.ts index 1d2a5ca440a..2fdb52cfcbc 100644 --- a/projects/igniteui-angular/grids/core/src/grid-mrl-navigation.service.ts +++ b/projects/igniteui-angular/grids/core/src/grid-mrl-navigation.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, QueryList } from '@angular/core'; import { first } from 'rxjs/operators'; import { IgxGridNavigationService } from './grid-navigation.service'; import { ColumnType } from 'igniteui-angular/core'; @@ -30,7 +30,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { const containerHeight = this.grid.calcHeight ? Math.ceil(this.grid.calcHeight) : 0; const scrollPos = this.getVerticalScrollPositions(targetRowIndex, visibleColIndex); return (!targetRow || targetRow.offsetTop + scrollPos.topOffset < Math.abs(this.containerTopOffset) - || containerHeight && containerHeight < scrollPos.rowBottom - Math.ceil(this.scrollTop)); + || containerHeight && containerHeight < scrollPos.rowBottom - Math.ceil(this.scrollTop)) as boolean; } public override isColumnFullyVisible(visibleColIndex: number): boolean { @@ -101,22 +101,22 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } public getNextHorizontalCellPosition(previous = false) { - const parent = this.parentByChildIndex(this.activeNode.column); + const parent = this.parentByChildIndex(this.activeNode.column!)!; if (!this.hasNextHorizontalPosition(previous, parent)) { - return { row: this.activeNode.row, column: this.activeNode.column }; + return { row: this.activeNode.row, column: this.activeNode.column! }; } - const columns = previous ? parent.children.filter(c => c.rowStart <= this.activeNode.layout.rowStart) - .sort((a, b) => b.visibleIndex - a.visibleIndex) : parent.children.filter(c => c.rowStart <= this.activeNode.layout.rowStart); + const columns = previous ? parent.children.filter(c => c.rowStart <= this.activeNode.layout!.rowStart) + .sort((a, b) => b.visibleIndex - a.visibleIndex) : parent.children.filter(c => c.rowStart <= this.activeNode.layout!.rowStart); let column = columns.find((col) => previous ? - col.visibleIndex < this.activeNode.column && this.rowEnd(col) > this.activeNode.layout.rowStart : - col.visibleIndex > this.activeNode.column && col.colStart > this.activeNode.layout.colStart); - if (!column || (previous && this.activeNode.layout.colStart === 1)) { + col.visibleIndex < this.activeNode.column! && this.rowEnd(col) > this.activeNode.layout!.rowStart : + col.visibleIndex > this.activeNode.column! && col.colStart > this.activeNode.layout!.colStart); + if (!column || (previous && this.activeNode.layout!.colStart === 1)) { const index = previous ? parent.visibleIndex - 1 : parent.visibleIndex + 1; - const children = this.grid.columns.find(cols => cols.columnLayout && cols.visibleIndex === index).children; - column = previous ? children.toArray().reverse().find(child => child.rowStart <= this.activeNode.layout.rowStart) : - children.find(child => this.rowEnd(child) > this.activeNode.layout.rowStart && child.colStart === 1); + const children = this.grid.columns.find(cols => cols.columnLayout && cols.visibleIndex === index)!.children; + column = previous ? children.toArray().reverse().find(child => child.rowStart <= this.activeNode.layout!.rowStart) : + children.find(child => this.rowEnd(child) > this.activeNode.layout!.rowStart && child.colStart === 1); } - return { row: this.activeNode.row, column: column.visibleIndex }; + return { row: this.activeNode.row, column: column!.visibleIndex }; } public getNextVerticalPosition(previous = false) { @@ -131,9 +131,9 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { if (nextBlock && !this.isDataRow(nextRI)) { return {row: nextRI, column: this.activeNode.column}; } - const children = this.parentByChildIndex(this.activeNode.column).children; + const children = this.parentByChildIndex(this.activeNode.column)!.children; const col = previous ? this.getPreviousRowIndex(children, nextBlock) : this.getNextRowIndex(children, nextBlock); - return { row: nextBlock ? nextRI : this.activeNode.row, column: col.visibleIndex }; + return { row: nextBlock ? nextRI : this.activeNode.row, column: col!.visibleIndex }; } public override headerNavigation(event: KeyboardEvent) { @@ -147,9 +147,9 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } const alt = event.altKey; const ctrl = event.ctrlKey; - this.performHeaderKeyCombination(this.grid.getColumnByVisibleIndex(this.activeNode.column), key, event.shiftKey, ctrl, alt, event); + this.performHeaderKeyCombination(this.grid.getColumnByVisibleIndex(this.activeNode.column!), key, event.shiftKey, ctrl, alt, event); if (!ctrl && !alt && (key.includes('down') || key.includes('up'))) { - const children = this.parentByChildIndex(this.activeNode.column).children; + const children = this.parentByChildIndex(this.activeNode.column!)!.children; const col = key.includes('down') ? this.getNextRowIndex(children, false) : this.getPreviousRowIndex(children, false); if (!col) { return; @@ -157,7 +157,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { this.activeNode.column = col.visibleIndex; const layout = this.layout(this.activeNode.column); const nextLayout = {...this.activeNode.layout, rowStart: layout.rowStart, rowEnd: layout.rowEnd}; - this.setActiveNode({row: this.activeNode.row, layout: nextLayout}); + this.setActiveNode({row: this.activeNode.row, column: this.activeNode.column, layout: nextLayout}); return; } this.horizontalNav(event, key, -1, 'headerCell'); @@ -167,7 +167,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { * @hidden * @internal */ - public layout(visibleIndex) { + public layout(visibleIndex: number) { const column = this.grid.getColumnByVisibleIndex(visibleIndex); return {colStart: column.colStart, rowStart: column.rowStart, colEnd: column.colEnd, rowEnd: column.rowEnd, columnVisibleIndex: column.visibleIndex }; @@ -207,13 +207,13 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { case 'arrowup': case 'up': const prevPos = this.getNextVerticalPosition(true); - colIndex = ctrl ? this.activeNode.column : prevPos.column; + colIndex = ctrl ? this.activeNode.column! : prevPos.column; rowIndex = ctrl ? this.findFirstDataRowIndex() : prevPos.row; break; case 'arrowdown': case 'down': const nextPos = this.getNextVerticalPosition(); - colIndex = ctrl ? this.activeNode.column : nextPos.column; + colIndex = ctrl ? this.activeNode.column! : nextPos.column; rowIndex = ctrl ? this.findLastDataRowIndex() : nextPos.row; break; default: @@ -240,14 +240,14 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { this.activeNode.row = rowIndex; const newActiveNode = { - column: this.activeNode.column, + column: this.activeNode.column!, mchCache: { - level: this.activeNode.level, - visibleIndex: this.activeNode.column + level: this.activeNode.level!, + visibleIndex: this.activeNode.column! } }; - if ((key.includes('left') || key === 'home') && this.activeNode.column > 0) { + if ((key.includes('left') || key === 'home') && this.activeNode.column! > 0) { newActiveNode.column = ctrl || key === 'home' ? this.firstIndexPerRow : this.getNextHorizontalCellPosition(true).column; } if ((key.includes('right') || key === 'end') && this.activeNode.column !== this.lastIndexPerRow) { @@ -261,28 +261,28 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } const layout = this.layout(newActiveNode.column); - const newLayout = {...this.activeNode.layout, colStart: layout.colStart, rowEnd: layout.rowEnd}; + const newLayout = {...this.activeNode.layout!, colStart: layout.colStart, rowEnd: layout.rowEnd}; this.setActiveNode({row: this.activeNode.row, column: newActiveNode.column, layout: newLayout, mchCache: newActiveNode.mchCache}); this.performHorizontalScrollToCell(newActiveNode.column); } - private isParentColumnFullyVisible(parent: ColumnType): boolean { + private isParentColumnFullyVisible(parent: ColumnType | null): boolean { if (!this.forOfDir().getScroll().clientWidth || parent?.pinned) { return true; } - const index = this.forOfDir().igxForOf.indexOf(parent); + const index = this.forOfDir().igxForOf!.indexOf(parent); return this.displayContainerWidth >= this.forOfDir().getColumnScrollLeft(index + 1) - this.displayContainerScrollLeft && this.displayContainerScrollLeft <= this.forOfDir().getColumnScrollLeft(index); } private getChildColumnScrollPositions(visibleColIndex: number) { const targetCol = this.grid.getColumnByVisibleIndex(visibleColIndex); - const parentVIndex = this.forOfDir().igxForOf.indexOf(targetCol.parent); + const parentVIndex = this.forOfDir().igxForOf!.indexOf(targetCol.parent); let leftScroll = this.forOfDir().getColumnScrollLeft(parentVIndex); let rightScroll = this.forOfDir().getColumnScrollLeft(parentVIndex + 1); - targetCol.parent.children.forEach((c) => { + targetCol.parent!.children.forEach((c) => { if (c.rowStart >= targetCol.rowStart && c.visibleIndex < targetCol.visibleIndex) { leftScroll += parseInt(c.width, 10); } @@ -293,34 +293,34 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { return { leftScroll, rightScroll }; } - private getNextRowIndex(children, next) { - const rowStart = next ? 1 : this.rowEnd(this.grid.getColumnByVisibleIndex(this.activeNode.column)); + private getNextRowIndex(children: QueryList, next: boolean) { + const rowStart = next ? 1 : this.rowEnd(this.grid.getColumnByVisibleIndex(this.activeNode.column!)); const col = children.filter(c => c.rowStart === rowStart); - return col.find(co => co.colStart === this.activeNode.layout.colStart) || - col.sort((a, b) => b.visibleIndex - a.visibleIndex).find(co => co.colStart <= this.activeNode.layout.colStart); + return col.find(co => co.colStart === this.activeNode.layout!.colStart) || + col.sort((a, b) => b.visibleIndex - a.visibleIndex).find(co => co.colStart <= this.activeNode.layout!.colStart); } - private getPreviousRowIndex(children, prev) { + private getPreviousRowIndex(children: QueryList, prev: boolean) { const end = prev ? Math.max(...children.map(c => this.rowEnd(c))) : - this.grid.getColumnByVisibleIndex(this.activeNode.column).rowStart; + this.grid.getColumnByVisibleIndex(this.activeNode.column!).rowStart; const col = children.filter(c => this.rowEnd(c) === end); - return col.find(co => co.colStart === this.activeNode.layout.colStart) || - col.sort((a, b) => b.visibleIndex - a.visibleIndex).find(co => co.colStart <= this.activeNode.layout.colStart); + return col.find(co => co.colStart === this.activeNode.layout!.colStart) || + col.sort((a, b) => b.visibleIndex - a.visibleIndex).find(co => co.colStart <= this.activeNode.layout!.colStart); } private get lastIndexPerRow(): number { - const children = this.grid.visibleColumns.find(c => c.visibleIndex === this.lastLayoutIndex && c.columnLayout) + const children = this.grid.visibleColumns.find(c => c.visibleIndex === this.lastLayoutIndex && c.columnLayout)! .children.toArray().reverse(); - const column = children.find(co => co.rowStart === this.activeNode.layout.rowStart) || - children.find(co => co.rowStart <= this.activeNode.layout.rowStart); - return column.visibleIndex; + const column = children.find(co => co.rowStart === this.activeNode.layout!.rowStart) || + children.find(co => co.rowStart <= this.activeNode.layout!.rowStart); + return column!.visibleIndex; } private get firstIndexPerRow(): number { - const children = this.grid.visibleColumns.find(c => c.visibleIndex === 0 && c.columnLayout).children; - const column = children.find(co => co.rowStart === this.activeNode.layout.rowStart) || - children.find(co => co.rowStart <= this.activeNode.layout.rowStart); - return column.visibleIndex; + const children = this.grid.visibleColumns.find(c => c.visibleIndex === 0 && c.columnLayout)!.children; + const column = children.find(co => co.rowStart === this.activeNode.layout!.rowStart) || + children.find(co => co.rowStart <= this.activeNode.layout!.rowStart); + return column!.visibleIndex; } private get lastLayoutIndex(): number { @@ -331,25 +331,25 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { return Math.abs(this.grid.verticalScrollContainer.getScroll().scrollTop); } - private lastColIndexPerMRLBlock(visibleIndex = this.activeNode.column): number { - return this.parentByChildIndex(visibleIndex).children.last.visibleIndex; + private lastColIndexPerMRLBlock(visibleIndex = this.activeNode.column!): number { + return this.parentByChildIndex(visibleIndex)!.children.last.visibleIndex; } - private lastRowStartPerBlock(visibleIndex = this.activeNode.column) { - return Math.max(...this.parentByChildIndex(visibleIndex).children.map(c => c.rowStart)); + private lastRowStartPerBlock(visibleIndex = this.activeNode.column!) { + return Math.max(...this.parentByChildIndex(visibleIndex)!.children.map(c => c.rowStart)); } - private rowEnd(column): number { + private rowEnd(column: ColumnType): number { return column.rowEnd && column.rowEnd - column.rowStart ? column.rowStart + column.rowEnd - column.rowStart : column.rowStart + 1; } - private parentByChildIndex(visibleIndex) { + private parentByChildIndex(visibleIndex: number) { return this.grid.getColumnByVisibleIndex(visibleIndex)?.parent; } - private hasNextHorizontalPosition(previous = false, parent) { - if (previous && parent.visibleIndex === 0 && this.activeNode.layout.colStart === 1 || + private hasNextHorizontalPosition(previous = false, parent: ColumnType) { + if (previous && parent.visibleIndex === 0 && this.activeNode.layout!.colStart === 1 || !previous && parent.visibleIndex === this.lastLayoutIndex && this.activeNode.column === this.lastIndexPerRow) { return false; } @@ -357,9 +357,9 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } private hasNextVerticalPosition(prev = false) { - if ((prev && this.activeNode.row === 0 && (!this.isDataRow(this.activeNode.row) || this.activeNode.layout.rowStart === 1)) || + if ((prev && this.activeNode.row === 0 && (!this.isDataRow(this.activeNode.row) || this.activeNode.layout!.rowStart === 1)) || (!prev && this.activeNode.row >= this.grid.dataView.length - 1 && - this.activeNode.layout.rowStart === this.lastRowStartPerBlock())) { + this.activeNode.layout!.rowStart === this.lastRowStartPerBlock())) { return false; } return true; diff --git a/projects/igniteui-angular/grids/core/src/grid-navigation.service.ts b/projects/igniteui-angular/grids/core/src/grid-navigation.service.ts index b4195b8c32d..14f0fa83532 100644 --- a/projects/igniteui-angular/grids/core/src/grid-navigation.service.ts +++ b/projects/igniteui-angular/grids/core/src/grid-navigation.service.ts @@ -1,8 +1,10 @@ import { inject, Injectable } from '@angular/core'; import { first, throttleTime } from 'rxjs/operators'; import { IgxForOfDirective } from 'igniteui-angular/directives'; -import { GridType } from './common/grid.interface'; +import { GridType, RowType } from './common/grid.interface'; import { + IMultiRowLayoutNode, + ISelectionNode, NAVIGATION_KEYS, PlatformUtil, SortingDirection @@ -16,8 +18,7 @@ import { ROW_ADD_KEYS } from './grid-navigation-keys'; import { GridKeydownTargetType, GridSelectionMode, FilterMode } from './common/enums'; -import { IActiveNodeChangeEventArgs } from './common/events'; -import { IMultiRowLayoutNode } from './common/types'; +import { IActiveNodeChangeEventArgs, IGridEditEventArgs } from './common/events'; import { animationFrameScheduler, Subject } from 'rxjs'; export interface ColumnGroupsCache { @@ -27,6 +28,7 @@ export interface ColumnGroupsCache { export interface IActiveNode { gridID?: string; row: number; + // Optional: setActiveNode merges via Object.assign, so omitting the column preserves the current one. column?: number; level?: number; mchCache?: ColumnGroupsCache; @@ -39,7 +41,7 @@ const VERTICAL_VIRTUALIZATION_NAV_KEYS = new Set(['arrowup', 'up', 'arrowdown', @Injectable() export class IgxGridNavigationService { protected platform = inject(PlatformUtil); - public grid: GridType; + public grid!: GridType; public _activeNode: IActiveNode = {} as IActiveNode; public lastActiveNode: IActiveNode = {} as IActiveNode; protected pendingNavigation = false; @@ -104,14 +106,14 @@ export class IgxGridNavigationService { return; } if ([' ', 'spacebar', 'space'].indexOf(key) === -1) { - this.grid.selectionService.keyboardStateOnKeydown(this.activeNode, shift, shift && key === 'tab'); + this.grid.selectionService.keyboardStateOnKeydown(this.activeNode as ISelectionNode, shift, shift && key === 'tab'); } - const position = this.getNextPosition(this.activeNode.row, this.activeNode.column, key, shift, ctrl, event); + const position = this.getNextPosition(this.activeNode.row, this.activeNode.column!, key, shift, ctrl, event); const shouldNotifyVirtualizedKeyboardSelection = - this.shouldNotifyVirtualizedKeyboardSelection(key, position.rowIndex, position.colIndex); + this.shouldNotifyVirtualizedKeyboardSelection(key, position!.rowIndex, position!.colIndex); if (NAVIGATION_KEYS.has(key)) { event.preventDefault(); - this.navigateInBody(position.rowIndex, position.colIndex, (obj) => { + this.navigateInBody(position!.rowIndex, position!.colIndex, (obj) => { obj.target.activate(event); if (shouldNotifyVirtualizedKeyboardSelection) { this.grid.notifyChanges(); @@ -148,10 +150,10 @@ export class IgxGridNavigationService { } } - public focusTbody(event) { + public focusTbody(event: FocusEvent) { const gridRows = this.grid.verticalScrollContainer.totalItemCount ?? this.grid.dataView.length; if (gridRows < 1) { - this.activeNode = null; + this.activeNode = null!; return; } if (!this.activeNode || !Object.keys(this.activeNode).length || this.activeNode.row < 0 || this.activeNode.row > gridRows - 1) { @@ -161,16 +163,16 @@ export class IgxGridNavigationService { this.firstVisibleNode(this.lastActiveNode.row) : this.firstVisibleNode()); if (shouldClearSelection || (this.grid.cellSelection !== GridSelectionMode.multiple)) { this.grid.clearCellSelection(); - this.grid.navigateTo(this.activeNode.row, this.activeNode.column, (obj) => { + this.grid.navigateTo(this.activeNode.row, this.activeNode.column!, (obj) => { obj.target?.activate(event); }); } else { - if (hasLastActiveNode && !this.grid.selectionService.selected(this.lastActiveNode)) { + if (hasLastActiveNode && !this.grid.selectionService.selected(this.lastActiveNode as ISelectionNode)) { return; } const range = { rowStart: this.activeNode.row, rowEnd: this.activeNode.row, - columnStart: this.activeNode.column, columnEnd: this.activeNode.column + columnStart: this.activeNode.column!, columnEnd: this.activeNode.column! }; this.grid.selectRange(range); this.grid.notifyChanges(); @@ -188,7 +190,7 @@ export class IgxGridNavigationService { (!header && this.lastActiveNode.row !== this.grid.dataView.length); this.setActiveNode(this.firstVisibleNode(header ? -1 : this.grid.dataView.length)); if (shouldScrollIntoView) { - this.performHorizontalScrollToCell(this.activeNode.column); + this.performHorizontalScrollToCell(this.activeNode.column!); } } @@ -229,7 +231,7 @@ export class IgxGridNavigationService { // this is workaround: endTopOffset - containerHeight > 5 and should be replaced with: containerHeight < endTopOffset // when the page is zoomed the grid does not scroll the row completely in the view return !targetRow || targetRow.offsetTop < Math.abs(this.containerTopOffset) - || containerHeight && endTopOffset - containerHeight > 5; + || ((containerHeight && endTopOffset - containerHeight > 5) as boolean); } protected shouldNotifyVirtualizedKeyboardSelection(key: string, rowIndex: number, visibleColIndex: number): boolean { @@ -264,12 +266,12 @@ export class IgxGridNavigationService { } public performHorizontalScrollToCell(visibleColumnIndex: number, cb?: () => void) { - if (this.grid.rowList < 1 && this.grid.summariesRowList.length < 1 && this.grid.hasColumnGroups) { + if (this.grid.rowList.length < 1 && this.grid.summariesRowList.length < 1 && this.grid.hasColumnGroups) { let column = this.grid.getColumnByVisibleIndex(visibleColumnIndex); while (column.parent) { column = column.parent; } - visibleColumnIndex = this.forOfDir().igxForOf.indexOf(column); + visibleColumnIndex = this.forOfDir().igxForOf!.indexOf(column); } if (!this.shouldPerformHorizontalScroll(visibleColumnIndex)) { return; @@ -290,7 +292,7 @@ export class IgxGridNavigationService { let curRow: any; if (rowIndex < 0 || rowIndex > this.grid.dataView.length - 1) { - curRow = this.grid.dataView[rowIndex - this.grid.virtualizationState.startIndex]; + curRow = this.grid.dataView[rowIndex - this.grid.virtualizationState.startIndex!]; if (!curRow) { // if data is remote, record might not be in the view yet. return this.grid.verticalScrollContainer.isRemote && rowIndex >= 0 && rowIndex <= (this.grid as any).totalItemCount - 1; @@ -329,7 +331,7 @@ export class IgxGridNavigationService { const args: IActiveNodeChangeEventArgs = { row: this.activeNode.row, - column: this.activeNode.column, + column: this.activeNode.column!, level: this.activeNode.level, tag: type }; @@ -339,7 +341,7 @@ export class IgxGridNavigationService { public isActiveNodeChanged(activeNode: IActiveNode) { let isChanged = false; - const checkInnerProp = (aciveNode: ColumnGroupsCache | IMultiRowLayoutNode, prop) => { + const checkInnerProp = (aciveNode: ColumnGroupsCache | IMultiRowLayoutNode, prop: any) => { if (!aciveNode) { isChanged = true; return; @@ -347,7 +349,7 @@ export class IgxGridNavigationService { props = Object.getOwnPropertyNames(aciveNode); for (const propName of props) { - if (this.activeNode[prop][propName] !== aciveNode[propName]) { + if ((this.activeNode as any)[prop][propName] !== (aciveNode as any)[propName]) { isChanged = true; } } @@ -359,9 +361,9 @@ export class IgxGridNavigationService { let props = Object.getOwnPropertyNames(activeNode); for (const propName of props) { - if (!!this.activeNode[propName] && typeof this.activeNode[propName] === 'object') { - checkInnerProp(activeNode[propName], propName); - } else if (this.activeNode[propName] !== activeNode[propName]) { + if (!!(this.activeNode as any)[propName] && typeof (this.activeNode as any)[propName] === 'object') { + checkInnerProp((activeNode as any)[propName], propName); + } else if ((this.activeNode as any)[propName] !== (activeNode as any)[propName]) { isChanged = true; } } @@ -420,11 +422,11 @@ export class IgxGridNavigationService { break; case 'arrowleft': case 'left': - colIndex = ctrl ? 0 : this.activeNode.column - 1; + colIndex = ctrl ? 0 : this.activeNode.column! - 1; break; case 'arrowright': case 'right': - colIndex = ctrl ? this.lastColumnIndex : this.activeNode.column + 1; + colIndex = ctrl ? this.lastColumnIndex : this.activeNode.column! + 1; break; case 'arrowup': case 'up': @@ -444,7 +446,7 @@ export class IgxGridNavigationService { break; case 'enter': case 'f2': - const cell = this.grid.gridAPI.get_cell_by_visible_index(this.activeNode.row, this.activeNode.column); + const cell = this.grid.gridAPI.get_cell_by_visible_index(this.activeNode.row, this.activeNode.column!); if (!this.isDataRow(rowIndex) || !cell.editable) { break; } @@ -505,18 +507,18 @@ export class IgxGridNavigationService { } const newActiveNode = { - column: this.activeNode.column, + column: this.activeNode.column!, mchCache: { - level: this.activeNode.level, - visibleIndex: this.activeNode.column + level: this.activeNode.level!, + visibleIndex: this.activeNode.column! } }; - if ((key.includes('left') || key === 'home') && this.activeNode.column > 0) { - newActiveNode.column = ctrl || key === 'home' ? 0 : this.activeNode.column - 1; + if ((key.includes('left') || key === 'home') && this.activeNode.column! > 0) { + newActiveNode.column = ctrl || key === 'home' ? 0 : this.activeNode.column! - 1; } - if ((key.includes('right') || key === 'end') && this.activeNode.column < this.lastColumnIndex) { - newActiveNode.column = ctrl || key === 'end' ? this.lastColumnIndex : this.activeNode.column + 1; + if ((key.includes('right') || key === 'end') && this.activeNode.column! < this.lastColumnIndex) { + newActiveNode.column = ctrl || key === 'end' ? this.lastColumnIndex : this.activeNode.column! + 1; } if (tag === 'headerCell') { @@ -526,7 +528,7 @@ export class IgxGridNavigationService { } this.setActiveNode({ row: this.activeNode.row, column: newActiveNode.column, mchCache: newActiveNode.mchCache }); - this.performHorizontalScrollToCell(this.activeNode.column); + this.performHorizontalScrollToCell(this.activeNode.column!); } public get lastColumnIndex() { @@ -545,7 +547,7 @@ export class IgxGridNavigationService { protected getColumnUnpinnedIndex(visibleColumnIndex: number) { const column = this.grid.unpinnedColumns.find((col) => !col.columnGroup && col.visibleIndex === visibleColumnIndex); - return this.grid.pinnedColumns.length ? this.grid.unpinnedColumns.filter((c) => !c.columnGroup).indexOf(column) : + return this.grid.pinnedColumns.length ? this.grid.unpinnedColumns.filter((c) => !c.columnGroup).indexOf(column!) : visibleColumnIndex; } @@ -593,8 +595,8 @@ export class IgxGridNavigationService { } protected handleEditing(shift: boolean, event: KeyboardEvent) { - const next = shift ? this.grid.getPreviousCell(this.activeNode.row, this.activeNode.column, col => col.editable) : - this.grid.getNextCell(this.activeNode.row, this.activeNode.column, col => col.editable); + const next = shift ? this.grid.getPreviousCell(this.activeNode.row, this.activeNode.column!, col => col.editable) : + this.grid.getNextCell(this.activeNode.row, this.activeNode.column!, col => col.editable); if (!this.grid.crudService.rowInEditMode && this.isActiveNode(next.rowIndex, next.visibleColumnIndex)) { this.grid.crudService.endEdit(true, event); this.grid.tbody.nativeElement.focus(); @@ -603,7 +605,7 @@ export class IgxGridNavigationService { event.preventDefault(); if ((this.grid.crudService.rowInEditMode && this.grid.rowEditTabs.length) && (this.activeNode.row !== next.rowIndex || this.isActiveNode(next.rowIndex, next.visibleColumnIndex))) { - const args = this.grid.crudService.updateCell(true, event); + const args = this.grid.crudService.updateCell(true, event) as IGridEditEventArgs; if (args.cancel) { return; } else if (shift) { @@ -629,7 +631,7 @@ export class IgxGridNavigationService { }); } - protected navigateInBody(rowIndex, visibleColIndex, cb: (arg: any) => void = null): void { + protected navigateInBody(rowIndex: number, visibleColIndex: number, cb: (arg: any) => void = null!): void { if (!this.isValidPosition(rowIndex, visibleColIndex) || this.isActiveNode(rowIndex, visibleColIndex)) { return; } @@ -637,14 +639,14 @@ export class IgxGridNavigationService { } - protected emitKeyDown(type: GridKeydownTargetType, rowIndex, event) { - const row = this.grid.summariesRowList.toArray().concat(this.grid.rowList.toArray()).find(r => r.index === rowIndex); + protected emitKeyDown(type: GridKeydownTargetType, rowIndex: number, event: KeyboardEvent) { + const row = this.grid.summariesRowList.find((r) => r.index === rowIndex) || this.grid.rowList.find((r) => r.index === rowIndex); if (!row) { return; } const target = type === 'groupRow' ? row : - type === 'dataCell' ? row.cells?.find(c => c.visibleColumnIndex === this.activeNode.column) : + type === 'dataCell' ? (row as RowType).cells?.find(c => c.visibleColumnIndex === this.activeNode.column) : row.summaryCells?.find(c => c.visibleColumnIndex === this.activeNode.column); const keydownArgs = { targetType: type, event, cancel: false, target }; this.grid.gridKeydown.emit(keydownArgs); @@ -674,16 +676,17 @@ export class IgxGridNavigationService { return i; } } + return undefined!; } - protected getRowElementByIndex(index) { + protected getRowElementByIndex(index: number): HTMLElement | null { if (this.grid.hasDetails) { const detail = this.grid.nativeElement.querySelector(`[detail="true"][data-rowindex="${index}"]`); if (detail) { - return detail; + return detail as HTMLElement; } } - return this.grid.rowList.toArray().concat(this.grid.summariesRowList.toArray()).find(r => r.index === index)?.nativeElement; + return this.grid.rowList.find((r) => r.index === index)?.nativeElement || this.grid.summariesRowList.find((r) => r.index === index)?.nativeElement || null; } protected isValidPosition(rowIndex: number, colIndex: number): boolean { @@ -693,7 +696,7 @@ export class IgxGridNavigationService { } return this.activeNode.column !== colIndex && !this.isDataRow(rowIndex, true) ? false : true; } - protected performHeaderKeyCombination(column, key, shift, ctrl, alt, event) { + protected performHeaderKeyCombination(column: any, key: any, shift: any, ctrl: any, alt: any, event: KeyboardEvent) { let direction = this.grid.sortingExpressions.find(expr => expr.fieldName === column.field)?.dir; if (ctrl && key.includes('up') && column.sortable && !column.columnGroup) { direction = direction === SortingDirection.Asc ? SortingDirection.None : SortingDirection.Asc; @@ -744,12 +747,12 @@ export class IgxGridNavigationService { } } - private firstVisibleNode(rowIndex?) { + private firstVisibleNode(rowIndex?: number) { const colIndex = this.lastActiveNode.column !== undefined ? this.lastActiveNode.column : this.grid.visibleColumns.sort((c1, c2) => c1.visibleIndex - c2.visibleIndex) .find(c => this.isColumnFullyVisible(c.visibleIndex))?.visibleIndex; const column = this.grid.visibleColumns.find((col) => !col.columnLayout && col.visibleIndex === colIndex); - const rowInd = rowIndex ? rowIndex : this.grid.rowList.find(r => !this.shouldPerformVerticalScroll(r.index, colIndex))?.index; + const rowInd = rowIndex ? rowIndex : this.grid.rowList.find((r: any) => !this.shouldPerformVerticalScroll(r.index, colIndex!))?.index; const node = { row: rowInd ?? 0, column: column?.visibleIndex ?? 0, level: column?.level ?? 0, @@ -757,52 +760,52 @@ export class IgxGridNavigationService { layout: column && column.columnLayoutChild ? { rowStart: column.rowStart, colStart: column.colStart, rowEnd: column.rowEnd, colEnd: column.colEnd, columnVisibleIndex: column.visibleIndex - } : null + } : null! }; return node; } private handleMCHeaderNav(key: string, ctrl: boolean) { const newHeaderNode: ColumnGroupsCache = { - visibleIndex: this.activeNode.mchCache.visibleIndex, - level: this.activeNode.mchCache.level + visibleIndex: this.activeNode.mchCache!.visibleIndex, + level: this.activeNode.mchCache!.level }; const activeCol = this.currentActiveColumn; const lastGroupIndex = Math.max(... this.grid.visibleColumns. - filter(c => c.level <= this.activeNode.level).map(col => col.visibleIndex)); + filter(c => c.level <= this.activeNode.level!).map(col => col.visibleIndex)); let nextCol = activeCol; - if ((key.includes('left') || key === 'home') && this.activeNode.column > 0) { - const index = ctrl || key === 'home' ? 0 : this.activeNode.column - 1; + if ((key.includes('left') || key === 'home') && this.activeNode.column! > 0) { + const index = ctrl || key === 'home' ? 0 : this.activeNode.column! - 1; nextCol = this.getNextColumnMCH(index); newHeaderNode.visibleIndex = nextCol.visibleIndex; } - if ((key.includes('right') || key === 'end') && activeCol.visibleIndex < lastGroupIndex) { - const nextVIndex = activeCol.children ? Math.max(...activeCol.allChildren.map(c => c.visibleIndex)) + 1 : - activeCol.visibleIndex + 1; + if ((key.includes('right') || key === 'end') && activeCol!.visibleIndex < lastGroupIndex) { + const nextVIndex = activeCol!.children ? Math.max(...activeCol!.allChildren.map(c => c.visibleIndex)) + 1 : + activeCol!.visibleIndex + 1; nextCol = ctrl || key === 'end' ? this.getNextColumnMCH(this.lastColumnIndex) : this.getNextColumnMCH(nextVIndex); newHeaderNode.visibleIndex = nextCol.visibleIndex; } - if (!ctrl && key.includes('up') && this.activeNode.level > 0) { - nextCol = activeCol.parent; + if (!ctrl && key.includes('up') && this.activeNode.level! > 0) { + nextCol = activeCol!.parent!; newHeaderNode.level = nextCol.level; } - if (!ctrl && key.includes('down') && activeCol.children) { - nextCol = activeCol.children.find(c => c.visibleIndex === newHeaderNode.visibleIndex) || - activeCol.children.toArray().sort((a, b) => b.visibleIndex - a.visibleIndex) + if (!ctrl && key.includes('down') && activeCol!.children) { + nextCol = activeCol!.children.find(c => c.visibleIndex === newHeaderNode.visibleIndex) || + activeCol!.children.toArray().sort((a, b) => b.visibleIndex - a.visibleIndex) .filter(col => col.visibleIndex < newHeaderNode.visibleIndex)[0]; newHeaderNode.level = nextCol.level; } this.setActiveNode({ row: this.activeNode.row, - column: nextCol.visibleIndex, - level: nextCol.level, + column: nextCol!.visibleIndex, + level: nextCol!.level, mchCache: newHeaderNode }); - this.performHorizontalScrollToCell(nextCol.visibleIndex); + this.performHorizontalScrollToCell(nextCol!.visibleIndex); } - private handleMCHExpandCollapse(key, column) { + private handleMCHExpandCollapse(key: any, column: any) { if (!column.children || !column.collapsible) { return; } @@ -813,13 +816,13 @@ export class IgxGridNavigationService { } } - private handleColumnSelection(column, event) { + private handleColumnSelection(column: any, event: KeyboardEvent) { if (!column.selectable || this.grid.columnSelection === GridSelectionMode.none) { return; } const clearSelection = this.grid.columnSelection === GridSelectionMode.single; const columnsToSelect = !column.children ? [column.field] : - column.allChildren.filter(c => !c.hidden && c.selectable && !c.columnGroup).map(c => c.field); + column.allChildren.filter((c: any) => !c.hidden && c.selectable && !c.columnGroup).map((c: any) => c.field); if (column.selected) { this.grid.selectionService.deselectColumns(columnsToSelect, event); } else { @@ -827,11 +830,11 @@ export class IgxGridNavigationService { } } - private getNextColumnMCH(visibleIndex) { + private getNextColumnMCH(visibleIndex: number) { let col = this.grid.getColumnByVisibleIndex(visibleIndex); let parent = col.parent; - while (parent && col.level > this.activeNode.mchCache.level) { - col = col.parent; + while (parent && col.level > this.activeNode.mchCache!.level) { + col = col.parent!; parent = col.parent; } return col; diff --git a/projects/igniteui-angular/grids/core/src/grid-public-cell.ts b/projects/igniteui-angular/grids/core/src/grid-public-cell.ts index d3eb8d61314..6bde85e03ad 100644 --- a/projects/igniteui-angular/grids/core/src/grid-public-cell.ts +++ b/projects/igniteui-angular/grids/core/src/grid-public-cell.ts @@ -1,6 +1,6 @@ +import { IgxCell } from './common/crud.service'; import type { CellType, GridType, IGridValidationState, RowType, ValidationStatus } from './common/grid.interface'; -import type { ISelectionNode } from './common/types'; -import { columnFieldPath, type ColumnType, resolveNestedPath } from 'igniteui-angular/core'; +import { columnFieldPath, type ColumnType, type ISelectionNode, resolveNestedPath } from 'igniteui-angular/core'; export class IgxGridCell implements CellType { @@ -12,7 +12,7 @@ export class IgxGridCell implements CellType { * @memberof IgxGridCell */ public grid: GridType; - private _row: RowType; + private _row!: RowType; private _rowIndex: number; private _column: ColumnType; @@ -42,7 +42,7 @@ export class IgxGridCell implements CellType { * @memberof IgxGridCell */ public get row(): RowType { - return this._row || this.grid.createRow(this._rowIndex); + return this._row || this.grid.createRow!(this._rowIndex); } /** @@ -67,7 +67,7 @@ export class IgxGridCell implements CellType { */ public get editValue(): any { if (this.isCellInEditMode()) { - return this.grid.crudService.cell.editValue; + return (this.grid.crudService.cell as IgxCell).editValue; } } @@ -82,7 +82,7 @@ export class IgxGridCell implements CellType { */ public set editValue(value: any) { if (this.isCellInEditMode()) { - this.grid.crudService.cell.editValue = value; + (this.grid.crudService.cell as IgxCell).editValue = value; } } @@ -96,7 +96,7 @@ export class IgxGridCell implements CellType { public get validation(): IGridValidationState { const form = this.grid.validation.getFormControl(this.row.key, this.column.field); - return { status: form?.status as ValidationStatus || 'VALID', errors: form?.errors } as const; + return { status: form?.status as ValidationStatus || 'VALID', errors: form?.errors! } as const; } /** @@ -248,7 +248,7 @@ export class IgxGridCell implements CellType { this.endEdit(); - const cell = this.isCellInEditMode() ? this.grid.crudService.cell : this.grid.crudService.createCell(this); + const cell = this.isCellInEditMode() ? this.grid.crudService.cell as IgxCell : this.grid.crudService.createCell(this); cell.editValue = val; this.grid.gridAPI.update_cell(cell); this.grid.crudService.endCellEdit(); @@ -258,30 +258,30 @@ export class IgxGridCell implements CellType { protected get selectionNode(): ISelectionNode { return { row: this.row?.index, - column: this.column.columnLayoutChild ? this.column.parent.visibleIndex : this.column.visibleIndex, + column: this.column.columnLayoutChild ? this.column.parent!.visibleIndex : this.column.visibleIndex, layout: this.column.columnLayoutChild ? { rowStart: this.column.rowStart, colStart: this.column.colStart, rowEnd: this.column.rowEnd, colEnd: this.column.colEnd, columnVisibleIndex: this.column.visibleIndex - } : null + } : null! }; } private isCellInEditMode(): boolean { if (this.grid.crudService.cellInEditMode) { - const cellInEditMode = this.grid.crudService.cell.id; - const isCurrentCell = cellInEditMode.rowID === this.id.rowID && - cellInEditMode.rowIndex === this.id.rowIndex && - cellInEditMode.columnID === this.id.columnID; + const cellInEditMode = this.grid.crudService.cell?.id; + const isCurrentCell = cellInEditMode?.rowID === this.id.rowID && + cellInEditMode?.rowIndex === this.id.rowIndex && + cellInEditMode?.columnID === this.id.columnID; return isCurrentCell; } return false; } private endEdit(): void { - if (!this.isCellInEditMode()) { + if (!this.isCellInEditMode() && this.grid.crudService.cell) { this.grid.gridAPI.update_cell(this.grid.crudService.cell); this.grid.crudService.endCellEdit(); } diff --git a/projects/igniteui-angular/grids/core/src/grid-public-row.ts b/projects/igniteui-angular/grids/core/src/grid-public-row.ts index d1242433367..4264353aaab 100644 --- a/projects/igniteui-angular/grids/core/src/grid-public-row.ts +++ b/projects/igniteui-angular/grids/core/src/grid-public-row.ts @@ -5,11 +5,11 @@ import { CellType, GridServiceType, GridType, IGridValidationState, RowType, Val import { GridSummaryCalculationMode, IGroupByRecord, IgxSummaryResult, ITreeGridRecord, mergeObjects } from 'igniteui-angular/core'; abstract class BaseRow implements RowType { - public index: number; + public index!: number; /** * The grid that contains the row. */ - public grid: GridType; + public grid!: GridType; protected _data?: any; /** @@ -56,7 +56,7 @@ abstract class BaseRow implements RowType { */ public get validation(): IGridValidationState { const formGroup = this.grid.validation.getFormGroup(this.key); - return { status: formGroup?.status as ValidationStatus || 'VALID', errors: formGroup?.errors } as const; + return { status: formGroup?.status as ValidationStatus || 'VALID', errors: formGroup?.errors! } as const; } /** @@ -232,7 +232,7 @@ abstract class BaseRow implements RowType { */ public update(value: any): void { const crudService = this.grid.crudService; - if (crudService.cellInEditMode && crudService.cell.id.rowID === this.key) { + if (crudService.cellInEditMode && crudService.cell?.id.rowID === this.key) { this.grid.transactions.endPending(false); } const row = new IgxEditRow(this.key, this.index, this.data, this.grid); @@ -272,18 +272,18 @@ export class IgxGridRow extends BaseRow implements RowType { public override get viewIndex(): number { if (this.grid.paginator) { const precedingDetailRows = []; - const precedingGroupRows = []; + const precedingGroupRows: any[] = []; const firstRow = this.grid.dataView[0]; const hasDetailRows = this.grid.expansionStates.size; - const hasGroupedRows = this.grid.groupingExpressions.length; + const hasGroupedRows = this.grid.groupingExpressions!.length; let precedingSummaryRows = 0; - const firstRowInd = this.grid.groupingFlatResult.indexOf(firstRow); + const firstRowInd = this.grid.groupingFlatResult!.indexOf(firstRow); // from groupingFlatResult, resolve two other collections: // precedingGroupedRows -> use it to resolve summaryRow for each group in previous pages // precedingDetailRows -> ise it to resolve the detail row for each expanded grid row in previous pages if (hasDetailRows || hasGroupedRows) { - this.grid.groupingFlatResult.forEach((r, ind) => { + this.grid.groupingFlatResult!.forEach((r, ind) => { const rowID = this.grid.primaryKey ? r[this.grid.primaryKey] : r; if (hasGroupedRows && ind < firstRowInd && this.grid.isGroupByRecord(r)) { precedingGroupRows.push(r); @@ -315,9 +315,9 @@ export class IgxGridRow extends BaseRow implements RowType { * Returns the parent row, if grid is grouped. */ public get parent(): RowType { - let parent: IgxGroupByRow; - if (!this.grid.groupingExpressions.length) { - return undefined; + let parent!: IgxGroupByRow; + if (!this.grid.groupingExpressions!.length) { + return undefined!; } let i = this.index - 1; @@ -350,11 +350,11 @@ export class IgxTreeGridRow extends BaseRow implements RowType { public override get viewIndex(): number { if (this.grid.hasSummarizedColumns && this.grid.page > 0) { if (this.grid.summaryCalculationMode !== GridSummaryCalculationMode.rootLevelOnly) { - const firstRowIndex = this.grid.processedExpandedFlatData.indexOf(this.grid.dataView[0].data); + const firstRowIndex = this.grid.processedExpandedFlatData!.indexOf(this.grid.dataView[0].data); // firstRowIndex is based on data result after all pipes triggered, excluding summary pipe const precedingSummaryRows = this.grid.summaryPosition === GridSummaryPosition.bottom ? - this.grid.rootRecords.indexOf(this.getRootParent(this.grid.dataView[0])) : - this.grid.rootRecords.indexOf(this.getRootParent(this.grid.dataView[0])) + 1; + this.grid.rootRecords!.indexOf(this.getRootParent(this.grid.dataView[0])) : + this.grid.rootRecords!.indexOf(this.getRootParent(this.grid.dataView[0])) + 1; // there is a summary row for each root record, so we calculate how many root records are rendered before the current row return firstRowIndex + precedingSummaryRows + this.index; } @@ -375,7 +375,7 @@ export class IgxTreeGridRow extends BaseRow implements RowType { this.grid.transactions.getAggregatedValue(this.key, false)); } const rec = this.grid.dataView[this.index]; - return this._data ? this._data : this.grid.isTreeRow(rec) ? rec.data : rec; + return this._data ? this._data : this.grid.isTreeRow!(rec) ? rec.data : rec; } /** @@ -384,7 +384,7 @@ export class IgxTreeGridRow extends BaseRow implements RowType { public get children(): RowType[] { const children: IgxTreeGridRow[] = []; if (this.treeRow.expanded) { - this.treeRow.children.forEach((rec, i) => { + this.treeRow.children!.forEach((rec, i) => { const row = new IgxTreeGridRow(this.grid, this.index + 1 + i, rec.data); children.push(row); }); @@ -396,7 +396,7 @@ export class IgxTreeGridRow extends BaseRow implements RowType { * Returns the parent row. */ public get parent(): RowType { - const row = this.grid.getRowByKey(this.treeRow.parent?.key); + const row = this.grid.getRowByKey!(this.treeRow.parent?.key); return row; } @@ -419,7 +419,7 @@ export class IgxTreeGridRow extends BaseRow implements RowType { * ``` */ public get treeRow(): ITreeGridRecord { - return this._treeRow ?? this.grid.records.get(this.key); + return this._treeRow ?? this.grid.records!.get(this.key)!; } /** @@ -499,15 +499,15 @@ export class IgxHierarchicalGridRow extends BaseRow implements RowType { * Returns true if row islands exist. */ public override get hasChildren(): boolean { - return !!this.grid.childLayoutKeys.length; + return !!this.grid.childLayoutKeys!.length; } /** * Returns the view index calculated per the grid page. */ public override get viewIndex() { - const firstRowInd = this.grid.filteredSortedData.indexOf(this.grid.dataView[0]); - const expandedRows = this.grid.filteredSortedData.filter((rec, ind) => { + const firstRowInd = this.grid.filteredSortedData!.indexOf(this.grid.dataView[0]); + const expandedRows = this.grid.filteredSortedData!.filter((rec, ind) => { const rowID = this.grid.primaryKey ? rec[this.grid.primaryKey] : rec; return this.grid.expansionStates.get(rowID) && ind < firstRowInd; }); @@ -568,18 +568,18 @@ export class IgxGroupByRow implements RowType { public get viewIndex(): number { if (this.grid.page) { const precedingDetailRows = []; - const precedingGroupRows = []; + const precedingGroupRows: any[] = []; const firstRow = this.grid.dataView[0]; const hasDetailRows = this.grid.expansionStates.size; - const hasGroupedRows = this.grid.groupingExpressions.length; + const hasGroupedRows = this.grid.groupingExpressions!.length; let precedingSummaryRows = 0; - const firstRowInd = this.grid.groupingFlatResult.indexOf(firstRow); + const firstRowInd = this.grid.groupingFlatResult!.indexOf(firstRow); // from groupingFlatResult, resolve two other collections: // precedingGroupedRows -> use it to resolve summaryRow for each group in previous pages // precedingDetailRows -> ise it to resolve the detail row for each expanded grid row in previous pages if (hasDetailRows || hasGroupedRows) { - this.grid.groupingFlatResult.forEach((r, ind) => { + this.grid.groupingFlatResult!.forEach((r, ind) => { const rowID = this.grid.primaryKey ? r[this.grid.primaryKey] : r; if (hasGroupedRows && ind < firstRowInd && this.grid.isGroupByRecord(r)) { precedingGroupRows.push(r); @@ -658,7 +658,7 @@ export class IgxGroupByRow implements RowType { } public set expanded(value: boolean) { - this.gridAPI.set_grouprow_expansion_state(this.groupRow, value); + this.gridAPI.set_grouprow_expansion_state!(this.groupRow, value); } public isActive(): boolean { @@ -672,7 +672,7 @@ export class IgxGroupByRow implements RowType { * ``` */ public toggle(): void { - this.grid.toggleGroup(this.groupRow); + this.grid.toggleGroup!(this.groupRow); } private get gridAPI(): GridServiceType { @@ -711,18 +711,18 @@ export class IgxSummaryRow implements RowType { if (this.grid.type === 'flat') { if (this.grid.page) { const precedingDetailRows = []; - const precedingGroupRows = []; + const precedingGroupRows: any[] = []; const firstRow = this.grid.dataView[0]; const hasDetailRows = this.grid.expansionStates.size; - const hasGroupedRows = this.grid.groupingExpressions.length; + const hasGroupedRows = this.grid.groupingExpressions!.length; let precedingSummaryRows = 0; - const firstRowInd = this.grid.groupingFlatResult.indexOf(firstRow); + const firstRowInd = this.grid.groupingFlatResult!.indexOf(firstRow); // from groupingFlatResult, resolve two other collections: // precedingGroupedRows -> use it to resolve summaryRow for each group in previous pages // precedingDetailRows -> ise it to resolve the detail row for each expanded grid row in previous pages if (hasDetailRows || hasGroupedRows) { - this.grid.groupingFlatResult.forEach((r, ind) => { + this.grid.groupingFlatResult!.forEach((r, ind) => { const rowID = this.grid.primaryKey ? r[this.grid.primaryKey] : r; if (hasGroupedRows && ind < firstRowInd && this.grid.isGroupByRecord(r)) { precedingGroupRows.push(r); @@ -751,10 +751,10 @@ export class IgxSummaryRow implements RowType { } } else if (this.grid.type === 'tree') { if (this.grid.summaryCalculationMode !== GridSummaryCalculationMode.rootLevelOnly) { - const firstRowIndex = this.grid.processedExpandedFlatData.indexOf(this.grid.dataView[0].data); + const firstRowIndex = this.grid.processedExpandedFlatData!.indexOf(this.grid.dataView[0].data); const precedingSummaryRows = this.grid.summaryPosition === GridSummaryPosition.bottom ? - this.grid.rootRecords.indexOf(this.getRootParent(this.grid.dataView[0])) : - this.grid.rootRecords.indexOf(this.getRootParent(this.grid.dataView[0])) + 1; + this.grid.rootRecords!.indexOf(this.getRootParent(this.grid.dataView[0])) : + this.grid.rootRecords!.indexOf(this.getRootParent(this.grid.dataView[0])) + 1; return firstRowIndex + precedingSummaryRows + this.index; } } diff --git a/projects/igniteui-angular/grids/core/src/grid-validation.service.ts b/projects/igniteui-angular/grids/core/src/grid-validation.service.ts index bb23dc85f87..c31246332cc 100644 --- a/projects/igniteui-angular/grids/core/src/grid-validation.service.ts +++ b/projects/igniteui-angular/grids/core/src/grid-validation.service.ts @@ -9,7 +9,7 @@ export class IgxGridValidationService { * @hidden * @internal */ - public grid: GridType; + public grid!: GridType; private _validityStates = new Map(); private _valid = true; @@ -24,7 +24,7 @@ export class IgxGridValidationService { * @hidden * @internal */ - public create(rowId, data) { + public create(rowId: any, data: any) { let formGroup = this.getFormGroup(rowId); if (!formGroup) { formGroup = new FormGroup({}); @@ -107,7 +107,7 @@ export class IgxGridValidationService { */ public isFieldInvalid(formGroup: FormGroup, fieldName: string): boolean { const path = this.getFormControlPath(fieldName); - return formGroup.get(path)?.invalid && formGroup.get(path)?.touched; + return (formGroup.get(path)?.invalid && formGroup.get(path)?.touched) as boolean; } /** @@ -115,7 +115,7 @@ export class IgxGridValidationService { */ public isFieldValidAfterEdit(formGroup: FormGroup, fieldName: string): boolean { const path = this.getFormControlPath(fieldName); - return !formGroup.get(path)?.invalid && formGroup.get(path)?.dirty; + return (!formGroup.get(path)?.invalid && formGroup.get(path)?.dirty) as boolean; } /** @@ -130,10 +130,10 @@ export class IgxGridValidationService { const path = this.getFormControlPath(col.field); const control = formGroup.get(path); if (control) { - state.push({ field: col.field, status: control.status as ValidationStatus, errors: control.errors }) + state.push({ field: col.field, status: control.status as ValidationStatus, errors: control.errors! }) } } - states.push({ key: key, status: formGroup.status as ValidationStatus, fields: state, errors: formGroup.errors }); + states.push({ key: key, status: formGroup.status as ValidationStatus, fields: state, errors: formGroup.errors! }); }); return states; } diff --git a/projects/igniteui-angular/grids/core/src/grid.common.ts b/projects/igniteui-angular/grids/core/src/grid.common.ts index 214791e8969..10f6da5084c 100644 --- a/projects/igniteui-angular/grids/core/src/grid.common.ts +++ b/projects/igniteui-angular/grids/core/src/grid.common.ts @@ -27,24 +27,24 @@ export interface RowEditPositionSettings extends PositionSettings { export class RowEditPositionStrategy extends ConnectedPositioningStrategy { public isTop = false; public isTopInitialPosition = null; - public override settings: RowEditPositionSettings; + public override settings!: RowEditPositionSettings; private io: IntersectionObserver | null = null; - public override position(contentElement: HTMLElement, _size: { width: number; height: number }, document?: Document, initialCall?: boolean, - target?: Point | HTMLElement): void { + public override position(contentElement: HTMLElement, _size: { width: number; height: number }, document: Document, initialCall: boolean, + target: Point | HTMLElement): void { this.internalPosition(contentElement, _size, document, initialCall, target); // Use the IntersectionObserverHelper to manage position updates when the target moves this.io?.disconnect(); const targetElement: HTMLElement = target as HTMLElement; // current grid.row this.io = Util.setupIntersectionObserver( targetElement, - document, + document!, () => this.internalPosition(contentElement, { width: targetElement.clientWidth, height: targetElement.clientHeight }, document, false, targetElement) ); } - private internalPosition(contentElement: HTMLElement, _size: { width: number; height: number }, document?: Document, initialCall?: boolean, - target?: Point | HTMLElement): void { + private internalPosition(contentElement: HTMLElement, _size: { width: number; height: number }, document: Document, initialCall: boolean, + target: Point | HTMLElement): void { const container = this.settings.container; // grid.tbody const targetElement: HTMLElement = target as HTMLElement; // current grid.row @@ -54,7 +54,7 @@ export class RowEditPositionStrategy extends ConnectedPositioningStrategy { // which means that when scrolling then overlay may hide, while the row is still visible (UX requirement). this.isTop = this.isTopInitialPosition !== null ? this.isTopInitialPosition : - container.getBoundingClientRect().bottom < + container!.getBoundingClientRect().bottom < targetElement.getBoundingClientRect().bottom + contentElement.getBoundingClientRect().height; // Set width of the row editing overlay to equal row width, otherwise it fits 100% of the grid. diff --git a/projects/igniteui-angular/grids/core/src/grid.directives.ts b/projects/igniteui-angular/grids/core/src/grid.directives.ts index f003503b4af..aeee19b85ea 100644 --- a/projects/igniteui-angular/grids/core/src/grid.directives.ts +++ b/projects/igniteui-angular/grids/core/src/grid.directives.ts @@ -1,5 +1,5 @@ import { Directive, HostBinding, TemplateRef, inject } from '@angular/core'; -import { IgxDropDirective } from 'igniteui-angular/directives'; +import { IgxDragCustomEventDetails, IgxDropDirective } from 'igniteui-angular/directives'; import { IgxColumnMovingDragDirective } from './moving/moving.drag.directive'; import { IgxGroupByAreaDirective } from './grouping/group-by-area.directive'; import { @@ -190,8 +190,8 @@ export class IgxGroupAreaDropDirective extends IgxDropDirective { @HostBinding('class.igx-drop-area--hover') public hovered = false; - public override onDragEnter(event) { - const drag: IgxColumnMovingDragDirective = event.detail.owner; + public override onDragEnter(event: CustomEvent) { + const drag: IgxColumnMovingDragDirective = event.detail.owner as IgxColumnMovingDragDirective; const column: ColumnType = drag.column; if (!this.columnBelongsToGrid(column)) { return; @@ -209,20 +209,20 @@ export class IgxGroupAreaDropDirective extends IgxDropDirective { } } - public override onDragLeave(event) { - const drag: IgxColumnMovingDragDirective = event.detail.owner; + public override onDragLeave(event: CustomEvent) { + const drag: IgxColumnMovingDragDirective = event.detail.owner as IgxColumnMovingDragDirective; const column: ColumnType = drag.column; if (!this.columnBelongsToGrid(column)) { return; } - event.detail.owner.icon.innerText = 'block'; + drag.icon.innerText = 'block'; this.hovered = false; } - private closestParentByAttr(elem, attr) { + private closestParentByAttr(elem: HTMLElement, attr: string): HTMLElement { return elem.hasAttribute(attr) ? elem : - this.closestParentByAttr(elem.parentElement, attr); + this.closestParentByAttr(elem.parentElement!, attr); } private columnBelongsToGrid(column: ColumnType) { diff --git a/projects/igniteui-angular/grids/core/src/grid.rowEdit.directive.ts b/projects/igniteui-angular/grids/core/src/grid.rowEdit.directive.ts index e36bf8a3e3f..2045c5262a1 100644 --- a/projects/igniteui-angular/grids/core/src/grid.rowEdit.directive.ts +++ b/projects/igniteui-angular/grids/core/src/grid.rowEdit.directive.ts @@ -60,7 +60,7 @@ export class IgxRowEditTabStopDirective { public grid = inject(IGX_GRID_BASE); public element = inject(ElementRef); - private currentCellIndex: number; + private currentCellIndex!: number; @HostListener('keydown.tab', [`$event`]) @HostListener('keydown.shift.tab', [`$event`]) @@ -93,11 +93,13 @@ export class IgxRowEditTabStopDirective { private move(event: KeyboardEvent) { event.preventDefault(); this.currentCellIndex = event.shiftKey ? this.grid.lastEditableColumnIndex : this.grid.firstEditableColumnIndex; - this.grid.navigation.activeNode.row = this.grid.crudService.rowInEditMode.index; + this.grid.navigation.activeNode.row = this.grid.crudService.rowInEditMode?.index; this.grid.navigation.activeNode.column = this.currentCellIndex; - this.grid.navigateTo(this.grid.crudService.rowInEditMode.index, this.currentCellIndex, (obj) => { - obj.target.activate(event); - this.grid.cdr.detectChanges(); - }); + if (this.grid.crudService.rowInEditMode) { + this.grid.navigateTo(this.grid.crudService.rowInEditMode.index, this.currentCellIndex, (obj) => { + obj.target.activate(event); + this.grid.cdr.detectChanges(); + }); + } } } diff --git a/projects/igniteui-angular/grids/core/src/grouping/events.ts b/projects/igniteui-angular/grids/core/src/grouping/events.ts new file mode 100644 index 00000000000..4fcc5bc1eb6 --- /dev/null +++ b/projects/igniteui-angular/grids/core/src/grouping/events.ts @@ -0,0 +1,8 @@ +import { IBaseEventArgs, ISortingExpression } from 'igniteui-angular/core'; +import { IgxColumnComponent } from '../columns/column.component'; + +export interface IGroupingDoneEventArgs extends IBaseEventArgs { + expressions: Array | ISortingExpression; + groupedColumns: Array | IgxColumnComponent; + ungroupedColumns: Array | IgxColumnComponent; +} \ No newline at end of file diff --git a/projects/igniteui-angular/grids/core/src/grouping/group-by-area.directive.ts b/projects/igniteui-angular/grids/core/src/grouping/group-by-area.directive.ts index 507fbbf4217..fd1776badb5 100644 --- a/projects/igniteui-angular/grids/core/src/grouping/group-by-area.directive.ts +++ b/projects/igniteui-angular/grids/core/src/grouping/group-by-area.directive.ts @@ -16,6 +16,7 @@ import { IChipsAreaReorderEventArgs, IgxChipComponent } from 'igniteui-angular/c import { FlatGridType, GridType } from '../common/grid.interface'; import { IgxColumnMovingDragDirective } from '../moving/moving.drag.directive'; import { IGroupingExpression, PlatformUtil, SortingDirection } from 'igniteui-angular/core'; +import { IgxDragCustomEventDetails } from 'igniteui-angular/directives'; /** * An internal component representing a base group-by drop area. @@ -32,7 +33,7 @@ export abstract class IgxGroupByAreaDirective { * Otherwise, uses the default internal one. */ @Input() - public dropAreaTemplate: TemplateRef; + public dropAreaTemplate!: TemplateRef; @HostBinding('class.igx-grid-grouparea') public defaultClass = true; @@ -45,7 +46,7 @@ export abstract class IgxGroupByAreaDirective { /** The parent grid containing the component. */ @Input() - public grid: FlatGridType | GridType; + public grid!: FlatGridType | GridType; /** * The group-by expressions provided by the parent grid. @@ -79,9 +80,9 @@ export abstract class IgxGroupByAreaDirective { public expressionsChange = new EventEmitter(); @ViewChildren(IgxChipComponent) - public chips: QueryList; + public chips!: QueryList; - public chipExpressions: IGroupingExpression[]; + public chipExpressions!: IGroupingExpression[]; /** The native DOM element. Used in sizing calculations. */ public get nativeElement() { @@ -89,7 +90,7 @@ export abstract class IgxGroupByAreaDirective { } private _expressions: IGroupingExpression[] = []; - private _dropAreaMessage: string; + private _dropAreaMessage!: string; public get dropAreaVisible(): boolean { return (this.grid.columnInDrag && this.grid.columnInDrag.groupable) || @@ -109,8 +110,8 @@ export abstract class IgxGroupByAreaDirective { this.updateGroupSorting(id); } - public onDragDrop(event) { - const drag: IgxColumnMovingDragDirective = event.detail.owner; + public onDragDrop(event: Event) { + const drag: IgxColumnMovingDragDirective = (event as CustomEvent).detail.owner as IgxColumnMovingDragDirective; if (drag instanceof IgxColumnMovingDragDirective) { const column = drag.column; if (!this.grid.columns.find(c => c === column)) { @@ -133,10 +134,10 @@ export abstract class IgxGroupByAreaDirective { } protected getReorderedExpressions(chipsArray: IgxChipComponent[]) { - const newExpressions = []; + const newExpressions: IGroupingExpression[] = []; chipsArray.forEach(chip => { - const expr = this.expressions.find(item => item.fieldName === chip.id); + const expr = this.expressions.find(item => item.fieldName === chip.id)!; // disallow changing order if there are columns with groupable: false if (!this.grid.getColumnByName(expr.fieldName)?.groupable) { @@ -150,7 +151,7 @@ export abstract class IgxGroupByAreaDirective { } protected updateGroupSorting(id: string) { - const expr = this.expressions.find(e => e.fieldName === id); + const expr = this.expressions.find(e => e.fieldName === id)!; expr.dir = 3 - expr.dir; const expressionsChangeEvent = this.grid.groupingExpressionsChange || this.expressionsChange; expressionsChangeEvent.emit(this.expressions); @@ -161,13 +162,13 @@ export abstract class IgxGroupByAreaDirective { protected expressionsChanged() { } - public abstract handleReorder(event: IChipsAreaReorderEventArgs); + public abstract handleReorder(event: IChipsAreaReorderEventArgs): void; - public abstract handleMoveEnd(); + public abstract handleMoveEnd(): void; - public abstract groupBy(expression: IGroupingExpression); + public abstract groupBy(expression: IGroupingExpression): void; - public abstract clearGrouping(name: string); + public abstract clearGrouping(name: string): void; } diff --git a/projects/igniteui-angular/grids/core/src/headers/grid-header-group.component.ts b/projects/igniteui-angular/grids/core/src/headers/grid-header-group.component.ts index 269708993f7..5127d79e5d5 100644 --- a/projects/igniteui-angular/grids/core/src/headers/grid-header-group.component.ts +++ b/projects/igniteui-angular/grids/core/src/headers/grid-header-group.component.ts @@ -83,7 +83,7 @@ export class IgxGridHeaderGroupComponent implements DoCheck { * @memberof IgxGridHeaderGroupComponent */ @Input() - public column: ColumnType; + public column!: ColumnType; @HostBinding('class.igx-grid-th--active') public get active() { @@ -101,19 +101,19 @@ export class IgxGridHeaderGroupComponent implements DoCheck { * @hidden */ @ViewChild(IgxGridHeaderComponent) - public header: IgxGridHeaderComponent; + public header!: IgxGridHeaderComponent; /** * @hidden */ @ViewChild(IgxGridFilteringCellComponent) - public filter: IgxGridFilteringCellComponent; + public filter!: IgxGridFilteringCellComponent; /** * @hidden */ @ViewChildren(forwardRef(() => IgxGridHeaderGroupComponent), { read: IgxGridHeaderGroupComponent }) - public children: QueryList; + public children!: QueryList; /** * Gets the width of the header group. @@ -279,7 +279,7 @@ export class IgxGridHeaderGroupComponent implements DoCheck { this.grid.selectionService.selectColumns(columnsToSelect, clearSelection, rangeSelection, event); } else { const selectedFields = this.grid.selectionService.getSelectedColumns(); - if ((selectedFields.length === columnsToSelect.length) && selectedFields.every(el => columnsToSelect.includes(el)) + if ((selectedFields.length === columnsToSelect.length) && selectedFields.every((el: string) => columnsToSelect.includes(el)) || !clearSelection) { this.grid.selectionService.deselectColumns(columnsToSelect, event); } else { @@ -292,7 +292,7 @@ export class IgxGridHeaderGroupComponent implements DoCheck { /** * @hidden @internal */ - public onPointerDownIndicator(event) { + public onPointerDownIndicator(event: PointerEvent) { // Stop propagation of pointer events to now allow column dragging using the header indicators. event.stopPropagation(); } diff --git a/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.html b/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.html index 55f6674f551..9408e74d523 100644 --- a/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.html +++ b/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.html @@ -38,7 +38,7 @@ @if (isHierarchicalGrid) {
@if (grid?.groupingExpressions?.length) {
diff --git a/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.ts b/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.ts index 414cc912696..dc79b273db0 100644 --- a/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.ts +++ b/projects/igniteui-angular/grids/core/src/headers/grid-header-row.component.ts @@ -47,7 +47,7 @@ export class IgxGridHeaderRowComponent implements DoCheck { /** The grid component containing this element. */ @Input() - public grid: GridType; + public grid!: GridType; /** Pinned columns of the grid at start. */ @Input() @@ -79,10 +79,10 @@ export class IgxGridHeaderRowComponent implements DoCheck { } @Input({ transform: booleanAttribute }) - public hasMRL: boolean; + public hasMRL!: boolean; @Input() - public width: number; + public width!: number; /** * Header groups inside the header row. @@ -95,7 +95,7 @@ export class IgxGridHeaderRowComponent implements DoCheck { * @hidden @internal * */ @ViewChildren(IgxGridHeaderGroupComponent) - public _groups: QueryList; + public _groups!: QueryList; /** * The flattened header groups collection. @@ -126,6 +126,7 @@ export class IgxGridHeaderRowComponent implements DoCheck { if (row && row.cells) { return row.cells.map(cell => cell.column); } + return undefined!; } /** @@ -138,26 +139,26 @@ export class IgxGridHeaderRowComponent implements DoCheck { /** The virtualized part of the header row containing the unpinned header groups. */ @ViewChild('headerVirtualContainer', { read: IgxGridForOfDirective, static: true }) - public headerContainer: IgxGridForOfDirective; + public headerContainer!: IgxGridForOfDirective; public get headerForOf() { return this.headerContainer; } @ViewChild('headerDragContainer') - public headerDragContainer: ElementRef; + public headerDragContainer!: ElementRef; @ViewChild('headerSelectorContainer') - public headerSelectorContainer: ElementRef; + public headerSelectorContainer!: ElementRef; @ViewChild('headerGroupContainer') - public headerGroupContainer: ElementRef; + public headerGroupContainer!: ElementRef; @ViewChild('headSelectorBaseTemplate') - public headSelectorBaseTemplate: TemplateRef; + public headSelectorBaseTemplate!: TemplateRef; @ViewChild(IgxGridFilteringRowComponent) - public filterRow: IgxGridFilteringRowComponent; + public filterRow!: IgxGridFilteringRowComponent; /** * Expand/collapse all child grids area in a hierarchical grid. @@ -166,7 +167,7 @@ export class IgxGridHeaderRowComponent implements DoCheck { * @internal @hidden */ @ViewChild('headerHierarchyExpander') - public headerHierarchyExpander: ElementRef; + public headerHierarchyExpander!: ElementRef; public get navigation() { return this.grid.navigation; @@ -187,7 +188,7 @@ export class IgxGridHeaderRowComponent implements DoCheck { } public get indentationCSSClasses() { - return `igx-grid__header-indentation igx-grid__row-indentation--level-${this.grid.groupingExpressions.length}`; + return `igx-grid__header-indentation igx-grid__row-indentation--level-${this.grid.groupingExpressions!.length}`; } public get rowSelectorsContext(): IgxHeadSelectorTemplateContext { @@ -222,7 +223,7 @@ export class IgxGridHeaderRowComponent implements DoCheck { * @hidden @internal */ public scroll(event: Event) { - this.grid.preventHeaderScroll(event); + this.grid.preventHeaderScroll!(event); } public headerRowSelection(event: MouseEvent) { diff --git a/projects/igniteui-angular/grids/core/src/headers/grid-header.component.ts b/projects/igniteui-angular/grids/core/src/headers/grid-header.component.ts index eb00efebccc..c2ca86a4492 100644 --- a/projects/igniteui-angular/grids/core/src/headers/grid-header.component.ts +++ b/projects/igniteui-angular/grids/core/src/headers/grid-header.component.ts @@ -37,25 +37,25 @@ export class IgxGridHeaderComponent implements DoCheck, OnDestroy { private ref = inject>(ElementRef); @Input() - public column: ColumnType; + public column!: ColumnType; /** * @hidden */ @ViewChild('defaultESFHeaderIconTemplate', { read: TemplateRef, static: true }) - protected defaultESFHeaderIconTemplate: TemplateRef; + protected defaultESFHeaderIconTemplate!: TemplateRef; /** * @hidden */ @ViewChild('defaultSortHeaderIconTemplate', { read: TemplateRef, static: true }) - protected defaultSortHeaderIconTemplate; + protected defaultSortHeaderIconTemplate!: TemplateRef; /** * @hidden */ @ViewChild('sortIconContainer', { read: ElementRef }) - protected sortIconContainer: ElementRef; + protected sortIconContainer!: ElementRef; @HostBinding('class.igx-grid-th--pinned') public get pinnedCss() { @@ -99,7 +99,7 @@ export class IgxGridHeaderComponent implements DoCheck, OnDestroy { */ @Input() @HostBinding('attr.id') - public id: string; + public id!: string; /** * Returns the `aria-selected` of the header. @@ -307,7 +307,7 @@ export class IgxGridHeaderComponent implements DoCheck, OnDestroy { /** * @hidden @internal */ - public onPointerDownIndicator(event) { + public onPointerDownIndicator(event: PointerEvent) { // Stop propagation of pointer events to now allow column dragging using the header indicators. event.stopPropagation(); } @@ -315,7 +315,7 @@ export class IgxGridHeaderComponent implements DoCheck, OnDestroy { /** * @hidden @internal */ - public onFilteringIconClick(event) { + public onFilteringIconClick(event: MouseEvent) { event.stopPropagation(); this.grid.filteringService.toggleFilterDropdown(this.nativeElement, this.column); } @@ -323,7 +323,7 @@ export class IgxGridHeaderComponent implements DoCheck, OnDestroy { /** * @hidden @internal */ - public onSortingIconClick(event) { + public onSortingIconClick(event: MouseEvent) { event.stopPropagation(); this.triggerSort(); } @@ -343,7 +343,7 @@ export class IgxGridHeaderComponent implements DoCheck, OnDestroy { private triggerSort() { const groupingExpr = this.grid.groupingExpressions ? this.grid.groupingExpressions.find((expr) => expr.fieldName === this.column.field) : - this.grid.groupArea?.expressions ? this.grid.groupArea?.expressions.find((expr) => expr.fieldName === this.column.field) : null; + this.grid.groupArea?.expressions ? this.grid.groupArea?.expressions.find(expr => expr.fieldName === this.column.field) : null; const sortDir = groupingExpr ? this.sortDirection + 1 > SortingDirection.Desc ? SortingDirection.Asc : SortingDirection.Desc : this.sortDirection + 1 > SortingDirection.Desc ? SortingDirection.None : this.sortDirection + 1; diff --git a/projects/igniteui-angular/grids/core/src/headers/pipes.ts b/projects/igniteui-angular/grids/core/src/headers/pipes.ts index 8049dc5b26c..1e4734f33d6 100644 --- a/projects/igniteui-angular/grids/core/src/headers/pipes.ts +++ b/projects/igniteui-angular/grids/core/src/headers/pipes.ts @@ -9,7 +9,7 @@ import { ColumnType, ISortingExpression } from 'igniteui-angular/core'; export class SortingIndexPipe implements PipeTransform { public transform(columnField: string, sortingExpressions: ISortingExpression[]): number { let sortIndex = sortingExpressions.findIndex(expression => expression.fieldName === columnField); - return sortIndex !== -1 ? ++sortIndex : null; + return sortIndex !== -1 ? ++sortIndex : null!; } } @@ -20,7 +20,7 @@ export class SortingIndexPipe implements PipeTransform { export class IgxHeaderGroupStylePipe implements PipeTransform { public transform(styles: { [prop: string]: any }, column: ColumnType, _: number): { [prop: string]: any } { - const css = {}; + const css: { [prop: string]: any } = {}; if (!styles) { return css; diff --git a/projects/igniteui-angular/grids/core/src/moving/moving.drag.directive.ts b/projects/igniteui-angular/grids/core/src/moving/moving.drag.directive.ts index 3be06517cb2..6bb90b46895 100644 --- a/projects/igniteui-angular/grids/core/src/moving/moving.drag.directive.ts +++ b/projects/igniteui-angular/grids/core/src/moving/moving.drag.directive.ts @@ -18,7 +18,7 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective implements On @Input('igxColumnMovingDrag') - public column: ColumnType; + public column!: ColumnType; public get draggable(): boolean { return this.column && (this.column.grid.moving || (this.column.groupable && !this.column.columnGroup)); @@ -28,7 +28,7 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective implements On return this.cms.icon; } - private subscription$: Subscription; + private subscription$!: Subscription; private _ghostClass = 'igx-grid__drag-ghost-image'; private ghostImgIconClass = 'igx-grid__drag-ghost-image-icon'; private ghostImgIconGroupClass = 'igx-grid__drag-ghost-image-icon-group'; @@ -44,12 +44,12 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective implements On super.ngOnDestroy(); } - public onEscape(event: Event) { + public cancelMove(event: PointerEvent) { this.cms.cancelDrop = true; this.onPointerUp(event); } - public override onPointerDown(event: Event) { + public override onPointerDown(event: PointerEvent) { if (!this.draggable || (event.target as HTMLElement).getAttribute('draggable') === 'false') { return; } @@ -57,7 +57,7 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective implements On super.onPointerDown(event); } - public override onPointerMove(event: Event) { + public override onPointerMove(event: PointerEvent) { if (this._clicked && !this._dragStarted) { this._removeOnDestroy = false; this.cms.column = this.column; @@ -67,9 +67,9 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective implements On source: this.column }; this.column.grid.columnMovingStart.emit(movingStartArgs); - this.subscription$ = fromEvent(this.column.grid.document.defaultView, 'keydown').pipe(takeUntil(this._destroy)).subscribe((ev: KeyboardEvent) => { + this.subscription$ = fromEvent(this.column.grid.document.defaultView, 'keydown').pipe(takeUntil(this._destroy)).subscribe((ev: KeyboardEvent) => { if (ev.key === this.platformUtil.KEYMAP.ESCAPE) { - this.onEscape(ev); + this.cancelMove(event); } }); } @@ -88,16 +88,16 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective implements On this.column.grid.columnMoving.emit(args); if (args.cancel) { - this.onEscape(event); + this.cancelMove(event); } } } - public override onPointerUp(event: Event) { + public override onPointerUp(event: PointerEvent) { // Run it explicitly inside the zone because sometimes onPointerUp executes after the code below. this.zone.run(() => { super.onPointerUp(event); - this.cms.column = null; + this.cms.column = null!; this.column.grid.cdr.detectChanges(); }); @@ -142,7 +142,7 @@ export class IgxColumnMovingDragDirective extends IgxDragDirective implements On private _unsubscribe() { if (this.subscription$) { this.subscription$.unsubscribe(); - this.subscription$ = null; + this.subscription$ = null!; } } } diff --git a/projects/igniteui-angular/grids/core/src/moving/moving.drop.directive.ts b/projects/igniteui-angular/grids/core/src/moving/moving.drop.directive.ts index 60354cd1e9b..e28f8cf0a71 100644 --- a/projects/igniteui-angular/grids/core/src/moving/moving.drop.directive.ts +++ b/projects/igniteui-angular/grids/core/src/moving/moving.drop.directive.ts @@ -3,7 +3,7 @@ import { DropPosition, IgxColumnMovingService } from './moving.service'; import { Subject, interval, animationFrameScheduler } from 'rxjs'; import { IgxColumnMovingDragDirective } from './moving.drag.directive'; import { takeUntil } from 'rxjs/operators'; -import { IgxDropDirective, IgxForOfDirective, IgxGridForOfDirective } from 'igniteui-angular/directives'; +import { IgxDragCustomEventDetails, IgxDropDirective, IgxForOfDirective, IgxGridForOfDirective } from 'igniteui-angular/directives'; import { ColumnType } from 'igniteui-angular/core'; @Directive({ @@ -43,11 +43,11 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On return this.element.nativeElement; } - private _dropPos: DropPosition; + private _dropPos!: DropPosition; private _dropIndicator = null; private _lastDropIndicator = null; - private _column: ColumnType; - private _displayContainer: IgxGridForOfDirective; + private _column!: ColumnType; + private _displayContainer!: IgxGridForOfDirective; private _dragLeave = new Subject(); private _dropIndicatorClass = 'igx-grid-th__drop-indicator--active'; @@ -61,7 +61,7 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On super.ngOnDestroy(); } - public override onDragOver(event) { + public override onDragOver(event: CustomEvent) { const drag = event.detail.owner; if (!(drag instanceof IgxColumnMovingDragDirective)) { return; @@ -94,7 +94,7 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On } } - public override onDragEnter(event) { + public override onDragEnter(event: CustomEvent) { const drag = event.detail.owner; if (!(drag instanceof IgxColumnMovingDragDirective)) { return; @@ -120,19 +120,19 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On } if (this.horizontalScroll) { - this.cms.icon.innerText = event.target.id === 'right' ? 'arrow_forward' : 'arrow_back'; + this.cms.icon.innerText = (event.target as HTMLElement).id === 'right' ? 'arrow_forward' : 'arrow_back'; interval(0, animationFrameScheduler).pipe(takeUntil(this._dragLeave)).subscribe(() => { - if (event.target.id === 'right') { - this.horizontalScroll.scrollPosition += 10; + if ((event.target as HTMLElement).id === 'right') { + this.horizontalScroll!.scrollPosition += 10; } else { - this.horizontalScroll.scrollPosition -= 10; + this.horizontalScroll!.scrollPosition -= 10; } }); } } - public override onDragLeave(event) { + public override onDragLeave(event: CustomEvent) { const drag = event.detail.owner; if (!(drag instanceof IgxColumnMovingDragDirective)) { return; @@ -149,7 +149,7 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On } } - public override onDragDrop(event) { + public override onDragDrop(event: CustomEvent) { event.preventDefault(); const drag = event.detail.owner; if (this.cms.cancelDrop || !(drag instanceof IgxColumnMovingDragDirective)) { @@ -168,7 +168,7 @@ export class IgxColumnMovingDropDirective extends IgxDropDirective implements On if (this.isDropTarget) { this.column.grid.moveColumn(this.cms.column, this.column, this._dropPos); - this.cms.column = null; + this.cms.column = null!; this.column.grid.cdr.detectChanges(); } } diff --git a/projects/igniteui-angular/grids/core/src/moving/moving.service.ts b/projects/igniteui-angular/grids/core/src/moving/moving.service.ts index a50f8516c6e..b6c86176d14 100644 --- a/projects/igniteui-angular/grids/core/src/moving/moving.service.ts +++ b/projects/igniteui-angular/grids/core/src/moving/moving.service.ts @@ -18,7 +18,7 @@ export enum DropPosition { */ @Injectable({ providedIn: 'root' }) export class IgxColumnMovingService { - public cancelDrop: boolean; - public icon: HTMLElement; - public column: ColumnType; + public cancelDrop!: boolean; + public icon!: HTMLElement; + public column!: ColumnType; } diff --git a/projects/igniteui-angular/grids/core/src/pivot-grid-aggregate.ts b/projects/igniteui-angular/grids/core/src/pivot-grid-aggregate.ts index 32ed36b21fa..e1dab84a4d4 100644 --- a/projects/igniteui-angular/grids/core/src/pivot-grid-aggregate.ts +++ b/projects/igniteui-angular/grids/core/src/pivot-grid-aggregate.ts @@ -1,5 +1,5 @@ import { IPivotAggregator } from './pivot-grid.interface'; -import { IgxDateSummaryOperand, IgxNumberSummaryOperand, IgxTimeSummaryOperand } from './summaries/grid-summary'; +import { IgxDateSummaryOperand, IgxNumberSummaryOperand, IgxTimeSummaryOperand } from 'igniteui-angular/core'; export class IgxPivotAggregate { diff --git a/projects/igniteui-angular/grids/core/src/pivot-grid-dimensions.ts b/projects/igniteui-angular/grids/core/src/pivot-grid-dimensions.ts index a0ee52c9459..4310581131b 100644 --- a/projects/igniteui-angular/grids/core/src/pivot-grid-dimensions.ts +++ b/projects/igniteui-angular/grids/core/src/pivot-grid-dimensions.ts @@ -108,8 +108,8 @@ export class IgxPivotDateDimension implements IPivotDimension { public memberName = 'AllPeriods'; /** @hidden @internal */ public locale?: string; - public displayName: string; - private _resourceStrings: IGridResourceStrings = null; + public displayName!: string; + private _resourceStrings: IGridResourceStrings = null!; private _baseDimension: IPivotDimension; private _options: IPivotDateDimensionOptions = {}; @@ -124,7 +124,7 @@ export class IgxPivotDateDimension implements IPivotDimension { * new IgxPivotDateDimension({ memberName: 'Date', enabled: true }, { total: false, months: false }); * ``` */ - constructor(inBaseDimension: IPivotDimension = null, inOptions: IPivotDateDimensionOptions = {}) { + constructor(inBaseDimension: IPivotDimension = null!, inOptions: IPivotDateDimensionOptions = {}) { this._baseDimension = inBaseDimension; this._options = inOptions; if (this.baseDimension && this.options) { @@ -132,7 +132,7 @@ export class IgxPivotDateDimension implements IPivotDimension { } } - protected initialize(inBaseDimension, inOptions) { + protected initialize(inBaseDimension: any, inOptions: any) { const options = { ...this.defaultOptions, ...inOptions }; this.dataType = GridColumnDataType.Date; @@ -147,7 +147,7 @@ export class IgxPivotDateDimension implements IPivotDimension { memberFunction: (rec) => { const recordValue = PivotUtil.extractValueFromDimension(inBaseDimension, rec); const dateValue = recordValue ? getDateFormatter().createDateFromValue(recordValue) : null; - return recordValue ? getDateFormatter().formatDateTime(dateValue, this.locale, { month: 'long'}) : rec['Months']; + return recordValue ? getDateFormatter().formatDateTime(dateValue!, this.locale, { month: 'long'}) : rec['Months']; }, enabled: true, childLevel: baseDimension @@ -159,7 +159,7 @@ export class IgxPivotDateDimension implements IPivotDimension { memberFunction: (rec) => { const recordValue = PivotUtil.extractValueFromDimension(inBaseDimension, rec); const dateValue = recordValue ? getDateFormatter().createDateFromValue(recordValue) : null; - return recordValue ? `Q` + Math.ceil((dateValue.getMonth() + 1) / 3) : rec['Quarters']; + return recordValue ? `Q` + Math.ceil((dateValue!.getMonth() + 1) / 3) : rec['Quarters']; }, enabled: true, childLevel: monthDimension @@ -171,7 +171,7 @@ export class IgxPivotDateDimension implements IPivotDimension { memberFunction: (rec) => { const recordValue = PivotUtil.extractValueFromDimension(inBaseDimension, rec); const dateValue = recordValue ? getDateFormatter().createDateFromValue(recordValue) : null; - return recordValue ? dateValue.getFullYear().toString() : rec['Years']; + return recordValue ? dateValue!.getFullYear().toString() : rec['Years']; }, enabled: true, childLevel: quarterDimension @@ -188,5 +188,5 @@ export class IgxPivotDateDimension implements IPivotDimension { } /** @hidden @internal */ - public memberFunction = (_data) => this.resourceStrings.igx_grid_pivot_date_dimension_total; + public memberFunction = (_data: any) => this.resourceStrings.igx_grid_pivot_date_dimension_total; } diff --git a/projects/igniteui-angular/grids/core/src/pivot-grid.interface.ts b/projects/igniteui-angular/grids/core/src/pivot-grid.interface.ts index 393aa18a658..48655fce2e1 100644 --- a/projects/igniteui-angular/grids/core/src/pivot-grid.interface.ts +++ b/projects/igniteui-angular/grids/core/src/pivot-grid.interface.ts @@ -14,7 +14,7 @@ export const DEFAULT_PIVOT_KEYS = { */ export interface IDimensionsChange { /** The new list of dimensions. */ - dimensions: IPivotDimension[], + dimensions: IPivotDimension[] | null; /* mustCoerceToInt */ /** The dimension list type - Row, Column or Filter. */ dimensionCollectionType: PivotDimensionType @@ -145,6 +145,10 @@ export interface IPivotDimension { horizontalSummary? : boolean; } +export interface IPivotExpandableDimension extends IPivotDimension { + expandable: boolean; +} + /* marshalByValue */ /** * Configuration of a pivot value aggregation. @@ -179,13 +183,13 @@ export interface IPivotValue { * Contains information on the related column dimensions and their values. */ export interface IPivotGridColumn { - field: string, - /* blazorSuppress */ - /** Gets/Sets the group value associated with the related column dimension by its memberName. **/ - dimensionValues: Map; - /** List of dimensions associated with the column.**/ - dimensions: IPivotDimension[]; - value: IPivotValue + field: string, + /* blazorSuppress */ + /** Gets/Sets the group value associated with the related column dimension by its memberName. **/ + dimensionValues: Map; + /** List of dimensions associated with the column.**/ + dimensions: IPivotDimension[]; + value: IPivotValue } /* marshalByValue */ @@ -259,7 +263,9 @@ export interface PivotRowHeaderGroupType { export interface DimensionValueType { value: string; - children: Map; + expandable: boolean; + dimension: IPivotDimension; + children: Map | null; } export interface IPivotGridRecord { diff --git a/projects/igniteui-angular/grids/core/src/pivot-util.ts b/projects/igniteui-angular/grids/core/src/pivot-util.ts index e8c005efb15..80c473661e2 100644 --- a/projects/igniteui-angular/grids/core/src/pivot-util.ts +++ b/projects/igniteui-angular/grids/core/src/pivot-util.ts @@ -1,6 +1,6 @@ import { DataUtil, FilteringExpressionsTree, FilteringLogic, GridColumnDataType, IDataCloneStrategy, IGridSortingStrategy, IgxSorting, ISortingExpression } from 'igniteui-angular/core'; import { IgxPivotAggregate, IgxPivotDateAggregate, IgxPivotNumericAggregate, IgxPivotTimeAggregate } from './pivot-grid-aggregate'; -import { IPivotAggregator, IPivotConfiguration, IPivotDimension, IPivotGridRecord, IPivotKeys, IPivotValue, PivotDimensionType, PivotSummaryPosition } from './pivot-grid.interface'; +import { DimensionValueType, IPivotAggregator, IPivotConfiguration, IPivotDimension, IPivotExpandableDimension, IPivotGridRecord, IPivotKeys, IPivotValue, PivotDimensionType, PivotSummaryPosition } from './pivot-grid.interface'; import { PivotGridType } from './common/grid.interface'; export class PivotUtil { @@ -17,14 +17,14 @@ export class PivotUtil { } // add children for current dimension const hierarchyFields = PivotUtil - .getFieldsHierarchy(rec.records, [dimension], PivotDimensionType.Row, pivotKeys, cloneStrategy); + .getFieldsHierarchy(rec.records!, [dimension], PivotDimensionType.Row, pivotKeys, cloneStrategy); const siblingData = PivotUtil .processHierarchy(hierarchyFields, pivotKeys, 0); - rec.children.set(dimension.memberName, siblingData); + rec.children!.set(dimension.memberName, siblingData); } } - public static flattenGroups(data: IPivotGridRecord[], dimension: IPivotDimension, expansionStates, defaultExpand: boolean, parent?: IPivotDimension, parentRec?: IPivotGridRecord) { + public static flattenGroups(data: IPivotGridRecord[], dimension: IPivotDimension, expansionStates: Map, defaultExpand: boolean, parent?: IPivotDimension, parentRec?: IPivotGridRecord) { for (let i = 0; i < data.length; i++) { const rec = data[i]; const field = dimension.memberName; @@ -32,10 +32,10 @@ export class PivotUtil { continue; } - let recordsData = rec.children.get(field); + let recordsData = rec.children!.get(field); if (!recordsData && parent) { // check parent - recordsData = rec.children.get(parent.memberName); + recordsData = rec.children!.get(parent.memberName); if (recordsData) { dimension = parent; } @@ -43,10 +43,10 @@ export class PivotUtil { if (parentRec) { parentRec.dimensionValues.forEach((value, key) => { - if (parent.memberName !== key) { + if (parent!.memberName !== key) { rec.dimensionValues.set(key, value); const dim = parentRec.dimensions.find(x => x.memberName === key); - rec.dimensions.unshift(dim); + rec.dimensions.unshift(dim!); } }); @@ -68,7 +68,7 @@ export class PivotUtil { if (dimension.memberName !== key) { x.dimensionValues.set(key, value); const dim = rec.dimensions.find(y => y.memberName === key); - x.dimensions.unshift(dim); + x.dimensions.unshift(dim!); } }); @@ -84,7 +84,7 @@ export class PivotUtil { public static flattenGroupsHorizontally(data: IPivotGridRecord[], dimension: IPivotDimension, - expansionStates, + expansionStates: Map, defaultExpand: boolean, visibleDimensions: IPivotDimension[], summariesPosition: PivotSummaryPosition, @@ -101,10 +101,10 @@ export class PivotUtil { visibleDimensions.push(rec.dimensions[0]); } - let recordsData = rec.children.get(field); + let recordsData = rec.children!.get(field); if (!recordsData && parent) { // check parent - recordsData = rec.children.get(parent.memberName); + recordsData = rec.children!.get(parent.memberName); if (recordsData) { dimension = parent; } @@ -114,7 +114,7 @@ export class PivotUtil { parentRec.dimensionValues.forEach((value, key) => { rec.dimensionValues.set(key, value); const dim = parentRec.dimensions.find(x => x.memberName === key); - rec.dimensions.unshift(dim); + rec.dimensions.unshift(dim!); }); } @@ -133,7 +133,7 @@ export class PivotUtil { if (dimension.memberName !== key) { x.dimensionValues.set(key, value); const dim = rec.dimensions.find(y => y.memberName === key); - x.dimensions.unshift(dim); + x.dimensions.unshift(dim!); } }); @@ -172,7 +172,7 @@ export class PivotUtil { } } - public static assignLevels(dims) { + public static assignLevels(dims: IPivotDimension[]) { for (const dim of dims) { let currDim = dim; let lvl = 0; @@ -185,8 +185,8 @@ export class PivotUtil { } } public static getFieldsHierarchy(data: any[], dimensions: IPivotDimension[], - dimensionType: PivotDimensionType, pivotKeys: IPivotKeys, cloneStrategy: IDataCloneStrategy): Map { - const hierarchy = new Map(); + dimensionType: PivotDimensionType, pivotKeys: IPivotKeys, cloneStrategy: IDataCloneStrategy): Map { + const hierarchy = new Map(); for (const rec of data) { const vals = dimensionType === PivotDimensionType.Column ? this.extractValuesForColumn(dimensions, rec, pivotKeys) : @@ -205,7 +205,7 @@ export class PivotUtil { public static sort(data: IPivotGridRecord[], expressions: ISortingExpression[], sorting: IGridSortingStrategy = new IgxSorting()): any[] { for (const rec of data) { - const children = rec.children; + const children = rec.children!; for (const [key, child] of children) { /** * DataUtil.sort is returning new reference of the sorted array @@ -232,8 +232,8 @@ export class PivotUtil { return lvl; } - public static extractValuesForRow(dims: IPivotDimension[], recData: any, pivotKeys: IPivotKeys, cloneStrategy: IDataCloneStrategy) { - const values = new Map(); + public static extractValuesForRow(dims: IPivotDimension[], recData: any, pivotKeys: IPivotKeys, cloneStrategy: IDataCloneStrategy) : Map { + const values = new Map(); for (const col of dims) { if (recData[pivotKeys.level] && recData[pivotKeys.level] > 0) { const childData = recData[pivotKeys.records]; @@ -241,12 +241,12 @@ export class PivotUtil { } const value = this.extractValueFromDimension(col, recData); - const objValue = {}; + const objValue: DimensionValueType = {} as any; objValue['value'] = value; objValue['dimension'] = col; if (col.childLevel) { const childValues = this.extractValuesForRow([col.childLevel], recData, pivotKeys, cloneStrategy); - objValue[pivotKeys.children] = childValues; + (objValue as any)[pivotKeys.children] = childValues; } values.set(value, objValue); } @@ -254,17 +254,17 @@ export class PivotUtil { return values; } - public static extractValuesForColumn(dims: IPivotDimension[], recData: any, pivotKeys: IPivotKeys, path = []) { - const vals = new Map(); + public static extractValuesForColumn(dims: IPivotDimension[], recData: any, pivotKeys: IPivotKeys, path: any[] = []) { + const vals = new Map(); let lvlCollection = vals; const flattenedDims = this.flatten(dims); for (const col of flattenedDims) { const value = this.extractValueFromDimension(col, recData); path.push(value); const newValue = path.join(pivotKeys.columnDimensionSeparator); - const newObj = { value: newValue, expandable: col.expandable, children: null, dimension: col }; + const newObj: DimensionValueType = { value: newValue, expandable: col.expandable, children: null, dimension: col }; if (!newObj.children) { - newObj.children = new Map(); + newObj.children = new Map(); } lvlCollection.set(newValue, newObj); lvlCollection = newObj.children; @@ -272,13 +272,13 @@ export class PivotUtil { return vals; } - public static flatten(arr, lvl = 0) { - const newArr = arr.reduce((acc, item) => { + public static flatten(arr: IPivotDimension[] | null, lvl = 0): IPivotExpandableDimension[] { + const newArr = (arr || []).reduce((acc: IPivotExpandableDimension[], item: IPivotDimension) => { if (item) { item.level = lvl; - acc.push(item); + acc.push(item as IPivotExpandableDimension); if (item.childLevel) { - item.expandable = true; + (item as IPivotExpandableDimension).expandable = true; acc = acc.concat(this.flatten([item.childLevel], lvl + 1)); } } @@ -287,11 +287,11 @@ export class PivotUtil { return newArr; } - public static applyAggregations(rec: IPivotGridRecord, hierarchies, values, pivotKeys: IPivotKeys) { + public static applyAggregations(rec: IPivotGridRecord, hierarchies: Map, values: IPivotValue[], pivotKeys: IPivotKeys) { if (hierarchies.size === 0) { // no column groups const aggregationResult = this.aggregate(rec.records, values); - this.applyAggregationRecordData(aggregationResult, undefined, rec, pivotKeys); + this.applyAggregationRecordData(aggregationResult, undefined!, rec, pivotKeys); return; } hierarchies.forEach((hierarchy) => { @@ -321,14 +321,14 @@ export class PivotUtil { } } - public static aggregate(records, values: IPivotValue[]) { - const result = {}; + public static aggregate(records: any, values: IPivotValue[]) { + const result: any = {}; for (const pivotValue of values) { - const aggregator = PivotUtil.getAggregatorForType(pivotValue.aggregate, pivotValue.dataType); + const aggregator = PivotUtil.getAggregatorForType(pivotValue.aggregate, pivotValue.dataType!); if (!aggregator) { throw `No valid aggregator found for ${pivotValue.member}. Please set either a valid aggregatorName or aggregator`; } - result[pivotValue.member] = aggregator(records.map(r => r[pivotValue.member]), records); + result[pivotValue.member] = aggregator(records.map((r: any) => r[pivotValue.member]), records); } return result; @@ -343,12 +343,12 @@ export class PivotUtil { } else if (dataType === 'time') { aggregators = aggregators.concat(IgxPivotTimeAggregate.aggregators()); } - aggregator = aggregators.find(x => x.key.toLocaleLowerCase() === aggregate.aggregatorName.toLocaleLowerCase())?.aggregator; + aggregator = aggregators.find(x => x.key.toLocaleLowerCase() === aggregate.aggregatorName!.toLocaleLowerCase())?.aggregator; } return aggregator; } - public static processHierarchy(hierarchies, pivotKeys, level = 0, rootData = false): IPivotGridRecord[] { + public static processHierarchy(hierarchies: Map, pivotKeys: IPivotKeys, level = 0, rootData = false): IPivotGridRecord[] { const flatData: IPivotGridRecord[] = []; hierarchies.forEach((h, key) => { const field = h.dimension.memberName; @@ -368,7 +368,7 @@ export class PivotUtil { const nestedData = this.processHierarchy(h[pivotKeys.children], pivotKeys, level + 1, rootData); rec.records = this.getDirectLeafs(nestedData); - rec.children.set(field, nestedData); + rec.children!.set(field, nestedData); } }); @@ -376,7 +376,7 @@ export class PivotUtil { } public static getDirectLeafs(records: IPivotGridRecord[]) { - let leafs = []; + let leafs: any[] = []; for (const rec of records) { if (rec.records) { const data = rec.records.filter(x => !x.records && leafs.indexOf(x) === -1); @@ -416,13 +416,13 @@ export class PivotUtil { return expressionsTree; } - private static collectRecords(children, pivotKeys: IPivotKeys) { - let result = []; - children.forEach(value => result = result.concat(value[pivotKeys.records])); + private static collectRecords(children: any, pivotKeys: IPivotKeys) { + let result: any[] = []; + children.forEach((value: any) => result = result.concat(value[pivotKeys.records])); return result; } - private static applyHierarchyChildren(hierarchy, val, rec, pivotKeys: IPivotKeys) { + private static applyHierarchyChildren(hierarchy: Map, val: any, rec: any, pivotKeys: IPivotKeys) { const recordsKey = pivotKeys.records; const childKey = pivotKeys.children; const childCollection = val[childKey]; @@ -455,7 +455,7 @@ export class PivotUtil { // not all nested children are valid const nestedValue = hierarchyChildValue.value; const dimension = hierarchyChildValue.dimension; - const validRecs = rec[recordsKey].filter(x => this.extractValueFromDimension(dimension, x) === nestedValue); + const validRecs = rec[recordsKey].filter((x: any) => this.extractValueFromDimension(dimension, x) === nestedValue); copy[recordsKey] = validRecs; } hierarchyChildValue[recordsKey].push(copy); @@ -477,7 +477,7 @@ export class PivotUtil { (x) => x.key === val.aggregate.key ); // resolve custom aggregations - if (!isDefault && grid.data[0][val.member] !== undefined) { + if (!isDefault && grid.data![0][val.member] !== undefined) { // if field exists, then we can apply default aggregations and add the custom one. defaultAggr.unshift(val.aggregate); } else if (!isDefault) { @@ -492,7 +492,7 @@ export class PivotUtil { } public static getAggregatorsForValue(value: IPivotValue, grid: PivotGridType): IPivotAggregator[] { - const dataType = value.dataType || grid.resolveDataTypes(grid.data[0][value.member]); + const dataType = value.dataType || grid.resolveDataTypes(grid.data![0][value.member]); switch (dataType) { case GridColumnDataType.Number: case GridColumnDataType.Currency: @@ -526,5 +526,6 @@ export class PivotUtil { } else if (value.dataType === GridColumnDataType.Percent && !isCountAggregator) { return GridColumnDataType.Percent; } + return undefined!; } } diff --git a/projects/igniteui-angular/grids/core/src/public_api.ts b/projects/igniteui-angular/grids/core/src/public_api.ts index 89faa1cbe8b..4545b5a9058 100644 --- a/projects/igniteui-angular/grids/core/src/public_api.ts +++ b/projects/igniteui-angular/grids/core/src/public_api.ts @@ -86,7 +86,6 @@ export * from './filtering/base/grid-filtering-cell.component'; export * from './filtering/base/grid-filtering-row.component'; export * from './filtering/grid-filtering.service'; export * from './selection/public_api'; -export * from './summaries/grid-summary'; export * from './summaries/grid-summary.service'; export * from './summaries/summary-row.component'; export * from './summaries/grid-root-summary.pipe'; @@ -107,6 +106,7 @@ export * from './grid-validation.service'; export * from './grid.common'; export { IgxGridCellComponent } from './cell.component'; export * from './grouping/group-by-area.directive'; +export * from './grouping/events'; export * from './grid-mrl-navigation.service'; export * from './api.service'; export * from './pivot-util'; diff --git a/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resize-handle.directive.ts b/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resize-handle.directive.ts index 9d429901246..688ac4fc623 100644 --- a/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resize-handle.directive.ts +++ b/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resize-handle.directive.ts @@ -35,7 +35,7 @@ export class IgxPivotResizeHandleDirective extends IgxResizeHandleDirective { * @hidden */ @Input('igxPivotResizeHandleHeader') - public rowHeaderGroup: PivotRowHeaderGroupType; + public rowHeaderGroup!: PivotRowHeaderGroupType; /** * @hidden diff --git a/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resizing.service.ts b/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resizing.service.ts index 2fbaca7072d..ed155c3183e 100644 --- a/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resizing.service.ts +++ b/projects/igniteui-angular/grids/core/src/resizing/pivot-grid/pivot-resizing.service.ts @@ -13,7 +13,7 @@ export class IgxPivotColumnResizingService extends IgxColumnResizingService { /** * @hidden */ - public rowHeaderGroup: PivotRowHeaderGroupType; + public rowHeaderGroup!: PivotRowHeaderGroupType; /** * @hidden diff --git a/projects/igniteui-angular/grids/core/src/resizing/resize-handle.directive.ts b/projects/igniteui-angular/grids/core/src/resizing/resize-handle.directive.ts index 4a2f4ecf3bf..50e9fa8d444 100644 --- a/projects/igniteui-angular/grids/core/src/resizing/resize-handle.directive.ts +++ b/projects/igniteui-angular/grids/core/src/resizing/resize-handle.directive.ts @@ -23,7 +23,7 @@ export class IgxResizeHandleDirective implements AfterViewInit, OnDestroy { * @hidden */ @Input('igxResizeHandle') - public column: ColumnType; + public column!: ColumnType; /** * @hidden @@ -40,10 +40,10 @@ export class IgxResizeHandleDirective implements AfterViewInit, OnDestroy { /** * @hidden */ - @HostListener('dblclick') - public onDoubleClick() { + @HostListener('dblclick', ['$event']) + public onDoubleClick(event: MouseEvent) { this._dblClick = true; - this.initResizeService(); + this.initResizeService(event); this.colResizingService.autosizeColumnOnDblClick(); } @@ -96,7 +96,7 @@ export class IgxResizeHandleDirective implements AfterViewInit, OnDestroy { /** * @hidden */ - private _onResizeAreaMouseDown(event) { + private _onResizeAreaMouseDown(event: MouseEvent) { this.initResizeService(event); this.colResizingService.showResizer = true; @@ -106,7 +106,7 @@ export class IgxResizeHandleDirective implements AfterViewInit, OnDestroy { /** * @hidden */ - protected initResizeService(event = null) { + protected initResizeService(event: MouseEvent | null = null) { this.colResizingService.column = this.column; if (event) { diff --git a/projects/igniteui-angular/grids/core/src/resizing/resizer.component.ts b/projects/igniteui-angular/grids/core/src/resizing/resizer.component.ts index b2e760491f0..8dd76549e14 100644 --- a/projects/igniteui-angular/grids/core/src/resizing/resizer.component.ts +++ b/projects/igniteui-angular/grids/core/src/resizing/resizer.component.ts @@ -12,8 +12,8 @@ export class IgxGridColumnResizerComponent { public colResizingService = inject(IgxColumnResizingService); @Input() - public restrictResizerTop: number; + public restrictResizerTop!: number; @ViewChild(IgxColumnResizerDirective, { static: true }) - public resizer: IgxColumnResizerDirective; + public resizer!: IgxColumnResizerDirective; } diff --git a/projects/igniteui-angular/grids/core/src/resizing/resizer.directive.ts b/projects/igniteui-angular/grids/core/src/resizing/resizer.directive.ts index ce89d99711a..1d2eef6d1a0 100644 --- a/projects/igniteui-angular/grids/core/src/resizing/resizer.directive.ts +++ b/projects/igniteui-angular/grids/core/src/resizing/resizer.directive.ts @@ -23,7 +23,7 @@ export class IgxColumnResizerDirective implements OnInit, OnDestroy { public restrictHResizeMax: number = Number.MAX_SAFE_INTEGER; @Input() - public restrictResizerTop: number; + public restrictResizerTop!: number; @Output() public resizeEnd = new Subject(); @@ -34,7 +34,7 @@ export class IgxColumnResizerDirective implements OnInit, OnDestroy { // eslint-disable-next-line @angular-eslint/no-output-native @Output() public resize = new Subject(); - private _left: number; + private _left!: number; private _ratio: number = 1; private _destroy = new Subject(); @@ -70,15 +70,15 @@ export class IgxColumnResizerDirective implements OnInit, OnDestroy { public ngOnInit() { this.zone.runOutsideAngular(() => { - fromEvent(this.document.defaultView, 'mousemove') + fromEvent(this.document.defaultView!, 'mousemove') .pipe( - takeUntil(this._destroy), + takeUntil(this._destroy), throttle(() => interval(0, animationFrameScheduler)), ) .subscribe((res) => this.onMousemove(res)); - fromEvent(this.document.defaultView, 'mouseup') - .pipe(takeUntil(this._destroy)) + fromEvent(this.document.defaultView!, 'mouseup') + .pipe(takeUntil(this._destroy)) .subscribe((res) => this.onMouseup(res)); }); } @@ -107,7 +107,7 @@ export class IgxColumnResizerDirective implements OnInit, OnDestroy { public onMousedown(event: MouseEvent, resizeHandleTarget: HTMLElement) { event.preventDefault(); - const parent = this.element.nativeElement.parentElement.parentElement; + const parent = this.element.nativeElement.parentElement!.parentElement!; const parentRectWidth = parent.getBoundingClientRect().width; const parentComputedWidth = parseFloat(window.getComputedStyle(parent).width); if (Math.abs(parentRectWidth - parentComputedWidth) > 1) { diff --git a/projects/igniteui-angular/grids/core/src/resizing/resizing.service.ts b/projects/igniteui-angular/grids/core/src/resizing/resizing.service.ts index 4bb2cc39758..5ce50cb279d 100644 --- a/projects/igniteui-angular/grids/core/src/resizing/resizing.service.ts +++ b/projects/igniteui-angular/grids/core/src/resizing/resizing.service.ts @@ -1,5 +1,5 @@ import { inject, Injectable, NgZone } from '@angular/core'; -import { ColumnType } from 'igniteui-angular/core'; +import { ColumnType, MRLResizeColumnInfo } from 'igniteui-angular/core'; /** * @hidden @@ -13,11 +13,11 @@ export class IgxColumnResizingService { /** * @hidden */ - public startResizePos: number; + public startResizePos!: number; /** * Indicates that a column is currently being resized. */ - public isColumnResizing: boolean; + public isColumnResizing!: boolean; /** * @hidden */ @@ -29,7 +29,7 @@ export class IgxColumnResizingService { /** * The column being resized. */ - public column: ColumnType; + public column!: ColumnType; /** * @hidden @@ -51,7 +51,7 @@ export class IgxColumnResizingService { } if (this.column.level !== 0) { - height -= this.column.topLevelParent.headerGroup.height - this.column.headerGroup.height * columnHeightMultiplier; + height -= this.column.topLevelParent!.headerGroup.height - this.column.headerGroup.height * columnHeightMultiplier; } return height; @@ -187,9 +187,9 @@ export class IgxColumnResizingService { // recalculating the diff there might be 1 more that reaches min width. setMinMaxCols = false; let newCombinedSpan = updatedCombinedSpan; - const newColsToResize = []; + const newColsToResize: MRLResizeColumnInfo[] = []; columnsToResize.forEach((col) => { - const currentResizeWidth = parseFloat(col.target.calcWidth); + const currentResizeWidth = parseFloat(col.target.calcWidth?.toString() || col.target.defaultWidth); const resizeScaled = (diff / updatedCombinedSpan) * col.target.gridColumnSpan; const colWidth = col.target.width; const isPercentageWidth = colWidth && typeof colWidth === 'string' && colWidth.indexOf('%') !== -1; diff --git a/projects/igniteui-angular/grids/core/src/row-drag.directive.ts b/projects/igniteui-angular/grids/core/src/row-drag.directive.ts index 40b47639bab..c78ebe004b4 100644 --- a/projects/igniteui-angular/grids/core/src/row-drag.directive.ts +++ b/projects/igniteui-angular/grids/core/src/row-drag.directive.ts @@ -29,28 +29,28 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy { return this._data.grid.createRow(this._data.index, this._data.data); } - private subscription$: Subscription; + private subscription$!: Subscription; private _rowDragStarted = false; private get row(): RowType { return this._data; } - public override onPointerDown(event) { + public override onPointerDown(event: PointerEvent) { event.preventDefault(); this._rowDragStarted = false; this._removeOnDestroy = false; super.onPointerDown(event); } - public override onPointerMove(event) { + public override onPointerMove(event: PointerEvent) { super.onPointerMove(event); if (this._dragStarted && !this._rowDragStarted) { this._rowDragStarted = true; const args: IRowDragStartEventArgs = { dragDirective: this, dragData: this.data, - dragElement: this.row.nativeElement, + dragElement: this.row.nativeElement!, cancel: false, owner: this.row.grid }; @@ -67,16 +67,16 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy { this.row.grid.rowDragging = true; this.row.grid.cdr.detectChanges(); - this.subscription$ = fromEvent(this.row.grid.document.defaultView, 'keydown').subscribe((ev: KeyboardEvent) => { + this.subscription$ = fromEvent(this.row.grid.document.defaultView!, 'keydown').subscribe((ev: KeyboardEvent) => { if (ev.key === this.platformUtil.KEYMAP.ESCAPE) { - this._lastDropArea = false; + this._lastDropArea = false as any; this.onPointerUp(event); } }); } } - public override onPointerUp(event) { + public override onPointerUp(event: PointerEvent) { if (!this._clicked) { return; @@ -85,7 +85,7 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy { const args: IRowDragEndEventArgs = { dragDirective: this, dragData: this.data, - dragElement: this.row.nativeElement, + dragElement: this.row.nativeElement!, animation: false, owner: this.row.grid }; @@ -102,7 +102,7 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy { } } - protected override createGhost(pageX, pageY) { + protected override createGhost(pageX: number, pageY: number) { this.row.grid.gridAPI.crudService.endEdit(false); this.row.grid.cdr.detectChanges(); this.ghostContext = { @@ -124,7 +124,7 @@ export class IgxRowDragDirective extends IgxDragDirective implements OnDestroy { const ghost = this.ghostElement; const gridRect = this.row.grid.nativeElement.getBoundingClientRect(); - const rowRect = this.row.nativeElement.getBoundingClientRect(); + const rowRect = this.row.nativeElement!.getBoundingClientRect(); ghost.style.overflow = 'hidden'; ghost.style.width = gridRect.width + 'px'; ghost.style.height = rowRect.height + 'px'; diff --git a/projects/igniteui-angular/grids/core/src/row.directive.ts b/projects/igniteui-angular/grids/core/src/row.directive.ts index 970fa1cefa6..45e18914216 100644 --- a/projects/igniteui-angular/grids/core/src/row.directive.ts +++ b/projects/igniteui-angular/grids/core/src/row.directive.ts @@ -21,7 +21,7 @@ import { IgxGridForOfDirective } from 'igniteui-angular/directives'; import { ColumnType, mergeObjects, TransactionType } from 'igniteui-angular/core'; import { IgxGridSelectionService } from './selection/selection.service'; import { IgxEditRow } from './common/crud.service'; -import { CellType, GridType, IGX_GRID_BASE } from './common/grid.interface'; +import { CellType, GridType, IGX_GRID_BASE, RowType } from './common/grid.interface'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { trackByIdentity } from 'igniteui-angular/core'; @@ -31,7 +31,7 @@ import { IgxCheckboxComponent } from 'igniteui-angular/checkbox'; selector: '[igxRowBaseComponent]', standalone: true }) -export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { +export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy, RowType { /* blazorSuppress */ public grid = inject(IGX_GRID_BASE); /* blazorSuppress */ @@ -89,7 +89,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { * ``` */ @Input() - public index: number; + public index!: number; /** * Sets whether this specific row has disabled functionality for editing and row selection. @@ -173,27 +173,27 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { * @hidden */ @Input() - public gridID: string; + public gridID!: string; /** * @hidden */ @ViewChildren('igxDirRef', { read: IgxGridForOfDirective }) - public _virtDirRow: QueryList>; + public _virtDirRow!: QueryList>; /* blazorSuppress */ public get virtDirRow(): IgxGridForOfDirective { - return this._virtDirRow ? this._virtDirRow.first : null; + return this._virtDirRow ? this._virtDirRow.first : null!; } /** * @hidden */ @ViewChild(forwardRef(() => IgxCheckboxComponent), { read: IgxCheckboxComponent }) - public checkboxElement: IgxCheckboxComponent; + public checkboxElement!: IgxCheckboxComponent; @ViewChildren('cell') - protected _cells: QueryList; + protected _cells!: QueryList; /** * Gets the rendered cells in the row component. @@ -208,7 +208,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { if (!this._cells) { return res; } - const cList = this._cells.filter((item) => item.nativeElement.parentElement !== null) + const cList = this._cells.filter((item) => item.nativeElement!.parentElement !== null) .sort((item1, item2) => item1.column.visibleIndex - item2.column.visibleIndex); res.reset(cList); return res; @@ -250,7 +250,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { */ public get viewIndex(): number { if ((this.grid as any).groupingExpressions.length) { - return this.grid.filteredSortedData.indexOf(this.data); + return this.grid.filteredSortedData!.indexOf(this.data); } return this.index + this.grid.page * this.grid.perPage; } @@ -402,7 +402,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { protected destroy$ = new Subject(); protected _data: any; - protected _addRow: boolean; + protected _addRow!: boolean; /** * @hidden @@ -413,8 +413,8 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { if (this.hasMergedCells && this.metaData?.cellMergeMeta) { const targetRowIndex = this.grid.navigation.activeNode.row; if (targetRowIndex != this.index) { - const row = this.grid.rowList.toArray().find(x => x.index === targetRowIndex); - row.onClick(event); + const row = this.grid.rowList.find(x => x.index === targetRowIndex); + row?.onClick?.(event); return; } } @@ -448,7 +448,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { const cell = (event.target as HTMLElement).closest('.igx-grid__td'); this.grid.contextMenu.emit({ row: this, - cell: this.cells.find(c => c.nativeElement === cell), + cell: this.cells.find(c => c.nativeElement === cell)!, event }); } @@ -474,7 +474,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { if (this.grid.actionStrip && this.grid.actionStrip.hideOnRowLeave) { this.grid.actionStrip.hide(); } - this.grid.hoverIndex = null; + this.grid.hoverIndex = null!; } /** @@ -502,7 +502,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { /** * @hidden */ - public onRowSelectorClick(event) { + public onRowSelectorClick(event: MouseEvent) { event.stopPropagation(); if (event.shiftKey && this.grid.isMultiRowSelectionEnabled) { this.selectionService.selectMultipleRows(this.key, this.data, event); @@ -526,7 +526,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { */ public update(value: any) { const crudService = this.grid.crudService; - if (crudService.cellInEditMode && crudService.cell.id.key === this.key) { + if (crudService.cellInEditMode && crudService.cell?.id.key === this.key) { this.grid.transactions.endPending(false); } const row = new IgxEditRow(this.key, this.index, this.data, this.grid); @@ -547,7 +547,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { this.grid.deleteRowById(this.key); } - public isCellActive(visibleColumnIndex) { + public isCellActive(visibleColumnIndex: number) { const node = this.grid.navigation.activeNode; const field = this.grid.visibleColumns[visibleColumnIndex]?.field; const rowSpan = this.metaData?.cellMergeMeta?.get(field)?.rowSpan; @@ -657,7 +657,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { const isPinned = this.pinned && !this.disabled; const indexInData = this.grid.isRowPinningToTop && !isPinned ? this.index - this.grid.pinnedRecordsCount : this.index; const range = isPinned ? this.grid.pinnedDataView.slice(indexInData, indexInData + rowCount) : this.grid.verticalScrollContainer.igxForOf.slice(indexInData, indexInData + rowCount); - const inRange = range.filter(x => this.selectionService.isRowSelected(this.extractRecordKey(x))).length > 0; + const inRange = range.filter((x: any) => this.selectionService.isRowSelected(this.extractRecordKey(x))).length > 0; return inRange; } return false; diff --git a/projects/igniteui-angular/grids/core/src/selection/drag-select.directive.ts b/projects/igniteui-angular/grids/core/src/selection/drag-select.directive.ts index 9aa941f4141..8e799a4fdec 100644 --- a/projects/igniteui-angular/grids/core/src/selection/drag-select.directive.ts +++ b/projects/igniteui-angular/grids/core/src/selection/drag-select.directive.ts @@ -53,9 +53,9 @@ export class IgxGridDragSelectDirective implements OnInit, OnDestroy { protected end$ = new Subject(); protected lastDirection = DragScrollDirection.NONE; protected _interval$: Observable; - protected _sub: Subscription; + protected _sub!: Subscription; - private _activeDrag: boolean; + private _activeDrag!: boolean; constructor() { this._interval$ = interval(0, animationFrameScheduler).pipe( diff --git a/projects/igniteui-angular/grids/core/src/selection/selection.service.ts b/projects/igniteui-angular/grids/core/src/selection/selection.service.ts index db318ff7c91..86e13602179 100644 --- a/projects/igniteui-angular/grids/core/src/selection/selection.service.ts +++ b/projects/igniteui-angular/grids/core/src/selection/selection.service.ts @@ -2,8 +2,7 @@ import { EventEmitter, Injectable, NgZone, inject } from '@angular/core'; import { Subject } from 'rxjs'; import { IRowSelectionEventArgs } from '../common/events'; import { GridType } from '../common/grid.interface'; -import { FilteringExpressionsTree, PlatformUtil } from 'igniteui-angular/core'; -import { GridSelectionRange, IColumnSelectionState, IMultiRowLayoutNode, ISelectionKeyboardState, ISelectionNode, ISelectionPointerState, SelectionState } from '../common/types'; +import { FilteringExpressionsTree, GridSelectionRange, IColumnSelectionState, IMultiRowLayoutNode, ISelectionKeyboardState, ISelectionNode, ISelectionPointerState, PlatformUtil, SelectionState } from 'igniteui-angular/core'; import { PivotUtil } from '../pivot-util'; @@ -12,9 +11,9 @@ export class IgxGridSelectionService { private zone = inject(NgZone); protected platform = inject(PlatformUtil); - public grid: GridType; + public grid!: GridType; public dragMode = false; - public activeElement: ISelectionNode | null; + public activeElement!: ISelectionNode | null; public keyboardState = {} as ISelectionKeyboardState; public pointerState = {} as ISelectionPointerState; public columnsState = {} as IColumnSelectionState; @@ -40,10 +39,10 @@ export class IgxGridSelectionService { */ private pointerEventInGridBody = false; - private allRowsSelected: boolean; - private _lastSelectedNode: ISelectionNode; + private allRowsSelected: boolean | undefined; + private _lastSelectedNode!: ISelectionNode; private _ranges: Set = new Set(); - private _selectionRange: Range; + private _selectionRange!: Range; /** * Returns the current selected ranges in the grid from both @@ -84,7 +83,7 @@ export class IgxGridSelectionService { public initKeyboardState(): void { this.keyboardState.node = null; this.keyboardState.shift = false; - this.keyboardState.range = null; + this.keyboardState.range = null!; this.keyboardState.active = false; } @@ -95,7 +94,7 @@ export class IgxGridSelectionService { this.pointerState.node = null; this.pointerState.ctrl = false; this.pointerState.shift = false; - this.pointerState.range = null; + this.pointerState.range = null!; this.pointerState.primaryButton = true; } @@ -113,9 +112,9 @@ export class IgxGridSelectionService { */ public add(node: ISelectionNode, addToRange = true): void { if (this.selection.has(node.row)) { - this.selection.get(node.row).add(node.column); + this.selection.get(node.row)!.add(node.column); } else { - this.selection.set(node.row, new Set()).get(node.row).add(node.column); + this.selection.set(node.row, new Set()).get(node.row)!.add(node.column); } if (addToRange) { @@ -134,7 +133,7 @@ export class IgxGridSelectionService { public remove(node: ISelectionNode): void { if (this.selection.has(node.row)) { - this.selection.get(node.row).delete(node.column); + this.selection.get(node.row)!.delete(node.column); } if (this.isActiveNode(node)) { this.activeElement = null; @@ -143,8 +142,8 @@ export class IgxGridSelectionService { } public isInMap(node: ISelectionNode): boolean { - return (this.selection.has(node.row) && this.selection.get(node.row).has(node.column)) || - (this.temp.has(node.row) && this.temp.get(node.row).has(node.column)); + return (this.selection.has(node.row) && this.selection.get(node.row)!.has(node.column)) || + (this.temp.has(node.row) && this.temp.get(node.row)!.has(node.column)); } public selected(node: ISelectionNode): boolean { @@ -156,7 +155,7 @@ export class IgxGridSelectionService { const isActive = this.activeElement.column === node.column && this.activeElement.row === node.row; if (this.grid.hasColumnLayouts) { const layout = this.activeElement.layout; - return isActive && this.isActiveLayout(layout, node.layout); + return isActive && this.isActiveLayout(layout!, node.layout!); } return isActive; } @@ -192,7 +191,7 @@ export class IgxGridSelectionService { }; } - const { row, column } = state.node; + const { row, column } = state.node!; const rowStart = Math.min(node.row, row); const rowEnd = Math.max(node.row, row); const columnStart = Math.min(node.column, column); @@ -219,7 +218,7 @@ export class IgxGridSelectionService { } } - public keyboardStateOnFocus(node: ISelectionNode, emitter: EventEmitter, dom): void { + public keyboardStateOnFocus(node: ISelectionNode, emitter: EventEmitter, dom: HTMLElement): void { const kbState = this.keyboardState; // Focus triggered by keyboard navigation @@ -282,7 +281,7 @@ export class IgxGridSelectionService { while (!pair.done) { [key, value] = pair.value; if (target.has(key)) { - const newValue = target.get(key); + const newValue = target.get(key)!; value.forEach(record => newValue.add(record)); target.set(key, newValue); } else { @@ -348,9 +347,9 @@ export class IgxGridSelectionService { for (let i = rowStart; i <= rowEnd; i++) { for (let j = columnStart as number; j <= (columnEnd as number); j++) { if (collection.has(i)) { - collection.get(i).add(j); + collection.get(i)!.add(j); } else { - collection.set(i, new Set()).get(i).add(j); + collection.set(i, new Set()).get(i)!.add(j); } } } @@ -375,7 +374,7 @@ export class IgxGridSelectionService { } public clearTextSelection(): void { - const selection = window.getSelection(); + const selection = window.getSelection()!; if (selection.rangeCount) { this._selectionRange = selection.getRangeAt(0); this._selectionRange.collapse(true); @@ -384,7 +383,7 @@ export class IgxGridSelectionService { } public restoreTextSelection(): void { - const selection = window.getSelection(); + const selection = window.getSelection()!; if (!selection.rangeCount) { selection.addRange(this._selectionRange || this.grid.document.createRange()); } @@ -393,19 +392,19 @@ export class IgxGridSelectionService { public getSelectedRowsData() { if (this.grid.type === 'pivot') { return this.grid.dataView.filter(r => { - const keys = r.dimensions.map(d => PivotUtil.getRecordKey(r, d)); - return keys.some(k => this.isPivotRowSelected(k)); + const keys = r.dimensions.map((d: any) => PivotUtil.getRecordKey(r, d)); + return keys.some((k: any) => this.isPivotRowSelected(k)); }); } if (!this.grid.primaryKey) { return Array.from(this.rowSelection); } - const selection = []; - const gridDataMap = {}; + const selection: any[] = []; + const gridDataMap: { [key: string]: any } = {}; this.grid.gridAPI.get_all_data(true).forEach(row => gridDataMap[this.getRecordKey(row)] = row); this.rowSelection.forEach(rID => { const rData = gridDataMap[rID]; - const partialRowData = {}; + const partialRowData: { [key: string]: any } = {}; partialRowData[this.grid.primaryKey] = rID; selection.push(rData ? rData : partialRowData); }); @@ -423,7 +422,7 @@ export class IgxGridSelectionService { } /** Clears row selection, if filtering is applied clears only selected rows from filtered data. */ - public clearRowSelection(event?): void { + public clearRowSelection(event?: MouseEvent): void { const selectedRows = this.getSelectedRowsData(); const removedRec = this.isFilteringApplied() ? this.allData.filter(row => this.isRowSelected(this.getRecordKey(row))) : selectedRows; @@ -439,7 +438,7 @@ export class IgxGridSelectionService { } /** Select all rows, if filtering is applied select only from filtered data. */ - public selectAllRows(event?) { + public selectAllRows(event?: MouseEvent): void { const addedRows = this.allData.filter((row) => !this.rowSelection.has(this.getRecordKey(row))); const selectedRows = this.getSelectedRowsData(); const newSelection = this.rowSelection.size ? selectedRows.concat(addedRows) : addedRows; @@ -448,13 +447,13 @@ export class IgxGridSelectionService { } /** Select the specified row and emit event. */ - public selectRowById(rowID, clearPrevSelection?, event?): void { + public selectRowById(rowID: any, clearPrevSelection?: boolean, event?: MouseEvent | KeyboardEvent): void { if (!(this.grid.isRowSelectable || this.grid.type === 'pivot') || this.isRowDeleted(rowID)) { return; } clearPrevSelection = !this.grid.isMultiRowSelectionEnabled || clearPrevSelection; if (this.grid.type === 'pivot') { - this.selectPivotRowById(rowID, clearPrevSelection, event); + this.selectPivotRowById(rowID, clearPrevSelection!, event); return; } const selectedRows = this.getSelectedRowsData(); @@ -464,7 +463,7 @@ export class IgxGridSelectionService { this.emitRowSelectionEvent(newSelection, [this.getRowDataById(rowID)], removed, event, selectedRows); } - public selectPivotRowById(rowID, clearPrevSelection: boolean, event?): void { + public selectPivotRowById(rowID: any, clearPrevSelection: boolean, event?: MouseEvent | KeyboardEvent): void { const selectedRows = this.getSelectedRows(); const newSelection = clearPrevSelection ? [rowID] : this.rowSelection.has(rowID) ? selectedRows : [...selectedRows, rowID]; const added = this.getPivotRowsByIds([rowID]); @@ -473,7 +472,7 @@ export class IgxGridSelectionService { } /** Deselect the specified row and emit event. */ - public deselectRow(rowID, event?): void { + public deselectRow(rowID: any, event?: MouseEvent | KeyboardEvent): void { if (!this.isRowSelected(rowID)) { return; } @@ -488,7 +487,7 @@ export class IgxGridSelectionService { } } - public deselectPivotRowByID(rowID, event?) { + public deselectPivotRowByID(rowID: any, event?: MouseEvent | KeyboardEvent): void { if (this.rowSelection.size && this.rowSelection.has(rowID)) { const currSelection = this.getSelectedRows(); const newSelection = currSelection.filter(r => r !== rowID); @@ -497,7 +496,7 @@ export class IgxGridSelectionService { } } - private emitRowSelectionEventPivotGrid(currSelection, newSelection, added, removed, event) { + private emitRowSelectionEventPivotGrid(currSelection: any, newSelection: any, added: any, removed: any, event?: MouseEvent | KeyboardEvent): void { if (this.areEqualCollections(currSelection, newSelection)) { return; } @@ -521,7 +520,7 @@ export class IgxGridSelectionService { } /** Select the specified rows and emit event. */ - public selectRows(keys: any[], clearPrevSelection?: boolean, event?): void { + public selectRows(keys: any[], clearPrevSelection?: boolean, event?: MouseEvent): void { if (!this.grid.isMultiRowSelectionEnabled) { return; } @@ -540,7 +539,7 @@ export class IgxGridSelectionService { this.emitRowSelectionEvent(newSelection, rowsToSelect, removed, event, selectedRows); } - public deselectRows(keys: any[], event?): void { + public deselectRows(keys: any[], event?: MouseEvent): void { if (!this.rowSelection.size) { return; } @@ -556,7 +555,7 @@ export class IgxGridSelectionService { } /** Select specified rows. No event is emitted. */ - public selectRowsWithNoEvent(rowIDs: any[], clearPrevSelection?): void { + public selectRowsWithNoEvent(rowIDs: any[], clearPrevSelection?: boolean): void { if (clearPrevSelection) { this.rowSelection.clear(); } @@ -572,11 +571,11 @@ export class IgxGridSelectionService { this.selectedRowsChange.next(this.getSelectedRows()); } - public isRowSelected(rowID): boolean { + public isRowSelected(rowID: any): boolean { return this.rowSelection.size > 0 && this.rowSelection.has(rowID); } - public isPivotRowSelected(rowID): boolean { + public isPivotRowSelected(rowID: any): boolean { let contains = false; this.rowSelection.forEach(x => { const correctRowId = rowID.replace(x,''); @@ -588,12 +587,12 @@ export class IgxGridSelectionService { return this.rowSelection.size > 0 && contains; } - public isRowInIndeterminateState(rowID): boolean { + public isRowInIndeterminateState(rowID: any): boolean { return this.indeterminateRows.size > 0 && this.indeterminateRows.has(rowID); } /** Select range from last selected row to the current specified row. */ - public selectMultipleRows(rowID, rowData, event?): void { + public selectMultipleRows(rowID: any, rowData: any, event?: MouseEvent): void { this.clearHeaderCBState(); if (!this.rowSelection.size || this.isRowDeleted(rowID)) { this.selectRowById(rowID); @@ -610,7 +609,7 @@ export class IgxGridSelectionService { this.emitRowSelectionEvent(newSelection, added, [], event, currSelection); } - public areAllRowSelected(newSelection?): boolean { + public areAllRowSelected(newSelection?: any): boolean { if (!this.grid.data && !newSelection) { return false; } @@ -633,10 +632,10 @@ export class IgxGridSelectionService { this.getSelectedRows().filter(rowID => !this.isRowDeleted(rowID)); } - public emitRowSelectionEvent(newSelection, added, removed, event?, currSelection?): boolean { + public emitRowSelectionEvent(newSelection: any, added: any, removed: any, event?: MouseEvent | KeyboardEvent, currSelection?: any): boolean { currSelection = currSelection ?? this.getSelectedRowsData(); if (this.areEqualCollections(currSelection, newSelection)) { - return; + return undefined!; } const args: IRowSelectionEventArgs = { @@ -653,19 +652,20 @@ export class IgxGridSelectionService { this.grid.rowSelectionChanging.emit(args); if (args.cancel) { this.clearHeaderCBState(); - return; + return undefined!; } this.selectRowsWithNoEvent(args.newSelection.map(r => this.getRecordKey(r)), true); + return undefined!; } public getPivotRowsByIds(ids: any[]) { return this.grid.dataView.filter(r => { - const keys = r.dimensions.map(d => PivotUtil.getRecordKey(r, d)); + const keys = r.dimensions.map((d: any) => PivotUtil.getRecordKey(r, d)); return new Set(ids.concat(keys)).size < ids.length + keys.length; }); } - public getRowDataById(rowID): any { + public getRowDataById(rowID: any): any { if (!this.grid.primaryKey) { return rowID; } @@ -677,11 +677,11 @@ export class IgxGridSelectionService { this.allRowsSelected = undefined; } - public getRowIDs(data): Array { - return this.grid.primaryKey && data.length ? data.map(rec => rec[this.grid.primaryKey]) : data; + public getRowIDs(data: any): Array { + return this.grid.primaryKey && data.length ? data.map((rec: any) => rec[this.grid.primaryKey]) : data; } - public getRecordKey(record) { + public getRecordKey(record: any) { return this.grid.primaryKey ? record[this.grid.primaryKey] : record; } @@ -702,7 +702,7 @@ export class IgxGridSelectionService { } else { allData = this.grid.gridAPI.get_all_data(true); } - return allData.filter(rData => !this.isRowDeleted(this.grid.gridAPI.get_row_id(rData))); + return allData!.filter((rData: any) => !this.isRowDeleted(this.grid.gridAPI.get_row_id(rData))); } /** Returns array of the selected columns fields. */ @@ -715,7 +715,7 @@ export class IgxGridSelectionService { } /** Select the specified column and emit event. */ - public selectColumn(field: string, clearPrevSelection?, selectColumnsRange?, event?): void { + public selectColumn(field: string, clearPrevSelection?: boolean, selectColumnsRange?: boolean, event?: MouseEvent): void { const stateColumn = this.columnsState.field ? this.grid.getColumnByName(this.columnsState.field) : null; if (!event || !stateColumn || stateColumn.visibleIndex < 0 || !selectColumnsRange) { this.columnsState.field = field; @@ -732,7 +732,7 @@ export class IgxGridSelectionService { } /** Select specified columns. And emit event. */ - public selectColumns(fields: string[], clearPrevSelection?, selectColumnsRange?, event?): void { + public selectColumns(fields: string[], clearPrevSelection?: boolean, selectColumnsRange?: boolean, event?: MouseEvent | KeyboardEvent): void { const columns = fields.map(f => this.grid.getColumnByName(f)).sort((a, b) => a.visibleIndex - b.visibleIndex); const stateColumn = this.columnsState.field ? this.grid.getColumnByName(this.columnsState.field) : null; if (!stateColumn || stateColumn.visibleIndex < 0 || !selectColumnsRange) { @@ -752,16 +752,16 @@ export class IgxGridSelectionService { } /** Select range from last clicked column to the current specified column. */ - public selectColumnsRange(field: string, event): void { - const currIndex = this.grid.getColumnByName(this.columnsState.field).visibleIndex; + public selectColumnsRange(field: string, event?: MouseEvent | KeyboardEvent): void { + const currIndex = this.grid.getColumnByName(this.columnsState.field!).visibleIndex; const newIndex = this.grid.columnToVisibleIndex(field); const columnsFields = this.grid.visibleColumns .filter(c => !c.columnGroup) .sort((a, b) => a.visibleIndex - b.visibleIndex) .slice(Math.min(currIndex, newIndex), Math.max(currIndex, newIndex) + 1) .filter(col => col.selectable).map(col => col.field); - const removed = []; - const oldAdded = []; + const removed: string[] = []; + const oldAdded: string[] = []; const added = columnsFields.filter(colField => !this.isColumnSelected(colField)); this.columnsState.range.forEach(f => { if (columnsFields.indexOf(f) === -1) { @@ -776,7 +776,7 @@ export class IgxGridSelectionService { } /** Select specified columns. No event is emitted. */ - public selectColumnsWithNoEvent(fields: string[], clearPrevSelection?): void { + public selectColumnsWithNoEvent(fields: string[], clearPrevSelection?: boolean): void { if (clearPrevSelection) { this.columnSelection.clear(); } @@ -786,7 +786,7 @@ export class IgxGridSelectionService { } /** Deselect the specified column and emit event. */ - public deselectColumn(field: string, event?): void { + public deselectColumn(field: string, event?: MouseEvent): void { this.initColumnsState(); const newSelection = this.getSelectedColumns().filter(c => c !== field); this.emitColumnSelectionEvent(newSelection, [], [field], event); @@ -798,17 +798,17 @@ export class IgxGridSelectionService { } /** Deselect specified columns. And emit event. */ - public deselectColumns(fields: string[], event?): void { + public deselectColumns(fields: string[], event?: MouseEvent | KeyboardEvent): void { const removed = this.getSelectedColumns().filter(colField => fields.indexOf(colField) > -1); const newSelection = this.getSelectedColumns().filter(colField => fields.indexOf(colField) === -1); this.emitColumnSelectionEvent(newSelection, [], removed, event); } - public emitColumnSelectionEvent(newSelection, added, removed, event?): boolean { + public emitColumnSelectionEvent(newSelection: any, added: any, removed: any, event?: MouseEvent | KeyboardEvent): boolean { const currSelection = this.getSelectedColumns(); if (this.areEqualCollections(currSelection, newSelection)) { - return; + return undefined!; } const args = { @@ -817,9 +817,10 @@ export class IgxGridSelectionService { }; this.grid.columnSelectionChanging.emit(args); if (args.cancel) { - return; + return undefined!; } this.selectColumnsWithNoEvent(args.newSelection, true); + return undefined!; } /** Clear columnSelection */ @@ -827,7 +828,7 @@ export class IgxGridSelectionService { this.columnSelection.clear(); } - protected areEqualCollections(first, second): boolean { + protected areEqualCollections(first: any, second: any): boolean { return first.length === second.length && new Set(first.concat(second)).size === first.length; } @@ -837,7 +838,7 @@ export class IgxGridSelectionService { * range after keyboard navigation, thus this. */ private _moveSelectionChrome(node: Node) { - const selection = window.getSelection(); + const selection = window.getSelection()!; selection.removeAllRanges(); const range = new Range(); range.selectNode(node); @@ -850,16 +851,16 @@ export class IgxGridSelectionService { !FilteringExpressionsTree.empty(this.grid.advancedFilteringExpressionsTree); } - private isRowDeleted(rowID): boolean { + private isRowDeleted(rowID: any): boolean { return this.grid.gridAPI.row_deleted_transaction(rowID); } - private pointerOriginHandler = (event) => { + private pointerOriginHandler = (event: PointerEvent) => { this.pointerEventInGridBody = false; this.grid.document.body.removeEventListener('pointerup', this.pointerOriginHandler); const gridCellSelectors = ['igx-grid-cell', 'igx-hierarchical-grid-cell', 'igx-tree-grid-cell']; - const isInsideGridCell = gridCellSelectors.some(selector => event.target.closest(selector)); + const isInsideGridCell = gridCellSelectors.some(selector => event.target ? (event.target as HTMLElement).closest(selector) : false); if (!isInsideGridCell) { this.pointerUp(this._lastSelectedNode, this.grid.rangeSelected, true); diff --git a/projects/igniteui-angular/grids/core/src/services/csv/char-separated-value-data.ts b/projects/igniteui-angular/grids/core/src/services/csv/char-separated-value-data.ts index cdcdfa6aa94..4526affbfeb 100644 --- a/projects/igniteui-angular/grids/core/src/services/csv/char-separated-value-data.ts +++ b/projects/igniteui-angular/grids/core/src/services/csv/char-separated-value-data.ts @@ -9,7 +9,7 @@ export class CharSeparatedValueData { private _headerRecord = ''; private _dataRecords = ''; private _eor = '\r\n'; - private _delimiter; + private _delimiter!: string; private _escapeCharacters = ['\r', '\n', '\r\n']; private _delimiterLength = 1; private _isSpecialData = false; @@ -44,8 +44,8 @@ export class CharSeparatedValueData { public prepareDataAsync(done: (result: string) => void, alwaysExportHeaders: boolean = true) { const columns = this.columns?.filter(c => !c.skip) - .sort((a, b) => a.startIndex - b.startIndex) - .sort((a, b) => a.pinnedIndex - b.pinnedIndex); + .sort((a, b) => a.startIndex! - b.startIndex!) + .sort((a, b) => a.pinnedIndex! - b.pinnedIndex!); const keys = columns && columns.length ? columns.map(c => c.field) : ExportUtilities.getKeysFromData(this._data); if (this._data && this._data.length > 0) { @@ -72,7 +72,7 @@ export class CharSeparatedValueData { } } - private processField(value, escapeChars): string { + private processField(value: any, escapeChars: string[]): string { let safeValue = ExportUtilities.hasValue(value) ? String(value) : ''; if (escapeChars.some((v) => safeValue.includes(v))) { safeValue = `"${safeValue}"`; @@ -80,7 +80,7 @@ export class CharSeparatedValueData { return safeValue + this._delimiter; } - private processHeaderRecord(keys, dataLength): string { + private processHeaderRecord(keys: any[], dataLength: number): string { let recordData = ''; for (const keyName of keys) { recordData += this.processField(keyName, this._escapeCharacters); @@ -91,7 +91,7 @@ export class CharSeparatedValueData { return dataLength > 0 ? result + this._eor : result; } - private processRecord(record, keys): string { + private processRecord(record: any, keys: any[]): string { const recordData = new Array(keys.length); for (let index = 0; index < keys.length; index++) { const value = (record[keys[index]] !== undefined) ? record[keys[index]] : this._isSpecialData ? record : ''; @@ -101,7 +101,7 @@ export class CharSeparatedValueData { return recordData.join('').slice(0, -this._delimiterLength) + this._eor; } - private processDataRecords(currentData, keys) { + private processDataRecords(currentData: any[], keys: any[]) { const dataRecords = new Array(currentData.length); for (let i = 0; i < currentData.length; i++) { @@ -112,7 +112,7 @@ export class CharSeparatedValueData { return dataRecords.join(''); } - private processDataRecordsAsync(currentData, keys, done: (result: string) => void) { + private processDataRecordsAsync(currentData: any[], keys: any[], done: (result: string) => void) { const dataRecords = new Array(currentData.length); yieldingLoop(currentData.length, 1000, @@ -125,7 +125,7 @@ export class CharSeparatedValueData { }); } - private setDelimiter(value) { + private setDelimiter(value: string) { this._delimiter = value; this._delimiterLength = value.length; } diff --git a/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter-options.ts b/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter-options.ts index 41b0fae97c5..9a0dea25201 100644 --- a/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter-options.ts +++ b/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter-options.ts @@ -6,8 +6,8 @@ import { IgxExporterOptionsBase } from '../exporter-common/exporter-options-base */ export class IgxCsvExporterOptions extends IgxExporterOptionsBase { - private _valueDelimiter; - private _fileType; + private _valueDelimiter!: string; + private _fileType!: CsvFileTypes; constructor(fileName: string, fileType: CsvFileTypes) { super(fileName, IgxCsvExporterOptions.getExtensionFromFileType(fileType)); @@ -81,7 +81,7 @@ export class IgxCsvExporterOptions extends IgxExporterOptionsBase { this.setFileType(value); } - private setFileType(value) { + private setFileType(value: CsvFileTypes) { if (value !== undefined && value !== null && value !== this._fileType) { this._fileType = value; const extension = IgxCsvExporterOptions.getExtensionFromFileType(value); @@ -94,7 +94,7 @@ export class IgxCsvExporterOptions extends IgxExporterOptionsBase { } } - private setDelimiter(value?) { + private setDelimiter(value?: string) { if (value !== undefined && value !== '' && value !== null) { this._valueDelimiter = value; } else { diff --git a/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter.ts b/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter.ts index a45624ff4e4..2a947121812 100644 --- a/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter.ts +++ b/projects/igniteui-angular/grids/core/src/services/csv/csv-exporter.ts @@ -49,7 +49,7 @@ export class IgxCsvExporterService extends IgxBaseExporter { */ public override exportEnded = new EventEmitter(); - private _stringData: string; + private _stringData!: string; protected exportDataImplementation(data: IExportRecord[], options: IgxCsvExporterOptions, done: () => void) { const firstDataElement = data[0]; @@ -97,7 +97,7 @@ export class IgxCsvExporterService extends IgxBaseExporter { }; return columnInfo; }); - columns.unshift(...dimensionCols); + columns!.unshift(...dimensionCols); } const csvData = new CharSeparatedValueData(allRecords, options.valueDelimiter, columns); diff --git a/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter-options.ts b/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter-options.ts index 264d6784d2d..533efbdc864 100644 --- a/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter-options.ts +++ b/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter-options.ts @@ -28,9 +28,9 @@ export class IgxExcelExporterOptions extends IgxExporterOptionsBase { */ public exportAsTable = true; - private _columnWidth: number; - private _rowHeight: number; - private _worksheetName: string; + private _columnWidth!: number; + private _rowHeight!: number; + private _worksheetName!: string; constructor(fileName: string) { super(fileName, '.xlsx'); diff --git a/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter.ts b/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter.ts index d5a8614b641..64e3a12129b 100644 --- a/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter.ts +++ b/projects/igniteui-angular/grids/core/src/services/excel/excel-exporter.ts @@ -5,7 +5,7 @@ import { ExcelElementsFactory } from './excel-elements-factory'; import { ExcelFolderTypes } from './excel-enums'; import { IgxExcelExporterOptions } from './excel-exporter-options'; import { IExcelFolder } from './excel-interfaces'; -import { ExportRecordType, IExportRecord, IgxBaseExporter, DEFAULT_OWNER, ExportHeaderType, GRID_LEVEL_COL } from '../exporter-common/base-export-service'; +import { ExportRecordType, IExportRecord, IgxBaseExporter, DEFAULT_OWNER, ExportHeaderType, GRID_LEVEL_COL, IColumnInfo } from '../exporter-common/base-export-service'; import { ExportUtilities } from '../exporter-common/export-utilities'; import { WorksheetData } from './worksheet-data'; import { WorksheetFile } from './excel-files'; @@ -61,7 +61,7 @@ export class IgxExcelExporterService extends IgxBaseExporter { private static async populateZipFileConfig(fileStructure: Object, folder: IExcelFolder, worksheetData: WorksheetData) { for (const childFolder of folder.childFolders(worksheetData)) { const folderInstance = ExcelElementsFactory.getExcelFolder(childFolder); - const childStructure = fileStructure[folderInstance.folderName] = {}; + const childStructure = (fileStructure as any)[folderInstance.folderName] = {}; await IgxExcelExporterService.populateZipFileConfig(childStructure, folderInstance, worksheetData); } @@ -82,7 +82,7 @@ export class IgxExcelExporterService extends IgxBaseExporter { const ownersKeys = Array.from(this._ownersMap.keys()); const firstKey = ownersKeys[0]; const isHierarchicalGridByMap = firstKey && typeof firstKey !== 'string'; - const filterColumns = (columns) => columns.filter(col => col.field !== GRID_LEVEL_COL && !col.skip && col.headerType === ExportHeaderType.ColumnHeader); + const filterColumns = (columns: IColumnInfo[]) => columns.filter(col => col.field !== GRID_LEVEL_COL && !col.skip && col.headerType === ExportHeaderType.ColumnHeader); let rootKeys; let columnCount; @@ -113,10 +113,10 @@ export class IgxExcelExporterService extends IgxBaseExporter { if (isHierarchicalGrid) { columnCount = data - .map(a => this._ownersMap.get(a.owner).columns.filter(c => !c.skip).length + a.level) + .map(a => this._ownersMap.get(a.owner)!.columns.filter(c => !c.skip).length + a.level) .sort((a, b) => b - a)[0]; - rootKeys = this._ownersMap.get(firstDataElement.owner).columns.filter(c => !c.skip).map(c => c.field); + rootKeys = this._ownersMap.get(firstDataElement.owner)!.columns.filter(c => !c.skip).map(c => c.field); defaultOwner = this._ownersMap.get(firstDataElement.owner); } else { // Check if this is actually a hierarchical grid (when data only contains summary records) @@ -146,8 +146,8 @@ export class IgxExcelExporterService extends IgxBaseExporter { } const worksheetData = - new WorksheetData(data, options, this._sort, columnCount, rootKeys, indexOfLastPinnedColumn, - columnWidths, defaultOwner, this._ownersMap); + new WorksheetData(data, options, this._sort, columnCount!, rootKeys!, indexOfLastPinnedColumn!, + columnWidths!, defaultOwner!, this._ownersMap); const rootFolder = ExcelElementsFactory.getExcelFolder(ExcelFolderTypes.RootExcelFolder); const fileData = {}; diff --git a/projects/igniteui-angular/grids/core/src/services/excel/excel-files.ts b/projects/igniteui-angular/grids/core/src/services/excel/excel-files.ts index ebf68e89262..f92cc2a99b5 100644 --- a/projects/igniteui-angular/grids/core/src/services/excel/excel-files.ts +++ b/projects/igniteui-angular/grids/core/src/services/excel/excel-files.ts @@ -11,7 +11,7 @@ import { yieldingLoop } from '../exporter-common/yielding-loop'; */ export class RootRelsFile implements IExcelFile { public writeElement(folder: Object) { - folder['.rels'] = strToU8(ExcelStrings.getRels()); + (folder as any)['.rels'] = strToU8(ExcelStrings.getRels()); } } @@ -20,7 +20,7 @@ export class RootRelsFile implements IExcelFile { */ export class AppFile implements IExcelFile { public writeElement(folder: Object, worksheetData: WorksheetData) { - folder['app.xml'] = strToU8(ExcelStrings.getApp(worksheetData.options.worksheetName)); + (folder as any)['app.xml'] = strToU8(ExcelStrings.getApp(worksheetData.options.worksheetName)); } } @@ -29,7 +29,7 @@ export class AppFile implements IExcelFile { */ export class CoreFile implements IExcelFile { public writeElement(folder: Object) { - folder['core.xml'] = strToU8(ExcelStrings.getCore()); + (folder as any)['core.xml'] = strToU8(ExcelStrings.getCore()); } } @@ -39,7 +39,7 @@ export class CoreFile implements IExcelFile { export class WorkbookRelsFile implements IExcelFile { public writeElement(folder: Object, worksheetData: WorksheetData) { const hasSharedStrings = !worksheetData.isEmpty || worksheetData.options.alwaysExportHeaders; - folder['workbook.xml.rels'] = strToU8(ExcelStrings.getWorkbookRels(hasSharedStrings)); + (folder as any)['workbook.xml.rels'] = strToU8(ExcelStrings.getWorkbookRels(hasSharedStrings)); } } @@ -48,7 +48,7 @@ export class WorkbookRelsFile implements IExcelFile { */ export class ThemeFile implements IExcelFile { public writeElement(folder: Object) { - folder['theme1.xml'] = strToU8(ExcelStrings.getTheme()); + (folder as any)['theme1.xml'] = strToU8(ExcelStrings.getTheme()); } } @@ -84,8 +84,8 @@ export class WorksheetFile implements IExcelFile { private currentHierarchicalOwner = ''; private firstColumn = Number.MAX_VALUE; private firstDataRow = Number.MAX_VALUE; - private isValidGrid: boolean; - private lastValidRow: string; + private isValidGrid!: boolean; + private lastValidRow!: string; private currencyStyleMap = new Map([ ['USD', {styleXf: 5, symbol: '$'}], @@ -103,7 +103,7 @@ export class WorksheetFile implements IExcelFile { const hasTable = (!worksheetData.isEmpty || worksheetData.options.alwaysExportHeaders) && worksheetData.options.exportAsTable; - folder['sheet1.xml'] = strToU8(ExcelStrings.getSheetXML( + (folder as any)['sheet1.xml'] = strToU8(ExcelStrings.getSheetXML( this.dimension, this.freezePane, cols, rows, hasTable, this.maxOutlineLevel, worksheetData.isHierarchical)); resolve(); }); @@ -136,8 +136,8 @@ export class WorksheetFile implements IExcelFile { let headersForLevel: IColumnInfo[] = []; - for(let i = 0; i <= owner.maxRowLevel; i++) { - headersForLevel = owner.columns.filter(c => c.level === i && c.rowSpan > 0 && !c.skip) + for(let i = 0; i <= owner.maxRowLevel!; i++) { + headersForLevel = owner.columns.filter(c => c.level === i && c.rowSpan! > 0 && !c.skip) this.printHeaders(worksheetData, headersForLevel, i, true); @@ -146,7 +146,7 @@ export class WorksheetFile implements IExcelFile { this.rowIndex = 0; - for (let i = 0; i <= owner.maxLevel; i++) { + for (let i = 0; i <= owner.maxLevel!; i++) { this.rowIndex++; const pivotGridColumns = this.pivotGridRowHeadersMap.get(this.rowIndex) ?? ""; this.sheetData += `${pivotGridColumns}`; @@ -158,15 +158,15 @@ export class WorksheetFile implements IExcelFile { headersForLevel = hasMultiColumnHeader ? allowedColumns - .filter(c => (c.level < i && - c.headerType !== ExportHeaderType.MultiColumnHeader || c.level === i) && c.columnSpan > 0 && !c.skip) - .sort((a, b) => a.startIndex - b.startIndex) - .sort((a, b) => a.pinnedIndex - b.pinnedIndex) : + .filter(c => (c.level! < i && + c.headerType !== ExportHeaderType.MultiColumnHeader || c.level === i) && c.columnSpan! > 0 && !c.skip) + .sort((a, b) => a.startIndex! - b.startIndex!) + .sort((a, b) => a.pinnedIndex! - b.pinnedIndex!) : hasUserSetIndex ? allowedColumns.filter(c => !c.skip) : allowedColumns.filter(c => !c.skip) - .sort((a, b) => a.startIndex - b.startIndex) - .sort((a, b) => a.pinnedIndex - b.pinnedIndex); + .sort((a, b) => a.startIndex! - b.startIndex!) + .sort((a, b) => a.pinnedIndex! - b.pinnedIndex!); this.printHeaders(worksheetData, headersForLevel, i, false); @@ -174,7 +174,7 @@ export class WorksheetFile implements IExcelFile { } const multiColumnHeaderLevel = worksheetData.options.ignoreMultiColumnHeaders ? 0 : owner.maxLevel; - const freezeHeaders = worksheetData.options.freezeHeaders ? 2 + multiColumnHeaderLevel : 1; + const freezeHeaders = worksheetData.options.freezeHeaders ? 2 + multiColumnHeaderLevel! : 1; if (!isHierarchicalGrid) { const col = worksheetData.hasSummaries ? worksheetData.columnCount + 1 : worksheetData.columnCount - 1 @@ -246,7 +246,7 @@ export class WorksheetFile implements IExcelFile { } private processDataRecordsAsync(worksheetData: WorksheetData, done: (rows: string) => void) { - const rowDataArr = []; + const rowDataArr: any[] = []; const height = worksheetData.options.rowHeight; this.rowHeight = height ? ' ht="' + height + '" customHeight="1"' : ''; @@ -264,8 +264,8 @@ export class WorksheetFile implements IExcelFile { } else { recordHeaders = worksheetData.owner.columns .filter(c => c.headerType === ExportHeaderType.ColumnHeader && !c.skip) - .sort((a, b) => a.startIndex-b.startIndex) - .sort((a, b) => a.pinnedIndex-b.pinnedIndex) + .sort((a, b) => a.startIndex!-b.startIndex!) + .sort((a, b) => a.pinnedIndex!-b.pinnedIndex!) .map(c => c.field); } } else { @@ -273,10 +273,10 @@ export class WorksheetFile implements IExcelFile { if (record.type === ExportRecordType.HeaderRecord) { const recordOwner = worksheetData.owners.get(record.owner); - const hasMultiColumnHeaders = recordOwner.columns.some(c => !c.skip && c.headerType === ExportHeaderType.MultiColumnHeader); + const hasMultiColumnHeaders = recordOwner!.columns.some(c => !c.skip && c.headerType === ExportHeaderType.MultiColumnHeader); if (hasMultiColumnHeaders) { - this.hGridPrintMultiColHeaders(worksheetData, rowDataArr, record, recordOwner); + this.hGridPrintMultiColHeaders(worksheetData, rowDataArr, record, recordOwner!); } } @@ -293,7 +293,7 @@ export class WorksheetFile implements IExcelFile { private hGridPrintMultiColHeaders(worksheetData: WorksheetData, rowDataArr: any[], record: IExportRecord, owner: IColumnList) { - for (let j = 0; j < owner.maxLevel; j++) { + for (let j = 0; j < owner.maxLevel!; j++) { const recordLevel = record.level; const outlineLevel = recordLevel > 0 ? ` outlineLevel="${recordLevel}"` : ''; this.maxOutlineLevel = this.maxOutlineLevel < recordLevel ? recordLevel : this.maxOutlineLevel; @@ -303,10 +303,10 @@ export class WorksheetFile implements IExcelFile { let row = ``; const headersForLevel = owner.columns - .filter(c => (c.level < j && - c.headerType !== ExportHeaderType.MultiColumnHeader || c.level === j) && c.columnSpan > 0 && !c.skip) - .sort((a, b) => a.startIndex - b.startIndex) - .sort((a, b) => a.pinnedIndex - b.pinnedIndex); + .filter(c => (c.level! < j && + c.headerType !== ExportHeaderType.MultiColumnHeader || c.level === j) && c.columnSpan! > 0 && !c.skip) + .sort((a, b) => a.startIndex! - b.startIndex!) + .sort((a, b) => a.pinnedIndex! - b.pinnedIndex!); let startValue = 0 + record.level; @@ -325,9 +325,9 @@ export class WorksheetFile implements IExcelFile { if (currentCol.headerType === ExportHeaderType.ColumnHeader) { columnCoordinate = ExcelStrings.getExcelColumn(startValue) + - (this.rowIndex + owner.maxLevel - currentCol.level); + (this.rowIndex + owner.maxLevel! - currentCol.level); } else { - for (let k = 1; k < currentCol.columnSpan; k++) { + for (let k = 1; k < currentCol.columnSpan!; k++) { columnCoordinate = ExcelStrings.getExcelColumn(startValue + k) + this.rowIndex; row += ``; } @@ -337,7 +337,7 @@ export class WorksheetFile implements IExcelFile { } } - startValue += currentCol.columnSpan; + startValue += currentCol.columnSpan!; } row += ``; rowDataArr.push(row); @@ -372,7 +372,7 @@ export class WorksheetFile implements IExcelFile { } for (let j = 0; j < keys.length; j++) { - const col = j + (isHierarchicalGrid ? rowLevel : worksheetData.isPivotGrid ? worksheetData.owner.maxRowLevel : 0); + const col = j + (isHierarchicalGrid ? rowLevel : worksheetData.isPivotGrid ? worksheetData.owner.maxRowLevel : 0)!; const cellData = this.getCellData(worksheetData, i, col, keys[j]); @@ -406,7 +406,7 @@ export class WorksheetFile implements IExcelFile { } if (worksheetData.hasSummaries && (isValidRecordType || (worksheetData.isGroupedGrid && isSummaryRecord))) { - this.setSummaryCoordinates(columnName, key, fullRow.hierarchicalOwner, worksheetData.isGroupedGrid && isSummaryRecord) + this.setSummaryCoordinates(columnName, key, fullRow.hierarchicalOwner!, worksheetData.isGroupedGrid && isSummaryRecord) } if (fullRow.summaryKey && fullRow.summaryKey === GRID_ROOT_SUMMARY && key !== GRID_LEVEL_COL && worksheetData.isGroupedGrid) { @@ -444,7 +444,7 @@ export class WorksheetFile implements IExcelFile { const isPercentage = targetCol?.dataType === 'percent'; const isColumnCurrencyType = targetCol?.dataType === 'currency'; - const format = isPercentage ? ` s="12"` : isDateTime ? ` s="11"` : isTime ? ` s="10"` : isHeaderRecord ? ` s="3"` : isSavedAsString ? '' : isSavedAsDate ? ` s="2"` : isColumnCurrencyType ? ` s="${this.currencyStyleMap.get(targetCol.currencyCode)?.styleXf || 0}"` : ` s="1"`; + const format = isPercentage ? ` s="12"` : isDateTime ? ` s="11"` : isTime ? ` s="10"` : isHeaderRecord ? ` s="3"` : isSavedAsString ? '' : isSavedAsDate ? ` s="2"` : isColumnCurrencyType ? ` s="${this.currencyStyleMap.get(targetCol.currencyCode!)?.styleXf || 0}"` : ` s="1"`; return `${value}`; } else { @@ -454,7 +454,7 @@ export class WorksheetFile implements IExcelFile { const dimensionMapKey = this.isValidGrid ? fullRow.hierarchicalOwner ?? GRID_PARENT : null; const level = worksheetData.isGroupedGrid ? worksheetData.maxLevel : fullRow.level; - summaryFunc = this.getSummaryFunction(cellValue.label, key, dimensionMapKey, level, targetCol); + summaryFunc = this.getSummaryFunction(cellValue.label, key, dimensionMapKey, level, targetCol!); if (!summaryFunc) { let summaryValue; @@ -506,7 +506,7 @@ export class WorksheetFile implements IExcelFile { this.dimensionMap.clear(); } - this.currentSummaryOwner = record.summaryKey; + this.currentSummaryOwner = record.summaryKey!; // For grouped grid we need to reset the parent map // so we can change the startCoordinate for each record @@ -514,7 +514,7 @@ export class WorksheetFile implements IExcelFile { this.hierarchicalDimensionMap.delete(GRID_PARENT) } - this.currentHierarchicalOwner = record.hierarchicalOwner; + this.currentHierarchicalOwner = record.hierarchicalOwner!; } } @@ -532,20 +532,20 @@ export class WorksheetFile implements IExcelFile { if (useLastValidEndCoordinate) { this.setEndCoordinates(targetDimensionMap, true); } else { - targetDimensionMap.get(key).endCoordinate = columnName; - this.lastValidRow = targetDimensionMap.get(key).endCoordinate.match(/[a-z]+|[^a-z]+/gi)[1] + targetDimensionMap.get(key)!.endCoordinate = columnName; + this.lastValidRow = targetDimensionMap.get(key)!.endCoordinate.match(/[a-z]+|[^a-z]+/gi)![1] } } if (this.isValidGrid && !useLastValidEndCoordinate && hierarchicalOwner !== GRID_PARENT) { const parentMap = this.hierarchicalDimensionMap.get(GRID_PARENT); - this.setEndCoordinates(parentMap); + this.setEndCoordinates(parentMap!); } } private setEndCoordinates(map: Map, useLastValidEndCoordinate = false) { for (const a of map.values()) { - const colName = a.endCoordinate.match(/[a-z]+|[^a-z]+/gi)[0]; + const colName = a.endCoordinate.match(/[a-z]+|[^a-z]+/gi)![0]; a.endCoordinate = `${colName}${useLastValidEndCoordinate ? this.lastValidRow : this.rowIndex}`; } } @@ -564,7 +564,7 @@ export class WorksheetFile implements IExcelFile { let func = ''; let funcType = ''; let result = ''; - const currencyInfo = this.currencyStyleMap.get(col.currencyCode); + const currencyInfo = this.currencyStyleMap.get(col.currencyCode!); switch(type?.toString().toLowerCase()) { case "count": @@ -612,14 +612,15 @@ export class WorksheetFile implements IExcelFile { // TODO: get date format from locale return `"Latest: "&_xlfn.TEXT(_xlfn.MAX(_xlfn.IF(${levelDimensions.startCoordinate}:${levelDimensions.endCoordinate}=${recordLevel}, ${dimensions.startCoordinate}:${dimensions.endCoordinate})), "m/d/yyyy")` } + return undefined!; } private setRootSummaryStartCoordinate(column: number, key: string) { const firstDataRecordColName = ExcelStrings.getExcelColumn(column) + (this.firstDataRow); const targetMap = this.hierarchicalDimensionMap.get(GRID_PARENT); - if (targetMap.get(key).startCoordinate !== firstDataRecordColName) { - targetMap.get(key).startCoordinate = firstDataRecordColName; + if (targetMap!.get(key)!.startCoordinate !== firstDataRecordColName) { + targetMap!.get(key)!.startCoordinate = firstDataRecordColName; } } @@ -645,7 +646,7 @@ export class WorksheetFile implements IExcelFile { : startValue + (owner.maxRowLevel ?? 0) let rowCoordinate = isVertical - ? startValue + owner.maxLevel + 2 + ? startValue + owner.maxLevel! + 2 : this.rowIndex if (currentCol.headerType === ExportHeaderType.PivotRowHeader) { rowCoordinate = startValue + 1; @@ -659,7 +660,7 @@ export class WorksheetFile implements IExcelFile { ? ExcelStrings.getExcelColumn(worksheetData.columnCount + 1) : ExcelStrings.getExcelColumn(column)) + rowCoordinate; - rowStyle = isVertical && currentCol.rowSpan > 1 ? ' s="4"' : rowStyle; + rowStyle = isVertical && currentCol.rowSpan! > 1 ? ' s="4"' : rowStyle; str = `${columnValue}`; if (isVertical) { @@ -683,11 +684,11 @@ export class WorksheetFile implements IExcelFile { const row = isVertical ? rowCoordinate - : owner.maxLevel + 1; + : owner.maxLevel! + 1; - columnCoordinate = ExcelStrings.getExcelColumn(col) + row; + columnCoordinate = ExcelStrings.getExcelColumn(col!) + row; } else { - for (let k = 1; k < spanLength; k++) { + for (let k = 1; k < spanLength!; k++) { const col = isVertical ? column : column + k; @@ -706,14 +707,14 @@ export class WorksheetFile implements IExcelFile { } if ((currentCol.headerType === ExportHeaderType.RowHeader || currentCol.headerType === ExportHeaderType.MultiRowHeader) && currentCol.columnSpan && currentCol.columnSpan > 1 ) { - columnCoordinate = ExcelStrings.getExcelColumn(column + currentCol.columnSpan - 1) + (rowCoordinate + spanLength - 1); + columnCoordinate = ExcelStrings.getExcelColumn(column + currentCol.columnSpan - 1) + (rowCoordinate + spanLength! - 1); } this.mergeCellStr += `${columnCoordinate}" />`; } } if (currentCol.headerType !== ExportHeaderType.PivotRowHeader) { - startValue += spanLength; + startValue += spanLength!; } } } @@ -724,7 +725,7 @@ export class WorksheetFile implements IExcelFile { */ export class StyleFile implements IExcelFile { public writeElement(folder: Object) { - folder['styles.xml'] = strToU8(ExcelStrings.getStyles()); + (folder as any)['styles.xml'] = strToU8(ExcelStrings.getStyles()); } } @@ -733,7 +734,7 @@ export class StyleFile implements IExcelFile { */ export class WorkbookFile implements IExcelFile { public writeElement(folder: Object, worksheetData: WorksheetData) { - folder['workbook.xml'] = strToU8(ExcelStrings.getWorkbook(worksheetData.options.worksheetName)); + (folder as any)['workbook.xml'] = strToU8(ExcelStrings.getWorkbook(worksheetData.options.worksheetName)); } } @@ -743,7 +744,7 @@ export class WorkbookFile implements IExcelFile { export class ContentTypesFile implements IExcelFile { public writeElement(folder: Object, worksheetData: WorksheetData) { const hasSharedStrings = !worksheetData.isEmpty || worksheetData.options.alwaysExportHeaders; - folder['[Content_Types].xml'] = strToU8(ExcelStrings.getContentTypesXML(hasSharedStrings, worksheetData.options.exportAsTable)); + (folder as any)['[Content_Types].xml'] = strToU8(ExcelStrings.getContentTypesXML(hasSharedStrings, worksheetData.options.exportAsTable)); } } @@ -760,7 +761,7 @@ export class SharedStringsFile implements IExcelFile { sharedStrings[dict.getSanitizedValue(value)] = '' + value + ''; } - folder['sharedStrings.xml'] = strToU8(ExcelStrings.getSharedStringXML( + (folder as any)['sharedStrings.xml'] = strToU8(ExcelStrings.getSharedStringXML( dict.stringsCount, sortedValues.length, sharedStrings.join('')) @@ -784,8 +785,8 @@ export class TablesFile implements IExcelFile { ? worksheetData.rootKeys : worksheetData.owner.columns .filter(c => !c.skip) - .sort((a, b) => a.startIndex - b.startIndex) - .sort((a, b) => a.pinnedIndex - b.pinnedIndex) + .sort((a, b) => a.startIndex! - b.startIndex!) + .sort((a, b) => a.pinnedIndex! - b.pinnedIndex!) .map(c => c.header); let sortString = ''; @@ -805,7 +806,7 @@ export class TablesFile implements IExcelFile { sortString = ``; } - folder['table1.xml'] = strToU8(ExcelStrings.getTablesXML(autoFilterDimension, tableDimension, tableColumns, sortString)); + (folder as any)['table1.xml'] = strToU8(ExcelStrings.getTablesXML(autoFilterDimension, tableDimension, tableColumns, sortString)); } } @@ -814,6 +815,6 @@ export class TablesFile implements IExcelFile { */ export class WorksheetRelsFile implements IExcelFile { public writeElement(folder: Object) { - folder['sheet1.xml.rels'] = strToU8(ExcelStrings.getWorksheetRels()); + (folder as any)['sheet1.xml.rels'] = strToU8(ExcelStrings.getWorksheetRels()); } } diff --git a/projects/igniteui-angular/grids/core/src/services/excel/excel-strings.ts b/projects/igniteui-angular/grids/core/src/services/excel/excel-strings.ts index fc9ba3b4d17..ae92f76862d 100644 --- a/projects/igniteui-angular/grids/core/src/services/excel/excel-strings.ts +++ b/projects/igniteui-angular/grids/core/src/services/excel/excel-strings.ts @@ -32,7 +32,7 @@ export class ExcelStrings { return ExcelStrings.XML_STRING + ``; } - public static getWorkbookRels(hasSharedStrings): string { + public static getWorkbookRels(hasSharedStrings: boolean): string { let retVal = ExcelStrings.XML_STRING + ``; if (hasSharedStrings) { diff --git a/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data-dictionary.ts b/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data-dictionary.ts index 9a6a86fed39..9c494d1c678 100644 --- a/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data-dictionary.ts +++ b/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data-dictionary.ts @@ -13,8 +13,8 @@ export class WorksheetDataDictionary { private _dictionary: any; private _widthsDictionary: any; - private _keys: string[]; - private _keysAreValid: boolean; + private _keys!: string[]; + private _keysAreValid!: boolean; private _counter: number; private _columnWidths: number[]; diff --git a/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data.ts b/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data.ts index ecd4aec9817..576fe4bfd77 100644 --- a/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data.ts +++ b/projects/igniteui-angular/grids/core/src/services/excel/worksheet-data.ts @@ -5,15 +5,15 @@ import { WorksheetDataDictionary } from './worksheet-data-dictionary'; /** @hidden */ export class WorksheetData { - private _rowCount: number; - private _dataDictionary: WorksheetDataDictionary; - private _isSpecialData: boolean; - private _hasMultiColumnHeader: boolean; - private _hasMultiRowHeader: boolean; - private _isHierarchical: boolean; - private _hasSummaries: boolean; - private _isPivotGrid: boolean; - private _isTreeGrid: boolean; + private _rowCount!: number; + private _dataDictionary!: WorksheetDataDictionary; + private _isSpecialData!: boolean; + private _hasMultiColumnHeader!: boolean; + private _hasMultiRowHeader!: boolean; + private _isHierarchical!: boolean; + private _hasSummaries!: boolean; + private _isPivotGrid!: boolean; + private _isTreeGrid!: boolean; constructor(private _data: IExportRecord[], public options: IgxExcelExporterOptions, @@ -37,7 +37,7 @@ export class WorksheetData { public get isEmpty(): boolean { return !this.rowCount - || this.rowCount === this.owner.maxLevel + 1 + || this.rowCount === this.owner.maxLevel! + 1 || !this.columnCount || this.owner.columns.every(c => c.skip); } @@ -83,7 +83,7 @@ export class WorksheetData { } public get multiColumnHeaderRows(): number { - return !this.options.ignoreMultiColumnHeaders ? Array.from(this.owners.values()).map(c => c.maxLevel).reduce((a,b) => a + b) : 0; + return !this.options.ignoreMultiColumnHeaders ? Array.from(this.owners.values()).map(c => c.maxLevel!).reduce((a,b) => a + b) : 0; } private initializeData() { @@ -112,7 +112,7 @@ export class WorksheetData { if (!this._data || this._data.length === 0) { if (!this._isHierarchical) { - this._rowCount = this.owner.maxLevel + 1; + this._rowCount = this.owner.maxLevel! + 1; } return; diff --git a/projects/igniteui-angular/grids/core/src/services/exporter-common/base-export-service.ts b/projects/igniteui-angular/grids/core/src/services/exporter-common/base-export-service.ts index abdf440e6f3..3a7a0e270e6 100644 --- a/projects/igniteui-angular/grids/core/src/services/exporter-common/base-export-service.ts +++ b/projects/igniteui-angular/grids/core/src/services/exporter-common/base-export-service.ts @@ -2,7 +2,8 @@ import { EventEmitter } from '@angular/core'; import { ExportUtilities } from './export-utilities'; import { IgxExporterOptionsBase } from './exporter-options-base'; import { yieldingLoop } from './yielding-loop'; -import { type ITreeGridRecord, type ColumnType, type GridTypeBase, type IPathSegment, type IgxSummaryResult, type GridColumnDataType, DataUtil, FilterUtil, GridSummaryCalculationMode, IBaseEventArgs, IFilteringState, IGroupByExpandState, IGroupByRecord, IGroupingState, TreeGridFilteringStrategy, cloneArray, cloneValue, columnFieldPath, resolveNestedPath, getHierarchy, isHierarchyMatch, BaseFormatter } from 'igniteui-angular/core'; +import { type ITreeGridRecord, type ColumnType, type GridTypeBase, type IPathSegment, type IgxSummaryResult, type GridColumnDataType, DataUtil, FilterUtil, GridSummaryCalculationMode, IBaseEventArgs, IFilteringState, IGroupByExpandState, IGroupByRecord, IGroupingState, TreeGridFilteringStrategy, cloneArray, cloneValue, columnFieldPath, resolveNestedPath, getHierarchy, isHierarchyMatch, BaseFormatter, ISortingExpression } from 'igniteui-angular/core'; +import { type GridType, type PivotGridType } from '../../common/grid.interface'; export enum ExportRecordType { GroupedRecord = 'GroupedRecord', @@ -145,7 +146,7 @@ class IgxColumnExportingEventArgs implements IColumnExportingEventArgs { private _columnIndex?: number; public get columnIndex(): number { - return this._columnIndex; + return this._columnIndex!; } public set columnIndex(value: number) { @@ -199,21 +200,21 @@ export abstract class IgxBaseExporter { */ public columnExporting = new EventEmitter(); - protected _sort = null; - protected pivotGridFilterFieldsCount: number; + protected _sort: ISortingExpression | null = null; + protected pivotGridFilterFieldsCount!: number; protected _ownersMap: Map = new Map(); - private locale: string + private locale!: string private _setChildSummaries = false - private isPivotGridExport: boolean; - private options: IgxExporterOptionsBase; + private isPivotGridExport!: boolean; + private options!: IgxExporterOptionsBase; private summaries: Map> = new Map>(); private rowIslandCounter = -1; private flatRecords: IExportRecord[] = []; private pivotGridColumns: IColumnInfo[] = [] - private pivotGridRowDimensionsMap: Map; + private pivotGridRowDimensionsMap!: Map; private ownerGrid: any; - private i18nFormatter: BaseFormatter; + private i18nFormatter!: BaseFormatter; /* alternateName: exportGrid */ /** @@ -233,7 +234,7 @@ export abstract class IgxBaseExporter { this.locale = grid.locale; this.ownerGrid = grid; this.i18nFormatter = grid.i18nFormatter; - let columns = grid.columns; + let columns = grid.columns as ColumnType[]; if (this.options.ignoreMultiColumnHeaders) { columns = columns.filter(col => col.children === undefined); @@ -255,7 +256,7 @@ export abstract class IgxBaseExporter { this.isPivotGridExport = true; this.pivotGridRowDimensionsMap = new Map(); - grid.visibleRowDimensions.filter(r => r.enabled).forEach(rowDimension => { + (grid as PivotGridType).visibleRowDimensions.filter(r => r.enabled).forEach((rowDimension) => { this.addToRowDimensionsMap(rowDimension, rowDimension.memberName); }); @@ -270,8 +271,10 @@ export abstract class IgxBaseExporter { this.addLevelColumns(); this.prepareData(grid); this.addLevelData(); - this.addPivotGridColumns(grid); - this.addPivotRowHeaders(grid); + if (grid.type === 'pivot') { + this.addPivotGridColumns(grid as PivotGridType); + this.addPivotRowHeaders(grid as PivotGridType); + } this.exportGridRecordsData(this.flatRecords, grid); } @@ -304,7 +307,7 @@ export abstract class IgxBaseExporter { } private addToRowDimensionsMap(rowDimension: any, rootParentName: string) { - this.pivotGridRowDimensionsMap[rowDimension.memberName] = rootParentName; + (this.pivotGridRowDimensionsMap as any)[rowDimension.memberName] = rootParentName; if (rowDimension.childLevel) { this.addToRowDimensionsMap(rowDimension.childLevel, rootParentName) } @@ -364,12 +367,12 @@ export abstract class IgxBaseExporter { skippedPinnedColumnsCount++; } - this.calculateColumnSpans(column, mapRecord, column.columnSpan); + this.calculateColumnSpans(column, mapRecord, column.columnSpan!); const nonSkippedColumns = mapRecord.columns.filter(c => !c.skip); if (nonSkippedColumns.length > 0) { - this._ownersMap.get(key).maxLevel = nonSkippedColumns.sort((a, b) => b.level - a.level)[0].level; + this._ownersMap.get(key)!.maxLevel = nonSkippedColumns.sort((a, b) => b.level! - a.level!)[0].level; } } @@ -412,7 +415,7 @@ export abstract class IgxBaseExporter { columnGroupChildren.forEach(cgc => { if (cgc.headerType === ExportHeaderType.MultiColumnHeader) { cgc.columnSpan = 0; - cgc.columnGroupParent = null; + cgc.columnGroupParent = null!; cgc.skip = true; this.calculateColumnSpans(cgc, mapRecord, cgc.columnSpan); @@ -424,7 +427,7 @@ export abstract class IgxBaseExporter { const targetCol = mapRecord.columns.filter(c => column.columnGroupParent !== null && column.columnGroupParent !== undefined && c.columnGroup === column.columnGroupParent)[0]; if (targetCol !== undefined) { - targetCol.columnSpan -= span; + targetCol.columnSpan = targetCol.columnSpan! - span; if (targetCol.columnGroupParent !== null) { this.calculateColumnSpans(targetCol, mapRecord, span); @@ -439,14 +442,14 @@ export abstract class IgxBaseExporter { private exportRow(data: IExportRecord[], record: IExportRecord, index: number, isSpecialData: boolean) { if (!isSpecialData) { const owner = record.owner === undefined ? DEFAULT_OWNER : record.owner; - const ownerCols = this._ownersMap.get(owner).columns; + const ownerCols = this._ownersMap.get(owner)!.columns; const hasRowHeaders = ownerCols.some(c => c.headerType === ExportHeaderType.RowHeader); if (record.type !== ExportRecordType.HeaderRecord) { const columns = ownerCols .filter(c => c.headerType === ExportHeaderType.ColumnHeader && !c.skip) - .sort((a, b) => a.startIndex - b.startIndex) - .sort((a, b) => a.pinnedIndex - b.pinnedIndex); + .sort((a, b) => a.startIndex! - b.startIndex!) + .sort((a, b) => a.pinnedIndex! - b.pinnedIndex!); if (hasRowHeaders) { record.rawData = record.data; @@ -480,9 +483,9 @@ export abstract class IgxBaseExporter { a[e.field] = formattedValue; } return a; - }, {}); + }, {} as any); } else { - record.data = record.data.filter((_, i) => !record.references[i].skip) + record.data = record.data.filter((_: any, i: any) => !record.references![i].skip) } } @@ -503,9 +506,9 @@ export abstract class IgxBaseExporter { private reorderColumns(columns: IColumnInfo[]): IColumnInfo[] { const filteredColumns = columns.filter(c => !c.skip); const length = filteredColumns.length; - const specificIndicesColumns = filteredColumns.filter((col) => !isNaN(col.exportIndex)) - .sort((a, b) => a.exportIndex - b.exportIndex); - const indices = specificIndicesColumns.map(col => col.exportIndex); + const specificIndicesColumns = filteredColumns.filter((col) => !isNaN(col.exportIndex!)) + .sort((a, b) => a.exportIndex! - b.exportIndex!); + const indices = specificIndicesColumns.map(col => col.exportIndex!); specificIndicesColumns.forEach(col => { filteredColumns.splice(filteredColumns.indexOf(col), 1); @@ -576,8 +579,8 @@ export abstract class IgxBaseExporter { private preparePivotGridData(grid: GridTypeBase) { for (const record of grid.filteredSortedData) { const recordData = Object.fromEntries(record.aggregationValues); - record.dimensionValues.forEach((value, key) => { - const actualKey = this.pivotGridRowDimensionsMap[key]; + record.dimensionValues.forEach((value: any, key: any) => { + const actualKey = (this.pivotGridRowDimensionsMap as any)[key]; recordData[actualKey] = value; }); @@ -614,22 +617,22 @@ export abstract class IgxBaseExporter { strategy: grid.filterStrategy }; - data = FilterUtil.filter(data, filteringState, grid); + data = FilterUtil.filter(data!, filteringState, grid); } if (hasSorting && !this.options.ignoreSorting) { - this._sort = cloneValue(grid.sortingExpressions[0]); + this._sort = cloneValue((grid as GridType).sortingExpressions[0]); - data = DataUtil.sort(data, grid.sortingExpressions, grid.sortStrategy, grid); + data = DataUtil.sort(data!, grid.sortingExpressions, grid.sortStrategy, grid); } - this.addHierarchicalGridData(grid, data); + this.addHierarchicalGridData(grid, data!); } } private addHierarchicalGridData(grid: GridTypeBase, records: any[]) { - const childLayoutList = grid.childLayoutList; - const columnFields = this._ownersMap.get(grid).columns.map(col => col.field); + const childLayoutList = (grid as GridType).childLayoutList; + const columnFields = this._ownersMap.get(grid)!.columns.map(col => col.field); for (const entry of records) { const rowKey = grid.primaryKey ? entry[grid.primaryKey] : entry; @@ -640,7 +643,7 @@ export abstract class IgxBaseExporter { .reduce((obj, key) => { obj[key] = entry[key]; return obj; - }, {}); + }, {} as any); const hierarchicalGridRecord: IExportRecord = { data: dataWithoutChildren, @@ -652,7 +655,7 @@ export abstract class IgxBaseExporter { this.flatRecords.push(hierarchicalGridRecord); - for (const island of childLayoutList) { + for (const island of childLayoutList ?? []) { const path: IPathSegment = { rowID: grid.primaryKey ? entry[grid.primaryKey] : entry, rowKey: grid.primaryKey ? entry[grid.primaryKey] : entry, @@ -692,7 +695,7 @@ export abstract class IgxBaseExporter { return summaries; } - private prepareIslandData(island: any, islandGrid: GridTypeBase, data: any[]): any[] { + private prepareIslandData(island: GridType, islandGrid: GridTypeBase, data: any[]): any[] { if (islandGrid !== undefined) { const hasFiltering = (islandGrid.filteringExpressionsTree && islandGrid.filteringExpressionsTree.filteringOperands.length > 0) || @@ -720,7 +723,7 @@ export abstract class IgxBaseExporter { } if (hasSorting && !this.options.ignoreSorting) { - this._sort = cloneValue(islandGrid.sortingExpressions[0]); + this._sort = cloneValue((islandGrid as GridType).sortingExpressions[0]); data = DataUtil.sort(data, islandGrid.sortingExpressions, islandGrid.sortStrategy, islandGrid); } @@ -760,10 +763,10 @@ export abstract class IgxBaseExporter { return data; } - private getAllChildColumnsAndData(island: any, + private getAllChildColumnsAndData(island: GridType, childData: any[], expansionStateVal: boolean, grid: GridTypeBase) { const hierarchicalOwner = `${GRID_CHILD}${++this.rowIslandCounter}`; - const columnList = this._ownersMap.get(island).columns; + const columnList = this._ownersMap.get(island)!.columns; const columnHeaders = columnList.filter(col => col.headerType === ExportHeaderType.ColumnHeader); const columnHeader = columnHeaders.map(col => col.header ? col.header : col.field); @@ -860,7 +863,7 @@ export abstract class IgxBaseExporter { strategy: grid.filterStrategy }; - gridData = FilterUtil.filter(gridData, filteringState, grid); + gridData = FilterUtil.filter(gridData!, filteringState, grid); } if (hasSorting && !this.options.ignoreSorting) { @@ -871,17 +874,17 @@ export abstract class IgxBaseExporter { // cloneValue(grid.sortingExpressions[1]) : // cloneValue(grid.sortingExpressions[0]); const expressions = grid.groupingExpressions ? grid.groupingExpressions.concat(grid.sortingExpressions || []) : grid.sortingExpressions; - gridData = DataUtil.sort(gridData, expressions, grid.sortStrategy, grid); + gridData = DataUtil.sort(gridData!, expressions, grid.sortStrategy, grid); } if (hasGrouping && !this.options.ignoreGrouping) { - const groupsRecords = []; - DataUtil.group(cloneArray(gridData), groupedGridGroupingState, grid.groupStrategy, grid, groupsRecords); + const groupsRecords: any[] = []; + DataUtil.group(cloneArray(gridData!), groupedGridGroupingState, grid.groupStrategy, grid, groupsRecords); gridData = groupsRecords; } if (hasGrouping && !this.options.ignoreGrouping) { - this.addGroupedData(grid, gridData, groupedGridGroupingState, true); + this.addGroupedData(grid, gridData!, groupedGridGroupingState, true); } else { this.addFlatData(gridData); } @@ -905,12 +908,12 @@ export abstract class IgxBaseExporter { strategy: (grid.filterStrategy) ? grid.filterStrategy : new TreeGridFilteringStrategy() }; - gridData = filteringState.strategy + gridData = filteringState.strategy! .filter(gridData, filteringState.expressionsTree, filteringState.advancedExpressionsTree); } if (hasSorting && !this.options.ignoreSorting) { - this._sort = cloneValue(grid.sortingExpressions[0]); + this._sort = cloneValue((grid as GridType).sortingExpressions[0]); gridData = DataUtil.treeGridSort(gridData, grid.sortingExpressions, grid.sortStrategy); } @@ -927,7 +930,7 @@ export abstract class IgxBaseExporter { for (const record of records) { const treeGridRecord: IExportRecord = { data: record.data, - level: record.level, + level: record.level!, hidden: !parentExpanded, type: ExportRecordType.TreeGridRecord, summaryKey: record.key, @@ -937,7 +940,7 @@ export abstract class IgxBaseExporter { this.flatRecords.push(treeGridRecord); if (record.children) { - this.getTreeGridChildData(record.children, record.key, record.level, record.expanded && parentExpanded) + this.getTreeGridChildData(record.children, record.key, record.level!, record.expanded && parentExpanded) } } } @@ -950,12 +953,12 @@ export abstract class IgxBaseExporter { for (const rc of recordChildren) { if (rc.children && rc.children.length > 0) { this.addTreeGridData([rc], parentExpanded, hierarchicalOwner); - summaryLevel = rc.level; + summaryLevel = rc.level!; } else { const currentRecord: IExportRecord = { data: rc.data, - level: rc.level, + level: rc.level!, hidden: !parentExpanded, type: ExportRecordType.DataRecord, hierarchicalOwner @@ -966,13 +969,13 @@ export abstract class IgxBaseExporter { } this.flatRecords.push(currentRecord); - summaryLevel = rc.level; + summaryLevel = rc.level!; summaryHidden = !parentExpanded } } if (this._setChildSummaries) { - this.setSummaries(key, summaryLevel, summaryHidden, null, null, hierarchicalOwner); + this.setSummaries(key, summaryLevel, summaryHidden, null, null!, hierarchicalOwner); } } @@ -999,7 +1002,7 @@ export abstract class IgxBaseExporter { const biggest = values.sort((a, b) => b.length - a.length)[0]; for (let i = 0; i < biggest.length; i++) { - const obj = {} + const obj: any = {} for (const [key, value] of rootSummary) { const summaries = value.map(s => ({ label: s.label, value: s.summaryResult })) @@ -1030,10 +1033,10 @@ export abstract class IgxBaseExporter { } let previousKey = '' - const firstCol = this._ownersMap.get(DEFAULT_OWNER).columns + const firstCol = this._ownersMap.get(DEFAULT_OWNER)!.columns .filter(c => c.headerType === ExportHeaderType.ColumnHeader && !c.skip) - .sort((a, b) => a.startIndex - b.startIndex) - .sort((a, b) => a.pinnedIndex - b.pinnedIndex)[0].field; + .sort((a, b) => a.startIndex! - b.startIndex!) + .sort((a, b) => a.pinnedIndex! - b.pinnedIndex!)[0].field; for (const record of records) { let recordVal = record.value; @@ -1042,7 +1045,7 @@ export abstract class IgxBaseExporter { const expandState: IGroupByExpandState = groupingState.expansion.find((s) => isHierarchyMatch(s.hierarchy || [{ fieldName: record.expression.fieldName, value: recordVal }], hierarchy, - grid.groupingExpressions)); + grid.groupingExpressions))!; const expanded = expandState ? expandState.expanded : groupingState.defaultExpanded; const isDate = recordVal instanceof Date; @@ -1081,8 +1084,8 @@ export abstract class IgxBaseExporter { groupExpression.summaryKey = summaryKey; } - if (record.groups.length > 0) { - this.addGroupedData(grid, record.groups, groupingState, false, expanded && parentExpanded, summaryKeysArr); + if (record.groups!.length > 0) { + this.addGroupedData(grid, record.groups!, groupingState, false, expanded && parentExpanded, summaryKeysArr); } else { const rowRecords = record.records; @@ -1104,22 +1107,22 @@ export abstract class IgxBaseExporter { } if (this._setChildSummaries) { - this.setSummaries(summaryKey, record.level + 1, !(expanded && parentExpanded), null, null, hierarchicalOwner); + this.setSummaries(summaryKey, record.level + 1, !(expanded && parentExpanded), null, null!, hierarchicalOwner); summaryKeysArr.pop(); } } } private getColumns(columns: ColumnType[]): IColumnList { - const colList = []; - const colWidthList = []; - const hiddenColumns = []; + const colList: IColumnInfo[] = []; + const colWidthList: number[] = []; + const hiddenColumns: IColumnInfo[] = []; let indexOfLastPinnedColumn = -1; let lastVisibleColumnIndex = -1; let maxLevel = 0; columns.forEach((column) => { - const columnHeader = !ExportUtilities.isNullOrWhitespaces(column.header) ? column.header : column.field; + const columnHeader = !ExportUtilities.isNullOrWhitespaces(column.header!) ? column.header : column.field; const exportColumn = !column.hidden || this.options.ignoreColumnsVisibility; const index = this.options.ignoreColumnsOrder || this.options.ignoreColumnsVisibility ? column.index : column.visibleIndex; const columnWidth = Number(column.width?.slice(0, -2)) || DEFAULT_COLUMN_WIDTH; @@ -1149,8 +1152,8 @@ export abstract class IgxBaseExporter { !column.hidden ? column.grid.pinnedColumns.indexOf(column) : NaN, - columnGroupParent: column.parent ? column.parent : null, - columnGroup: isMultiColHeader ? column : null + columnGroupParent: column.parent ? column.parent : null!, + columnGroup: isMultiColHeader ? column : null! }; if (column.dataType === 'currency') { @@ -1210,11 +1213,11 @@ export abstract class IgxBaseExporter { if (island.autoGenerate) { keyData = gridData && gridData[island.key] ? gridData[island.key] : undefined; - const islandKeys = island.children && island.children.length > 0 ? island.children.map(i => i.key) : []; + const islandKeys = island.children && island.children.length > 0 ? island.children.map((i: any) => i.key) : []; if (keyData && Array.isArray(keyData) && keyData.length > 0) { const islandData = keyData.map(i => { - const newItem = {}; + const newItem: any = {}; Object.keys(i).map(k => { if (!islandKeys.includes(k)) { @@ -1246,8 +1249,8 @@ export abstract class IgxBaseExporter { } private getAutoGeneratedColumns(data: any[]) { - const colList = []; - const colWidthList = []; + const colList: IColumnInfo[] = []; + const colWidthList: number[] = []; const keys = Object.keys(data[0]); keys.forEach((colKey, i) => { @@ -1277,14 +1280,14 @@ export abstract class IgxBaseExporter { return result; } - private addPivotRowHeaders(grid: any) { + private addPivotRowHeaders(grid: PivotGridType) { if (grid?.pivotUI?.showRowHeaders) { - const headersList = this._ownersMap.get(DEFAULT_OWNER); - const enabledRows = grid.visibleRowDimensions.filter(r => r.enabled).map((r, index) => ({ name: r.displayName || r.memberName, level: index })); + const headersList = this._ownersMap.get(DEFAULT_OWNER)!; + const enabledRows = grid.visibleRowDimensions.filter((r) => r.enabled).map((r, index) => ({ name: r.displayName || r.memberName, level: index })); let startIndex = 0; - enabledRows.forEach(x => { + enabledRows.forEach((x) => { headersList.columns.unshift({ - rowSpan: headersList.maxLevel + 1, + rowSpan: headersList.maxLevel! + 1, field: x.name, header: x.name, startIndex: startIndex, @@ -1300,17 +1303,13 @@ export abstract class IgxBaseExporter { } } - private addPivotGridColumns(grid: any) { - if (grid.type !== 'pivot') { - return; - } - + private addPivotGridColumns(grid: PivotGridType) { const enabledRows = grid.visibleRowDimensions.map((r, i) => ({ name: r.memberName, level: i })); this.preparePivotGridColumns(enabledRows); this.pivotGridFilterFieldsCount = enabledRows.length; - const columnList = this._ownersMap.get(DEFAULT_OWNER); + const columnList = this._ownersMap.get(DEFAULT_OWNER)!; columnList.columns.unshift(...this.pivotGridColumns); columnList.columnWidths.unshift(...Array(this.pivotGridColumns.length).fill(200)); columnList.indexOfLastPinnedColumn = enabledRows.length - 1; diff --git a/projects/igniteui-angular/grids/core/src/services/exporter-common/export-utilities.ts b/projects/igniteui-angular/grids/core/src/services/exporter-common/export-utilities.ts index 7aebffbed55..551ce9ecbea 100644 --- a/projects/igniteui-angular/grids/core/src/services/exporter-common/export-utilities.ts +++ b/projects/igniteui-angular/grids/core/src/services/exporter-common/export-utilities.ts @@ -21,7 +21,7 @@ export class ExportUtilities { return !ExportUtilities.isSpecialData(dataEntry) ? Array.from(keys) : ['Column 1']; } - public static saveBlobToFile(blob: Blob, fileName) { + public static saveBlobToFile(blob: Blob, fileName: string) { const doc = globalThis.document; const a = doc.createElement('a'); const url = window.URL.createObjectURL(blob); diff --git a/projects/igniteui-angular/grids/core/src/services/exporter-common/exporter-options-base.ts b/projects/igniteui-angular/grids/core/src/services/exporter-common/exporter-options-base.ts index a7a6de40a0e..67a0f19db6b 100644 --- a/projects/igniteui-angular/grids/core/src/services/exporter-common/exporter-options-base.ts +++ b/projects/igniteui-angular/grids/core/src/services/exporter-common/exporter-options-base.ts @@ -100,7 +100,7 @@ export abstract class IgxExporterOptionsBase { */ public alwaysExportHeaders = true; - private _fileName: string; + private _fileName!: string; constructor(fileName: string, protected _fileExtension: string) { this.setFileName(fileName); diff --git a/projects/igniteui-angular/grids/core/src/services/pdf/pdf-exporter.ts b/projects/igniteui-angular/grids/core/src/services/pdf/pdf-exporter.ts index 4cb73f6931a..e5908fd6c13 100644 --- a/projects/igniteui-angular/grids/core/src/services/pdf/pdf-exporter.ts +++ b/projects/igniteui-angular/grids/core/src/services/pdf/pdf-exporter.ts @@ -749,7 +749,7 @@ export class IgxPdfExporterService extends IgxBaseExporter { } // Draw child table headers - const hasMultiColumnHeaders = maxLevel > 0 && childOwnerObj.columns.some(col => col.headerType === ExportHeaderType.MultiColumnHeader); + const hasMultiColumnHeaders = maxLevel > 0 && childOwnerObj!.columns.some(col => col.headerType === ExportHeaderType.MultiColumnHeader); if (hasMultiColumnHeaders) { yPosition = this.drawMultiLevelHeaders( diff --git a/projects/igniteui-angular/grids/core/src/setImmediate.ts b/projects/igniteui-angular/grids/core/src/setImmediate.ts index ca3edd360ca..9421e1f3e93 100644 --- a/projects/igniteui-angular/grids/core/src/setImmediate.ts +++ b/projects/igniteui-angular/grids/core/src/setImmediate.ts @@ -21,7 +21,7 @@ // Note: Originally copied from core-js-pure package and modified. (https://github.com/zloirock/core-js) -const queue = {}; +const queue: Record void> = {}; let counter = 0; let eventListenerAdded = false; @@ -32,7 +32,7 @@ declare global { } } -const run = (id) => { +const run = (id: any) => { if (queue.hasOwnProperty(id)) { const fn = queue[id]; delete queue[id]; @@ -40,10 +40,10 @@ const run = (id) => { } }; -const listener = (event) => run(event.data); +const listener = (event: MessageEvent) => run(event.data); // Use function instead of arrow function to workaround an issue in codesandbox -export function setImmediate(cb: () => void, ...args) { +export function setImmediate(cb: () => void, ...args: any[]) { if (window.setImmediate) { return window.setImmediate(cb); } @@ -54,7 +54,7 @@ export function setImmediate(cb: () => void, ...args) { } queue[++counter] = () => { - cb.apply(undefined, args); + cb.apply(undefined, args as []); }; const windowLocation = window.location; diff --git a/projects/igniteui-angular/grids/core/src/state-base.directive.ts b/projects/igniteui-angular/grids/core/src/state-base.directive.ts index 2d9aae8a97e..38519169b44 100644 --- a/projects/igniteui-angular/grids/core/src/state-base.directive.ts +++ b/projects/igniteui-angular/grids/core/src/state-base.directive.ts @@ -1,9 +1,8 @@ import { Directive, Input, ViewContainerRef, createComponent, EnvironmentInjector, Injector, inject } from '@angular/core'; import { IgxColumnComponent } from './columns/column.component'; import { IgxColumnGroupComponent } from './columns/column-group.component'; -import { GridSelectionRange } from './common/types'; import { GridType, IGX_GRID_BASE, IPinningConfig, PivotGridType } from './common/grid.interface'; -import { cloneArray, cloneValue, ColumnType, FieldType, GridColumnDataType, IExpressionTree, IFilteringExpressionsTree, IGroupByExpandState, IGroupingExpression, IGroupingState, IPagingState, ISortingExpression, recreateTreeFromFields } from 'igniteui-angular/core'; +import { cloneArray, cloneValue, ColumnType, FieldType, GridColumnDataType, GridSelectionRange, IExpressionTree, IFilteringExpressionsTree, IGroupByExpandState, IGroupingExpression, IGroupingState, IPagingState, ISortingExpression, recreateTreeFromFields } from 'igniteui-angular/core'; import { IgxColumnLayoutComponent } from './columns/column-layout.component'; import { IPivotConfiguration, IPivotDimension } from './pivot-grid.interface'; import { PivotUtil } from './pivot-util'; @@ -118,8 +117,7 @@ export class IgxGridStateBaseDirective { private featureKeys: GridFeatures[] = []; - private state: IGridState; - private currGrid: GridType; + private currGrid!: GridType; protected _options: IGridStateOptions = { columns: true, filtering: true, @@ -193,12 +191,12 @@ export class IgxGridStateBaseDirective { hasSummary: c.hasSummary, field: c.field, width: ((c as IgxColumnComponent).widthSetByUser || context.currGrid.columnWidthSetByUser) ? c.width : undefined, - header: c.header, + header: c.header!, resizable: c.resizable, searchable: c.searchable, selectable: c.selectable, key: c.columnGroup ? this.getColumnGroupKey(c) : c.field, - parentKey: c.parent ? this.getColumnGroupKey(c.parent) : undefined, + parentKey: c.parent ? this.getColumnGroupKey(c.parent) : undefined!, columnGroup: c.columnGroup, columnLayout: c.columnLayout || undefined, rowStart: c.parent?.columnLayout ? c.rowStart : undefined, @@ -214,7 +212,7 @@ export class IgxGridStateBaseDirective { return { columns: gridColumns }; }, restoreFeatureState: (context: IgxGridStateBaseDirective, state: IColumnState[]): void => { - const newColumns = []; + const newColumns: any[] = []; // Helper to restore column state without auto-persisting widths const restoreColumnState = (column: IgxColumnComponent | IgxColumnGroupComponent, colState: IColumnState) => { @@ -233,7 +231,7 @@ export class IgxGridStateBaseDirective { state.forEach((colState) => { const hasColumnGroup = colState.columnGroup; const hasColumnLayouts = colState.columnLayout; - delete colState.columnGroup; + delete (colState as any).columnGroup; delete colState.columnLayout; if (hasColumnGroup) { let ref1: IgxColumnGroupComponent = context.currGrid.columns.find(x => x.columnGroup && (colState.key ? this.getColumnGroupKey(x) === colState.key : x.header === colState.header)) as IgxColumnGroupComponent; @@ -288,7 +286,7 @@ export class IgxGridStateBaseDirective { groupBy: { getFeatureState: (context: IgxGridStateBaseDirective): IGridState => { const grid = context.currGrid; - const groupingExpressions = grid.groupingExpressions.map(expr => { + const groupingExpressions = grid.groupingExpressions!.map(expr => { const copy = { ...expr }; delete copy.strategy; delete copy.owner; @@ -297,21 +295,21 @@ export class IgxGridStateBaseDirective { const expansionState = grid.groupingExpansionState; const groupsExpanded = grid.groupsExpanded; - return { groupBy: { expressions: groupingExpressions, expansion: expansionState, defaultExpanded: groupsExpanded} }; + return { groupBy: { expressions: groupingExpressions, expansion: expansionState!, defaultExpanded: groupsExpanded!} }; }, restoreFeatureState: (context: IgxGridStateBaseDirective, state: IGroupingState): void => { const grid = context.currGrid; grid.groupingExpressions = state.expressions as IGroupingExpression[]; state.expansion.forEach(exp => { exp.hierarchy.forEach(h => { - const dataType = grid.columns.find(c => c.field === h.fieldName).dataType; + const dataType = grid.columns.find(c => c.field === h.fieldName)!.dataType; if (dataType.includes(GridColumnDataType.Date) || dataType.includes(GridColumnDataType.Time)) { h.value = h.value ? new Date(Date.parse(h.value)) : h.value; } }); }); if (grid.groupsExpanded !== state.defaultExpanded) { - grid.toggleAllGroupRows(); + grid.toggleAllGroupRows!(); } grid.groupingExpansionState = state.expansion as IGroupByExpandState[]; } @@ -404,9 +402,9 @@ export class IgxGridStateBaseDirective { const childGridStates: IGridStateCollection[] = []; const rowIslands = (context.currGrid as any).allLayoutList; if (rowIslands) { - rowIslands.forEach(rowIsland => { + rowIslands.forEach((rowIsland: any) => { const childGrids = rowIsland.rowIslandAPI.getChildGrids(); - childGrids.forEach(chGrid => { + childGrids.forEach((chGrid: any) => { const parentRowID = this.getParentRowID(chGrid); context.currGrid = chGrid; if (context.currGrid) { @@ -416,25 +414,25 @@ export class IgxGridStateBaseDirective { }); }); } - context.currGrid = context.grid; + context.currGrid = context.grid!; return { rowIslands: childGridStates }; }, restoreFeatureState(context: IgxGridStateBaseDirective, state: any): void { const rowIslands = context.currGrid.allLayoutList; if (rowIslands) { - rowIslands.forEach(rowIsland => { + rowIslands.forEach((rowIsland: any) => { const childGrids = rowIsland.rowIslandAPI.getChildGrids(); - childGrids.forEach(chGrid => { + childGrids.forEach((chGrid: any) => { const parentRowID = this.getParentRowID(chGrid); context.currGrid = chGrid; - const childGridState = state.find(st => st.id === rowIsland.id && st.parentRowID === parentRowID); + const childGridState = state.find((st: any) => st.id === rowIsland.id && st.parentRowID === parentRowID); if (childGridState && context.currGrid) { context.restoreGridState(childGridState.state, context.featureKeys); } }); }); } - context.currGrid = context.grid; + context.currGrid = context.grid!; }, /** * Traverses the hierarchy up to the root grid to return the ID of the expanded row. @@ -445,7 +443,7 @@ export class IgxGridStateBaseDirective { childGrid = grid; grid = grid.parent; } - return grid.gridAPI.getParentRowId(childGrid); + return grid.gridAPI.getParentRowId!(childGrid!); } }, pivotConfiguration: { @@ -496,7 +494,7 @@ export class IgxGridStateBaseDirective { public set options(value: IGridStateOptions) { Object.assign(this._options, value); - if (this.grid.type !== 'flat') { + if (this.grid!.type !== 'flat') { delete this._options.groupBy; } else { delete this._options.rowIslands; @@ -520,8 +518,8 @@ export class IgxGridStateBaseDirective { */ protected getStateInternal(serialize = true, features?: GridFeatures | GridFeatures[]): IGridState | string { let state: IGridState | string; - this.currGrid = this.grid; - this.state = state = this.buildState(features) as IGridState; + this.currGrid = this.grid!; + state = this.buildState(features) as IGridState; if (serialize) { state = JSON.stringify(state, this.stringifyCallback) as string; } @@ -543,10 +541,9 @@ export class IgxGridStateBaseDirective { * ``` */ protected setStateInternal(state: IGridState, features?: GridFeatures | GridFeatures[]) { - this.state = state; - this.currGrid = this.grid; + this.currGrid = this.grid!; this.restoreGridState(state, features); - this.grid.cdr.detectChanges(); // TODO + this.grid!.cdr.detectChanges(); // TODO } /** @@ -557,7 +554,7 @@ export class IgxGridStateBaseDirective { let gridState = {} as IGridState; this.featureKeys.forEach(f => { if (this.options[f]) { - if (this.grid.type !== 'flat' && f === 'groupBy') { + if (this.grid!.type !== 'flat' && f === 'groupBy') { return; } const feature = this.getFeature(f); @@ -582,7 +579,7 @@ export class IgxGridStateBaseDirective { const featureState = state[f]; if (f === 'moving' || featureState) { const feature = this.getFeature(f); - feature.restoreFeatureState(this, featureState); + feature.restoreFeatureState(this, featureState as any); } } }); @@ -611,8 +608,8 @@ export class IgxGridStateBaseDirective { private restoreDimensions(config: IPivotConfiguration) { const collections = [config.rows, config.columns, config.filters]; for (const collection of collections) { - for (let index = 0; index < collection?.length; index++) { - const dim = collection[index]; + for (let index = 0; index < (collection?.length ?? 0); index++) { + const dim = collection![index]; if (this.isDateDimension(dim)) { this.restoreDateDimension(dim as IgxPivotDateDimension); } @@ -637,7 +634,7 @@ export class IgxGridStateBaseDirective { let originDim: IPivotDimension = dateDim; while (currDim.childLevel) { currDim = currDim.childLevel; - originDim = originDim.childLevel; + originDim = originDim.childLevel!; currDim.memberFunction = originDim.memberFunction; } } @@ -656,7 +653,7 @@ export class IgxGridStateBaseDirective { private restoreValues(config: IPivotConfiguration, grid: PivotGridType) { // restore aggregator func if it matches the default aggregators key and label const values = config.values; - for (const value of values) { + for (const value of values!) { const aggregateList = value.aggregateList; const aggregators = PivotUtil.getAggregatorsForValue(value, grid); value.aggregate.aggregator = aggregators.find(x => x.key === value.aggregate.key && x.label === value.aggregate.label)?.aggregator; @@ -689,11 +686,11 @@ export class IgxGridStateBaseDirective { */ private createExpressionsTreeFromObject(exprTreeObject: IExpressionTree): IExpressionTree { if (!exprTreeObject || !exprTreeObject.filteringOperands) { - return null; + return null!; } if (this.currGrid.type === 'pivot') { - return recreateTreeFromFields(exprTreeObject, this.currGrid.allDimensions.map(d => ({ dataType: d.dataType, field: d.memberName })) as FieldType[]) as IExpressionTree; + return recreateTreeFromFields(exprTreeObject, this.currGrid.allDimensions.map((d: any) => ({ dataType: d.dataType, field: d.memberName })) as FieldType[]) as IExpressionTree; } return recreateTreeFromFields(exprTreeObject, this.currGrid.columns) as IExpressionTree; @@ -711,7 +708,7 @@ export class IgxGridStateBaseDirective { } private getFeature(key: string): Feature { - const feature: Feature = this.FEATURES[key]; + const feature: Feature = (this.FEATURES as any)[key]; return feature; } } diff --git a/projects/igniteui-angular/grids/core/src/state.directive.spec.ts b/projects/igniteui-angular/grids/core/src/state.directive.spec.ts index fc333a89790..8a413ad5918 100644 --- a/projects/igniteui-angular/grids/core/src/state.directive.spec.ts +++ b/projects/igniteui-angular/grids/core/src/state.directive.spec.ts @@ -12,7 +12,7 @@ import { IGroupByExpandState } from '../../../core/src/data-operations/groupby-e import { GridSelectionMode } from './common/enums'; import { FilteringLogic } from '../../../core/src/data-operations/filtering-expression.interface'; import { DefaultSortingStrategy, ISortingExpression, SortingDirection } from '../../../core/src/data-operations/sorting-strategy'; -import { GridSelectionRange } from './common/types'; +import { GridSelectionRange } from '../../../core/src/data-operations/grid-types'; import { CustomFilter } from '../../../test-utils/grid-samples.spec'; import { IgxPaginatorComponent } from 'igniteui-angular/paginator'; import { IgxColumnComponent, IgxColumnGroupComponent, IgxColumnLayoutComponent, IgxGridDetailTemplateDirective, IgxGridMRLNavigationService } from './public_api'; @@ -931,7 +931,7 @@ describe('IgxGridState - input properties #grid', () => { // Get and save the state with all columns hidden const gridState = state.getState(false) as IGridState; - expect(gridState.columns.every(col => col.hidden)).toBe(true); + expect((gridState.columns as IColumnState[]).every(col => col.hidden)).toBe(true); // Restore the state state.setState(gridState); @@ -950,14 +950,14 @@ describe('IgxGridState - input properties #grid', () => { grid.columns.forEach((col, index) => { expect(col.width).toBe(initialWidths[index], `Column ${index} width should be preserved`); // The calcWidth should be based on the column width or grid default, not forced to 0px - const calcWidth = parseFloat(col.calcWidth); + const calcWidth = parseFloat(String(col.calcWidth)); // Note: some columns may be constrained by minWidth which is expected // The key is they shouldn't all be the same minimum width expect(calcWidth).toBeGreaterThan(0, `Column ${index} calcWidth should be greater than 0`); }); // Verify that not all columns have the same width (which would indicate the bug) - const calcWidths = grid.columns.map(col => parseFloat(col.calcWidth)); + const calcWidths = grid.columns.map(col => parseFloat(String(col.calcWidth))); const allSameWidth = calcWidths.every(w => w === calcWidths[0]); expect(allSameWidth).toBe(false, 'Columns should not all have the same width'); }); @@ -966,19 +966,19 @@ describe('IgxGridState - input properties #grid', () => { class HelperFunctions { public static verifyColumns(columns: IColumnState[], gridState: IGridState) { columns.forEach((c, index) => { - expect(gridState.columns[index]).toEqual(jasmine.objectContaining(c)); + expect(gridState.columns?.[index]).toEqual(jasmine.objectContaining(c)); }); } public static verifySortingExpressions(sortingExpressions: ISortingExpression[], gridState: IGridState) { sortingExpressions.forEach((expr, i) => { - expect(expr).toEqual(jasmine.objectContaining(gridState.sorting[i])); + expect(expr).toEqual(jasmine.objectContaining((gridState.sorting as ISortingExpression[])[i])); }); } public static verifyGroupingExpressions(groupingExpressions: IGroupingExpression[], gridState: IGridState) { groupingExpressions.forEach((expr, i) => { - expect(expr).toEqual(jasmine.objectContaining(gridState.groupBy.expressions[i])); + expect(expr).toEqual(jasmine.objectContaining((gridState.groupBy as IGroupingState).expressions[i])); }); } @@ -989,10 +989,10 @@ class HelperFunctions { } public static verifyFilteringExpressions(expressions: IFilteringExpressionsTree, gridState: IGridState) { - expect(expressions.fieldName).toBe(gridState.filtering.fieldName, 'Filtering expression field name is not correct'); - expect(expressions.operator).toBe(gridState.filtering.operator, 'Filtering expression operator value is not correct'); + expect(expressions.fieldName).toBe(gridState.filtering?.fieldName, 'Filtering expression field name is not correct'); + expect(expressions.operator).toBe((gridState.filtering as IFilteringExpressionsTree).operator, 'Filtering expression operator value is not correct'); expressions.filteringOperands.forEach((expr, i) => { - expect(expr).toEqual(jasmine.objectContaining(gridState.filtering.filteringOperands[i])); + expect(expr).toEqual(jasmine.objectContaining((gridState.filtering as IFilteringExpressionsTree).filteringOperands[i])); }); } @@ -1001,7 +1001,7 @@ class HelperFunctions { expect(expressions.fieldName).toBe(gridState.advancedFiltering.fieldName, 'Filtering expression field name is not correct'); expect(expressions.operator).toBe(gridState.advancedFiltering.operator, 'Filtering expression operator value is not correct'); expressions.filteringOperands.forEach((expr, i) => { - expect(expr).toEqual(jasmine.objectContaining(gridState.advancedFiltering.filteringOperands[i])); + expect(expr).toEqual(jasmine.objectContaining((gridState.advancedFiltering as IFilteringExpressionsTree).filteringOperands[i])); }); } else { expect(expressions).toBeFalsy(); @@ -1009,22 +1009,22 @@ class HelperFunctions { } public static verifyPaging(paging: IPagingState, gridState: IGridState) { - expect(paging).toEqual(jasmine.objectContaining(gridState.paging)); + expect(paging).toEqual(jasmine.objectContaining(gridState.paging as IPagingState)); } public static verifyMoving(moving: boolean, gridState: IGridState){ - expect(moving).toEqual(gridState.moving); + expect(moving).toEqual(!!gridState.moving); } public static verifyRowSelection(selectedRows: any[], gridState: IGridState) { - gridState.rowSelection.forEach((s, index) => { + gridState.rowSelection?.forEach((s, index) => { expect(s).toBe(selectedRows[index]); }); } public static verifyCellSelection(selectedCells: GridSelectionRange[], gridState: IGridState) { selectedCells.forEach((expr, i) => { - expect(expr).toEqual(jasmine.objectContaining(gridState.cellSelection[i])); + expect(expr).toEqual(jasmine.objectContaining((gridState.cellSelection as GridSelectionRange[])[i])); }); } diff --git a/projects/igniteui-angular/grids/core/src/state.hierarchicalgrid.spec.ts b/projects/igniteui-angular/grids/core/src/state.hierarchicalgrid.spec.ts index 9a30565484c..d3d2dcd875c 100644 --- a/projects/igniteui-angular/grids/core/src/state.hierarchicalgrid.spec.ts +++ b/projects/igniteui-angular/grids/core/src/state.hierarchicalgrid.spec.ts @@ -3,7 +3,7 @@ import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { IgxGridStateDirective } from './state.directive'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { GridSelectionMode } from './common/enums'; -import { GridSelectionRange } from './common/types'; +import { GridSelectionRange } from '../../../core/src/data-operations/grid-types'; import { IgxColumnComponent } from './public_api'; import { IgxPaginatorComponent } from 'igniteui-angular/paginator'; import { IColumnState, IGridState } from './state-base.directive'; diff --git a/projects/igniteui-angular/grids/core/src/state.treegrid.spec.ts b/projects/igniteui-angular/grids/core/src/state.treegrid.spec.ts index 265b4b366ce..eb6bd13edc2 100644 --- a/projects/igniteui-angular/grids/core/src/state.treegrid.spec.ts +++ b/projects/igniteui-angular/grids/core/src/state.treegrid.spec.ts @@ -12,7 +12,7 @@ import { IGroupByExpandState } from '../../../core/src/data-operations/groupby-e import { GridSelectionMode } from './common/enums'; import { FilteringLogic } from '../../../core/src/data-operations/filtering-expression.interface'; import { ISortingExpression } from '../../../core/src/data-operations/sorting-strategy'; -import { GridSelectionRange } from './common/types'; +import { GridSelectionRange } from '../../../core/src/data-operations/grid-types'; import { IgxPaginatorComponent } from 'igniteui-angular/paginator'; import { IgxColumnComponent } from './public_api'; import { IColumnState, IGridState } from './state-base.directive'; diff --git a/projects/igniteui-angular/grids/core/src/summaries/grid-summary.service.ts b/projects/igniteui-angular/grids/core/src/summaries/grid-summary.service.ts index e6ed4b536b1..a057f07c9c6 100644 --- a/projects/igniteui-angular/grids/core/src/summaries/grid-summary.service.ts +++ b/projects/igniteui-angular/grids/core/src/summaries/grid-summary.service.ts @@ -1,15 +1,27 @@ import { Injectable } from '@angular/core'; import type { GridType, FlatGridType, TreeGridType } from '../common/grid.interface'; -import { cloneArray, columnFieldPath, DataUtil, type IgxSummaryResult, resolveNestedPath } from 'igniteui-angular/core'; +import { cloneArray, columnFieldPath, DataUtil, IGroupingExpression, type IgxSummaryResult, resolveNestedPath } from 'igniteui-angular/core'; +import { IGroupingDoneEventArgs } from '../grouping/events'; +import { IRowDataEventArgs } from '../common/events'; + +/** + * @hidden + * The argument shapes `clearSummaryCache` is called with: row data events, cell edit + * events, or a bare `{ rowID }` (see IgxTreeGridAPIService). + */ +type SummaryCacheArgs = Partial & { + rowID?: any; + cellID?: { rowID: any; columnID: number; rowIndex: number }; +}; /** @hidden */ @Injectable() export class IgxGridSummaryService { - public grid: GridType; + public grid!: GridType; public rootSummaryID = 'igxGridRootSummary'; public summaryHeight = 0; public maxSummariesLength = 0; - public groupingExpressions = []; + public groupingExpressions: IGroupingExpression [] = []; public retriggerRootPipe = 0; public deleteOperation = false; @@ -20,7 +32,7 @@ export class IgxGridSummaryService { this.grid.notifyChanges(true); } - public clearSummaryCache(args?) { + public clearSummaryCache(args?: SummaryCacheArgs) { if (!this.summaryCacheMap.size) { return; } @@ -31,18 +43,18 @@ export class IgxGridSummaryService { } return; } - if (args.data) { - const rowID = this.grid.primaryKey ? args.data[this.grid.primaryKey] : args.data; + if (args.rowData) { + const rowID = this.grid.primaryKey ? args.rowData[this.grid.primaryKey] : args.rowData; this.removeSummaries(rowID); } if (args.rowID !== undefined && args.rowID !== null) { - let columnName = args.cellID ? this.grid.columns.find(col => col.index === args.cellID.columnID).field : undefined; + let columnName = args.cellID ? this.grid.columns.find(col => col.index === args.cellID!.columnID)?.field : undefined; if (columnName && this.grid.rowEditable) { return; } const isGroupedColumn = (this.grid as FlatGridType).groupingExpressions && - (this.grid as FlatGridType).groupingExpressions.map(expr => expr.fieldName).indexOf(columnName) !== -1; + (this.grid as FlatGridType).groupingExpressions.map(expr => expr.fieldName).indexOf(columnName!) !== -1; if (columnName && isGroupedColumn) { columnName = undefined; } @@ -50,7 +62,7 @@ export class IgxGridSummaryService { } } - public removeSummaries(rowID, columnName?) { + public removeSummaries(rowID: any, columnName?: any) { this.deleteSummaryCache(this.rootSummaryID, columnName); if (this.summaryCacheMap.size === 1 && this.summaryCacheMap.has(this.rootSummaryID)) { return; @@ -76,7 +88,7 @@ export class IgxGridSummaryService { } } - public removeSummariesCachePerColumn(columnName) { + public removeSummariesCachePerColumn(columnName: string) { this.summaryCacheMap.forEach((cache) => { if (cache.get(columnName)) { cache.delete(columnName); @@ -97,8 +109,8 @@ export class IgxGridSummaryService { let maxSummaryLength = 0; this.grid.columns.filter((col) => col.hasSummary && !col.hidden).forEach((column) => { const getCurrentSummary = column.summaries.operate([], [], column.field); - const getCurrentSummaryColumn = column.disabledSummaries.length > 0 - ? getCurrentSummary.filter(s => !column.disabledSummaries.includes(s.key)).length + const getCurrentSummaryColumn = column.disabledSummaries!.length > 0 + ? getCurrentSummary.filter((s) => !column.disabledSummaries!.includes(s.key)).length : getCurrentSummary.length; if (maxSummaryLength < getCurrentSummaryColumn) { @@ -110,7 +122,7 @@ export class IgxGridSummaryService { return this.summaryHeight; } - public calculateSummaries(rowID, data, groupRecord) { + public calculateSummaries(rowID: any, data: any, groupRecord: any) { let rowSummaries = this.summaryCacheMap.get(rowID); if (!rowSummaries) { rowSummaries = new Map(); @@ -127,16 +139,14 @@ export class IgxGridSummaryService { for (const [idx, column] of columns.entries()) { if (!rowSummaries.get(column.field)) { let summaryResult = column.summaries.operate( - data.map(r => resolveNestedPath(r, columnPathParts[idx])), + data.map((r: any) => resolveNestedPath(r, columnPathParts[idx])), data, column.field, - groupRecord, - this.grid.locale, - column.pipeArgs + groupRecord ); - summaryResult = column.disabledSummaries.length > 0 - ? summaryResult.filter(s => !column.disabledSummaries.includes(s.key)) + summaryResult = column.disabledSummaries!.length > 0 + ? summaryResult.filter(s => !column.disabledSummaries!.includes(s.key)) : summaryResult; rowSummaries.set(column.field, summaryResult); @@ -157,21 +167,21 @@ export class IgxGridSummaryService { } } - public updateSummaryCache(groupingArgs) { + public updateSummaryCache(groupingArgs: IGroupingDoneEventArgs) { if (this.summaryCacheMap.size === 0 || !this.hasSummarizedColumns) { return; } if (this.groupingExpressions.length === 0) { - this.groupingExpressions = groupingArgs.expressions.map(record => record.fieldName); + this.groupingExpressions = groupingArgs.expressions instanceof Array ? groupingArgs.expressions.map((record) => record.fieldName) : [] as any; return; } - if (groupingArgs.length === 0) { + if (groupingArgs.expressions instanceof Array && groupingArgs.expressions.length === 0) { this.groupingExpressions = []; this.clearSummaryCache(); return; } this.compareGroupingExpressions(this.groupingExpressions, groupingArgs); - this.groupingExpressions = groupingArgs.expressions.map(record => record.fieldName); + this.groupingExpressions = groupingArgs.expressions instanceof Array ? groupingArgs.expressions.map((record) => record.fieldName) : [] as any; } public get hasSummarizedColumns(): boolean { @@ -179,12 +189,12 @@ export class IgxGridSummaryService { return summarizedColumns.length > 0; } - private deleteSummaryCache(id, columnName) { + private deleteSummaryCache(id: any, columnName: any) { if (this.summaryCacheMap.get(id)) { const filteringApplied = columnName && this.grid.filteringExpressionsTree && this.grid.filteringExpressionsTree.filteringOperands.map((expr) => expr.fieldName).indexOf(columnName) !== -1; - if (columnName && this.summaryCacheMap.get(id).get(columnName) && !filteringApplied) { - this.summaryCacheMap.get(id).delete(columnName); + if (columnName && this.summaryCacheMap.get(id)!.get(columnName) && !filteringApplied) { + this.summaryCacheMap.get(id)!.delete(columnName); } else { this.summaryCacheMap.delete(id); } @@ -194,21 +204,21 @@ export class IgxGridSummaryService { } } - private getSummaryID(rowID, groupingExpressions) { + private getSummaryID(rowID: any, groupingExpressions: IGroupingExpression[]): string[] { if (groupingExpressions.length === 0) { return []; } - const summaryIDs = []; + const summaryIDs: string[] = []; let data = this.grid.data; if (this.grid.transactions.enabled) { data = DataUtil.mergeTransactions( - cloneArray(this.grid.data), + cloneArray(this.grid.data!), this.grid.transactions.getAggregatedChanges(true), this.grid.primaryKey, this.grid.dataCloneStrategy ); } - const rowData = this.grid.primaryKey ? data.find(rec => rec[this.grid.primaryKey] === rowID) : rowID; + const rowData = this.grid.primaryKey ? data!.find(rec => rec[this.grid.primaryKey] === rowID) : rowID; if (!rowData) { return summaryIDs; } @@ -221,7 +231,7 @@ export class IgxGridSummaryService { return summaryIDs; } - private removeAllTreeGridSummaries(rowID, columnName?) { + private removeAllTreeGridSummaries(rowID: any, columnName?: any) { let row = (this.grid as TreeGridType).records.get(rowID); if (!row) { return; @@ -238,8 +248,8 @@ export class IgxGridSummaryService { // private removeChildRowSummaries(rowID, columnName?) { // } - private compareGroupingExpressions(current, groupingArgs) { - const newExpressions = groupingArgs.expressions.map(record => record.fieldName); + private compareGroupingExpressions(current: IGroupingExpression[], groupingArgs: IGroupingDoneEventArgs) { + const newExpressions = groupingArgs.expressions instanceof Array ? groupingArgs.expressions.map((record) => record.fieldName) : []; const removedCols = groupingArgs.ungroupedColumns; if (current.length <= newExpressions.length) { const newExpr = newExpressions.slice(0, current.length).toString(); @@ -252,7 +262,7 @@ export class IgxGridSummaryService { this.clearSummaryCache(); return; } - removedCols.map(col => col.field).forEach(colName => { + removedCols instanceof Array && removedCols.map(col => col.field).forEach(colName => { this.summaryCacheMap.forEach((_cache, id) => { if (id.indexOf(colName) !== -1) { this.summaryCacheMap.delete(id); diff --git a/projects/igniteui-angular/grids/core/src/summaries/summary-cell.component.ts b/projects/igniteui-angular/grids/core/src/summaries/summary-cell.component.ts index 546ff2ea00b..f1cd1e5c522 100644 --- a/projects/igniteui-angular/grids/core/src/summaries/summary-cell.component.ts +++ b/projects/igniteui-angular/grids/core/src/summaries/summary-cell.component.ts @@ -1,10 +1,6 @@ import { Component, Input, HostBinding, HostListener, ChangeDetectionStrategy, ElementRef, TemplateRef, booleanAttribute, inject } from '@angular/core'; -import { - IgxSummaryOperand -} from './grid-summary'; import { NgTemplateOutlet } from '@angular/common'; -import { ISelectionNode } from '../common/types'; -import { GridTypeBase, ColumnType, GridColumnDataType, IgxSummaryResult, trackByIdentity, BaseFormatter } from 'igniteui-angular/core'; +import { GridTypeBase, ColumnType, GridColumnDataType, IgxSummaryResult, trackByIdentity, BaseFormatter, IgxSummaryOperand, ISelectionNode } from 'igniteui-angular/core'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -17,10 +13,10 @@ export class IgxSummaryCellComponent { @Input() - public summaryResults: IgxSummaryResult[]; + public summaryResults!: IgxSummaryResult[]; @Input() - public column: ColumnType; + public column!: ColumnType; @Input() public firstCellIndentation = 0; @@ -29,25 +25,25 @@ export class IgxSummaryCellComponent { public hasSummary = false; @Input() - public summaryFormatter: (summaryResult: IgxSummaryResult, summaryOperand: IgxSummaryOperand) => any; + public summaryFormatter!: (summaryResult: IgxSummaryResult, summaryOperand: IgxSummaryOperand) => any; @Input() - public summaryTemplate: TemplateRef; + public summaryTemplate!: TemplateRef; @Input() - public locale; + public locale: any; @Input() - public gridResourceStrings; + public gridResourceStrings: any; /** @hidden */ @Input() @HostBinding('class.igx-grid-summary--active') - public active: boolean; + public active!: boolean; @Input() @HostBinding('attr.data-rowIndex') - public rowIndex: number; + public rowIndex!: number; @HostBinding('attr.data-visibleIndex') public get visibleColumnIndex(): number { @@ -73,7 +69,7 @@ export class IgxSummaryCellComponent { protected get selectionNode(): ISelectionNode { return { row: this.rowIndex, - column: this.column.columnLayoutChild ? this.column.parent.visibleIndex : this.visibleColumnIndex, + column: this.column.columnLayoutChild ? this.column.parent!.visibleIndex : this.visibleColumnIndex, isSummaryRow: true }; } @@ -148,7 +144,7 @@ export class IgxSummaryCellComponent { case GridColumnDataType.Date: case GridColumnDataType.DateTime: case GridColumnDataType.Time: - return this.i18nFormatter.formatDate(summary.summaryResult, args.format, locale, args.timezone); + return this.i18nFormatter.formatDate(summary.summaryResult, args.format!, locale, args.timezone); case GridColumnDataType.Currency: return this.i18nFormatter.formatCurrency(summary.summaryResult, locale, args.display, this.currencyCode, args.digitsInfo); case GridColumnDataType.Percent: diff --git a/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.html b/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.html index a4b14cac6d1..2c7a1b50e36 100644 --- a/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.html +++ b/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.html @@ -21,7 +21,7 @@ [gridResourceStrings]="grid.resourceStrings" [rowIndex]="index" [firstCellIndentation]="firstCellIndentation" - [summaryResults]="getColumnSummaries(col.field)" + [summaryResults]="getColumnSummaries(col.field)!" [summaryTemplate]="col.summaryTemplate" [hasSummary]="col.hasSummary" [summaryFormatter]="col.summaryFormatter" @@ -51,7 +51,7 @@ [gridResourceStrings]="grid.resourceStrings" [firstCellIndentation]="firstCellIndentation" [rowIndex]="index" - [summaryResults]="getColumnSummaries(col.field)" + [summaryResults]="getColumnSummaries(col.field)!" [summaryTemplate]="col.summaryTemplate" [hasSummary]="col.hasSummary" [active]="isCellActive(col.visibleIndex)" diff --git a/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.ts b/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.ts index 963f721eb2b..8a32367c7ab 100644 --- a/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.ts +++ b/projects/igniteui-angular/grids/core/src/summaries/summary-row.component.ts @@ -33,13 +33,13 @@ export class IgxSummaryRowComponent implements DoCheck { @Input() - public summaries: Map; + public summaries!: Map; @Input() - public gridID; + public gridID: any; @Input() - public index: number; + public index!: number; @Input() public firstCellIndentation = -1; @@ -54,7 +54,7 @@ export class IgxSummaryRowComponent implements DoCheck { } @ViewChildren(IgxSummaryCellComponent, { read: IgxSummaryCellComponent }) - public _summaryCells: QueryList; + public _summaryCells!: QueryList; public get summaryCells(): QueryList { const res = new QueryList(); @@ -71,7 +71,7 @@ export class IgxSummaryRowComponent implements DoCheck { * @hidden */ @ViewChild('igxDirRef', { read: IgxGridForOfDirective }) - public virtDirRow: IgxGridForOfDirective; + public virtDirRow!: IgxGridForOfDirective; public ngDoCheck() { this.cdr.markForCheck(); @@ -93,7 +93,7 @@ export class IgxSummaryRowComponent implements DoCheck { * @hidden * @internal */ - public isCellActive(visibleColumnIndex) { + public isCellActive(visibleColumnIndex: any) { const node = this.grid.navigation.activeNode; return node ? node.row === this.index && node.column === visibleColumnIndex : false; } @@ -128,7 +128,7 @@ export class IgxSummaryRowComponent implements DoCheck { return this.grid.unpinnedColumns; } - public getContext(row, cols) { + public getContext(row: any, cols: any) { return { $implicit: row, columns: cols diff --git a/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-advanced-filtering.component.ts b/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-advanced-filtering.component.ts index 2fc181e9c59..6db1ccde0ce 100644 --- a/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-advanced-filtering.component.ts +++ b/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-advanced-filtering.component.ts @@ -32,7 +32,7 @@ import { IFilteringExpressionsTree, isTree, OverlaySettings } from 'igniteui-ang export class IgxGridToolbarAdvancedFilteringComponent implements OnInit { private toolbar = inject(IgxToolbarToken); - protected numberOfColumns: number; + protected numberOfColumns!: number; /** * Returns the grid containing this component. * @hidden @internal @@ -42,7 +42,7 @@ export class IgxGridToolbarAdvancedFilteringComponent implements OnInit { } @Input() - public overlaySettings: OverlaySettings; + public overlaySettings!: OverlaySettings; /** * @hidden @@ -58,7 +58,7 @@ export class IgxGridToolbarAdvancedFilteringComponent implements OnInit { } protected extractUniqueFieldNamesFromFilterTree(filteringTree?: IFilteringExpressionsTree) : string[] { - const columnNames = []; + const columnNames: string[] = []; if (!filteringTree) return columnNames; filteringTree.filteringOperands.forEach((expr) => { if (isTree(expr)) { diff --git a/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-hiding.component.html b/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-hiding.component.html index 0a552b03a80..1ad0daa8252 100644 --- a/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-hiding.component.html +++ b/projects/igniteui-angular/grids/core/src/toolbar/grid-toolbar-hiding.component.html @@ -1,10 +1,6 @@ @if (grid.rendered$ | async) { @@ -250,8 +250,8 @@
+ *ngTemplateOutlet="$any(this.crudService.row?.isAddRow ? rowAddTextTemplate : resolveRowEditText || defaultRowEditText); + context: { $implicit: $any(!this.crudService.row?.isAddRow ? rowChangesCount : null) }">
diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.ts index a4dc18f5940..ff18b39b181 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.ts @@ -29,7 +29,7 @@ import { IgxGridDragSelectDirective } from 'igniteui-angular/grids/core'; import { IgxGridBodyDirective } from 'igniteui-angular/grids/core'; import { IgxGridHeaderRowComponent } from 'igniteui-angular/grids/core'; import { IgxGridSelectionService } from 'igniteui-angular/grids/core'; -import { IgxButtonDirective, IgxForOfScrollSyncService, IgxForOfSyncService, IgxGridForOfDirective, IgxRippleDirective, IgxScrollInertiaDirective, IgxTemplateOutletDirective, IgxToggleDirective } from 'igniteui-angular/directives'; +import { IForOfState, IgxButtonDirective, IgxForOfScrollSyncService, IgxForOfSyncService, IgxGridForOfDirective, IgxRippleDirective, IgxScrollInertiaDirective, IgxTemplateOutletDirective, IgxToggleDirective, IViewChangeEventArgs } from 'igniteui-angular/directives'; import { IgxCircularProgressBarComponent } from 'igniteui-angular/progressbar'; import { IgxSnackbarComponent } from 'igniteui-angular/snackbar'; import { IgxIconComponent } from 'igniteui-angular/icon'; @@ -58,7 +58,7 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { public cdr = inject(ChangeDetectorRef); @Input() - public layout: IgxRowIslandComponent; + public layout!: IgxRowIslandComponent; /** * @hidden @@ -72,7 +72,7 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { * @hidden */ @Input() - public parentGridID: string; + public parentGridID!: string; /** * The data passed to the row component. @@ -103,16 +103,16 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { * ``` */ @Input() - public index: number; + public index!: number; /* blazorSuppress */ @ViewChild('container', { read: ViewContainerRef, static: true }) - public container: ViewContainerRef; + public container!: ViewContainerRef; /** * @hidden */ - public hGrid: IgxHierarchicalGridComponent; + public hGrid!: IgxHierarchicalGridComponent; /* blazorSuppress */ /** @@ -171,7 +171,7 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { const ref = this.container.createComponent(IgxHierarchicalGridComponent, { injector: this.container.injector }); this.hGrid = ref.instance; this.hGrid.setDataInternal(this.data.childGridsData[this.layout.key]); - this.hGrid.nativeElement["__componentRef"] = ref; + (this.hGrid.nativeElement as any)["__componentRef"] = ref; this.layout.layoutChange.subscribe((ch) => { this._handleLayoutChanges(ch); }); @@ -217,21 +217,21 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { const mirror = reflectComponentType(IgxGridComponent); // exclude outputs related to two-way binding functionality - const inputNames = mirror.inputs.map(input => input.propName); - const outputs = mirror.outputs.filter(o => { + const inputNames = mirror!.inputs.map(input => input.propName); + const outputs = mirror!.outputs.filter(o => { const matchingInputPropName = o.propName.slice(0, o.propName.indexOf('Change')); return inputNames.indexOf(matchingInputPropName) === -1; }); // TODO: Skip the `rendered` output. Rendered should be called once per grid. outputs.filter(o => o.propName !== 'rendered').forEach(output => { - if (this.hGrid[output.propName]) { - this.hGrid[output.propName].pipe(destructor).subscribe((args) => { + if ((this.hGrid as any)[output.propName]) { + (this.hGrid as any)[output.propName].pipe(destructor).subscribe((args: any) => { if (!args) { args = {}; } args.owner = this.hGrid; - this.layout[output.propName].emit(args); + (this.layout as any)[output.propName].emit(args); }); } }); @@ -241,7 +241,7 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { protected _handleLayoutChanges(changes: SimpleChanges) { for (const change in changes) { if (changes.hasOwnProperty(change)) { - this.hGrid[change] = changes[change].currentValue; + (this.hGrid as any)[change] = changes[change].currentValue; } } } @@ -335,42 +335,42 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti * @hidden */ @ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: false }) - public childLayoutList: QueryList; + public childLayoutList!: QueryList; /** * @hidden */ @ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: true }) - public allLayoutList: QueryList; + public allLayoutList!: QueryList; /** @hidden @internal */ @ContentChildren(IgxPaginatorToken, { descendants: true }) - public paginatorList: QueryList; + public paginatorList!: QueryList; /** @hidden @internal */ @ViewChild('toolbarOutlet', { read: ViewContainerRef }) - public toolbarOutlet: ViewContainerRef; + public toolbarOutlet!: ViewContainerRef; /** @hidden @internal */ @ViewChild('paginatorOutlet', { read: ViewContainerRef }) - public paginatorOutlet: ViewContainerRef; + public paginatorOutlet!: ViewContainerRef; /** * @hidden */ @ViewChildren(IgxTemplateOutletDirective, { read: IgxTemplateOutletDirective }) - public templateOutlets: QueryList; + public templateOutlets!: QueryList; /** * @hidden */ @ViewChildren(IgxChildGridRowComponent) - public hierarchicalRows: QueryList; + public hierarchicalRows!: QueryList; @ViewChild('hierarchical_record_template', { read: TemplateRef, static: true }) - protected hierarchicalRecordTemplate: TemplateRef; + protected hierarchicalRecordTemplate!: TemplateRef; @ViewChild('child_record_template', { read: TemplateRef, static: true }) - protected childTemplate: TemplateRef; + protected childTemplate!: TemplateRef; // @ViewChild('headerHierarchyExpander', { read: ElementRef, static: true }) protected get headerHierarchyExpander() { @@ -380,7 +380,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public childLayoutKeys = []; + public childLayoutKeys: any[] = []; /** @hidden @internal */ public dataSetByUser = false; @@ -398,12 +398,12 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public parent: IgxHierarchicalGridComponent = null; + public parent: IgxHierarchicalGridComponent = null!; /** * @hidden @internal */ - public childRow: IgxChildGridRowComponent; + public childRow!: IgxChildGridRowComponent; /** @hidden @internal */ public override get actionStrip() { @@ -423,7 +423,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti super.advancedFilteringExpressionsTree = value; } - private _data; + private _data: any; private h_id = `igx-hierarchical-grid-${NEXT_ID++}`; private childGridTemplates: Map = new Map(); @@ -656,7 +656,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti // }); this.batchEditing = !!this.rootGrid.batchEditing; if (this.rootGrid !== this) { - this.rootGrid.batchEditingChange.pipe(takeUntil(this.destroy$)).subscribe((val: boolean) => { + this.rootGrid.batchEditingChange!.pipe(takeUntil(this.destroy$)).subscribe((val: boolean) => { this.batchEditing = val; }); } @@ -669,7 +669,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti if (this.rowEditable && this.crudService.rowInEditMode && this.rowEditingOverlay && this.rowEditingOverlay.collapsed) { // Row is in edit mode, but overlay is closed - reopen. - this.openRowOverlay(this.crudService.rowInEditMode.id); + this.openRowOverlay(this.crudService.rowInEditMode.key); } } @@ -726,7 +726,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti this.parentIsland.hasChildrenKey || this.rootGrid.hasChildrenKey : this.rootGrid.hasChildrenKey; this.showExpandAll = this.parentIsland ? - this.parentIsland.showExpandAll : this.rootGrid.showExpandAll; + this.parentIsland.showExpandAll : this.rootGrid.showExpandAll!; } /** @@ -755,7 +755,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti */ public getRowByIndex(index: number): RowType { if (index < 0 || index >= this.dataView.length) { - return undefined; + return undefined!; } return this.createRow(index); } @@ -776,10 +776,10 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti data.find(record => record === key); const index = data.indexOf(rec); if (index < 0 || index > data.length) { - return undefined; + return undefined!; } - return new IgxHierarchicalGridRow(this as any, index, rec); + return new IgxHierarchicalGridRow(this, index, rec); } /** @@ -807,7 +807,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti * ``` */ public get selectedCells(): CellType[] { - return this.dataRows().map((row) => row.cells.filter((cell) => cell.selected)) + return this.dataRows().map((row) => row.cells!.filter((cell) => cell.selected)) .reduce((a, b) => a.concat(b), []); } @@ -850,6 +850,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti if (row && row instanceof IgxHierarchicalGridRow && column) { return new IgxGridCell(this, rowIndex, column); } + return undefined!; } /** @@ -870,6 +871,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti if (row && column) { return new IgxGridCell(this, row.index, column); } + return undefined!; } public override pinRow(rowID: any, index?: number): boolean { @@ -904,7 +906,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden @internal */ - public dataLoading(event) { + public dataLoading(event: IForOfState) { this.dataPreLoad.emit(event); } @@ -946,7 +948,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public isRowHighlighted(rowData) { + public isRowHighlighted(rowData: any) { return this.highlightedRowID === rowData.rowID; } @@ -971,7 +973,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public trackChanges(_index, rec) { + public trackChanges(_index: number, rec: any) { if (rec.childGridsData !== undefined) { // if is child rec return rec.rowID; @@ -982,7 +984,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public getContext(rowData, rowIndex, pinned): any { + public getContext(rowData: any, rowIndex: number, pinned: boolean): any { if (this.isChildGridRecord(rowData)) { const cachedData = this.childGridTemplates.get(rowData.rowID); if (cachedData) { @@ -1116,7 +1118,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public viewCreatedHandler(args) { + public viewCreatedHandler(args: IViewChangeEventArgs) { if (this.isChildGridRecord(args.context.$implicit)) { const key = args.context.$implicit.rowID; this.childGridTemplates.set(key, args); @@ -1126,7 +1128,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public viewMovedHandler(args) { + public viewMovedHandler(args: IViewChangeEventArgs) { if (this.isChildGridRecord(args.context.$implicit)) { // view was moved, update owner in cache const key = args.context.$implicit.rowID; @@ -1153,7 +1155,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti * @hidden */ public createRow(index: number, data?: any): RowType { - let row: RowType; + let row!: RowType; const dataIndex = this._getDataViewIndex(index); const rec: any = data ?? this.dataView[dataIndex]; @@ -1187,7 +1189,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - protected override initColumns(collection: IgxColumnComponent[], cb: (args: any) => void = null) { + protected override initColumns(collection: IgxColumnComponent[], cb: (args: any) => void = null!) { if (this.hasColumnLayouts) { // invalid configuration - hierarchical grid should not allow column layouts // remove column layouts @@ -1208,7 +1210,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti protected override getColumnList() { const childLayouts = this.parent ? this.childLayoutList : this.allLayoutList; const nestedColumns = childLayouts.map((layout) => layout.columnList.toArray()); - const colsArray = [].concat.apply([], nestedColumns); + const colsArray = ([] as IgxColumnComponent[]).concat.apply([], nestedColumns); if (colsArray.length > 0) { const topCols = this.columnList.filter((item) => colsArray.indexOf(item) === -1); return topCols; @@ -1223,7 +1225,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti }); } - protected override _shouldAutoSize(renderedHeight) { + protected override _shouldAutoSize(renderedHeight: number): boolean { if (this.isPercentHeight && this.parent) { return true; } @@ -1233,7 +1235,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti private updateColumnList(recalcColSizes = true) { const childLayouts = this.parent ? this.childLayoutList : this.allLayoutList; const nestedColumns = childLayouts.map((layout) => layout.columnList.toArray()); - const colsArray = [].concat.apply([], nestedColumns); + const colsArray = ([] as IgxColumnComponent[]).concat.apply([], nestedColumns); const colLength = this.columns.length; const topCols = this.columnList.filter((item) => colsArray.indexOf(item) === -1); if (topCols.length > 0) { @@ -1245,7 +1247,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti } private _clearSeletionHighlights() { - [this.rootGrid, ...this.rootGrid.getChildGrids(true)].forEach(grid => { + [this.rootGrid, ...this.rootGrid.getChildGrids!(true)].forEach(grid => { grid.selectionService.clear(); grid.selectionService.activeElement = null; grid.nativeElement.classList.remove('igx-grid__tr--highlighted'); @@ -1256,12 +1258,12 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti private generateSchema() { const filterableFields = this.columns.filter((column) => !column.columnGroup && column.filterable); - let entities: EntityType[]; + let entities!: EntityType[]; if(filterableFields.length !== 0) { entities = [ { - name: null, + name: null!, fields: filterableFields.map(f => ({ field: f.field, dataType: f.dataType, @@ -1276,19 +1278,19 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti ]; entities[0].childEntities = this.childLayoutList.reduce((acc, rowIsland) => { - const childFirstRowData = this.data?.length > 0 && this.data[0][rowIsland.key]?.length > 0 ? - this.data[0][rowIsland.key][0] : null; + const childFirstRowData = this.data?.length! > 0 && this.data![0][rowIsland.key]?.length > 0 ? + this.data![0][rowIsland.key][0] : null; return acc.concat(this.generateChildEntity(rowIsland, childFirstRowData)); } - , []); + , [] as any); } return entities; } - private generateChildEntity(rowIsland: IgxRowIslandComponent, firstRowData: any[]): EntityType { + private generateChildEntity(rowIsland: IgxRowIslandComponent, firstRowData: any): EntityType { const entityName = rowIsland.key; - let fields = []; + let fields: any[] = []; let childEntities; if (!rowIsland.autoGenerate) { fields = flatten(rowIsland.childColumns.toArray()).filter(col => col.field) @@ -1314,7 +1316,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti const childFirstRowData = firstRowData.length > 0 && firstRowData[childRowIsland.key]?.length > 0 ? firstRowData[childRowIsland.key][0] : null; return acc.concat(this.generateChildEntity(childRowIsland, childFirstRowData)); - }, []); + }, [] as any); if (rowIslandChildEntities?.length > 0) { childEntities = rowIslandChildEntities; diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.integration.spec.ts index 8dc915919eb..bfac7007eda 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.integration.spec.ts @@ -470,7 +470,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // Expect expansion cell to be rendered and sized the same as the expansion cell inside the grid const summaryRow = childGrid.summariesRowList.first.nativeElement; - const summaryRowIndentation = summaryRow.querySelector(SUMMARIES_MARGIN_CLASS); + const summaryRowIndentation = summaryRow.querySelector(SUMMARIES_MARGIN_CLASS); expect(summaryRow.children.length).toEqual(2); expect(summaryRowIndentation.offsetWidth).toEqual(expander.nativeElement.offsetWidth); @@ -507,7 +507,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { const rootExpander = (hierarchicalGrid.dataRowList.first as IgxHierarchicalRowComponent).expander; const rootCheckbox = hierarchicalGrid.headerSelectorContainer; const rootSummaryRow = hierarchicalGrid.summariesRowList.first.nativeElement; - const rootSummaryIndentation = rootSummaryRow.querySelector(SUMMARIES_MARGIN_CLASS); + const rootSummaryIndentation = rootSummaryRow.querySelector(SUMMARIES_MARGIN_CLASS); expect(rootSummaryRow.children.length).toEqual(2); expect(rootSummaryIndentation.offsetWidth) @@ -518,7 +518,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // Expect expansion cell to be rendered and sized the same as the expansion cell inside the grid const summaryRow = childGrid.summariesRowList.first.nativeElement; - const childSummaryIndentation = summaryRow.querySelector(SUMMARIES_MARGIN_CLASS); + const childSummaryIndentation = summaryRow.querySelector(SUMMARIES_MARGIN_CLASS); expect(summaryRow.children.length).toEqual(2); expect(childSummaryIndentation.offsetWidth).toEqual(expander.nativeElement.offsetWidth); diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.pipes.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.pipes.ts index 77508392be4..41a2d2fb8e2 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.pipes.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.pipes.ts @@ -31,12 +31,12 @@ export class IgxGridHierarchicalPipe implements PipeTransform { return result; } - public addHierarchy(grid, data: T[], _state, primaryKey, childKeys: string[]): T[] { - const result = []; + public addHierarchy(grid: GridType, data: T[], _state: Map, primaryKey: any, childKeys: string[]): T[] { + const result: any[] = []; - data.forEach((v) => { + data.forEach((v: any) => { result.push(v); - const childGridsData = {}; + const childGridsData: any = {}; childKeys.forEach((childKey) => { if (!v[childKey]) { v[childKey] = []; diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.selection.spec.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.selection.spec.ts index 7291eab9e8c..b729c542211 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.selection.spec.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.selection.spec.ts @@ -1341,7 +1341,7 @@ describe('IgxHierarchicalGrid selection #hGrid', () => { }); it('should deselect deleted row', () => { - hierarchicalGrid.onHeaderSelectorClick(UIInteractions.getMouseEvent('click')); + GridSelectionFunctions.clickHeaderRowCheckbox(fix); fix.detectChanges(); GridSelectionFunctions.verifyHeaderRowCheckboxState(hierarchicalGrid, true); diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.spec.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.spec.ts index 03702d736fc..25c13af2608 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.spec.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.spec.ts @@ -1227,7 +1227,7 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { it('should create a child grid with null height when its data is unset then set to a number under 10', () => { fixture.detectChanges(); // expansion - const row = hierarchicalGrid.rowList.first as IgxHierarchicalRowComponent; + const row = hierarchicalGrid.rowList.first as unknown as IgxHierarchicalRowComponent; UIInteractions.simulateClickAndSelectEvent(row.expander); fixture.detectChanges(); const childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); @@ -1249,7 +1249,7 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { it('should create a child grid with auto-size when its data is unset then set to a number above 10', () => { fixture.detectChanges(); // expansion - const row = hierarchicalGrid.rowList.first as IgxHierarchicalRowComponent; + const row = hierarchicalGrid.rowList.first as unknown as IgxHierarchicalRowComponent; UIInteractions.simulateClickAndSelectEvent(row.expander); fixture.detectChanges(); const childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); @@ -1272,7 +1272,7 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { fixture.componentInstance.childHeight = '50%'; fixture.detectChanges(); // expansion - const row = hierarchicalGrid.rowList.first as IgxHierarchicalRowComponent; + const row = hierarchicalGrid.rowList.first as unknown as IgxHierarchicalRowComponent; UIInteractions.simulateClickAndSelectEvent(row.expander); fixture.detectChanges(); const childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); @@ -1295,7 +1295,7 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { fixture.componentInstance.childHeight = '600px'; fixture.detectChanges(); // expansion - const row = hierarchicalGrid.rowList.first as IgxHierarchicalRowComponent; + const row = hierarchicalGrid.rowList.first as unknown as IgxHierarchicalRowComponent; UIInteractions.simulateClickAndSelectEvent(row.expander); fixture.detectChanges(); const childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); @@ -1325,7 +1325,7 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => { fixture.componentInstance.childHeight = null; fixture.detectChanges(); // expansion - const row = hierarchicalGrid.rowList.first as IgxHierarchicalRowComponent; + const row = hierarchicalGrid.rowList.first as unknown as IgxHierarchicalRowComponent; UIInteractions.simulateClickAndSelectEvent(row.expander); fixture.detectChanges(); const childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-row.component.html b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-row.component.html index c3ca8efb454..00d03078f27 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-row.component.html +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-row.component.html @@ -31,7 +31,7 @@ role="gridcell" [igxRowDrag]="this" (click)="$event.stopPropagation()" - [ghostTemplate]="this.grid.getDragGhostCustomTemplate()" + [ghostTemplate]="this.grid.getDragGhostCustomTemplate()!" (pointerdown)="$event.preventDefault()" > ; + public expander!: ElementRef; @ViewChildren(forwardRef(() => IgxHierarchicalGridCellComponent), { read: IgxHierarchicalGridCellComponent }) - protected override _cells: QueryList; + protected override _cells!: QueryList; /** * @hidden */ @ViewChild('defaultExpandedTemplate', { read: TemplateRef, static: true }) - protected defaultExpandedTemplate: TemplateRef; + protected defaultExpandedTemplate!: TemplateRef; /** * @hidden */ @ViewChild('defaultEmptyTemplate', { read: TemplateRef, static: true }) - protected defaultEmptyTemplate: TemplateRef; + protected defaultEmptyTemplate!: TemplateRef; /** * @hidden */ @ViewChild('defaultCollapsedTemplate', { read: TemplateRef, static: true }) - protected defaultCollapsedTemplate: TemplateRef; + protected defaultCollapsedTemplate!: TemplateRef; protected expanderClass = 'igx-grid__hierarchical-expander'; protected rolActionClass = 'igx-grid__tr-action'; @@ -87,7 +87,7 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective { } public override get hasChildren() { - return !!this.grid.childLayoutKeys.length; + return !!this.grid.childLayoutKeys!.length; } /** @@ -101,7 +101,7 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective { /** * @hidden */ - public expanderClick(event) { + public expanderClick(event: MouseEvent) { event.stopPropagation(); this.toggle(); } @@ -161,7 +161,7 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective { if (grid.gridAPI.crudService.cellInEditMode) { grid.gridAPI.crudService.endEdit(); } - grid.gridAPI.getChildGrids(true).forEach(g => { + grid.gridAPI.getChildGrids!(true).forEach(g => { if (g.gridAPI.crudService.cellInEditMode) { g.gridAPI.crudService.endEdit(); } diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/row-island-api.service.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/row-island-api.service.ts index c6d6160df14..372b0b0195d 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/row-island-api.service.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/row-island-api.service.ts @@ -5,7 +5,7 @@ import { Injectable } from '@angular/core'; @Injectable() export class IgxRowIslandAPIService { - public rowIsland: IgxRowIslandComponent; + public rowIsland!: IgxRowIslandComponent; public change: Subject = new Subject(); protected state: Map = new Map(); protected destroyMap: Map> = new Map>(); @@ -23,7 +23,7 @@ export class IgxRowIslandAPIService { } public get(id: string): IgxRowIslandComponent { - return this.state.get(id); + return this.state.get(id)!; } public unset(id: string) { @@ -65,7 +65,7 @@ export class IgxRowIslandAPIService { } public getChildGrids(inDepth?: boolean) { - let allChildren = []; + let allChildren: IgxHierarchicalGridComponent[] = []; this.childGrids.forEach((grid) => { allChildren.push(grid); }); @@ -78,7 +78,7 @@ export class IgxRowIslandAPIService { return allChildren; } - public getChildGridByID(rowID) { + public getChildGridByID(rowID: any) { return this.childGrids.get(rowID); } } diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts index 680aeb0e56f..1aa4d9a78cc 100644 --- a/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts +++ b/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts @@ -16,7 +16,9 @@ import { Output, QueryList, TemplateRef, - inject + inject, + SimpleChanges, + IterableDiffer } from '@angular/core'; import { GridType, @@ -79,7 +81,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective * @memberof IgxRowIslandComponent */ @Input() - public key: string; + public key!: string; /* treatAsRef */ /** @@ -117,10 +119,10 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective public childColumns = new QueryList(); @ContentChild(IgxGridToolbarDirective, { read: TemplateRef, descendants: false }) - protected toolbarDirectiveTemplate: TemplateRef; + protected toolbarDirectiveTemplate!: TemplateRef; @ContentChild(IgxPaginatorDirective, { read: TemplateRef, descendants: false }) - protected paginatorDirectiveTemplate: TemplateRef; + protected paginatorDirectiveTemplate!: TemplateRef; /* csSuppress */ /** @@ -153,7 +155,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective * @hidden */ @Output() - public layoutChange = new EventEmitter(); + public layoutChange = new EventEmitter>(); /** * Event emitted when a grid is being created based on this row island. @@ -189,15 +191,15 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective /** * @hidden */ - public initialChanges = []; + public initialChanges: SimpleChanges[] = []; /** * @hidden */ - public rootGrid: GridType = null; + public rootGrid: GridType = null!; /** @hidden */ - public readonly data: any[] | null; + public readonly data!: any[] | null; /** @hidden */ public override get hiddenColumnsCount(): number { @@ -211,7 +213,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective /** @hidden */ public override get lastSearchInfo(): ISearchInfo { - return null; + return null!; } /** @hidden */ @@ -226,7 +228,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective /** @hidden */ public override get virtualizationState(): IForOfState { - return null; + return null!; } /** @hidden */ @@ -263,9 +265,9 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective public override tabindex = -1; /** @hidden @internal */ - public override hostRole = null; + public override hostRole: string = null!; - protected override baseClass = null; + protected override baseClass: string = null!; /** @hidden @internal */ public override get hostWidth(): any { @@ -273,14 +275,14 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective } protected override displayStyle = 'none'; - protected override templateRows = null; + protected override templateRows: string = null!; //#endregion - private ri_columnListDiffer; + private ri_columnListDiffer: IterableDiffer = null!; private layout_id = `igx-row-island-`; private isInit = false; - private _toolbarTemplate: TemplateRef; - private _paginatorTemplate: TemplateRef; + private _toolbarTemplate!: TemplateRef; + private _paginatorTemplate!: TemplateRef; /** * Sets if all immediate children of the grids for this row island should be expanded/collapsed. @@ -324,7 +326,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective /** * @hidden */ - public get id() { + public get id(): string { const pId = this.parentId ? this.parentId.substring(this.parentId.indexOf(this.layout_id) + this.layout_id.length) + '-' : ''; return this.layout_id + pId + this.key; } @@ -332,7 +334,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective /** * @hidden */ - public get parentId() { + public get parentId(): string | null { return this.parentIsland ? this.parentIsland.id : null; } @@ -356,7 +358,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective this.filteringService.grid = this as GridType; this.rootGrid = this.gridAPI.grid; this.rowIslandAPI.rowIsland = this; - this.ri_columnListDiffer = this.differs.find([]).create(null); + this.ri_columnListDiffer = this.differs.find([]).create(null!); } /** @@ -370,11 +372,11 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective this.updateChildren(); // update existing grids since their child ri have been changed. this.rowIslandAPI.getChildGrids(false).forEach(grid => { - (grid as any).onRowIslandChange(this.children); + grid.onRowIslandChange(); }); }); const nestedColumns = this.children.map((layout) => layout.columnList.toArray()); - const colsArray = [].concat.apply([], nestedColumns); + const colsArray = ([] as IgxColumnComponent[]).concat.apply([], nestedColumns); const topCols = this.columnList.filter((item) => colsArray.indexOf(item) === -1); this._childColumns = topCols; this.updateColumns(this._childColumns); @@ -405,7 +407,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective if (this.parentIsland) { this.parentIsland.rowIslandAPI.registerChildRowIsland(this); } else { - this.rootGrid.gridAPI.registerChildRowIsland(this); + this.rootGrid.gridAPI.registerChildRowIsland!(this); } this._init = false; @@ -415,7 +417,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective .subscribe(() => grid.toolbarOutlet.createEmbeddedView(this.toolbarTemplate, { $implicit: grid }, { injector: grid.toolbarOutlet.injector })); grid.rendered$.pipe(first(), filter(() => !!this.paginatorTemplate)) .subscribe(() => { - this.rootGrid.paginatorList.changes.pipe(takeUntil(this.destroy$)).subscribe((changes: QueryList) => { + this.rootGrid.paginatorList!.changes.pipe(takeUntil(this.destroy$)).subscribe((changes: QueryList) => { changes.forEach(p => { if (p.nativeElement.offsetParent?.id === grid.id) { // Optimize update only for those grids that have related changed paginator. @@ -432,7 +434,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective /** * @hidden */ - public ngOnChanges(changes) { + public ngOnChanges(changes: SimpleChanges) { this.layoutChange.emit(changes); if (!this.isInit) { this.initialChanges.push(changes); @@ -451,11 +453,11 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective if (this.parentIsland) { this.getGridsForIsland(this.key).forEach(grid => { this.cleanGridState(grid); - grid.gridAPI.unsetChildRowIsland(this); + grid.gridAPI.unsetChildRowIsland!(this); }); this.parentIsland.rowIslandAPI.unsetChildRowIsland(this); } else { - this.rootGrid.gridAPI.unsetChildRowIsland(this); + this.rootGrid.gridAPI.unsetChildRowIsland!(this); this.cleanGridState(this.rootGrid); } } @@ -475,16 +477,16 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective */ public override calculateGridWidth() { } - protected _childColumns = []; + protected _childColumns: IgxColumnComponent[] = []; protected updateColumnList() { const nestedColumns = this.children.map((layout) => layout.columnList.toArray()); - const colsArray = [].concat.apply([], nestedColumns); + const colsArray = ([] as IgxColumnComponent[]).concat.apply([], nestedColumns); const topCols = this.columnList.filter((item) => { if (colsArray.indexOf(item) === -1) { /* Reset the default width of the columns that come into this row island, because the root catches them first during the detectChanges() and sets their defaultWidth. */ - item.defaultWidth = undefined; + item.defaultWidth = undefined!; return true; } return false; @@ -492,7 +494,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective this._childColumns = topCols; this.updateColumns(this._childColumns); this.rowIslandAPI.getChildGrids().forEach((grid: GridType) => { - grid.createColumnsList(this._childColumns); + grid.createColumnsList!(this._childColumns); if (!this.document.body.contains(grid.nativeElement)) { grid.updateOnRender = true; } @@ -508,8 +510,8 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective }); } - private cleanGridState(grid) { - grid.childGridTemplates.forEach((tmpl) => { + private cleanGridState(grid: GridType) { + grid.childGridTemplates.forEach((tmpl: any) => { tmpl.owner.cleanView(tmpl.context.templateID); }); grid.childGridTemplates.clear(); diff --git a/projects/igniteui-angular/grids/lite/src/grid-lite-column.component.ts b/projects/igniteui-angular/grids/lite/src/grid-lite-column.component.ts index c9acbb85053..8b654051bcb 100644 --- a/projects/igniteui-angular/grids/lite/src/grid-lite-column.component.ts +++ b/projects/igniteui-angular/grids/lite/src/grid-lite-column.component.ts @@ -147,14 +147,14 @@ export class IgxGridLiteColumnComponent { const template = this.cellTemplate() ?? directive?.template; if (template) { this.cellTemplateFunc = (ctx: IgcCellContext) => { - const oldViewRef = this.cellViewRefs.get(ctx.row.data); + const oldViewRef = this.cellViewRefs!.get(ctx.row.data!); const angularContext = { ...ctx, $implicit: ctx.value, } as IgxGridLiteCellTemplateContext; if (!oldViewRef) { const newViewRef = this._view.createEmbeddedView(template, angularContext); - this.cellViewRefs.set(ctx.row.data, newViewRef); + this.cellViewRefs!.set(ctx.row.data!, newViewRef); return newViewRef.rootNodes; } Object.assign(oldViewRef.context, angularContext); @@ -162,7 +162,7 @@ export class IgxGridLiteColumnComponent { }; } onCleanup(() => { - this.cellViewRefs.forEach((viewRef) => { + this.cellViewRefs!.forEach((viewRef) => { viewRef.destroy(); }); this.cellViewRefs?.clear(); diff --git a/projects/igniteui-angular/grids/lite/src/grid-lite.component.ts b/projects/igniteui-angular/grids/lite/src/grid-lite.component.ts index 0cb0d20ed5b..f2d857a451b 100644 --- a/projects/igniteui-angular/grids/lite/src/grid-lite.component.ts +++ b/projects/igniteui-angular/grids/lite/src/grid-lite.component.ts @@ -169,7 +169,7 @@ export class IgxGridLiteComponent implements OnInit { * Performs a filter operation in the grid based on the passed expression(s). */ public filter(config: IgxGridLiteFilteringExpression | IgxGridLiteFilteringExpression[]): void { - this.gridRef.nativeElement.filter(config as FilterExpression | FilterExpression[]); + this.gridRef.nativeElement.filter(config as unknown as FilterExpression | FilterExpression[]); } /** diff --git a/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.html b/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.html index 4fa3b34c669..1f29d493dfc 100644 --- a/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.html +++ b/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.html @@ -14,7 +14,7 @@ item of dims | filterPivotItems : input.value - : $safeNavigationMigration(grid?.pipeTrigger); + : grid?.pipeTrigger; track item.memberName ) { @@ -31,7 +31,7 @@ item of values | filterPivotItems : input.value - : $safeNavigationMigration(grid?.pipeTrigger); + : grid?.pipeTrigger; track item ) { @@ -51,19 +51,19 @@ @for (panel of _panels; track panel) {
- {{ grid?.resourceStrings[panel.i18n] }} + {{ $any(grid?.resourceStrings)[panel.i18n] }}
@@ -76,7 +76,7 @@
@if (this.grid && this.grid[panel.dataKey].length > 0) { @@ -96,13 +96,13 @@
(leave)="onItemDragLeave($event)" (dragMove)="onItemDragMove($event)" (dragEnd)="onItemDragEnd($event)" - (dropped)="onItemDropped($event, panel.type)" + (dropped)="onItemDropped($event, panel.type!)" [id]="item[panel.itemKey]" >
( } {{ - item[panel.displayKey] || item[panel.itemKey] + item[panel.displayKey!] || item[panel.itemKey] }} @if (panel.type === null) { ) diff --git a/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.ts b/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.ts index a402f658c7f..6cd6532f085 100644 --- a/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.ts +++ b/projects/igniteui-angular/grids/pivot-grid/src/pivot-data-selector.component.ts @@ -18,7 +18,8 @@ import { IPivotAggregator, IPivotDimension, IPivotValue, PivotDimensionType, Piv interface IDataSelectorPanel { name: string; i18n: string; - type?: PivotDimensionType; + // The Values panel is not tied to a dimension type, so it is explicitly null. + type?: PivotDimensionType | null; dataKey: string; icon: string; itemKey: string; @@ -183,7 +184,7 @@ export class IgxPivotDataSelectorComponent { @Output() public valuesExpandedChange = new EventEmitter(); - private _grid: PivotGridType; + private _grid!: PivotGridType; private _dropDelta = 0; /** @hidden @internal **/ @@ -196,7 +197,7 @@ export class IgxPivotDataSelectorComponent { } /** @hidden @internal **/ - public dimensions: IPivotDimension[]; + public dimensions!: IPivotDimension[]; private _subMenuPositionSettings: PositionSettings = { verticalStartPoint: VerticalAlignment.Bottom, @@ -229,13 +230,13 @@ export class IgxPivotDataSelectorComponent { /** @hidden @internal */ public aggregateList: IPivotAggregator[] = []; /** @hidden @internal */ - public value: IPivotValue; + public value!: IPivotValue; /** @hidden @internal */ - public ghostText: string; + public ghostText!: string; /** @hidden @internal */ - public ghostWidth: number; + public ghostWidth!: number; /** @hidden @internal */ - public dropAllowed: boolean; + public dropAllowed!: boolean; /** @hidden @internal */ public get dims(): IPivotDimension[] { return this._grid?.allDimensions || []; @@ -325,7 +326,7 @@ export class IgxPivotDataSelectorComponent { if ( !this._panels.find( (panel: IDataSelectorPanel) => panel.type === dimensionType - ).sortable + )!.sortable ) return; @@ -353,7 +354,7 @@ export class IgxPivotDataSelectorComponent { event.preventDefault(); let dim = dimension; - let col: ColumnType; + let col!: ColumnType | undefined; while (dim) { col = this.grid.dimensionDataColumns.find( @@ -362,11 +363,14 @@ export class IgxPivotDataSelectorComponent { if (col) { break; } else { - dim = dim.childLevel; + dim = dim.childLevel as IPivotDimension; } } - this.grid.filteringService.toggleFilterDropdown(event.target, col); + if (!col) { + return; + } + this.grid.filteringService.toggleFilterDropdown(event.target as HTMLElement, col); } /** @@ -391,13 +395,13 @@ export class IgxPivotDataSelectorComponent { * @internal */ protected moveValueItem(itemId: string) { - const aggregation = this.grid.pivotConfiguration.values; + const aggregation = this.grid.pivotConfiguration.values!; const valueIndex = aggregation.findIndex((x) => x.member === itemId) !== -1 ? aggregation?.findIndex((x) => x.member === itemId) : aggregation.length; const newValueIndex = - valueIndex + this._dropDelta < 0 ? 0 : valueIndex + this._dropDelta; + valueIndex! + this._dropDelta < 0 ? 0 : valueIndex! + this._dropDelta; const aggregationItem = aggregation.find( (x) => x.member === itemId || x.displayName === itemId @@ -406,7 +410,7 @@ export class IgxPivotDataSelectorComponent { if (aggregationItem) { this.grid.moveValue(aggregationItem, newValueIndex); this.grid.valuesChange.emit({ - values: this.grid.pivotConfiguration.values, + values: this.grid.pivotConfiguration.values!, }); } } @@ -449,16 +453,16 @@ export class IgxPivotDataSelectorComponent { if (reorder) { targetIndex = - itemIndex + this._dropDelta < 0 + itemIndex! + this._dropDelta < 0 ? 0 - : itemIndex + this._dropDelta; + : itemIndex! + this._dropDelta; } if (dimensionItem) { this.grid.moveDimension(dimensionItem, dimensionType, targetIndex); } else { const newDim = dimensions.find((x) => x.memberName === itemId); - this.grid.moveDimension(newDim, dimensionType, targetIndex); + this.grid.moveDimension(newDim!, dimensionType, targetIndex); } this.grid.dimensionsChange.emit({ diff --git a/projects/igniteui-angular/grids/pivot-grid/src/pivot-filtering.service.ts b/projects/igniteui-angular/grids/pivot-grid/src/pivot-filtering.service.ts index ab6e0706130..a229d1f5250 100644 --- a/projects/igniteui-angular/grids/pivot-grid/src/pivot-filtering.service.ts +++ b/projects/igniteui-angular/grids/pivot-grid/src/pivot-filtering.service.ts @@ -1,12 +1,13 @@ import { Injectable } from '@angular/core'; import { first, takeUntil } from 'rxjs/operators'; -import { DimensionValuesFilteringStrategy, PivotUtil } from 'igniteui-angular/grids/core'; +import { DimensionValuesFilteringStrategy, IPivotDimension, PivotGridType, PivotUtil } from 'igniteui-angular/grids/core'; import { IgxFilteringService } from 'igniteui-angular/grids/core'; -import { ColumnType, FilteringExpressionsTree, FilteringLogic, IFilteringExpressionsTree, IFilteringOperation } from 'igniteui-angular/core'; +import { ColumnType, ExpressionsTreeUtil, FilteringExpressionsTree, FilteringLogic, IFilteringExpressionsTree, IFilteringOperation } from 'igniteui-angular/core'; + @Injectable() export class IgxPivotFilteringService extends IgxFilteringService { - private filtersESFId; + private filtersESFId: any; public override clearFilter(field: string): void { this.clear_filter(field); @@ -14,27 +15,33 @@ export class IgxPivotFilteringService extends IgxFilteringService { public override clear_filter(fieldName: string) { super.clear_filter(fieldName); - const grid = this.grid; - const allDimensions = grid.allDimensions; - const allDimensionsFlat = PivotUtil.flatten(allDimensions); - const dim = allDimensionsFlat.find(x => x.memberName === fieldName); + const grid = this.grid as PivotGridType; + const allDimensions = (grid as PivotGridType).allDimensions; + const allDimensionsFlat = PivotUtil.flatten(allDimensions) as IPivotDimension[]; + const dim = allDimensionsFlat.find((x: any) => x.memberName === fieldName); + if (!dim) { + return; + } dim.filter = undefined; grid.filteringPipeTrigger++; if (allDimensions.indexOf(dim) !== -1) { // update columns - (grid as any).setupColumns(); + grid.setupColumns(); } } - protected override filter_internal(fieldName: string, term, conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree, + protected override filter_internal(fieldName: string, term: any, conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree, ignoreCase: boolean) { super.filter_internal(fieldName, term, conditionOrExpressionsTree, ignoreCase); - const grid = this.grid; + const grid = (this.grid as PivotGridType); const config = grid.pivotConfiguration; - const allDimensions = PivotUtil.flatten(config.rows.concat(config.columns).concat(config.filters).filter(x => x !== null && x !== undefined)); - const enabledDimensions = allDimensions.filter(x => x && x.enabled); - const dim = enabledDimensions.find(x => x.memberName === fieldName || x.member === fieldName); - const filteringTree = dim.filter || new FilteringExpressionsTree(FilteringLogic.And); - const fieldFilterIndex = filteringTree.findIndex(fieldName); + const allDimensions = PivotUtil.flatten((config.rows ?? []).concat(config.columns ?? []).concat(config.filters ?? []).filter((x) => x !== null && x !== undefined)) as IPivotDimension[]; + const enabledDimensions = allDimensions.filter((x) => x && x.enabled); + const dim = enabledDimensions.find((x) => x.memberName === fieldName || x.memberName === fieldName); + if (!dim) { + return; + } + const filteringTree = dim.filter ?? new FilteringExpressionsTree(FilteringLogic.And); + const fieldFilterIndex = ExpressionsTreeUtil.findIndex(filteringTree, fieldName); if (fieldFilterIndex > -1) { filteringTree.filteringOperands.splice(fieldFilterIndex, 1); } diff --git a/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid-navigation.service.ts b/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid-navigation.service.ts index 1e95875805a..c5eac225e6c 100644 --- a/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid-navigation.service.ts +++ b/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid-navigation.service.ts @@ -1,13 +1,13 @@ -import { IActiveNode, IgxGridNavigationService, IMultiRowLayoutNode, IPivotDimension, IPivotGridRecord, PivotSummaryPosition, PivotUtil, HEADER_KEYS, ROW_COLLAPSE_KEYS, ROW_EXPAND_KEYS } from 'igniteui-angular/grids/core'; +import { IActiveNode, IgxGridNavigationService, IPivotDimension, IPivotGridRecord, PivotSummaryPosition, PivotUtil, HEADER_KEYS, ROW_COLLAPSE_KEYS, ROW_EXPAND_KEYS } from 'igniteui-angular/grids/core'; import { Injectable } from '@angular/core'; import { IgxPivotGridComponent } from './pivot-grid.component'; import { IgxPivotRowDimensionMrlRowComponent } from './pivot-row-dimension-mrl-row.component'; import { take, timeout } from 'rxjs/operators'; -import { SortingDirection } from 'igniteui-angular/core'; +import { IMultiRowLayoutNode, SortingDirection } from 'igniteui-angular/core'; @Injectable() export class IgxPivotGridNavigationService extends IgxGridNavigationService { - public override grid: IgxPivotGridComponent; + public override grid!: IgxPivotGridComponent; public isRowHeaderActive = false; public isRowDimensionHeaderActive = false; @@ -16,7 +16,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } public get lastRowDimensionMRLRowIndex() { - return this.grid.verticalRowDimScrollContainers.first.igxGridForOf.length - 1; + return this.grid.verticalRowDimScrollContainers.first.igxGridForOf!.length - 1; } public focusOutRowHeader() { @@ -36,8 +36,8 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { const newActiveNode: IActiveNode = { row: this.activeNode.row, column: this.activeNode.column, - level: null, - mchCache: null, + level: null!, + mchCache: null!, layout: this.activeNode.layout } @@ -72,14 +72,14 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { newActiveNode.column = newPosition.column; newActiveNode.layout = newPosition.layout; } else { - if ((key.includes('left') || key === 'home') && this.activeNode.column > 0) { - newActiveNode.column = ctrl || key === 'home' ? 0 : this.activeNode.column - 1; + if ((key.includes('left') || key === 'home') && this.activeNode.column! > 0) { + newActiveNode.column = ctrl || key === 'home' ? 0 : this.activeNode.column! - 1; } - if ((key.includes('right') || key === 'end') && this.activeNode.column < this.lastRowDimensionsIndex) { - newActiveNode.column = ctrl || key === 'end' ? this.lastRowDimensionsIndex : this.activeNode.column + 1; + if ((key.includes('right') || key === 'end') && this.activeNode.column! < this.lastRowDimensionsIndex) { + newActiveNode.column = ctrl || key === 'end' ? this.lastRowDimensionsIndex : this.activeNode.column! + 1; } - verticalContainer = this.grid.verticalRowDimScrollContainers.toArray()[newActiveNode.column]; + verticalContainer = this.grid.verticalRowDimScrollContainers.toArray()[newActiveNode.column!]; if (key.includes('up')) { if (ctrl) { newActiveNode.row = 0; @@ -88,7 +88,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } else { newActiveNode.row = -1; newActiveNode.column = newActiveNode.layout ? newActiveNode.layout.colStart - 1 : 0; - newActiveNode.layout = null; + newActiveNode.layout = null!; this.isRowDimensionHeaderActive = true; this.isRowHeaderActive = false; this.grid.theadRow.nativeElement.focus(); @@ -96,19 +96,19 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } if (key.includes('down') && this.activeNode.row < this.findLastDataRowIndex()) { - newActiveNode.row = ctrl ? verticalContainer.igxForOf.length - 1 : Math.min(this.activeNode.row + 1, verticalContainer.igxForOf.length - 1); + newActiveNode.row = ctrl ? verticalContainer.igxForOf!.length - 1 : Math.min(this.activeNode.row + 1, verticalContainer.igxForOf!.length - 1); } if (key.includes('left') || key.includes('right')) { const prevRIndex = this.activeNode.row; - const prevScrContainer = this.grid.verticalRowDimScrollContainers.toArray()[this.activeNode.column]; + const prevScrContainer = this.grid.verticalRowDimScrollContainers.toArray()[this.activeNode.column!]; const src = prevScrContainer.getScrollForIndex(prevRIndex); newActiveNode.row = this.activeNode.mchCache && this.activeNode.mchCache.level === newActiveNode.column ? this.activeNode.mchCache.visibleIndex : verticalContainer.getIndexAtScroll(src); newActiveNode.mchCache = { visibleIndex: this.activeNode.row, - level: this.activeNode.column + level: this.activeNode.column! }; } } @@ -128,14 +128,14 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { let rowData, dimIndex; if (!this.grid.hasHorizontalLayout) { dimIndex = this.activeNode.column; - const scrContainer = this.grid.verticalRowDimScrollContainers.toArray()[dimIndex]; - rowData = scrContainer.igxGridForOf[this.activeNode.row]; + const scrContainer = this.grid.verticalRowDimScrollContainers.toArray()[dimIndex!]; + rowData = scrContainer.igxGridForOf![this.activeNode.row]; } else { const mrlRow = this.grid.rowDimensionMrlRowsCollection.find(mrl => mrl.rowIndex === this.activeNode.row); - rowData = mrlRow.rowGroup[this.activeNode.layout.rowStart - 1]; - dimIndex = this.activeNode.layout.colStart - 1; + rowData = mrlRow!.rowGroup[this.activeNode.layout!.rowStart - 1]; + dimIndex = this.activeNode.layout!.colStart - 1; } - const dimension = this.grid.visibleRowDimensions[dimIndex]; + const dimension = this.grid.visibleRowDimensions[dimIndex!]; const expansionRowKey = PivotUtil.getRecordKey(rowData, dimension); const isExpanded = this.grid.expansionStates.get(expansionRowKey) ?? true; @@ -143,9 +143,9 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { if (this.grid.hasHorizontalLayout) { const parentRow = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === this.activeNode.row); prevCellLayout = this.getNextVerticalColumnIndex( - parentRow, - Math.min(parentRow.rowGroup.length, this.activeNode.layout.rowStart), - this.activeNode.layout.colStart); + parentRow!, + Math.min(parentRow!.rowGroup.length, this.activeNode.layout!.rowStart), + this.activeNode.layout!.colStart); } if (ROW_EXPAND_KEYS.has(key) && !isExpanded) { @@ -155,7 +155,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } if ((ROW_EXPAND_KEYS.has(key) && !isExpanded) || (ROW_COLLAPSE_KEYS.has(key) && isExpanded)) { - this.onRowToggle(!isExpanded, dimension, rowData, prevCellLayout); + this.onRowToggle(!isExpanded, dimension, rowData, prevCellLayout!); } this.updateActiveNodeLayout(); this.grid.notifyChanges(); @@ -164,7 +164,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { public updateActiveNodeLayout() { if (this.grid.hasHorizontalLayout) { const mrlRow = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === this.activeNode.row); - const activeCell = mrlRow.contentCells.toArray()[this.activeNode.column]; + const activeCell = mrlRow!.contentCells.toArray()[this.activeNode.column!]; this.activeNode.layout = activeCell.layout; } } @@ -176,12 +176,12 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { dimension.horizontalSummary && this.grid.pivotUI.horizontalSummariesPosition === PivotSummaryPosition.Top) { const maxActiveRow = Math.min(this.lastRowDimensionMRLRowIndex, this.activeNode.row); const parentRowUpdated = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === maxActiveRow); - const maxRowEnd = parentRowUpdated.rowGroup.length + 1; - const nextRowStart = Math.max(1, this.activeNode.layout.rowStart + (!newExpandState ? -1 : 1)); - const curValidRowStart = Math.min(parentRowUpdated.rowGroup.length, nextRowStart); + const maxRowEnd = parentRowUpdated!.rowGroup.length + 1; + const nextRowStart = Math.max(1, this.activeNode.layout!.rowStart + (!newExpandState ? -1 : 1)); + const curValidRowStart = Math.min(parentRowUpdated!.rowGroup.length, nextRowStart); // Get current cell layout, because the actineNode the rowStart might be different, based on where we come from(might be smaller cell). - const curCellLayout = this.getNextVerticalColumnIndex(parentRowUpdated, curValidRowStart, this.activeNode.layout.colStart); + const curCellLayout = this.getNextVerticalColumnIndex(parentRowUpdated!, curValidRowStart, this.activeNode.layout!.colStart); const nextBlock = (!newExpandState && prevCellLayout.rowStart === 1) || (newExpandState && prevCellLayout.rowEnd >= maxRowEnd); this.activeNode.row += nextBlock ? (!newExpandState ? -1 : 1) : 0; this.activeNode.column = curCellLayout.columnVisibleIndex; @@ -202,14 +202,14 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { const newActiveNode: IActiveNode = { row: this.activeNode.row, column: this.activeNode.column, - level: null, + level: null!, mchCache: this.activeNode.mchCache, - layout: null + layout: null! } if (ctrl) { const dimIndex = this.activeNode.column; - const dim = this.grid.visibleRowDimensions[dimIndex]; + const dim = this.grid.visibleRowDimensions[dimIndex!]; if (this.activeNode.row === -1) { if (key.includes('down') || key.includes('up')) { let newSortDirection = SortingDirection.None; @@ -223,11 +223,11 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } } } - if ((key.includes('left') || key === 'home') && this.activeNode.column > 0) { - newActiveNode.column = ctrl || key === 'home' ? 0 : this.activeNode.column - 1; + if ((key.includes('left') || key === 'home') && this.activeNode.column! > 0) { + newActiveNode.column = ctrl || key === 'home' ? 0 : this.activeNode.column! - 1; } - if ((key.includes('right') || key === 'end') && this.activeNode.column < this.lastRowDimensionsIndex) { - newActiveNode.column = ctrl || key === 'end' ? this.lastRowDimensionsIndex : this.activeNode.column + 1; + if ((key.includes('right') || key === 'end') && this.activeNode.column! < this.lastRowDimensionsIndex) { + newActiveNode.column = ctrl || key === 'end' ? this.lastRowDimensionsIndex : this.activeNode.column! + 1; } else if (key.includes('right')) { this.isRowDimensionHeaderActive = false; newActiveNode.column = 0; @@ -244,9 +244,9 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { this.activeNode.layout = { rowStart: 1, rowEnd: 2, - colStart: newActiveNode.column + 1, - colEnd: newActiveNode.column + 2, - columnVisibleIndex: newActiveNode.column + colStart: newActiveNode.column! + 1, + colEnd: newActiveNode.column! + 2, + columnVisibleIndex: newActiveNode.column! }; const newPosition = await this.getNextVerticalPosition(true, ctrl || key === 'home', key === 'home'); @@ -254,13 +254,13 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { newActiveNode.column = newPosition.column; newActiveNode.layout = newPosition.layout; } else { - const verticalContainer = this.grid.verticalRowDimScrollContainers.toArray()[newActiveNode.column]; - newActiveNode.row = ctrl ? verticalContainer.igxForOf.length - 1 : 0; + const verticalContainer = this.grid.verticalRowDimScrollContainers.toArray()[newActiveNode.column!]; + newActiveNode.row = ctrl ? verticalContainer.igxForOf!.length - 1 : 0; } this.isRowDimensionHeaderActive = false; this.isRowHeaderActive = true; - this.grid.rowDimensionContainer.toArray()[this.grid.hasHorizontalLayout ? 0 : newActiveNode.column].nativeElement.focus(); + this.grid.rowDimensionContainer.toArray()[this.grid.hasHorizontalLayout ? 0 : newActiveNode.column!].nativeElement.focus(); } this.setActiveNode(newActiveNode); @@ -269,9 +269,9 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { const newActiveNode: IActiveNode = { row: this.activeNode.row, column: this.lastRowDimensionsIndex, - level: null, + level: null!, mchCache: this.activeNode.mchCache, - layout: null + layout: null! } this.setActiveNode(newActiveNode); @@ -280,7 +280,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } } - public override focusTbody(event) { + public override focusTbody(event: FocusEvent) { if (!this.activeNode || this.activeNode.row === null || this.activeNode.row === undefined) { this.activeNode = this.lastActiveNode; } else { @@ -288,12 +288,12 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } } - public async getNextVerticalPosition(previous, ctrl, homeEnd) { + public async getNextVerticalPosition(previous: boolean, ctrl: boolean, homeEnd: boolean) { const parentRow = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === this.activeNode.row); - const maxRowEnd = parentRow.rowGroup.length + 1; - const curValidRowStart = Math.min(parentRow.rowGroup.length, this.activeNode.layout.rowStart); + const maxRowEnd = parentRow!.rowGroup.length + 1; + const curValidRowStart = Math.min(parentRow!.rowGroup.length, this.activeNode.layout!.rowStart); // Get current cell layout, because the actineNode the rowStart might be different, based on where we come from(might be smaller cell). - const curCellLayout = this.getNextVerticalColumnIndex(parentRow, curValidRowStart, this.activeNode.layout.colStart); + const curCellLayout = this.getNextVerticalColumnIndex(parentRow!, curValidRowStart, this.activeNode.layout!.colStart); const nextBlock = (previous && curCellLayout.rowStart === 1) || (!previous && curCellLayout.rowEnd === maxRowEnd); if (nextBlock && ((previous && this.activeNode.row === 0) || @@ -302,7 +302,7 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { this.isRowDimensionHeaderActive = true; this.isRowHeaderActive = false; this.grid.theadRow.nativeElement.focus(); - return { row: -1, column: this.activeNode.layout.colStart - 1, layout: this.activeNode.layout }; + return { row: -1, column: this.activeNode.layout!.colStart - 1, layout: this.activeNode.layout }; } return { row: this.activeNode.row, column: this.activeNode.column, layout: this.activeNode.layout }; } @@ -313,26 +313,26 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { let nextRow = nextBlock || ctrl ? this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === nextMRLRowIndex) : parentRow; if (!nextRow) { const nextDataViewIndex = previous ? - (ctrl ? 0 : parentRow.rowGroup[curCellLayout.rowStart - 1].dataIndex - 1) : - (ctrl ? this.grid.dataView.length - 1 : parentRow.rowGroup[curCellLayout.rowEnd - 2].dataIndex + 1); + (ctrl ? 0 : parentRow!.rowGroup[curCellLayout.rowStart - 1].dataIndex! - 1) : + (ctrl ? this.grid.dataView.length - 1 : parentRow!.rowGroup[curCellLayout.rowEnd - 2].dataIndex! + 1); await this.scrollToNextHorizontalDimRow(nextDataViewIndex); nextRow = nextBlock || ctrl ? this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === nextMRLRowIndex) : parentRow; } const nextRowStart = nextBlock ? - (previous ? nextRow.rowGroup.length : 1) : + (previous ? nextRow!.rowGroup.length : 1) : (previous ? curCellLayout.rowStart - 1 : curCellLayout.rowEnd); - const maxColEnd = Math.max(...nextRow.contentCells.map(cell => cell.layout.colEnd)); + const maxColEnd = Math.max(...nextRow!.contentCells.map(cell => cell.layout.colEnd)); const nextColumnLayout = this.getNextVerticalColumnIndex( - nextRow, - ctrl ? (previous ? 1 : nextRow.rowGroup.length) : nextRowStart, - homeEnd ? (previous ? 1 : maxColEnd - 1) : this.activeNode.layout.colStart + nextRow!, + ctrl ? (previous ? 1 : nextRow!.rowGroup.length) : nextRowStart, + homeEnd ? (previous ? 1 : maxColEnd - 1) : this.activeNode.layout!.colStart ); const nextDataViewIndex = previous ? - nextRow.rowGroup[nextColumnLayout.rowStart - 1].dataIndex: - nextRow.rowGroup[nextColumnLayout.rowEnd - 2].dataIndex; - await this.scrollToNextHorizontalDimRow(nextDataViewIndex); + nextRow!.rowGroup[nextColumnLayout.rowStart - 1].dataIndex: + nextRow!.rowGroup[nextColumnLayout.rowEnd - 2].dataIndex; + await this.scrollToNextHorizontalDimRow(nextDataViewIndex!); return { row: nextBlock || ctrl ? nextMRLRowIndex : this.activeNode.row, @@ -340,18 +340,18 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { layout: { rowStart: nextColumnLayout.rowStart, rowEnd: nextColumnLayout.rowEnd, - colStart: homeEnd ? nextColumnLayout.colStart : this.activeNode.layout.colStart, + colStart: homeEnd ? nextColumnLayout.colStart : this.activeNode.layout!.colStart, colEnd: nextColumnLayout.colEnd, columnVisibleIndex: nextColumnLayout.columnVisibleIndex } as IMultiRowLayoutNode }; } - public async getNextHorizontalPosition(previous, ctrl) { + public async getNextHorizontalPosition(previous: boolean, ctrl: boolean) { const parentRow = this.grid.rowDimensionMrlRowsCollection.find(row => row.rowIndex === this.activeNode.row); - const maxColEnd = Math.max(...parentRow.contentCells.map(cell => cell.layout.colEnd)); + const maxColEnd = Math.max(...parentRow!.contentCells.map(cell => cell.layout.colEnd)); // Get current cell layout, because the actineNode the rowStart might be different, based on where we come from(might be smaller cell). - const curCellLayout = this.getNextVerticalColumnIndex(parentRow, this.activeNode.layout.rowStart, this.activeNode.layout.colStart); + const curCellLayout = this.getNextVerticalColumnIndex(parentRow!, this.activeNode.layout!.rowStart, this.activeNode.layout!.colStart); if ((previous && curCellLayout.colStart === 1) || (!previous && curCellLayout.colEnd === maxColEnd)) { return { row: this.activeNode.row, column: this.activeNode.column, layout: this.activeNode.layout }; @@ -359,19 +359,19 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { const nextColStartNormal = curCellLayout.colStart + (previous ? -1 : curCellLayout.colEnd - curCellLayout.colStart); const nextColumnLayout = this.getNextVerticalColumnIndex( - parentRow, - this.activeNode.layout.rowStart, + parentRow!, + this.activeNode.layout!.rowStart, ctrl ? (previous ? 1 : maxColEnd - 1) : nextColStartNormal ); - const nextDataViewIndex = parentRow.rowGroup[nextColumnLayout.rowStart - 1].dataIndex - await this.scrollToNextHorizontalDimRow(nextDataViewIndex); + const nextDataViewIndex = parentRow!.rowGroup[nextColumnLayout.rowStart - 1].dataIndex + await this.scrollToNextHorizontalDimRow(nextDataViewIndex!); return { row: this.activeNode.row, column: nextColumnLayout.columnVisibleIndex, layout: { - rowStart: this.activeNode.layout.rowStart, + rowStart: this.activeNode.layout!.rowStart, rowEnd: nextColumnLayout.rowEnd, colStart: nextColumnLayout.colStart, colEnd: nextColumnLayout.colEnd, @@ -394,11 +394,11 @@ export class IgxPivotGridNavigationService extends IgxGridNavigationService { } - private getNextVerticalColumnIndex(nextRow: IgxPivotRowDimensionMrlRowComponent, newRowStart, newColStart) { + private getNextVerticalColumnIndex(nextRow: IgxPivotRowDimensionMrlRowComponent, newRowStart: number, newColStart: number): IMultiRowLayoutNode { const nextCell = nextRow.contentCells.find(cell => { return cell.layout.rowStart <= newRowStart && newRowStart < cell.layout.rowEnd && cell.layout.colStart <= newColStart && newColStart < cell.layout.colEnd; }); - return nextCell.layout; + return nextCell!.layout; } } diff --git a/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.html b/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.html index 69dbf5ec03a..6b3ede852c8 100644 --- a/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.html +++ b/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.html @@ -9,15 +9,15 @@ [pinnedStartColumnCollection]="pinnedStartColumns" [pinnedEndColumnCollection]="pinnedEndColumns" [unpinnedColumnCollection]="unpinnedColumns" - (keydown.meta.c)="copyHandler($event)" - (keydown.control.c)="copyHandler($event)" + (keydown.meta.c)="copyHandler($any($event))" + (keydown.control.c)="copyHandler($any($event))" (copy)="copyHandler($event)" (keydown)="navigation.headerNavigation($event)" (scroll)="preventHeaderScroll($event)" > -