diff --git a/.eslintrc.json b/.eslintrc.json index 435ebed3d..d999020ad 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -126,6 +126,6 @@ "@typescript-eslint/semi": ["error", "always"], "@typescript-eslint/type-annotation-spacing": "error", "@typescript-eslint/unified-signatures": "error", - "@typescript-eslint/no-explicit-any": "off" + "@typescript-eslint/no-explicit-any": "warn" } } diff --git a/packages/qgrid-core/public-api.d.ts b/packages/qgrid-core/public-api.d.ts index 748d44c91..17d2813b9 100644 --- a/packages/qgrid-core/public-api.d.ts +++ b/packages/qgrid-core/public-api.d.ts @@ -525,6 +525,7 @@ export { uniq, yes, } from './src/utility/kit'; +export { Nullable } from './src/utility/types'; // validation export { createValidator, diff --git a/packages/qgrid-core/src/format/format.service.d.ts b/packages/qgrid-core/src/format/format.service.d.ts index 522179d6f..ddaf5b601 100644 --- a/packages/qgrid-core/src/format/format.service.d.ts +++ b/packages/qgrid-core/src/format/format.service.d.ts @@ -1,5 +1,7 @@ +import { Nullable } from '../utility/types'; + export declare class FormatService { - static number(x: number, format: string): string; - static date(x: Date, format: string): string; - static currency(x: number, format: string): string; + static number(x: number, format: string): Nullable; + static date(x: Date, format: string): Nullable; + static currency(x: number, format: string): Nullable; } diff --git a/packages/qgrid-core/src/plugin/grid.plugin.d.ts b/packages/qgrid-core/src/plugin/grid.plugin.d.ts index 0f12ecbbc..5c82adf7f 100644 --- a/packages/qgrid-core/src/plugin/grid.plugin.d.ts +++ b/packages/qgrid-core/src/plugin/grid.plugin.d.ts @@ -1,9 +1,9 @@ -import { Model } from '../model/model'; import { Table } from '../dom/table'; -import { GridLet } from '../grid/grid.let'; -import { ObservableLike } from '../rx/rx'; import { Event } from '../event/event'; +import { GridLet } from '../grid/grid.let'; import { GridService } from '../grid/grid.service'; +import { Model } from '../model/model'; +import { ObservableLike } from '../rx/rx'; export interface GridPlugin { readonly model: Model; diff --git a/packages/qgrid-core/src/row/row.state.d.ts b/packages/qgrid-core/src/row/row.state.d.ts index 091cf7e11..fea472702 100644 --- a/packages/qgrid-core/src/row/row.state.d.ts +++ b/packages/qgrid-core/src/row/row.state.d.ts @@ -30,7 +30,7 @@ export declare class RowState { */ unit: RowStateUnit; - height: (element: HTMLElement, index: number) => number | number; + height: number | ((element: HTMLElement, index: number) => number); /** * Indicates row details status, key is a data row value is a details status. diff --git a/packages/qgrid-core/src/scene/render/render.d.ts b/packages/qgrid-core/src/scene/render/render.d.ts index 6a4a4348c..2c22febd5 100644 --- a/packages/qgrid-core/src/scene/render/render.d.ts +++ b/packages/qgrid-core/src/scene/render/render.d.ts @@ -3,9 +3,11 @@ import { GridPlugin } from '../../plugin/grid.plugin'; import { ColumnView } from '../view/column.view'; import { RenderStrategy } from './render.strategy'; +export type RowsSite = Record<'left' | 'mid' | 'right' | 'bottom' | 'body', any[]>; + export declare class Renderer { defaultStrategy: RenderStrategy; - readonly rows: { left: any[]; right: any[]; mid: any[] }; + readonly rows: RowsSite; constructor(plugin: GridPlugin); diff --git a/packages/qgrid-core/src/utility/types.d.ts b/packages/qgrid-core/src/utility/types.d.ts new file mode 100644 index 000000000..4ff4c9eb9 --- /dev/null +++ b/packages/qgrid-core/src/utility/types.d.ts @@ -0,0 +1 @@ +export declare type Nullable = T | null; diff --git a/packages/qgrid-ngx/.eslintrc.json b/packages/qgrid-ngx/.eslintrc.json index 8e87738e3..7ce9e7dab 100644 --- a/packages/qgrid-ngx/.eslintrc.json +++ b/packages/qgrid-ngx/.eslintrc.json @@ -1,13 +1,13 @@ { "extends": "../../.eslintrc.angular.json", - "parserOptions": { - "project": ["./tsconfig.lib.json"], - "createDefaultProgram": true - }, "overrides": [ { "files": ["*.html"], "parser": "@angular-eslint/template-parser" } - ] + ], + "parserOptions": { + "project": ["./tsconfig.lib.json"], + "createDefaultProgram": true, + } } diff --git a/packages/qgrid-ngx/src/lib/body/body-core.component.ts b/packages/qgrid-ngx/src/lib/body/body-core.component.ts index 043434896..776236632 100644 --- a/packages/qgrid-ngx/src/lib/body/body-core.component.ts +++ b/packages/qgrid-ngx/src/lib/body/body-core.component.ts @@ -65,12 +65,12 @@ export class BodyCoreComponent implements OnInit { scrollSettings, )); - disposable.add(listener.on('wheel', e => host.wheel(e))); - disposable.add(listener.on('mouseleave', e => host.mouseLeave(e))); + disposable.add(listener.on('wheel', (e: WheelEvent) => host.wheel(e))); + disposable.add(listener.on('mouseleave', (e: WheelEvent) => host.mouseLeave(e))); }); observeReply(model.sceneChanged) - .subscribe(e => { + .subscribe((e: any) => { if (model.grid().interactionMode === 'detached') { if (e.hasChanges('status')) { switch (e.state.status) { @@ -86,22 +86,22 @@ export class BodyCoreComponent implements OnInit { }); observe(model.sceneChanged) - .subscribe(e => { + .subscribe((e: any) => { if (e.hasChanges('status') && e.state.status === 'push') { this.cd.markForCheck(); } }); } - columnId(index: number, item: ColumnView) { + columnId(index: number, item: ColumnView): string | undefined { return item.model.key; } - rowId(index: number) { + rowId(index: number): number { return index; } - mapToDataIndex(viewIndex: number) { + mapToDataIndex(viewIndex: number): number { return this.$view.scroll.y.container.position + viewIndex; } } diff --git a/packages/qgrid-ngx/src/lib/body/td-core.directive.ts b/packages/qgrid-ngx/src/lib/body/td-core.directive.ts index dcf77ac77..da948865b 100644 --- a/packages/qgrid-ngx/src/lib/body/td-core.directive.ts +++ b/packages/qgrid-ngx/src/lib/body/td-core.directive.ts @@ -29,7 +29,7 @@ import { TrCoreDirective } from '../row/tr-core.directive'; }) export class TdCoreDirective implements DomTd, OnInit, OnDestroy, OnChanges { @Input('q-grid-core-value') actualValue: any; - @Input('q-grid-core-label') actualLabel: any; + @Input('q-grid-core-label') actualLabel: string; @Input('q-grid-core-td') columnView: ColumnView; diff --git a/packages/qgrid-ngx/src/lib/cell-handler/cell-handler.component.ts b/packages/qgrid-ngx/src/lib/cell-handler/cell-handler.component.ts index 5e606b780..3032ecc31 100644 --- a/packages/qgrid-ngx/src/lib/cell-handler/cell-handler.component.ts +++ b/packages/qgrid-ngx/src/lib/cell-handler/cell-handler.component.ts @@ -14,6 +14,7 @@ import { jobLine, NavigationState, RowDetails, + Nullable } from '@qgrid/core'; import { GridEventArg } from '../grid/grid-model'; import { GridPlugin } from '../plugin/grid-plugin'; @@ -25,7 +26,7 @@ import { GridPlugin } from '../plugin/grid-plugin'; providers: [GridPlugin], }) export class CellHandlerComponent implements OnInit, AfterViewInit { - private endBatchEdit: () => void; + private endBatchEdit: Nullable<() => void>; @ViewChild('marker', { static: true }) marker: ElementRef; diff --git a/packages/qgrid-ngx/src/lib/cell/cell-template.service.ts b/packages/qgrid-ngx/src/lib/cell/cell-template.service.ts index a0e1205f2..f4924eefb 100644 --- a/packages/qgrid-ngx/src/lib/cell/cell-template.service.ts +++ b/packages/qgrid-ngx/src/lib/cell/cell-template.service.ts @@ -2,18 +2,18 @@ import { Injectable, ViewContainerRef } from '@angular/core'; import { ColumnModel, GridError, noop } from '@qgrid/core'; import { TemplateService } from '../template/template.service'; -function canBuild(column) { +function canBuild(column: ColumnModel) { return column.type !== 'pad'; } function buildId(source: string, column: ColumnModel, mode = 'view') { - const { key, type, itemType } = column as any; + const { key, type, itemType } = column; return `${source}-${mode}-cell-${type}-of-${itemType}-the-${key}.tpl.html`; } function buildKeys(source: string, column: ColumnModel, mode = 'view') { - const { key, itemType } = column as any; - let { type } = column as any; + const { key, itemType } = column; + let { type } = column; switch (mode) { case 'view': { @@ -59,7 +59,7 @@ function buildKeys(source: string, column: ColumnModel, mode = 'view') { @Injectable() export class CellTemplateService { - private commits = new Map void>(); + private commits = new Map void>(); constructor(private templateService: TemplateService) { } @@ -80,7 +80,7 @@ export class CellTemplateService { return noop; } - commit = (container: ViewContainerRef, context: any) => { + commit = (container: ViewContainerRef, context: unknown) => { container.clear(); return container.createEmbeddedView(templateLink.template, context); }; diff --git a/packages/qgrid-ngx/src/lib/change-detector/dirty.directive.ts b/packages/qgrid-ngx/src/lib/change-detector/dirty.directive.ts index 872691089..7079941b3 100644 --- a/packages/qgrid-ngx/src/lib/change-detector/dirty.directive.ts +++ b/packages/qgrid-ngx/src/lib/change-detector/dirty.directive.ts @@ -10,7 +10,7 @@ import { selector: '[q-grid-dirty]', }) export class DirtyDirective implements OnChanges { - @Input('q-grid-dirty') trigger: any; + @Input('q-grid-dirty') trigger: unknown; constructor(private cd: ChangeDetectorRef) { } diff --git a/packages/qgrid-ngx/src/lib/column-list/column-list.service.ts b/packages/qgrid-ngx/src/lib/column-list/column-list.service.ts index 286913801..7a23cc516 100644 --- a/packages/qgrid-ngx/src/lib/column-list/column-list.service.ts +++ b/packages/qgrid-ngx/src/lib/column-list/column-list.service.ts @@ -11,7 +11,7 @@ import { GridPlugin } from '../plugin/grid-plugin'; @Injectable() export class ColumnListService { private host = new Lazy(() => { - const canCopy = (key: string, source, target) => + const canCopy = (key: string, source: any, target: any) => Object.prototype.hasOwnProperty.call(target, key) && !isUndefined(source[key]); return new ColumnListHost(this.plugin.model, canCopy, parseFactory); @@ -20,27 +20,27 @@ export class ColumnListService { constructor(private plugin: GridPlugin) { } - add(column: ColumnModel) { + add(column: ColumnModel): void { this.host.instance.add(column); } - copy(target, source) { + copy(target: any, source: any): void { this.host.instance.copy(target, source); } - generateKey(source) { + generateKey(source: any): string { return this.host.instance.generateKey(source); } - extract(key, type): ColumnModel { + extract(key: string, type: string): ColumnModel { return this.host.instance.extract(key, type); } - register(column: ColumnModel) { + register(column: ColumnModel): void { this.host.instance.register(column); } - delete(key: string) { + delete(key: string): void { this.host.instance.delete(key); } } diff --git a/packages/qgrid-ngx/src/lib/column/column-body-template.directive.ts b/packages/qgrid-ngx/src/lib/column/column-body-template.directive.ts index db2e32976..6afe59e77 100644 --- a/packages/qgrid-ngx/src/lib/column/column-body-template.directive.ts +++ b/packages/qgrid-ngx/src/lib/column/column-body-template.directive.ts @@ -11,7 +11,7 @@ export class ColumnBodyTemplateDirective implements OnInit { constructor( private templateCache: TemplateCacheService, - private templateRef: TemplateRef, + private templateRef: TemplateRef, ) { } diff --git a/packages/qgrid-ngx/src/lib/column/column-edit-template.directive.ts b/packages/qgrid-ngx/src/lib/column/column-edit-template.directive.ts index 2dd441e99..9b3a8571f 100644 --- a/packages/qgrid-ngx/src/lib/column/column-edit-template.directive.ts +++ b/packages/qgrid-ngx/src/lib/column/column-edit-template.directive.ts @@ -11,7 +11,7 @@ export class ColumnEditTemplateDirective implements OnInit { constructor( private templateCache: TemplateCacheService, - private templateRef: TemplateRef, + private templateRef: TemplateRef, ) { } diff --git a/packages/qgrid-ngx/src/lib/column/column-foot-template.directive.ts b/packages/qgrid-ngx/src/lib/column/column-foot-template.directive.ts index 53194cbfa..63665625a 100644 --- a/packages/qgrid-ngx/src/lib/column/column-foot-template.directive.ts +++ b/packages/qgrid-ngx/src/lib/column/column-foot-template.directive.ts @@ -11,7 +11,7 @@ export class ColumnFootTemplateDirective implements OnInit { constructor( private templateCache: TemplateCacheService, - private templateRef: TemplateRef, + private templateRef: TemplateRef, ) { } diff --git a/packages/qgrid-ngx/src/lib/column/column-head-template.directive.ts b/packages/qgrid-ngx/src/lib/column/column-head-template.directive.ts index 9e309fa79..e329c73c8 100644 --- a/packages/qgrid-ngx/src/lib/column/column-head-template.directive.ts +++ b/packages/qgrid-ngx/src/lib/column/column-head-template.directive.ts @@ -11,7 +11,7 @@ export class ColumnHeadTemplateDirective implements OnInit { constructor( private templateCache: TemplateCacheService, - private templateRef: TemplateRef, + private templateRef: TemplateRef, ) { } diff --git a/packages/qgrid-ngx/src/lib/column/column.component.ts b/packages/qgrid-ngx/src/lib/column/column.component.ts index 4fd09857c..133d665ac 100644 --- a/packages/qgrid-ngx/src/lib/column/column.component.ts +++ b/packages/qgrid-ngx/src/lib/column/column.component.ts @@ -18,6 +18,7 @@ import { ColumnModelWidthMode, guid, isUndefined, + Row, } from '@qgrid/core'; import { ColumnListService } from '../column-list/column-list.service'; import { GridPlugin } from '../plugin/grid-plugin'; @@ -73,17 +74,17 @@ export class ColumnComponent implements OnInit, OnDestroy, OnChanges { @Input() index: number; - @Input() label: ((row: any, value?: any) => any) | any; + @Input() label: ((row: Row, value?: unknown) => string) | any; @Input() labelPath: string; - @Input() itemLabel: (row: any, value?: any) => any; + @Input() itemLabel: (row: any, value?: unknown) => string; @Input() itemFormat: string; @Input() itemType: string; - @Input() value: (row: any, value?: any) => any; + @Input() value: (row: Row, value?: unknown) => any; @Input() path: string; - @Input() compare: (x: any, y: any) => number; + @Input() compare: (x: number, y: number) => number; @Input() trueValue: any; @Input() falseValue: any; @@ -109,7 +110,7 @@ export class ColumnComponent implements OnInit, OnDestroy, OnChanges { // We want to update model when ngOntInit is triggered and not in afterViewInit // so we apply dirty hack to understand if column is cohort or not. const element = this.elementRef.nativeElement as HTMLElement; - if (element.children.length && element.children.item(0).tagName === 'Q-GRID-COLUMN') { + if (element.children.length && element.children.item(0)?.tagName === 'Q-GRID-COLUMN') { this.type = 'cohort'; if (!withKey) { this.key = `$cohort-${this.title || guid()}`; @@ -142,7 +143,7 @@ export class ColumnComponent implements OnInit, OnDestroy, OnChanges { if (withKey) { if (this.parentHost) { - this.parentHost.column.children.push(column); + this.parentHost.column.children?.push(column); } else { this.columnList.add(column); } @@ -152,9 +153,9 @@ export class ColumnComponent implements OnInit, OnDestroy, OnChanges { const settings = Object .keys(this) - .filter(key => !isUndefined(this[key]) && Object.prototype.hasOwnProperty.call(column, key)) - .reduce((memo, key) => { - memo[key] = column[key]; + .filter(key => !isUndefined(this.key) && Object.prototype.hasOwnProperty.call(column, key)) + .reduce((memo: { [key: string]: ColumnModel }, key: string) => { + memo[key] = column[key as keyof ColumnModel]; return memo; }, {}) as ColumnModel; @@ -180,7 +181,7 @@ export class ColumnComponent implements OnInit, OnDestroy, OnChanges { ngOnDestroy() { const { column } = this.selfHost; - if (column && column.source === 'template') { + if (column && column.key && column.source === 'template') { this.columnList.delete(column.key); } } diff --git a/packages/qgrid-ngx/src/lib/dnd/drag.directive.ts b/packages/qgrid-ngx/src/lib/dnd/drag.directive.ts index 93f1513e5..88d43f445 100644 --- a/packages/qgrid-ngx/src/lib/dnd/drag.directive.ts +++ b/packages/qgrid-ngx/src/lib/dnd/drag.directive.ts @@ -13,7 +13,7 @@ import { GridPlugin } from '../plugin/grid-plugin'; selector: '[q-grid-drag]', }) export class DragDirective { - @Input('q-grid-drag-data') data: any; + @Input('q-grid-drag-data') data: string | number | undefined | Node; @Input('q-grid-drag-effect') effect: undefined | 'move'; @Input('q-grid-drag') drag: Command; @Input('q-grid-drop-area') area: string; @@ -38,7 +38,9 @@ export class DragDirective { if (this.drag.canExecute(eventArg) === false) { e.preventDefault(); - transfer.effectAllowed = 'none'; + if (transfer) { + transfer.effectAllowed = 'none'; + } return false; } @@ -50,8 +52,10 @@ export class DragDirective { this.elementRef.nativeElement.classList.add(`${GRID_PREFIX}-drag`); - transfer.setData(DragService.mimeType, DragService.encode(data)); - transfer.effectAllowed = this.effect || 'move'; + if(transfer) { + transfer.setData(DragService.mimeType, DragService.encode(data)); + transfer.effectAllowed = this.effect || 'move'; + } DragService.data = data; DragService.area = this.area; @@ -78,8 +82,5 @@ export class DragDirective { this.elementRef.nativeElement.classList.remove(`${GRID_PREFIX}-drag`); DragService.data = null; - DragService.area = null; - DragService.element = null; - DragService.startPosition = null; } } diff --git a/packages/qgrid-ngx/src/lib/dnd/drop.directive.ts b/packages/qgrid-ngx/src/lib/dnd/drop.directive.ts index 70baae7bf..c7b3ba9c5 100644 --- a/packages/qgrid-ngx/src/lib/dnd/drop.directive.ts +++ b/packages/qgrid-ngx/src/lib/dnd/drop.directive.ts @@ -86,6 +86,7 @@ export class DropDirective implements OnInit { this.elementRef.nativeElement.classList.remove(`${GRID_PREFIX}-dragover`); const eventArg = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any path: (e as any).path, dragData: DragService.data, dropData: this.dropData, @@ -105,7 +106,9 @@ export class DropDirective implements OnInit { e.preventDefault(); this.elementRef.nativeElement.classList.add(`${GRID_PREFIX}-dragover`); - e.dataTransfer.dropEffect = 'move'; + if (e.dataTransfer) { + e.dataTransfer.dropEffect = 'move'; + } return false; } @@ -117,7 +120,9 @@ export class DropDirective implements OnInit { } if (this.area !== DragService.area) { - e.dataTransfer.dropEffect = 'none'; + if (e.dataTransfer) { + e.dataTransfer.dropEffect = 'none'; + } return false; } @@ -142,7 +147,9 @@ export class DropDirective implements OnInit { DragService.data = eventArg.dragData; } - e.dataTransfer.dropEffect = 'move'; + if(e.dataTransfer) { + e.dataTransfer.dropEffect = 'move'; + } } return false; diff --git a/packages/qgrid-ngx/src/lib/foot/tf-core.directive.ts b/packages/qgrid-ngx/src/lib/foot/tf-core.directive.ts index 1e3428f2a..e96d9fce4 100644 --- a/packages/qgrid-ngx/src/lib/foot/tf-core.directive.ts +++ b/packages/qgrid-ngx/src/lib/foot/tf-core.directive.ts @@ -21,7 +21,7 @@ export class TfCoreDirective implements DomTd, OnInit, OnDestroy { @Input('q-grid-core-tf') columnView: ColumnView; $implicit = this; - element: HTMLElement = null; + element: HTMLElement; get value() { const column = this.column; @@ -29,7 +29,7 @@ export class TfCoreDirective implements DomTd, OnInit, OnDestroy { } get label() { - return this.label; + return this.value; } get column(): ColumnModel { diff --git a/packages/qgrid-ngx/src/lib/grid/grid.component.ts b/packages/qgrid-ngx/src/lib/grid/grid.component.ts index 62d45192f..b74ba9b26 100644 --- a/packages/qgrid-ngx/src/lib/grid/grid.component.ts +++ b/packages/qgrid-ngx/src/lib/grid/grid.component.ts @@ -32,6 +32,7 @@ import { GroupStateMode, GroupStateSummary, PivotState, + Row, ScrollState, ScrollStateMode, SelectionState, @@ -131,7 +132,7 @@ export class GridComponent implements OnInit, OnChanges { @Input() set pivotBy(by: Array) { this.pivotState({ by }); } - @Input('selection') set selectionItems(items: Array) { this.selectionState({ items }); } + @Input('selection') set selectionItems(items: Array) { this.selectionState({ items }); } @Input() set selectionArea(area: SelectionStateArea) { this.selectionState({ area }); } @Input() set selectionMode(mode: SelectionStateMode) { this.selectionState({ mode }); } @Input() set selectionUnit(unit: SelectionStateUnit) { this.selectionState({ unit }); } @@ -154,7 +155,7 @@ export class GridComponent implements OnInit, OnChanges { private cd: ChangeDetectorRef, private stateAccessor: StateAccessor, private modelBuilder: GridModelBuilder, - @Inject(DOCUMENT) private document: any, + @Inject(DOCUMENT) private document: Document, theme: ThemeService, ) { if (!theme.component) { diff --git a/packages/qgrid-ngx/src/lib/grid/grid.module.ts b/packages/qgrid-ngx/src/lib/grid/grid.module.ts index 2963d7050..0dc0549d4 100644 --- a/packages/qgrid-ngx/src/lib/grid/grid.module.ts +++ b/packages/qgrid-ngx/src/lib/grid/grid.module.ts @@ -22,7 +22,6 @@ import { GridComponent } from './grid.component'; ], imports: [ CommonModule, - BoxModule, LayerModule, MarkupModule, @@ -47,10 +46,11 @@ export class GridModule { numberPipe: DecimalPipe, currencyPipe: CurrencyPipe, ) { - FormatService.date = (x, format) => datePipe.transform(x, format); + FormatService.date = (x: Date, format: string) => datePipe.transform(x, format); FormatService.number = (x, format) => numberPipe.transform(x, format); FormatService.currency = (x, format) => currencyPipe.transform(x, format); + // eslint-disable-next-line @typescript-eslint/no-explicit-any Fastdom.invoke = task => zone.runOutsideAngular(task); } } diff --git a/packages/qgrid-ngx/src/lib/head/th-core.directive.ts b/packages/qgrid-ngx/src/lib/head/th-core.directive.ts index 34bf51096..111cf837d 100644 --- a/packages/qgrid-ngx/src/lib/head/th-core.directive.ts +++ b/packages/qgrid-ngx/src/lib/head/th-core.directive.ts @@ -22,8 +22,9 @@ export class ThCoreDirective implements DomTd, OnInit, OnDestroy { $implicit = this; element: HTMLElement; + // eslint-disable-next-line @typescript-eslint/no-explicit-any value: any; - label: any; + label: string; get column(): ColumnModel { return this.columnView.model; diff --git a/packages/qgrid-ngx/src/lib/infrastructure/disposable.ts b/packages/qgrid-ngx/src/lib/infrastructure/disposable.ts index cef20a8ad..a09a25d36 100644 --- a/packages/qgrid-ngx/src/lib/infrastructure/disposable.ts +++ b/packages/qgrid-ngx/src/lib/infrastructure/disposable.ts @@ -5,7 +5,7 @@ import { Disposable as DisposableCore, DisposableResource } from '@qgrid/core'; export class Disposable implements OnDestroy { private disposable = new DisposableCore(); - add(resource: DisposableResource) { + add(resource: DisposableResource): void { this.disposable.add(resource); } @@ -13,7 +13,7 @@ export class Disposable implements OnDestroy { return this.disposable.remove(resource); } - finalize() { + finalize(): void { this.disposable.finalize(); } diff --git a/packages/qgrid-ngx/src/lib/layer/layer.service.ts b/packages/qgrid-ngx/src/lib/layer/layer.service.ts index 583d4c5bc..0c4159ecb 100644 --- a/packages/qgrid-ngx/src/lib/layer/layer.service.ts +++ b/packages/qgrid-ngx/src/lib/layer/layer.service.ts @@ -14,13 +14,13 @@ export class LayerService { constructor(private templateService: TemplateService) { } - init(container: ViewContainerRef) { + init(container: ViewContainerRef): void { this.container = container; } - create(name) { + create(name: string): Layer { if (this.layers.has(name)) { - return this.layers.get(name); + return this.layers.get(name) as Layer; } const { container, templateService } = this; @@ -47,7 +47,7 @@ export class LayerService { return layer; } - private getHostElement() { + private getHostElement(): HTMLElement | null { const { nativeElement } = this.container.element; for (let el = nativeElement; el; el = el.parentElement) { if (el.tagName === 'Q-GRID') { diff --git a/packages/qgrid-ngx/src/lib/plugin/grid-plugin.ts b/packages/qgrid-ngx/src/lib/plugin/grid-plugin.ts index bc6bb62b9..b673aa680 100644 --- a/packages/qgrid-ngx/src/lib/plugin/grid-plugin.ts +++ b/packages/qgrid-ngx/src/lib/plugin/grid-plugin.ts @@ -4,7 +4,6 @@ import { GridLet, Lazy, ObservableEvent, - ObservableLike, ObservableReplyEvent, } from '@qgrid/core'; import { DomTable } from '../dom/dom'; @@ -12,10 +11,11 @@ import { Grid, GridService } from '../grid/grid'; import { GridLet as NgxGridLet } from '../grid/grid-let'; import { GridModel } from '../grid/grid-model'; import { GridRoot } from '../grid/grid-root'; +import { GridPlugin as GridPluginInterface } from '@qgrid/core'; import { Disposable } from '../infrastructure/disposable'; @Injectable() -export class GridPlugin implements OnDestroy { +export class GridPlugin implements OnDestroy, GridPluginInterface { private serviceLazy = new Lazy(() => this.qgrid.service(this.$root.model)); readonly disposable = new Disposable(); @@ -45,9 +45,9 @@ export class GridPlugin implements OnDestroy { ) { } - readonly observe = (event: Event): ObservableLike => new ObservableEvent(event, this.disposable); + readonly observe = (event: Event): ObservableEvent => new ObservableEvent(event, this.disposable); - readonly observeReply = (event: Event): ObservableLike => new ObservableReplyEvent(event, this.disposable); + readonly observeReply = (event: Event): ObservableReplyEvent => new ObservableReplyEvent(event, this.disposable); ngOnDestroy() { this.disposable.finalize(); diff --git a/packages/qgrid-ngx/src/lib/resize/autosize.directive.ts b/packages/qgrid-ngx/src/lib/resize/autosize.directive.ts index f79f4d08b..57e5b15dc 100644 --- a/packages/qgrid-ngx/src/lib/resize/autosize.directive.ts +++ b/packages/qgrid-ngx/src/lib/resize/autosize.directive.ts @@ -9,7 +9,7 @@ export class AutoSizeDirective implements OnInit { private host: HTMLElement; private element: HTMLInputElement; - @Input('q-grid-autosize') selector; + @Input('q-grid-autosize') selector: string; @Input('q-grid-autosize-empty-width') emptyWidth = 75; @Input('q-grid-autosize-value') set value(value: string) { @@ -24,7 +24,7 @@ export class AutoSizeDirective implements OnInit { this.element = this.selector ? this.host.querySelector(this.selector) as HTMLInputElement : this.host as HTMLInputElement; } - autoWidth(text) { + autoWidth(text: string) { if (!text) { this.actualText = text; Fastdom.measure(() => { diff --git a/packages/qgrid-ngx/src/lib/resize/resize.directive.ts b/packages/qgrid-ngx/src/lib/resize/resize.directive.ts index dcee61c70..b43d4bbaf 100644 --- a/packages/qgrid-ngx/src/lib/resize/resize.directive.ts +++ b/packages/qgrid-ngx/src/lib/resize/resize.directive.ts @@ -37,16 +37,16 @@ export class ResizeDirective implements OnInit, OnDestroy { return this.plugin.model; } - @Input('q-grid-resize') key; - @Input('q-grid-resize-path') path; - @Input('q-grid-can-resize') canResize; - @Input('q-grid-resize-selector') selector; + @Input('q-grid-resize') key?: string; + @Input('q-grid-resize-path') path: string; + @Input('q-grid-can-resize') canResize: (e: Record) => boolean; + @Input('q-grid-resize-selector') selector: string; constructor( private zone: NgZone, @Optional() private plugin: GridPlugin, private qgrid: Grid, - @Inject(DOCUMENT) document: any, + @Inject(DOCUMENT) document: Document, elementRef: ElementRef, ) { this.element = elementRef.nativeElement; @@ -88,8 +88,8 @@ export class ResizeDirective implements OnInit, OnDestroy { const context = this.context; const host = this.select(); - context.width = host.clientWidth; - context.height = host.clientHeight; + context.width = host?.clientWidth as number; + context.height = host?.clientHeight as number; context.x = e.screenX; context.y = e.screenY; @@ -106,7 +106,7 @@ export class ResizeDirective implements OnInit, OnDestroy { const { context, path, key } = this; const { layout } = this.model; - const state = clone(layout()[path]); + const state = clone(layout()[path as keyof typeof layout]); state.set(key, { width: context.width + e.screenX - context.x, @@ -123,7 +123,7 @@ export class ResizeDirective implements OnInit, OnDestroy { model.drag({ isActive: false }); } - private select(): HTMLElement { + private select(): HTMLElement | null { if (this.selector === 'parent') { return this.element.parentElement; } diff --git a/packages/qgrid-ngx/src/lib/row/row.component.ts b/packages/qgrid-ngx/src/lib/row/row.component.ts index e568c755f..d2838dcda 100644 --- a/packages/qgrid-ngx/src/lib/row/row.component.ts +++ b/packages/qgrid-ngx/src/lib/row/row.component.ts @@ -11,6 +11,7 @@ import { RowState, RowStateMode, RowStateUnit, + Td, } from '@qgrid/core'; import { GridPlugin } from '../plugin/grid-plugin'; import { StateAccessor } from '../state/state-accessor'; @@ -46,14 +47,14 @@ export class RowComponent implements OnChanges, OnInit { }, }); - @Input() behavior = []; + @Input() behavior: string[] = []; @Input() set mode(mode: RowStateMode) { this.rowAccessor({ mode }); } @Input() set unit(unit: RowStateUnit) { this.rowAccessor({ unit }); } @Input() set canMove(canMove: boolean) { this.rowAccessor({ canMove }); } @Input() set canResize(canResize: boolean) { this.rowAccessor({ canResize }); } - @Input() set minHeight(minHeight) { this.rowAccessor({ minHeight }); } - @Input() set height(height) { this.rowAccessor({ height }); } + @Input() set minHeight(minHeight: number) { this.rowAccessor({ minHeight }); } + @Input() set height(height: number | ((element: HTMLElement, index: number) => number)) { this.rowAccessor({ height }); } constructor( private plugin: GridPlugin, @@ -104,7 +105,7 @@ export class RowComponent implements OnChanges, OnInit { } if (this.behavior.indexOf('expandOnDblClick') >= 0) { - let firstClickTarget = null; + let firstClickTarget: Td | null = null; observe(model.mouseChanged) .subscribe(e => { @@ -115,10 +116,13 @@ export class RowComponent implements OnChanges, OnInit { firstClickTarget = target; } else { const dblClickInterval = 300; - if (firstClickTarget === target && timestamp.newValue - timestamp.oldValue <= dblClickInterval) { - if (target.column.type !== 'row-expand') { - if (this.toggleStatus.canExecute(target.row)) { - this.toggleStatus.execute(target.row); + const timestampNewValue = timestamp.newValue ?? 0; + const timestampOldValue = timestamp.oldValue ?? 0; + const delay = timestampNewValue - timestampOldValue; + if (firstClickTarget === target && delay <= dblClickInterval) { + if (target?.column.type !== 'row-expand') { + if (this.toggleStatus.canExecute(target?.row)) { + this.toggleStatus.execute(target?.row); } } } diff --git a/packages/qgrid-ngx/src/lib/row/tr-core.directive.ts b/packages/qgrid-ngx/src/lib/row/tr-core.directive.ts index c4dfacd41..2eff467da 100644 --- a/packages/qgrid-ngx/src/lib/row/tr-core.directive.ts +++ b/packages/qgrid-ngx/src/lib/row/tr-core.directive.ts @@ -5,6 +5,7 @@ import { OnDestroy, OnInit, } from '@angular/core'; +import { Bag } from '@qgrid/core'; import { DomTr } from '../dom/dom'; import { GridLet } from '../grid/grid-let'; import { GridPlugin } from '../plugin/grid-plugin'; @@ -14,8 +15,8 @@ import { GridPlugin } from '../plugin/grid-plugin'; }) export class TrCoreDirective implements DomTr, OnInit, OnDestroy { @Input('q-grid-core-index') viewIndex: number; - @Input('q-grid-core-tr') model: any; - @Input('q-grid-core-source') source; + @Input('q-grid-core-tr') model: unknown; + @Input('q-grid-core-source') source: string; element: HTMLElement; @@ -32,10 +33,10 @@ export class TrCoreDirective implements DomTr, OnInit, OnDestroy { } ngOnInit() { - this.plugin.table.box.bag[this.source].addRow(this); + this.plugin.table.box.bag[this.source as keyof { body: Bag; head: Bag; foot: Bag }].addRow(this); } ngOnDestroy() { - this.plugin.table.box.bag[this.source].deleteRow(this); + this.plugin.table.box.bag[this.source as keyof { body: Bag; head: Bag; foot: Bag }].deleteRow(this); } } diff --git a/packages/qgrid-ngx/src/lib/row/trh-core.directive.ts b/packages/qgrid-ngx/src/lib/row/trh-core.directive.ts index 7a7e36745..5fb898c12 100644 --- a/packages/qgrid-ngx/src/lib/row/trh-core.directive.ts +++ b/packages/qgrid-ngx/src/lib/row/trh-core.directive.ts @@ -5,6 +5,7 @@ import { OnDestroy, OnInit, } from '@angular/core'; +import { Bag } from '@qgrid/core'; import { DomTr } from '../dom/dom'; import { GridLet } from '../grid/grid-let'; import { GridPlugin } from '../plugin/grid-plugin'; @@ -14,8 +15,8 @@ import { GridPlugin } from '../plugin/grid-plugin'; }) export class TrhCoreDirective implements DomTr, OnInit, OnDestroy { @Input('q-grid-core-index') index: number; - @Input('q-grid-core-trh') model: any; - @Input('q-grid-core-source') source; + @Input('q-grid-core-trh') model: unknown; + @Input('q-grid-core-source') source: string; element: HTMLElement; @@ -28,10 +29,10 @@ export class TrhCoreDirective implements DomTr, OnInit, OnDestroy { } ngOnInit() { - this.plugin.table.box.bag[this.source].addRow(this); + this.plugin.table.box.bag[this.source as keyof { body: Bag; head: Bag; foot: Bag }].addRow(this); } ngOnDestroy() { - this.plugin.table.box.bag[this.source].deleteRow(this); + this.plugin.table.box.bag[this.source as keyof { body: Bag; head: Bag; foot: Bag }].deleteRow(this); } } diff --git a/packages/qgrid-ngx/src/lib/state/state-accessor.ts b/packages/qgrid-ngx/src/lib/state/state-accessor.ts index 8be3e7693..b7ce6e5a3 100644 --- a/packages/qgrid-ngx/src/lib/state/state-accessor.ts +++ b/packages/qgrid-ngx/src/lib/state/state-accessor.ts @@ -14,7 +14,7 @@ export class StateAccessor { }; } - write(model: GridModel) { + write(model: GridModel): void { for (const setter of this.setters) { setter(model); } diff --git a/packages/qgrid-ngx/src/lib/table/table.module.ts b/packages/qgrid-ngx/src/lib/table/table.module.ts index e2991c49f..4f6bab817 100644 --- a/packages/qgrid-ngx/src/lib/table/table.module.ts +++ b/packages/qgrid-ngx/src/lib/table/table.module.ts @@ -17,7 +17,6 @@ import { VscrollModule } from '../vscroll/vscroll.module'; ], imports: [ CommonModule, - HeadModule, FootModule, BodyModule, diff --git a/packages/qgrid-ngx/src/lib/template/template-cache.directive.ts b/packages/qgrid-ngx/src/lib/template/template-cache.directive.ts index 3a08397e9..3f915a9a5 100644 --- a/packages/qgrid-ngx/src/lib/template/template-cache.directive.ts +++ b/packages/qgrid-ngx/src/lib/template/template-cache.directive.ts @@ -18,7 +18,7 @@ export class TemplateCacheDirective implements OnInit { constructor( private templateCache: TemplateCacheService, - private templateRef: TemplateRef, + private templateRef: TemplateRef, @Optional() private templateHost: TemplateHostService) { } diff --git a/packages/qgrid-ngx/src/lib/template/template-cache.service.ts b/packages/qgrid-ngx/src/lib/template/template-cache.service.ts index 4f3b283c7..82880b803 100644 --- a/packages/qgrid-ngx/src/lib/template/template-cache.service.ts +++ b/packages/qgrid-ngx/src/lib/template/template-cache.service.ts @@ -8,7 +8,7 @@ export class TemplateCacheService { constructor() { } - get(key: string): TemplateLink { + get(key: string): TemplateLink | undefined { return this.cache.get(key); } diff --git a/packages/qgrid-ngx/src/lib/template/template-link.directive.ts b/packages/qgrid-ngx/src/lib/template/template-link.directive.ts index 9f1cace7c..daf1311a6 100644 --- a/packages/qgrid-ngx/src/lib/template/template-link.directive.ts +++ b/packages/qgrid-ngx/src/lib/template/template-link.directive.ts @@ -9,7 +9,7 @@ export class TemplateLinkDirective implements OnInit { @Input() key = ''; @Input() context = {}; - constructor(private templateLink: TemplateLinkService, private templateRef: TemplateRef) { + constructor(private templateLink: TemplateLinkService, private templateRef: TemplateRef) { } ngOnInit() { diff --git a/packages/qgrid-ngx/src/lib/template/template-link.service.ts b/packages/qgrid-ngx/src/lib/template/template-link.service.ts index ccba2bcfb..86673f506 100644 --- a/packages/qgrid-ngx/src/lib/template/template-link.service.ts +++ b/packages/qgrid-ngx/src/lib/template/template-link.service.ts @@ -5,11 +5,11 @@ import { TemplateLink } from './template-link'; export class TemplateLinkService { private cache: Map = new Map(); - get(key: string): TemplateLink { + get(key: string): TemplateLink | undefined { return this.cache.get(key); } - put(key: string, value: TemplateLink) { + put(key: string, value: TemplateLink): void { this.cache.set(key, value); } } diff --git a/packages/qgrid-ngx/src/lib/template/template-link.ts b/packages/qgrid-ngx/src/lib/template/template-link.ts index 7e431bb1d..475f2b807 100644 --- a/packages/qgrid-ngx/src/lib/template/template-link.ts +++ b/packages/qgrid-ngx/src/lib/template/template-link.ts @@ -1,6 +1,6 @@ import { TemplateRef } from '@angular/core'; export class TemplateLink { - constructor(public template: TemplateRef, public context: any) { + constructor(public template: TemplateRef, public context: unknown) { } } diff --git a/packages/qgrid-ngx/src/lib/template/template.directive.ts b/packages/qgrid-ngx/src/lib/template/template.directive.ts index 4c390f78b..e4e111caa 100644 --- a/packages/qgrid-ngx/src/lib/template/template.directive.ts +++ b/packages/qgrid-ngx/src/lib/template/template.directive.ts @@ -9,16 +9,17 @@ import { SimpleChanges, OnChanges, } from '@angular/core'; +import { Nullable } from '@qgrid/core'; import { TemplateService } from './template.service'; @Directive({ selector: 'ng-container[key]', // eslint-disable-line @angular-eslint/directive-selector }) export class TemplateDirective implements DoCheck, OnChanges { - private viewRef: EmbeddedViewRef; + private viewRef: EmbeddedViewRef | null; @Input() key = ''; - @Input() context: any = null; + @Input() context: Nullable<{ $implicit: Object }> = null; @Input() check = false; constructor( diff --git a/packages/qgrid-ngx/src/lib/template/template.service.ts b/packages/qgrid-ngx/src/lib/template/template.service.ts index 8afc5f6a6..9fdf147c4 100644 --- a/packages/qgrid-ngx/src/lib/template/template.service.ts +++ b/packages/qgrid-ngx/src/lib/template/template.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { isArray, isString } from '@qgrid/core'; +import { isArray, isString, Nullable } from '@qgrid/core'; import { TemplateCacheService } from './template-cache.service'; import { TemplateLink } from './template-link'; import { TemplateLinkService } from './template-link.service'; @@ -11,7 +11,7 @@ export class TemplateService { private templateCache: TemplateCacheService, ) { } - find(keys: string | string[]): TemplateLink { + find(keys: string | string[]): Nullable { if (isString(keys)) { const key = keys as string; const link = this.templateCache.get(key) || this.templateLink.get(key); @@ -19,11 +19,13 @@ export class TemplateService { } if (isArray(keys)) { - return this.lookInCache(keys) || this.lookInLink(keys); + return this.lookInCache(keys as string[]) || this.lookInLink(keys as string[]); } + + return null; } - private lookInCache(keys) { + private lookInCache(keys: string[]) { for (const key of keys) { const link = this.templateCache.get(key); if (link) { @@ -34,7 +36,7 @@ export class TemplateService { return null; } - private lookInLink(keys) { + private lookInLink(keys: string[]) { for (const key of keys) { const link = this.templateLink.get(key); if (link) { diff --git a/packages/qgrid-ngx/src/lib/theme/theme.service.ts b/packages/qgrid-ngx/src/lib/theme/theme.service.ts index a1e4e3246..021219163 100644 --- a/packages/qgrid-ngx/src/lib/theme/theme.service.ts +++ b/packages/qgrid-ngx/src/lib/theme/theme.service.ts @@ -11,7 +11,7 @@ export class ThemeService { private themeName = ''; changed = new Event(); - component: any; + component: unknown; get name() { return this.themeName; diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll-column.directive.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll-column.directive.ts index 19e839b53..620a2642e 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll-column.directive.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll-column.directive.ts @@ -14,6 +14,7 @@ import { VscrollPortYDirective } from './vscroll-port-y.directive'; }) export class VscrollColumnDirective implements OnDestroy, OnChanges { private column: HTMLElement; + private onChangesRan = false; private get layout() { return this.port.layout; @@ -34,9 +35,12 @@ export class VscrollColumnDirective implements OnDestroy, OnChanges { } ngOnChanges(changes: SimpleChanges) { + if (this.onChangesRan) { + return; + } if (changes['index']) { if (this.port.getItemSize()) { - this.ngOnChanges = null; + this.onChangesRan = true; return; } @@ -47,21 +51,21 @@ export class VscrollColumnDirective implements OnDestroy, OnChanges { const change = e['index']; const newIndex = change.currentValue; const oldIndex = change.previousValue; - layout.removeItem(oldIndex); + layout?.removeItem(oldIndex); const size = sizeFactory(rowHeight, container, column, newIndex); - layout.setItem(newIndex, size); + layout?.setItem(newIndex, size); } }; const firstChange = changes['index']; const firstIndex = firstChange.currentValue; const firstSize = sizeFactory(rowHeight, container, column, firstIndex); - layout.setItem(firstIndex, firstSize); + layout?.setItem(firstIndex, firstSize); } } ngOnDestroy() { - this.port.layout.removeItem(this.index); + this.port.layout?.removeItem(this.index); } } diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-x.directive.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-x.directive.ts index 4c4200a5d..a6c82e526 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-x.directive.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-x.directive.ts @@ -5,7 +5,7 @@ import { OnChanges, SimpleChanges, } from '@angular/core'; -import { isNumber } from '@qgrid/core'; +import { isNumber, Nullable } from '@qgrid/core'; import { VscrollBox } from './vscroll.box'; import { VscrollContext } from './vscroll.context'; import { VscrollDirective } from './vscroll.directive'; @@ -19,12 +19,12 @@ import { capitalize } from './vscroll.utility'; selector: '[q-grid-vscroll-port-x]', }) export class VscrollPortXDirective implements VscrollPort, OnChanges { - private link: VscrollLink = null; + private link: VscrollLink; @Input('q-grid-vscroll-port-x') context: VscrollContext; markup: { [key: string]: HTMLElement } = {}; - layout: VscrollLayout = null; + layout: Nullable = null; constructor( private elementRef: ElementRef, @@ -41,11 +41,11 @@ export class VscrollPortXDirective implements VscrollPort, OnChanges { } } - reset() { + reset(): void { this.view.resetX(); } - emit(f: () => void) { + emit(f: () => void): void { const { settings } = this.context; if (settings.emit) { @@ -71,7 +71,7 @@ export class VscrollPortXDirective implements VscrollPort, OnChanges { return findPositionUsingOffsets(value, offsets); } - move(left: number, right: number) { + move(left: number, right: number): void { this.pad('left', left); this.pad('right', right); } @@ -81,15 +81,15 @@ export class VscrollPortXDirective implements VscrollPort, OnChanges { return isNumber(columnWidth) ? columnWidth : 0; } - getScrollSize(box: VscrollBox) { + getScrollSize(box: VscrollBox): number { return box.scrollWidth; } - getSize(box: VscrollBox) { + getSize(box: VscrollBox): number { return box.portWidth; } - recycleFactory(items: Array) { + recycleFactory(items: Array<(() => number)>): (index: number, count: number) => Array { const recycle = recycleFactory(items); return (index: number, count: number) => { const size = this.getItemSize(); @@ -101,11 +101,11 @@ export class VscrollPortXDirective implements VscrollPort, OnChanges { }; } - hasChanges(newBox: VscrollBox, oldBox: VscrollBox) { + hasChanges(newBox: VscrollBox, oldBox: VscrollBox): boolean { return !oldBox.portWidth || newBox.scrollWidth !== oldBox.scrollWidth; } - private pad(pos: string, value: number) { + private pad(pos: string, value: number): void { if (Object.prototype.hasOwnProperty.call(this.markup, pos)) { const mark = this.markup[pos]; mark.style.width = value + 'px'; diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-y.directive.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-y.directive.ts index 0d52834d7..35d44ce8a 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-y.directive.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll-port-y.directive.ts @@ -5,7 +5,7 @@ import { OnChanges, SimpleChanges, } from '@angular/core'; -import { isNumber } from '@qgrid/core'; +import { isNumber, Nullable } from '@qgrid/core'; import { VscrollBox } from './vscroll.box'; import { VscrollContext } from './vscroll.context'; import { VscrollDirective } from './vscroll.directive'; @@ -19,11 +19,11 @@ import { capitalize } from './vscroll.utility'; selector: '[q-grid-vscroll-port-y]', }) export class VscrollPortYDirective implements VscrollPort, OnChanges { - private link: VscrollLink = null; + private link: VscrollLink; @Input('q-grid-vscroll-port-y') context: VscrollContext; - layout: VscrollLayout = null; + layout: Nullable = null; markup: { [key: string]: HTMLElement } = {}; constructor( @@ -41,11 +41,11 @@ export class VscrollPortYDirective implements VscrollPort, OnChanges { } } - public reset() { + reset(): void { this.view.resetY(); } - emit(f: () => void) { + emit(f: () => void): void { const { settings } = this.context; if (settings.emit) { settings.emit(f); @@ -68,7 +68,7 @@ export class VscrollPortYDirective implements VscrollPort, OnChanges { return findPositionUsingOffsets(value, offsets); } - move(top: number, bottom: number) { + move(top: number, bottom: number): void { this.pad('top', top); this.pad('bottom', bottom); } @@ -78,15 +78,15 @@ export class VscrollPortYDirective implements VscrollPort, OnChanges { return isNumber(rowHeight) ? rowHeight : 0; } - getScrollSize(box: VscrollBox) { + getScrollSize(box: VscrollBox): number { return box.scrollHeight; } - getSize(box: VscrollBox) { + getSize(box: VscrollBox): number { return box.portHeight; } - recycleFactory(items: Array) { + recycleFactory(items: Array<(() => number)>): (index: number, count: number) => Array { const recycle = recycleFactory(items); return (index: number, count: number) => { const size = this.getItemSize(); @@ -98,11 +98,11 @@ export class VscrollPortYDirective implements VscrollPort, OnChanges { }; } - hasChanges(newBox: VscrollBox, oldBox: VscrollBox) { + hasChanges(newBox: VscrollBox, oldBox: VscrollBox): boolean { return !oldBox.portHeight || newBox.scrollTop !== oldBox.scrollTop; } - private pad(pos: string, value: number) { + private pad(pos: string, value: number): void { if (Object.prototype.hasOwnProperty.call(this.markup, pos)) { const mark = this.markup[pos]; mark.style.height = value + 'px'; diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll-row.directive.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll-row.directive.ts index efa3ec01d..24b0a3a83 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll-row.directive.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll-row.directive.ts @@ -36,6 +36,7 @@ export class VscrollRowDirective implements OnDestroy, OnChanges { ngOnChanges(changes: SimpleChanges) { if (changes['index']) { if (this.port.getItemSize()) { + // @ts-ignore: Type null is not assignable to type (changes: SimpleChanges) => void this.ngOnChanges = null; return; } @@ -47,21 +48,21 @@ export class VscrollRowDirective implements OnDestroy, OnChanges { const change = e['index']; const newIndex = change.currentValue; const oldIndex = change.previousValue; - layout.removeItem(oldIndex); + layout?.removeItem(oldIndex); const size = sizeFactory(rowHeight, container, row, newIndex); - layout.setItem(newIndex, size); + layout?.setItem(newIndex, size); } }; const firstChange = changes['index']; const firstNewIndex = firstChange.currentValue; const firstSize = sizeFactory(rowHeight, container, row, firstNewIndex); - layout.setItem(firstNewIndex, firstSize); + layout?.setItem(firstNewIndex, firstSize); } } ngOnDestroy() { - this.port.layout.removeItem(this.index); + this.port.layout?.removeItem(this.index); } } diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll.layout.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll.layout.ts index 69e090d6c..5c8441dd6 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll.layout.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll.layout.ts @@ -9,7 +9,7 @@ function empty() { } export class VscrollLayout { - private items = []; + private items: (() => number)[] = []; private minArm = UNSET_ARM; private position = findPositionUsingOffsets(0, []); private getOffsets = recycleFactory(this.items); diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll.link.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll.link.ts index a9a90b6dc..7fd6baaf2 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll.link.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll.link.ts @@ -25,7 +25,7 @@ export class VscrollLink { if (settings.placeholderHeight > 0 || settings.placeholderWidth > 0) { const width = settings.placeholderWidth || (isNumber(settings.columnWidth) && settings.columnWidth as number); const height = settings.placeholderHeight || (isNumber(settings.rowHeight) && settings.rowHeight as number); - view.drawPlaceholder(width, height); + view.drawPlaceholder(width as number, height as number); } view.scroll.subscribe(() => this.update(false)); @@ -44,7 +44,9 @@ export class VscrollLink { return; } - container.position = layout.reset(); + if (layout) { + container.position = layout.reset(); + } port.reset(); container.fetchPage(0); @@ -58,16 +60,21 @@ export class VscrollLink { const { port, container, box } = this; const count = container.count; + if(!port.layout) { + return; + } const position = port.layout.recycle(count, box, force); if (position) { const draw = () => { - container.position = port.layout.invalidate(position); - container.draw$.emit({ - position: container.position, - }); + if (port.layout) { + container.position = port.layout.invalidate(position); + container.draw$.emit({ + position: container.position, + }); + } }; - const emit = f => port.emit(f); + const emit = (f: () => void) => port.emit(f); container.apply(draw, emit); } } diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll.pipe.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll.pipe.ts index 17ac40f14..744fb3d6f 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll.pipe.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll.pipe.ts @@ -17,7 +17,7 @@ export class VscrollPipe implements OnDestroy, PipeTransform { constructor(private cd: ChangeDetectorRef) { } - transform(data: any[], context: IVscrollContext): ObservableLike { + transform(data: any[], context: IVscrollContext): ObservableLike { this.disposable.finalize(); if (!context) { diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll.port.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll.port.ts index 424805c71..0c3212390 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll.port.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll.port.ts @@ -2,26 +2,27 @@ import { VscrollBox } from './vscroll.box'; import { IVscrollPosition } from './vscroll.position'; import { VscrollLayout } from './vscroll.layout'; import { VscrollContext } from './vscroll.context'; +import { Nullable } from '@qgrid/core'; export function applyHTML(element: HTMLElement) { element.tabIndex = 0; element.style.outline = 'none'; - (element.style as any).overflowAnchor = 'none'; + element.style.overflowAnchor = 'none'; } export interface VscrollPort { markup: { [key: string]: HTMLElement }; - layout: VscrollLayout; + layout: Nullable; context: VscrollContext; - reset(); - hasChanges(newBox: VscrollBox, oldBox: VscrollBox); - emit(f: () => void); - move(pad1: number, pad2: number); + reset(): void; + hasChanges(newBox: VscrollBox, oldBox: VscrollBox): boolean; + emit(f: () => void): void; + move(pad1: number, pad2: number): void; recycleFactory(items: Array<(() => number)>): (index: number, count: number) => Array; getPositionUsingOffsets(offsets: Array, box: VscrollBox, arm: number): IVscrollPosition; getPositionUsingItemSize(itemsSize: number, box: VscrollBox, arm: number): IVscrollPosition; - getItemSize(); - getScrollSize(box: VscrollBox); - getSize(box: VscrollBox); + getItemSize(): number; + getScrollSize(box: VscrollBox): number; + getSize(box: VscrollBox): number; } diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll.position.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll.position.ts index 7662ba607..8a4c24d21 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll.position.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll.position.ts @@ -1,4 +1,4 @@ -function findIndexAt(items: Array, value: number) { +function findIndexAt(items: Array, value: number): number { const length = items.length; let min = 0; let max = length - 1; diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll.service.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll.service.ts index c33490622..a51319747 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll.service.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll.service.ts @@ -4,7 +4,7 @@ import { VscrollContext } from './vscroll.context'; @Injectable() export class VscrollService { - context(settings: Partial = {}) { + context(settings: Partial = {}): VscrollContext { const context = new VscrollContext(); Object.assign(context.settings, settings); diff --git a/packages/qgrid-ngx/src/lib/vscroll/vscroll.utility.ts b/packages/qgrid-ngx/src/lib/vscroll/vscroll.utility.ts index 29900bc96..a29aea3cf 100644 --- a/packages/qgrid-ngx/src/lib/vscroll/vscroll.utility.ts +++ b/packages/qgrid-ngx/src/lib/vscroll/vscroll.utility.ts @@ -10,10 +10,12 @@ export function placeholderBitmap(width: number, height: number) { canvas.height = Math.max(height * 2, 1); const ctx = canvas.getContext('2d'); - ctx.fillStyle = 'rgba(0, 0, 0, 0.04)'; - ctx.fillRect(0, 0, minWidth, minHeight); - ctx.fillStyle = 'rgba(0, 0, 0, 0.08)'; - ctx.fillRect(width, height, minWidth, minHeight); + if (ctx) { + ctx.fillStyle = 'rgba(0, 0, 0, 0.04)'; + ctx.fillRect(0, 0, minWidth, minHeight); + ctx.fillStyle = 'rgba(0, 0, 0, 0.08)'; + ctx.fillRect(width, height, minWidth, minHeight); + } return canvas.toDataURL(); } diff --git a/packages/qgrid-ngx/tsconfig.lib.json b/packages/qgrid-ngx/tsconfig.lib.json index c8c95961d..44dce243d 100644 --- a/packages/qgrid-ngx/tsconfig.lib.json +++ b/packages/qgrid-ngx/tsconfig.lib.json @@ -20,7 +20,14 @@ "lib": [ "dom", "esnext" - ] + ], + "alwaysStrict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictPropertyInitialization": false, + "strictFunctionTypes": true, + "noImplicitThis": true, + "strictBindCallApply": true, }, "angularCompilerOptions": { "skipTemplateCodegen": true,