From 3c70df026668bcc4d71aba04368c77e946aeeb7c Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 27 Feb 2025 17:15:57 +0100 Subject: [PATCH 001/105] fix: allow partial overrides of CSS classes (#151) --- .../src/lib/components/datatable.component.ts | 10 +--------- .../lib/components/footer/footer.component.ts | 8 ++++---- .../src/lib/components/footer/pager.component.ts | 16 ++++++++-------- .../components/header/header-cell.component.ts | 12 ++++++------ .../lib/components/header/header.component.ts | 6 +++--- 5 files changed, 22 insertions(+), 30 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 0e77d9708..429ba3f60 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -349,15 +349,7 @@ export class DatatableComponent /** * Css class overrides */ - @Input() cssClasses: Partial = { - sortAscending: 'datatable-icon-up', - sortDescending: 'datatable-icon-down', - sortUnset: 'datatable-icon-sort-unset', - pagerLeftArrow: 'datatable-icon-left', - pagerRightArrow: 'datatable-icon-right', - pagerPrevious: 'datatable-icon-prev', - pagerNext: 'datatable-icon-skip' - }; + @Input() cssClasses: Partial = {}; /** * Message overrides for localization diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts index d9ccb0fb6..559bcad0d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts @@ -56,10 +56,10 @@ export class DataTableFooterComponent { @Input() rowCount: number; @Input() pageSize: number; @Input() offset: number; - @Input() pagerLeftArrowIcon: string; - @Input() pagerRightArrowIcon: string; - @Input() pagerPreviousIcon: string; - @Input() pagerNextIcon: string; + @Input() pagerLeftArrowIcon?: string; + @Input() pagerRightArrowIcon?: string; + @Input() pagerPreviousIcon?: string; + @Input() pagerNextIcon?: string; @Input() totalMessage: string; @Input() footerTemplate: DatatableFooterDirective; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts index 5c83b200e..02bc90e97 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts @@ -8,12 +8,12 @@ import { Page } from '../../types/internal.types';
  • - +
  • - +
  • @for (pg of pages; track pg.number) { @@ -30,12 +30,12 @@ import { Page } from '../../types/internal.types'; }
  • - +
  • - +
@@ -47,10 +47,10 @@ import { Page } from '../../types/internal.types'; standalone: true }) export class DataTablePagerComponent { - @Input() pagerLeftArrowIcon: string; - @Input() pagerRightArrowIcon: string; - @Input() pagerPreviousIcon: string; - @Input() pagerNextIcon: string; + @Input() pagerLeftArrowIcon?: string; + @Input() pagerRightArrowIcon?: string; + @Input() pagerPreviousIcon?: string; + @Input() pagerNextIcon?: string; @Input() set size(val: number) { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts index 74e1bc4f2..12cd857d9 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts @@ -63,9 +63,9 @@ export class DataTableHeaderCellComponent implements OnInit { private cd = inject(ChangeDetectorRef); @Input() sortType: SortType; - @Input() sortAscendingIcon: string; - @Input() sortDescendingIcon: string; - @Input() sortUnsetIcon: string; + @Input() sortAscendingIcon?: string; + @Input() sortDescendingIcon?: string; + @Input() sortUnsetIcon?: string; @Input() isTarget: boolean; @Input() targetMarkerTemplate: TemplateRef; @@ -255,11 +255,11 @@ export class DataTableHeaderCellComponent implements OnInit { return; } if (sortDir === SortDirection.asc) { - return `sort-btn sort-asc ${this.sortAscendingIcon}`; + return `sort-btn sort-asc ${this.sortAscendingIcon ?? 'datatable-icon-up'}`; } else if (sortDir === SortDirection.desc) { - return `sort-btn sort-desc ${this.sortDescendingIcon}`; + return `sort-btn sort-desc ${this.sortDescendingIcon ?? 'datatable-icon-down'}`; } else { - return `sort-btn ${this.sortUnsetIcon}`; + return `sort-btn ${this.sortUnsetIcon ?? 'datatable-icon-sort-unset'}`; } } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index b5a0023ff..8636024ce 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -107,9 +107,9 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { private cd = inject(ChangeDetectorRef); private scrollbarHelper = inject(ScrollbarHelper); - @Input() sortAscendingIcon: string; - @Input() sortDescendingIcon: string; - @Input() sortUnsetIcon: string; + @Input() sortAscendingIcon?: string; + @Input() sortDescendingIcon?: string; + @Input() sortUnsetIcon?: string; @Input() scrollbarH: boolean; @Input() dealsWithGroup: boolean; @Input() targetMarkerTemplate: TemplateRef; From 0c7c2fa6e1d02b7ec316adaff647b1e2b184ca9d Mon Sep 17 00:00:00 2001 From: Maxi Date: Sun, 2 Mar 2025 12:44:28 +0100 Subject: [PATCH 002/105] refactor: use interface for row properties that may be set by the datatable (#153) --- .../src/lib/components/body/body-cell.component.ts | 5 ++--- .../src/lib/components/body/body.component.ts | 8 +++----- .../src/lib/components/datatable.component.ts | 3 ++- .../ngx-datatable/src/lib/types/public.types.ts | 10 ++++++++++ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 6936306f2..00b77acbc 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -22,6 +22,7 @@ import { BehaviorSubject } from 'rxjs'; import { ActivateEvent, CellContext, + Row, RowOrGroup, SortDirection, SortPropDir, @@ -87,9 +88,7 @@ import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; `, imports: [NgTemplateOutlet, DataTableGhostLoaderComponent, AsyncPipe] }) -export class DataTableBodyCellComponent - implements DoCheck, OnDestroy -{ +export class DataTableBodyCellComponent implements DoCheck, OnDestroy { private cd = inject(ChangeDetectorRef); @Input() displayCheck: (row: RowOrGroup, column: TableColumn, value: any) => boolean; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index bfd027042..b80ce2e4d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -28,10 +28,10 @@ import { ActivateEvent, DragEventData, Group, + Row, RowOrGroup, ScrollEvent, - SelectionType, - TreeStatus + SelectionType } from '../../types/public.types'; import { DraggableDirective } from '../../directives/draggable.directive'; import { DatatableRowDefInternalDirective } from './body-row-def.component'; @@ -265,9 +265,7 @@ import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.compo DraggableDirective ] }) -export class DataTableBodyComponent - implements OnInit, OnDestroy -{ +export class DataTableBodyComponent implements OnInit, OnDestroy { cd = inject(ChangeDetectorRef); @Input() rowDefTemplate?: TemplateRef; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 429ba3f60..8fdd9f7e5 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -56,6 +56,7 @@ import { PageEvent, PagerPageEvent, ReorderEvent, + Row, RowOrGroup, ScrollEvent, SelectionType, @@ -94,7 +95,7 @@ import { ProgressBarComponent } from './body/progress-bar.component'; ProgressBarComponent ] }) -export class DatatableComponent +export class DatatableComponent implements OnInit, DoCheck, AfterViewInit, AfterContentInit, OnDestroy { private scrollbarHelper = inject(ScrollbarHelper); diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index 027992c63..7b2731006 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -109,6 +109,16 @@ export interface RowDetailContext { disableRow$?: Observable; } +/** + * Consumer provided rows should extend this interface + * to get access to implicit row properties which are set by the datatable if required. + */ +export interface Row { + [key: TableColumnProp]: any; + treeStatus?: TreeStatus; + level?: number; +} + export interface ReorderEvent { column: TableColumn; prevValue: number; From 652216343a435de93d0e300ba9a30c0b4024541e Mon Sep 17 00:00:00 2001 From: Maxi Date: Mon, 10 Mar 2025 09:27:31 +0100 Subject: [PATCH 003/105] fix: allow partial overrides of messages (#152) --- .../lib/components/datatable.component.html | 94 ++++++++++--------- .../src/lib/components/datatable.component.ts | 25 ++--- .../src/lib/ngx-datatable.module.ts | 9 +- 3 files changed, 66 insertions(+), 62 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html index d51309697..188001db2 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html @@ -1,33 +1,33 @@
@if (headerHeight) { - - + + } -
+
+
+
@if (footerHeight) { - - + + }
diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 8fdd9f7e5..4a86e6e19 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -355,21 +355,16 @@ export class DatatableComponent /** * Message overrides for localization * - * emptyMessage [default] = 'No data to display' - * totalMessage [default] = 'total' - * selectedMessage [default] = 'selected' - */ - @Input() messages: Partial = { - // Message to show when array is presented - // but contains no values - emptyMessage: 'No data to display', - - // Footer total message - totalMessage: 'total', - - // Footer selected message - selectedMessage: 'selected' - }; + * @defaultValue + * ``` + * { + * emptyMessage: 'No data to display', + * totalMessage: 'total', + * selectedMessage: 'selected' + * } + * ``` + */ + @Input() messages: Partial = {}; /** * A function which is called with the row and should return either: diff --git a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts index 4d22bbf5f..1acac6a3d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts +++ b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts @@ -74,9 +74,12 @@ export class NgxDatatableModule { */ export interface INgxDatatableConfig { messages?: { - emptyMessage: string; // Message to show when array is presented, but contains no values - totalMessage: string; // Footer total message - selectedMessage: string; // Footer selected message + /** Message to show when the array is present but empty */ + emptyMessage: string; + /** Footer total message */ + totalMessage: string; + /** Footer selected message */ + selectedMessage: string; }; cssClasses?: { sortAscending: string; From 724a6ae237632ec11934ae90e0bf7b3e776c8674 Mon Sep 17 00:00:00 2001 From: Maximilian Koeller Date: Wed, 26 Feb 2025 15:13:00 +0100 Subject: [PATCH 004/105] refactor: only export symbols that are meant to be exported BREAKING CHANGE: Removed several symbols from the public API that were intended to be internal. --- .../src/lib/ngx-datatable.module.ts | 3 -- .../swimlane/ngx-datatable/src/public-api.ts | 35 ------------------- 2 files changed, 38 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts index 1acac6a3d..694a27be7 100644 --- a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts +++ b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts @@ -2,7 +2,6 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { DataTableFooterTemplateDirective } from './components/footer/footer-template.directive'; import { DatatableComponent } from './components/datatable.component'; import { DataTableColumnDirective } from './components/columns/column.directive'; -import { DataTablePagerComponent } from './components/footer/pager.component'; import { DatatableRowDetailDirective } from './components/row-detail/row-detail.directive'; import { DatatableGroupHeaderDirective } from './components/body/body-group-header.directive'; import { DatatableRowDetailTemplateDirective } from './components/row-detail/row-detail-template.directive'; @@ -23,7 +22,6 @@ import { DataTableFooterTemplateDirective, DatatableComponent, DataTableColumnDirective, - DataTablePagerComponent, DatatableRowDetailDirective, DatatableGroupHeaderDirective, DatatableRowDetailTemplateDirective, @@ -49,7 +47,6 @@ import { DataTableColumnCellTreeToggle, DataTableFooterTemplateDirective, DatatableFooterDirective, - DataTablePagerComponent, DatatableGroupHeaderTemplateDirective, DisableRowDirective, DatatableRowDefComponent, diff --git a/projects/swimlane/ngx-datatable/src/public-api.ts b/projects/swimlane/ngx-datatable/src/public-api.ts index 876bb569f..6969d6e21 100644 --- a/projects/swimlane/ngx-datatable/src/public-api.ts +++ b/projects/swimlane/ngx-datatable/src/public-api.ts @@ -5,20 +5,8 @@ // components export * from './lib/ngx-datatable.module'; export * from './lib/components/datatable.component'; -export * from './lib/components/header/header.component'; -export * from './lib/components/header/header-cell.component'; -export * from './lib/components/body/body.component'; -export * from './lib/components/body/body-cell.component'; -export * from './lib/components/body/body-row.component'; -export * from './lib/components/body/progress-bar.component'; -export * from './lib/components/body/scroller.component'; -export * from './lib/components/body/body-row-wrapper.component'; -export * from './lib/components/body/selection.component'; export * from './lib/components/body/body-group-header.directive'; export * from './lib/components/body/body-group-header-template.directive'; -export * from './lib/components/body/summary/summary-row.component'; -export * from './lib/components/footer/footer.component'; -export * from './lib/components/footer/pager.component'; export * from './lib/components/footer/footer.directive'; export * from './lib/components/footer/footer-template.directive'; export * from './lib/components/columns/column.directive'; @@ -31,31 +19,8 @@ export * from './lib/components/row-detail/row-detail-template.directive'; export * from './lib/components/body/body-row-def.component'; // directives -export * from './lib/directives/draggable.directive'; -export * from './lib/directives/long-press.directive'; -export * from './lib/directives/orderable.directive'; -export * from './lib/directives/resizeable.directive'; -export * from './lib/directives/visibility.directive'; export * from './lib/directives/disable-row.directive'; -// services -export * from './lib/services/scrollbar-helper.service'; -export * from './lib/services/column-changes.service'; - // types export * from './lib/types/public.types'; export * from './lib/types/table-column.type'; - -// utils -export * from './lib/utils/id'; -export * from './lib/utils/column'; -export * from './lib/utils/column-prop-getters'; -export * from './lib/utils/camel-case'; -export * from './lib/utils/keys'; -export * from './lib/utils/math'; -export * from './lib/utils/selection'; -export * from './lib/utils/throttle'; -export * from './lib/utils/sort'; -export * from './lib/utils/row-height-cache'; -export * from './lib/utils/column-helper'; -export * from './lib/utils/tree'; From bd5eca0f0c5f40c02122e8fcf56d8aebd965c82a Mon Sep 17 00:00:00 2001 From: Maxi Date: Mon, 10 Mar 2025 16:58:06 +0100 Subject: [PATCH 005/105] refactor: simplify column directive converting (#154) --- .../src/lib/components/datatable.component.ts | 14 +++++-- .../src/lib/utils/column-helper.ts | 42 ------------------- 2 files changed, 10 insertions(+), 46 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 4a86e6e19..2d5f7c941 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -33,7 +33,7 @@ import { BehaviorSubject, Subscription } from 'rxjs'; import { INgxDatatableConfig } from '../ngx-datatable.module'; import { groupRowsByParents, optionalGetterForProp } from '../utils/tree'; import { TableColumn } from '../types/table-column.type'; -import { setColumnDefaults, translateTemplates } from '../utils/column-helper'; +import { setColumnDefaults } from '../utils/column-helper'; import { DataTableColumnDirective } from './columns/column.directive'; import { DatatableRowDetailDirective } from './row-detail/row-detail.directive'; import { DatatableFooterDirective } from './footer/footer.directive'; @@ -789,9 +789,15 @@ export class DatatableComponent */ translateColumns(val: QueryList>) { if (val) { - const arr = val.toArray(); - if (arr.length) { - this._internalColumns = translateTemplates(arr); + if (val.length) { + this._internalColumns = val.map(column => ({ + ...column, + // explicitly call getters + headerTemplate: column.headerTemplate, + cellTemplate: column.cellTemplate, + summaryTemplate: column.summaryTemplate, + ghostCellTemplate: column.ghostCellTemplate + })); setColumnDefaults(this._internalColumns, this._defaultColumnWidth); this.recalculateColumns(); if (!this.externalSorting && this.rows?.length) { diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts b/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts index a7388fb23..2d896067c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts @@ -2,7 +2,6 @@ import { camelCase, deCamelCase } from './camel-case'; import { id } from './id'; import { getterForProp } from './column-prop-getters'; import { TableColumn } from '../types/table-column.type'; -import { DataTableColumnDirective } from '../components/columns/column.directive'; /** * Sets the column defaults @@ -80,44 +79,3 @@ export function setColumnDefaults(columns: TableColumn[], defaultColumnWidth = 1 export function isNullOrUndefined(value: T | null | undefined): value is null | undefined { return value === null || value === undefined; } - -/** - * Translates templates definitions to objects - */ -export function translateTemplates( - templates: DataTableColumnDirective[] -): TableColumn[] { - const result: TableColumn[] = []; - for (const temp of templates) { - const col: TableColumn = {}; - - const props = Object.getOwnPropertyNames(temp); - for (const prop of props) { - col[prop] = temp[prop]; - } - - if (temp.headerTemplate) { - col.headerTemplate = temp.headerTemplate; - } - - if (temp.cellTemplate) { - col.cellTemplate = temp.cellTemplate; - } - - if (temp.ghostCellTemplate) { - col.ghostCellTemplate = temp.ghostCellTemplate; - } - - if (temp.summaryFunc) { - col.summaryFunc = temp.summaryFunc; - } - - if (temp.summaryTemplate) { - col.summaryTemplate = temp.summaryTemplate; - } - - result.push(col); - } - - return result; -} From 156fb64aa17b89a82cd6d8e21a895ebe60d57875 Mon Sep 17 00:00:00 2001 From: Maxi Date: Mon, 10 Mar 2025 17:54:05 +0100 Subject: [PATCH 006/105] refactor: always use type event (#158) --- .../components/body/body-cell.component.ts | 4 ++-- .../components/body/selection.component.ts | 22 ++++++++++++++----- .../src/lib/types/public.types.ts | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 00b77acbc..6a646cfbb 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -308,7 +308,7 @@ export class DataTableBodyCellComponent implements DoChe constructor() { this.cellContext = { - onCheckboxChangeFn: (event: MouseEvent | KeyboardEvent) => this.onCheckboxChange(event), + onCheckboxChangeFn: (event: Event) => this.onCheckboxChange(event), activateFn: (event: ActivateEvent) => this.activate.emit(event), row: this.row, group: this.group, @@ -428,7 +428,7 @@ export class DataTableBodyCellComponent implements DoChe } } - onCheckboxChange(event: MouseEvent | KeyboardEvent): void { + onCheckboxChange(event: Event): void { this.activate.emit({ type: 'checkbox', event, diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts index 23a6719bf..aceae9672 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts @@ -23,7 +23,7 @@ export class DataTableSelectionComponent { prevIndex: number; - selectRow(event: KeyboardEvent | MouseEvent, index: number, row: TRow): void { + selectRow(event: Event, index: number, row: TRow): void { if (!this.selectEnabled) { return; } @@ -33,13 +33,22 @@ export class DataTableSelectionComponent { const multiClick = this.selectionType === SelectionType.multiClick; let selected: TRow[] = []; + // TODO: this code needs cleanup. Casting it to KeyboardEvent is not correct as it could also be other types. if (multi || chkbox || multiClick) { - if (event.shiftKey) { + if ((event as KeyboardEvent).shiftKey) { selected = selectRowsBetween([], this.rows, index, this.prevIndex); - } else if ((event as KeyboardEvent).key === 'a' && (event.ctrlKey || event.metaKey)) { + } else if ( + (event as KeyboardEvent).key === 'a' && + ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) + ) { // select all rows except dummy rows which are added for ghostloader in case of virtual scroll selected = this.rows.filter(rowItem => !!rowItem); - } else if (event.ctrlKey || event.metaKey || multiClick || chkbox) { + } else if ( + (event as KeyboardEvent).ctrlKey || + (event as KeyboardEvent).metaKey || + multiClick || + chkbox + ) { selected = selectRows([...this.selected], row, this.getRowSelectedIdx.bind(this)); } else { selected = selectRows([], row, this.getRowSelectedIdx.bind(this)); @@ -77,7 +86,10 @@ export class DataTableSelectionComponent { } else if (type === 'keydown') { if ((event as KeyboardEvent).key === Keys.return) { this.selectRow(event, index, row); - } else if ((event as KeyboardEvent).key === 'a' && (event.ctrlKey || event.metaKey)) { + } else if ( + (event as KeyboardEvent).key === 'a' && + ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) + ) { this.selectRow(event, 0, this.rows[this.rows.length - 1]); } else { this.onKeyboardFocus(model); diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index 7b2731006..718bfd5a3 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -36,7 +36,7 @@ export type TreeStatus = 'collapsed' | 'expanded' | 'loading' | 'disabled'; export interface ActivateEvent { type: 'checkbox' | 'click' | 'dblclick' | 'keydown' | 'mouseenter'; - event: MouseEvent | KeyboardEvent; + event: Event; row: TRow; group?: TRow[]; rowHeight?: number; From 0edece62ea826ff2b0f10553b20453f25528c78b Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 13 Mar 2025 15:22:11 +0100 Subject: [PATCH 007/105] refactor: remove useless cleanup (#164) This never made any sense. `cellTemplate` and `ghostLoaderTemplate` were never defined. --- .../components/body/body-cell.component.ts | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 6a646cfbb..3355ad477 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -9,11 +9,8 @@ import { HostListener, inject, Input, - OnDestroy, Output, - PipeTransform, - ViewChild, - ViewContainerRef + PipeTransform } from '@angular/core'; import { TableColumn } from '../../types/table-column.type'; @@ -74,11 +71,7 @@ import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; } @else { {{ value }} } } @else { - + } @@ -88,7 +81,7 @@ import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; `, imports: [NgTemplateOutlet, DataTableGhostLoaderComponent, AsyncPipe] }) -export class DataTableBodyCellComponent implements DoCheck, OnDestroy { +export class DataTableBodyCellComponent implements DoCheck { private cd = inject(ChangeDetectorRef); @Input() displayCheck: (row: RowOrGroup, column: TableColumn, value: any) => boolean; @@ -212,12 +205,6 @@ export class DataTableBodyCellComponent implements DoChe @Output() treeAction: EventEmitter = new EventEmitter(); - @ViewChild('cellTemplate', { read: ViewContainerRef, static: true }) - cellTemplate: ViewContainerRef; - - @ViewChild('ghostLoaderTemplate', { read: ViewContainerRef, static: true }) - ghostLoaderTemplate: ViewContainerRef; - @HostBinding('class') get columnCssClasses(): string { let cls = 'datatable-body-cell'; @@ -327,15 +314,6 @@ export class DataTableBodyCellComponent implements DoChe this.checkValueUpdates(); } - ngOnDestroy(): void { - if (this.cellTemplate) { - this.cellTemplate.clear(); - } - if (this.ghostLoaderTemplate) { - this.ghostLoaderTemplate.clear(); - } - } - checkValueUpdates(): void { let value = ''; From 946310925fdcb89618a0aa0c37c6e97d0c7e93f7 Mon Sep 17 00:00:00 2001 From: Maximilian Koeller Date: Tue, 11 Mar 2025 09:50:54 +0100 Subject: [PATCH 008/105] fix: only run disabled check on rows We previously ran `disableRowCheck` on groups instead of each row if rows were grouped. With this change, we only run the check on rows. Besides this, the uncommon `disableRow$` subject was removed from template contexts and replaced with a proper `disabled` field. This simplifies the usage and prevents wrong expectations. Although even shown in our example, calling `next` on the subject works but the value will be overridden on the next CD cycle, so it was pointless. Replacing the subject with a normal boolean resolves this problem. Being able to subscribe to the subject is also not needed. An application always knows whether a row was disabled because they set it. BREAKING CHANGE: The row detail context (`RowDetailContext`) no longer contains `disableRow$?: Observable`. Use the new `disabled: boolean` value instead. BREAKING CHANGE: The cell context (`CellContext`) no longer contains `disableRow$?: Observable`. Use the new `disabled: boolean` value instead. BREAKING CHANGE: `disableRowCheck` will only be called with actual rows. Although documented otherwise, in the case of groups, the `disableRowCheck` was only called for groups instead of each row inside that group. This allows disabling single rows inside a group and not only entire groups. To update the disabled state of a row just update the row itself instead of using the previous `disableRow$` subject. --- playwright/e2e/row-disabled.spec.ts | 14 ++++ .../disabled-chromium-linux.png | 3 + .../components/body/body-cell.component.ts | 29 ++++---- .../body/body-row-wrapper.component.ts | 19 +---- .../lib/components/body/body-row.component.ts | 22 ++---- .../components/body/body.component.spec.ts | 72 ++++++++++++++----- .../src/lib/components/body/body.component.ts | 11 +-- .../src/lib/types/public.types.ts | 5 +- src/app/basic/disabled-rows.component.ts | 30 ++++---- 9 files changed, 118 insertions(+), 87 deletions(-) create mode 100644 playwright/e2e/row-disabled.spec.ts create mode 100644 playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png diff --git a/playwright/e2e/row-disabled.spec.ts b/playwright/e2e/row-disabled.spec.ts new file mode 100644 index 000000000..ac4eb0708 --- /dev/null +++ b/playwright/e2e/row-disabled.spec.ts @@ -0,0 +1,14 @@ +import { test } from '../support/test-helpers'; + +test('disabled rows', async ({ si, page }) => { + await si.visitExample('disabled'); + await page + .getByRole('row', { name: 'Merritt Booker' }) + .getByRole('button', { name: 'Disable row' }) + .click(); + await si.runVisualAndA11yTests(undefined, [ + { id: 'color-contrast', enabled: false }, + { id: 'label', enabled: false }, + { id: 'select-name', enabled: false } + ]); +}); diff --git a/playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png b/playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png new file mode 100644 index 000000000..29b4875ab --- /dev/null +++ b/playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da4606a7a5aa0d295588c2955d881d989c0aa0c316af9078d91648e38867f1ca +size 73082 diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 3355ad477..304e9a60a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -15,7 +15,6 @@ import { import { TableColumn } from '../../types/table-column.type'; import { Keys } from '../../utils/keys'; -import { BehaviorSubject } from 'rxjs'; import { ActivateEvent, CellContext, @@ -26,7 +25,7 @@ import { TreeStatus } from '../../types/public.types'; import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.component'; -import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; +import { NgTemplateOutlet } from '@angular/common'; @Component({ selector: 'datatable-body-cell', @@ -38,7 +37,7 @@ import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, NgClass] }) export class ColumnReorderComponent { rows: Employee[] = []; diff --git a/src/app/columns/column-standard.component.ts b/src/app/columns/column-standard.component.ts index 493e0cff8..8c78e7bfe 100644 --- a/src/app/columns/column-standard.component.ts +++ b/src/app/columns/column-standard.component.ts @@ -1,5 +1,10 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnCellDirective, + DataTableColumnDirective, + DatatableComponent +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -44,7 +49,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class ColumnStandardComponent { rows: Employee[] = []; diff --git a/src/app/columns/column-toggle.component.ts b/src/app/columns/column-toggle.component.ts index 9ddbb4e40..8cb4203b1 100644 --- a/src/app/columns/column-toggle.component.ts +++ b/src/app/columns/column-toggle.component.ts @@ -1,5 +1,10 @@ import { Component } from '@angular/core'; -import { ColumnMode, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnDirective, + DatatableComponent, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; @Component({ @@ -49,7 +54,8 @@ import { Employee } from '../data.model'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective] }) export class ColumnToggleComponent { rows: Employee[] = [ diff --git a/src/app/columns/pinning.component.ts b/src/app/columns/pinning.component.ts index 2238a435f..cc1be0b25 100644 --- a/src/app/columns/pinning.component.ts +++ b/src/app/columns/pinning.component.ts @@ -1,5 +1,9 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnDirective, + DatatableComponent +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { FullEmployee } from '../data.model'; import { DataService } from '../data.service'; @@ -37,7 +41,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective] }) export class ColumnPinningComponent { rows: FullEmployee[] = []; diff --git a/src/app/drag-drop/drag-drop.component.ts b/src/app/drag-drop/drag-drop.component.ts index fa757994c..b64223123 100644 --- a/src/app/drag-drop/drag-drop.component.ts +++ b/src/app/drag-drop/drag-drop.component.ts @@ -1,6 +1,11 @@ -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop'; import { Component, inject } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + DatatableRowDefComponent, + DatatableRowDefDirective +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { DataService } from '../data.service'; import { Employee } from '../data.model'; @@ -38,7 +43,14 @@ import { Employee } from '../data.model'; `, - standalone: false + standalone: true, + imports: [ + DatatableComponent, + CdkDropList, + DatatableRowDefDirective, + DatatableRowDefComponent, + CdkDrag + ] }) export class DragDropComponent { rows: Employee[] = []; diff --git a/src/app/paging/paging-client.component.ts b/src/app/paging/paging-client.component.ts index f4db06642..629028d11 100644 --- a/src/app/paging/paging-client.component.ts +++ b/src/app/paging/paging-client.component.ts @@ -1,5 +1,5 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { ColumnMode, DatatableComponent } from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -31,7 +31,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class ClientPagingComponent { rows: Employee[] = []; diff --git a/src/app/paging/paging-scrolling-novirtualization.component.ts b/src/app/paging/paging-scrolling-novirtualization.component.ts index 2798d92e3..e38932944 100644 --- a/src/app/paging/paging-scrolling-novirtualization.component.ts +++ b/src/app/paging/paging-scrolling-novirtualization.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { MockServerResultsService } from './mock-server-results-service'; import { Page } from './model/page'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { ColumnMode, DatatableComponent } from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; @Component({ @@ -40,7 +40,8 @@ import { Employee } from '../data.model'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class PagingScrollingNoVirtualizationComponent implements OnInit { page: Page = { diff --git a/src/app/paging/paging-server.component.ts b/src/app/paging/paging-server.component.ts index 756baa552..1196525a0 100644 --- a/src/app/paging/paging-server.component.ts +++ b/src/app/paging/paging-server.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { MockServerResultsService } from './mock-server-results-service'; import { Page } from './model/page'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { ColumnMode, DatatableComponent } from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; @Component({ @@ -37,7 +37,8 @@ import { Employee } from '../data.model'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class ServerPagingComponent implements OnInit { page: Page = { diff --git a/src/app/paging/paging-virtual.component.ts b/src/app/paging/paging-virtual.component.ts index e91519d74..d08c63298 100644 --- a/src/app/paging/paging-virtual.component.ts +++ b/src/app/paging/paging-virtual.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { MockServerResultsService } from './mock-server-results-service'; import { Page } from './model/page'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { ColumnMode, DatatableComponent } from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; interface PageInfo { @@ -53,7 +53,8 @@ interface PageInfo { `, styleUrls: ['./paging-virtual.component.scss'], - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class VirtualPagingComponent { totalElements: number; diff --git a/src/app/paging/scrolling-server.component.ts b/src/app/paging/scrolling-server.component.ts index 9266474e9..f185f0f7e 100644 --- a/src/app/paging/scrolling-server.component.ts +++ b/src/app/paging/scrolling-server.component.ts @@ -3,7 +3,7 @@ import { Observable, of } from 'rxjs'; import { delay, map } from 'rxjs/operators'; import data from 'src/assets/data/company.json'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { ColumnMode, DatatableComponent } from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; const companyData = data as any[]; @@ -56,7 +56,8 @@ export class MockServerResultsService { `, styleUrls: ['./scrolling-server.component.css'], - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class ServerScrollingComponent { readonly headerHeight = 50; diff --git a/src/app/selection/selection-cell.component.ts b/src/app/selection/selection-cell.component.ts index 6de0dab60..28626cb8e 100644 --- a/src/app/selection/selection-cell.component.ts +++ b/src/app/selection/selection-cell.component.ts @@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DatatableComponent, SelectEvent, SelectionType, TableColumn @@ -40,7 +41,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class CellSelectionComponent { rows: Employee[] = []; diff --git a/src/app/selection/selection-chkbox-template.component.ts b/src/app/selection/selection-chkbox-template.component.ts index d72b81058..c9cfa1601 100644 --- a/src/app/selection/selection-chkbox-template.component.ts +++ b/src/app/selection/selection-chkbox-template.component.ts @@ -2,6 +2,10 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DataTableColumnCellDirective, + DataTableColumnDirective, + DataTableColumnHeaderDirective, + DatatableComponent, SelectEvent, SelectionType } from 'projects/swimlane/ngx-datatable/src/public-api'; @@ -88,7 +92,13 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [ + DatatableComponent, + DataTableColumnDirective, + DataTableColumnHeaderDirective, + DataTableColumnCellDirective + ] }) export class CustomCheckboxSelectionComponent { rows: Employee[] = []; diff --git a/src/app/selection/selection-chkbox.component.ts b/src/app/selection/selection-chkbox.component.ts index e13ceb269..22c2e2864 100644 --- a/src/app/selection/selection-chkbox.component.ts +++ b/src/app/selection/selection-chkbox.component.ts @@ -2,6 +2,8 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DataTableColumnDirective, + DatatableComponent, SelectEvent, SelectionType } from 'projects/swimlane/ngx-datatable/src/public-api'; @@ -77,7 +79,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective] }) export class CheckboxSelectionComponent { rows: Employee[] = []; diff --git a/src/app/selection/selection-disabled.component.ts b/src/app/selection/selection-disabled.component.ts index 12300a0ac..2915c2cc7 100644 --- a/src/app/selection/selection-disabled.component.ts +++ b/src/app/selection/selection-disabled.component.ts @@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DatatableComponent, SelectEvent, SelectionType, TableColumn @@ -57,7 +58,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class MultiDisableSelectionComponent { rows: Employee[] = []; diff --git a/src/app/selection/selection-multi-click-chkbox.component.ts b/src/app/selection/selection-multi-click-chkbox.component.ts index 5491c453e..99194dd1d 100644 --- a/src/app/selection/selection-multi-click-chkbox.component.ts +++ b/src/app/selection/selection-multi-click-chkbox.component.ts @@ -2,6 +2,8 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DataTableColumnDirective, + DatatableComponent, SelectEvent, SelectionType } from 'projects/swimlane/ngx-datatable/src/public-api'; @@ -78,7 +80,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective] }) export class MultiClickCheckboxSelectionComponent { rows: Employee[] = []; diff --git a/src/app/selection/selection-multi-click.component.ts b/src/app/selection/selection-multi-click.component.ts index 02f0ef964..78de4a20a 100644 --- a/src/app/selection/selection-multi-click.component.ts +++ b/src/app/selection/selection-multi-click.component.ts @@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DatatableComponent, SelectEvent, SelectionType, TableColumn @@ -60,7 +61,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class MultiClickSelectionComponent { rows: Employee[] = []; diff --git a/src/app/selection/selection-multi.component.ts b/src/app/selection/selection-multi.component.ts index 5db9e332d..84128e721 100644 --- a/src/app/selection/selection-multi.component.ts +++ b/src/app/selection/selection-multi.component.ts @@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DatatableComponent, SelectEvent, SelectionType, TableColumn @@ -63,7 +64,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class MultiSelectionComponent { rows: Employee[] = []; diff --git a/src/app/selection/selection-single.component.ts b/src/app/selection/selection-single.component.ts index 0886e0be9..c81124ab0 100644 --- a/src/app/selection/selection-single.component.ts +++ b/src/app/selection/selection-single.component.ts @@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core'; import { ActivateEvent, ColumnMode, + DatatableComponent, SelectEvent, SelectionType, TableColumn @@ -63,7 +64,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class SingleSelectionComponent { rows: Employee[] = []; diff --git a/src/app/sorting/sorting-client.component.ts b/src/app/sorting/sorting-client.component.ts index f5492b1c5..8d49a6c7f 100644 --- a/src/app/sorting/sorting-client.component.ts +++ b/src/app/sorting/sorting-client.component.ts @@ -1,5 +1,10 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode, SortType, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + SortType, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -32,7 +37,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class ClientSortingComponent { rows: Employee[] = []; diff --git a/src/app/sorting/sorting-comparator.component.ts b/src/app/sorting/sorting-comparator.component.ts index 950406e54..cb079a7a8 100644 --- a/src/app/sorting/sorting-comparator.component.ts +++ b/src/app/sorting/sorting-comparator.component.ts @@ -1,5 +1,9 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -30,7 +34,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class SortingComparatorComponent { rows: Employee[] = []; diff --git a/src/app/sorting/sorting-default.component.ts b/src/app/sorting/sorting-default.component.ts index 6a1da0057..ac662ac44 100644 --- a/src/app/sorting/sorting-default.component.ts +++ b/src/app/sorting/sorting-default.component.ts @@ -1,5 +1,10 @@ import { Component, inject, OnInit } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnCellDirective, + DataTableColumnDirective, + DatatableComponent +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -45,7 +50,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class DefaultSortingComponent implements OnInit { rows: Employee[] = []; diff --git a/src/app/sorting/sorting-server.component.ts b/src/app/sorting/sorting-server.component.ts index 8c7ae714d..81e308a8f 100644 --- a/src/app/sorting/sorting-server.component.ts +++ b/src/app/sorting/sorting-server.component.ts @@ -1,5 +1,10 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode, SortEvent, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + SortEvent, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -33,7 +38,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class ServerSortingComponent { loading = false; diff --git a/src/app/summary/summary-row-custom-template.component.ts b/src/app/summary/summary-row-custom-template.component.ts index 1b15e0c0c..e6414d6b1 100644 --- a/src/app/summary/summary-row-custom-template.component.ts +++ b/src/app/summary/summary-row-custom-template.component.ts @@ -1,5 +1,9 @@ import { Component, inject, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { ColumnMode, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -40,7 +44,8 @@ import { DataService } from '../data.service'; `, styleUrls: ['./summary-row-custom-template.component.scss'], - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class SummaryRowCustomTemplateComponent implements OnInit { rows: Employee[] = []; diff --git a/src/app/summary/summary-row-inline-html.component.ts b/src/app/summary/summary-row-inline-html.component.ts index 32e01d5e8..4f7d7764e 100644 --- a/src/app/summary/summary-row-inline-html.component.ts +++ b/src/app/summary/summary-row-inline-html.component.ts @@ -1,5 +1,9 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnDirective, + DatatableComponent +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -45,7 +49,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective] }) export class SummaryRowInlineHtmlComponent { rows: Employee[] = []; diff --git a/src/app/summary/summary-row-server-paging.component.ts b/src/app/summary/summary-row-server-paging.component.ts index 659cd20f3..b79cf7d37 100644 --- a/src/app/summary/summary-row-server-paging.component.ts +++ b/src/app/summary/summary-row-server-paging.component.ts @@ -1,7 +1,11 @@ import { Component, OnInit } from '@angular/core'; import { MockServerResultsService } from '../paging/mock-server-results-service'; import { Page } from '../paging/model/page'; -import { ColumnMode, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; @Component({ @@ -38,7 +42,8 @@ import { Employee } from '../data.model'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class SummaryRowServerPagingComponent implements OnInit { page: Page = { diff --git a/src/app/summary/summary-row-simple.component.ts b/src/app/summary/summary-row-simple.component.ts index 1f1759c55..8e09d7765 100644 --- a/src/app/summary/summary-row-simple.component.ts +++ b/src/app/summary/summary-row-simple.component.ts @@ -1,5 +1,9 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -50,7 +54,8 @@ import { DataService } from '../data.service'; `, styleUrls: ['./summary-row-simple.component.scss'], - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class SummaryRowSimpleComponent { rows: Employee[] = []; diff --git a/src/app/templates/template-dom.component.ts b/src/app/templates/template-dom.component.ts index fea518b2f..652006c22 100644 --- a/src/app/templates/template-dom.component.ts +++ b/src/app/templates/template-dom.component.ts @@ -1,5 +1,11 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnCellDirective, + DataTableColumnDirective, + DataTableColumnHeaderDirective, + DatatableComponent +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -53,7 +59,13 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [ + DatatableComponent, + DataTableColumnDirective, + DataTableColumnHeaderDirective, + DataTableColumnCellDirective + ] }) export class InlineTemplatesComponent { rows: Employee[] = []; diff --git a/src/app/templates/template-obj.component.ts b/src/app/templates/template-obj.component.ts index 4d52bedd4..a4727e305 100644 --- a/src/app/templates/template-obj.component.ts +++ b/src/app/templates/template-obj.component.ts @@ -1,5 +1,9 @@ import { Component, inject, TemplateRef, ViewChild } from '@angular/core'; -import { ColumnMode, TableColumn } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + TableColumn +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; import { DataService } from '../data.service'; @@ -42,7 +46,8 @@ import { DataService } from '../data.service'; `, - standalone: false + standalone: true, + imports: [DatatableComponent] }) export class TemplateRefTemplatesComponent { @ViewChild('editTmpl', { static: true }) editTmpl: TemplateRef; diff --git a/src/app/tree/client-tree.component.ts b/src/app/tree/client-tree.component.ts index 5c3cc62a6..b7a39082d 100644 --- a/src/app/tree/client-tree.component.ts +++ b/src/app/tree/client-tree.component.ts @@ -1,5 +1,10 @@ import { Component, inject } from '@angular/core'; -import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnCellDirective, + DataTableColumnDirective, + DatatableComponent +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { TreeEmployee } from '../data.model'; import { DataService } from '../data.service'; @@ -48,7 +53,8 @@ import { DataService } from '../data.service'; `, styles: ['.icon {height: 10px; width: 10px; }', '.disabled {opacity: 0.5; }'], - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class ClientTreeComponent { rows: TreeEmployee[] = []; diff --git a/src/app/tree/fullscreen.component.ts b/src/app/tree/fullscreen.component.ts index 027c33711..96bb75ebf 100644 --- a/src/app/tree/fullscreen.component.ts +++ b/src/app/tree/fullscreen.component.ts @@ -1,5 +1,11 @@ import { ChangeDetectorRef, Component } from '@angular/core'; -import { ColumnMode, TreeStatus } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DataTableColumnCellTreeToggle, + DataTableColumnDirective, + DatatableComponent, + TreeStatus +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { FullEmployee } from '../data.model'; import { DataService } from '../data.service'; @@ -65,7 +71,8 @@ import { DataService } from '../data.service'; `, styles: ['.icon {height: 10px; width: 10px; }', '.disabled {opacity: 0.5; }'], - standalone: false + standalone: true, + imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellTreeToggle] }) export class FullScreenTreeComponent { rows: (FullEmployee & { treeStatus: TreeStatus; parentId?: string })[] = []; From db448ffd1d3ce1bbe8f548634872b6d110a8ee7e Mon Sep 17 00:00:00 2001 From: Maxi Date: Wed, 26 Mar 2025 09:17:01 +0100 Subject: [PATCH 042/105] docs: bootstrap application in a standalone way (#200) --- src/app/app.component.ts | 5 +- src/app/app.module.ts | 153 --------------------------------------- src/main.ts | 27 +++++-- 3 files changed, 24 insertions(+), 161 deletions(-) delete mode 100644 src/app/app.module.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 21b2a8eac..055c93170 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,7 +1,7 @@ import { Component, signal, ViewEncapsulation } from '@angular/core'; import { HashLocationStrategy, Location, LocationStrategy } from '@angular/common'; import packageInfo from 'projects/swimlane/ngx-datatable/package.json'; -import { RouterOutlet } from '@angular/router'; +import { RouterLink, RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', @@ -20,7 +20,8 @@ import { RouterOutlet } from '@angular/router'; useClass: HashLocationStrategy } ], - standalone: false + standalone: true, + imports: [RouterLink, RouterOutlet] }) export class AppComponent { version = packageInfo.version; diff --git a/src/app/app.module.ts b/src/app/app.module.ts deleted file mode 100644 index f4a8f264a..000000000 --- a/src/app/app.module.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; - -import { NgxDatatableModule } from '../../projects/swimlane/ngx-datatable/src/public-api'; -import { AppComponent } from './app.component'; - -// -- Basic -import { BasicFixedComponent } from './basic/basic-fixed.component'; -import { BasicAutoComponent } from './basic/basic-auto.component'; -import { VirtualScrollComponent } from './basic/virtual.component'; -import { InlineEditComponent } from './basic/inline.component'; -import { HorzVertScrollingComponent } from './basic/scrolling.component'; -import { MultipleTablesComponent } from './basic/multiple.component'; -import { FullScreenComponent } from './basic/fullscreen.component'; -import { RowDetailsComponent } from './basic/row-detail.component'; -import { ResponsiveComponent } from './basic/responsive.component'; -import { FilterComponent } from './basic/filter.component'; -import { TabsDemoComponent } from './basic/tabs.component'; -import { LiveDataComponent } from './basic/live.component'; -import { RxDemoComponent } from './basic/rx.component'; -import { ContextMenuDemoComponent } from './basic/contextmenu.component'; -import { RowCssComponent } from './basic/css.component'; -import { DynamicHeightComponent } from './basic/dynamic-height.component'; -import { FooterDemoComponent } from './basic/footer.component'; -import { RowGroupingComponent } from './basic/row-grouping.component'; -import { BasicEmptyComponent } from './basic/empty.component'; -import { DisabledRowsComponent } from './basic/disabled-rows.component'; - -// -- Themes -import { BootstrapThemeComponent } from './basic/bootstrap.component'; -import { DarkThemeComponent } from './basic/dark-theme.component'; - -// -- Paging -import { ClientPagingComponent } from './paging/paging-client.component'; -import { ServerPagingComponent } from './paging/paging-server.component'; -import { ServerScrollingComponent } from './paging/scrolling-server.component'; -import { VirtualPagingComponent } from './paging/paging-virtual.component'; -import { PagingScrollingNoVirtualizationComponent } from './paging/paging-scrolling-novirtualization.component'; - -// -- Sorting -import { SortingComparatorComponent } from './sorting/sorting-comparator.component'; -import { DefaultSortingComponent } from './sorting/sorting-default.component'; -import { ServerSortingComponent } from './sorting/sorting-server.component'; -import { ClientSortingComponent } from './sorting/sorting-client.component'; - -// -- Templates -import { InlineTemplatesComponent } from './templates/template-dom.component'; -import { TemplateRefTemplatesComponent } from './templates/template-obj.component'; - -// -- Tree -import { FullScreenTreeComponent } from './tree/fullscreen.component'; -import { ClientTreeComponent } from './tree/client-tree.component'; - -// -- Selection -import { CellSelectionComponent } from './selection/selection-cell.component'; -import { MultiSelectionComponent } from './selection/selection-multi.component'; -import { SingleSelectionComponent } from './selection/selection-single.component'; -import { MultiDisableSelectionComponent } from './selection/selection-disabled.component'; -import { CheckboxSelectionComponent } from './selection/selection-chkbox.component'; -import { MultiClickSelectionComponent } from './selection/selection-multi-click.component'; -import { MultiClickCheckboxSelectionComponent } from './selection/selection-multi-click-chkbox.component'; -import { CustomCheckboxSelectionComponent } from './selection/selection-chkbox-template.component'; - -// -- Columns -import { ColumnToggleComponent } from './columns/column-toggle.component'; -import { ColumnStandardComponent } from './columns/column-standard.component'; -import { ColumnForceComponent } from './columns/column-force.component'; -import { ColumnFlexComponent } from './columns/column-flex.component'; -import { ColumnPinningComponent } from './columns/pinning.component'; -import { ColumnReorderComponent } from './columns/column-reorder.component'; - -// -- Summary row -import { SummaryRowSimpleComponent } from './summary/summary-row-simple.component'; -import { SummaryRowCustomTemplateComponent } from './summary/summary-row-custom-template.component'; -import { SummaryRowServerPagingComponent } from './summary/summary-row-server-paging.component'; -import { SummaryRowInlineHtmlComponent } from './summary/summary-row-inline-html.component'; -import { AppRoutingModule } from './app-routing.module'; -import { ScrollingDynamicallyComponent } from './basic/scrolling-dynamically.component'; -import { DragDropComponent } from './drag-drop/drag-drop.component'; -import { provideHttpClient } from '@angular/common/http'; - -@NgModule({ - declarations: [AppComponent], - imports: [ - BrowserModule, - AppRoutingModule, - NgxDatatableModule.forRoot({ - messages: { - emptyMessage: 'No data to display', // Message to show when array is presented, but contains no values - totalMessage: 'total', // Footer total message - selectedMessage: 'selected' // Footer selected message - } - }), - BasicAutoComponent, - BasicFixedComponent, - DragDropComponent, - FullScreenComponent, - FullScreenTreeComponent, - InlineEditComponent, - VirtualScrollComponent, - HorzVertScrollingComponent, - ScrollingDynamicallyComponent, - MultipleTablesComponent, - RowDetailsComponent, - ResponsiveComponent, - ClientPagingComponent, - ServerPagingComponent, - PagingScrollingNoVirtualizationComponent, - ServerScrollingComponent, - ClientSortingComponent, - DefaultSortingComponent, - ServerSortingComponent, - SortingComparatorComponent, - CellSelectionComponent, - MultiSelectionComponent, - MultiClickCheckboxSelectionComponent, - InlineTemplatesComponent, - TemplateRefTemplatesComponent, - ColumnFlexComponent, - ColumnToggleComponent, - ColumnStandardComponent, - ColumnForceComponent, - ColumnPinningComponent, - ColumnReorderComponent, - FilterComponent, - VirtualPagingComponent, - DarkThemeComponent, - TabsDemoComponent, - SingleSelectionComponent, - LiveDataComponent, - MultiDisableSelectionComponent, - RxDemoComponent, - ContextMenuDemoComponent, - CheckboxSelectionComponent, - CustomCheckboxSelectionComponent, - MultiClickSelectionComponent, - RowCssComponent, - DynamicHeightComponent, - FooterDemoComponent, - RowGroupingComponent, - BasicEmptyComponent, - BootstrapThemeComponent, - ClientTreeComponent, - SummaryRowSimpleComponent, - SummaryRowCustomTemplateComponent, - SummaryRowServerPagingComponent, - SummaryRowInlineHtmlComponent, - DisabledRowsComponent - ], - providers: [provideHttpClient()], - bootstrap: [AppComponent] -}) -export class AppModule {} diff --git a/src/main.ts b/src/main.ts index fa4e0aef3..a986504e8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,13 +1,28 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { enableProdMode, importProvidersFrom } from '@angular/core'; -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +import { provideHttpClient } from '@angular/common/http'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppRoutingModule } from './app/app-routing.module'; +import { NgxDatatableModule } from 'projects/ngx-datatable/src/public-api'; +import { AppComponent } from './app/app.component'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch(err => console.error(err)); +bootstrapApplication(AppComponent, { + providers: [ + importProvidersFrom( + AppRoutingModule, + NgxDatatableModule.forRoot({ + messages: { + emptyMessage: 'No data to display', // Message to show when array is presented, but contains no values + totalMessage: 'total', // Footer total message + selectedMessage: 'selected' // Footer selected message + } + }) + ), + provideHttpClient() + ] +}).catch(err => console.error(err)); From b1db41b5a5d548c8b70a775bc14d115ff19a3f59 Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Thu, 26 Jun 2025 13:05:02 -0500 Subject: [PATCH 043/105] fix import in main.ts --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index a986504e8..1d01c49fe 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import { environment } from './environments/environment'; import { provideHttpClient } from '@angular/common/http'; import { bootstrapApplication } from '@angular/platform-browser'; import { AppRoutingModule } from './app/app-routing.module'; -import { NgxDatatableModule } from 'projects/ngx-datatable/src/public-api'; +import { NgxDatatableModule } from 'projects/swimlane/ngx-datatable/src/public-api'; import { AppComponent } from './app/app.component'; if (environment.production) { From 1ec711914805cfda49c738149288dcb4b49ef4f0 Mon Sep 17 00:00:00 2001 From: Maximilian Koeller Date: Wed, 26 Mar 2025 08:45:12 +0100 Subject: [PATCH 044/105] refactor: add undefined to types were needed --- .../lib/components/body/body-cell.component.ts | 18 ++++++++---------- .../lib/components/body/body-row.component.ts | 2 +- .../src/lib/components/body/body.component.ts | 4 ++-- .../lib/components/body/scroller.component.ts | 6 +++--- .../src/lib/components/datatable.component.ts | 4 ++-- .../components/header/header-cell.component.ts | 16 ++++++++-------- .../lib/components/header/header.component.ts | 4 ++-- 7 files changed, 26 insertions(+), 28 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 764c557ee..901a7f14a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -84,7 +84,7 @@ import { TableColumnInternal } from '../../types/internal.types'; export class DataTableBodyCellComponent implements DoCheck { private cd = inject(ChangeDetectorRef); - @Input() displayCheck: (row: TRow, column: TableColumnInternal, value: any) => boolean; + @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value: any) => boolean; @Input() set disabled(value: boolean) { this.cellContext.disabled = value; @@ -179,7 +179,7 @@ export class DataTableBodyCellComponent implements DoChe return this._sorts; } - @Input() set treeStatus(status: TreeStatus) { + @Input() set treeStatus(status: TreeStatus | undefined) { if ( status !== 'collapsed' && status !== 'expanded' && @@ -257,12 +257,12 @@ export class DataTableBodyCellComponent implements DoChe } @HostBinding('style.minWidth.px') - get minWidth(): number { + get minWidth(): number | undefined { return this.column.minWidth; } @HostBinding('style.maxWidth.px') - get maxWidth(): number { + get maxWidth(): number | undefined { return this.column.maxWidth; } @@ -277,7 +277,7 @@ export class DataTableBodyCellComponent implements DoChe sanitizedValue: string; value: any; - sortDir: SortDirection; + sortDir?: SortDirection; isFocused = false; cellContext: CellContext; @@ -421,16 +421,14 @@ export class DataTableBodyCellComponent implements DoChe }); } - calcSortDir(sorts: SortPropDir[]): SortDirection { + calcSortDir(sorts: SortPropDir[]): SortDirection | undefined { if (!sorts) { - return; + return undefined; } const sort = sorts.find(s => s.prop === this.column.prop); - if (sort) { - return sort.dir as SortDirection; - } + return sort?.dir as SortDirection; } stripHtml(html: string): string { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index 0ec73dd83..4b3520bb0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -90,7 +90,7 @@ export class DataTableBodyRowComponent implements DoCheck, OnChanges @Input() group: TRow[]; @Input() isSelected: boolean; @Input() rowIndex: number; - @Input() displayCheck: (row: TRow, column: TableColumnInternal, value?: any) => boolean; + @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value?: any) => boolean; @Input() treeStatus?: TreeStatus = 'collapsed'; @Input() ghostLoadingIndicator = false; @Input() verticalScrollVisible = false; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index ee36bced1..6cbac2233 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -439,8 +439,8 @@ export class DataTableBodyComponent implements OnInit, O _pageSize: number; _offsetEvent = -1; - private _draggedRow: RowOrGroup; - private _draggedRowElement: HTMLElement; + private _draggedRow?: RowOrGroup; + private _draggedRowElement?: HTMLElement; /** * Creates an instance of DataTableBodyComponent. diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts index 8b244cf34..7f4651155 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts @@ -29,11 +29,11 @@ export class ScrollerComponent implements OnInit, OnDestroy { @HostBinding('style.height.px') @Input() - scrollHeight: number; + scrollHeight?: number; @HostBinding('style.width.px') @Input() - scrollWidth: number; + scrollWidth?: number; @Output() scroll: EventEmitter = new EventEmitter(); @@ -82,7 +82,7 @@ export class ScrollerComponent implements OnInit, OnDestroy { let direction: string; if (this.scrollYPos < this.prevScrollYPos) { direction = 'down'; - } else if (this.scrollYPos > this.prevScrollYPos) { + } else { direction = 'up'; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index e2647f264..ffad41586 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -454,7 +454,7 @@ export class DatatableComponent * return row.name !== 'Ethel Price'; * } */ - @Input() disableRowCheck: (row: TRow) => boolean; + @Input() disableRowCheck?: (row: TRow) => boolean; /** * A flag to enable drag behavior of native HTML5 drag and drop API on rows. @@ -1220,7 +1220,7 @@ export class DatatableComponent } else { let relevantRows; if (this.disableRowCheck) { - relevantRows = this.rows.filter(row => !this.disableRowCheck(row)); + relevantRows = this.rows.filter(row => !this.disableRowCheck!(row)); } else { relevantRows = this.rows; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts index 55070a3b5..b779d47db 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts @@ -67,7 +67,7 @@ export class DataTableHeaderCellComponent implements OnInit { @Input() sortDescendingIcon?: string; @Input() sortUnsetIcon?: string; - @Input() isTarget: boolean; + @Input() isTarget?: boolean; @Input() targetMarkerTemplate: TemplateRef; @Input() targetMarkerContext: any; @Input() enableClearingSortState = false; @@ -157,18 +157,18 @@ export class DataTableHeaderCellComponent implements OnInit { } @HostBinding('attr.title') - get name(): string { + get name(): string | undefined { // guaranteed to have a value by setColumnDefaults() in column-helper.ts return this.column.headerTemplate === undefined ? this.column.name : undefined; } @HostBinding('style.minWidth.px') - get minWidth(): number { + get minWidth(): number | undefined { return this.column.minWidth; } @HostBinding('style.maxWidth.px') - get maxWidth(): number { + get maxWidth(): number | undefined { return this.column.maxWidth; } @@ -181,11 +181,11 @@ export class DataTableHeaderCellComponent implements OnInit { return this.column.sortable ? 0 : -1; } - get isCheckboxable(): boolean { + get isCheckboxable(): boolean | undefined { return this.column.headerCheckboxable; } - sortClass: string; + sortClass?: string; sortDir: SortDirection; cellContext: HeaderCellContext; @@ -253,9 +253,9 @@ export class DataTableHeaderCellComponent implements OnInit { }); } - calcSortClass(sortDir: SortDirection): string { + calcSortClass(sortDir: SortDirection): string | undefined { if (!this.cellContext.column.sortable) { - return; + return undefined; } if (sortDir === SortDirection.asc) { return `sort-btn sort-asc ${this.sortAscendingIcon ?? 'datatable-icon-up'}`; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index ecc35bee6..e97108e24 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -260,9 +260,9 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { width: number, column: TableColumnInternal ): ColumnResizeEventInternal { - if (width <= column.minWidth) { + if (column.minWidth && width <= column.minWidth) { width = column.minWidth; - } else if (width >= column.maxWidth) { + } else if (column.maxWidth && width >= column.maxWidth) { width = column.maxWidth; } return { From 21f8435c57e7f4287281db428b30dcc42299e081 Mon Sep 17 00:00:00 2001 From: Maxi Date: Wed, 26 Mar 2025 14:18:48 +0100 Subject: [PATCH 045/105] refactor: remove unused vendor prefixes (#193) --- .../lib/components/datatable.component.scss | 29 +------------------ .../ngx-datatable/src/lib/themes/dark.scss | 1 - .../src/lib/themes/material.scss | 7 ----- src/assets/app.css | 2 -- 4 files changed, 1 insertion(+), 38 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 4fec1fdb8..100247d87 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -12,8 +12,6 @@ *, *:before, *:after { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; box-sizing: border-box; } @@ -39,7 +37,7 @@ &.scroll-horz { .datatable-body { overflow-x: auto; - -webkit-overflow-scrolling: touch; + -webkit-overflow-scrolling: touch; // Required for iOS optimization } } @@ -90,17 +88,7 @@ .datatable-body-row, .datatable-row-center, .datatable-header-inner { - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; display: flex; - - flex-direction: row; - -webkit-flex-flow: row; - -moz-flex-flow: row; - -ms-flex-flow: row; - -o-flex-flow: row; flex-flow: row; } @@ -155,18 +143,7 @@ } .datatable-row-wrapper { - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; display: flex; - - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -moz-box-orient: vertical; - -moz-box-direction: normal; - -ms-flex-direction: column; flex-direction: column; } @@ -174,10 +151,6 @@ outline: none; > div { - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; display: flex; } } diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss b/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss index d20ac9f42..2a428da8a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss +++ b/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss @@ -99,7 +99,6 @@ border-radius: 3px; margin: 0 3px; text-align: center; - vertical-align: top; text-decoration: none; vertical-align: bottom; color: #72809b; diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss index 2bf123e03..81a365ea5 100644 --- a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss +++ b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss @@ -337,13 +337,11 @@ $datatble-ghost-cell-animation-duration: 10s; overflow: hidden; width: 100%; height: 5px; - -webkit-transform: translate(0, 0) scale(1, 1); transform: translate(0, 0) scale(1, 1); background-color: rgb(170, 209, 249); .bar { transition: all 0.2s linear; - -webkit-animation: query 0.8s infinite cubic-bezier(0.39, 0.575, 0.565, 1); animation: query 0.8s infinite cubic-bezier(0.39, 0.575, 0.565, 1); transition: -webkit-transform 0.2s linear; @@ -469,8 +467,6 @@ $datatble-ghost-cell-animation-duration: 10s; outline: none; &:before { - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; content: ''; position: absolute; @@ -482,9 +478,6 @@ $datatble-ghost-cell-animation-duration: 10s; } &:checked:before { - -webkit-transform: rotate(-45deg); - -moz-transform: rotate(-45deg); - -ms-transform: rotate(-45deg); transform: rotate(-45deg); height: 0.5rem; border-color: #009688; diff --git a/src/assets/app.css b/src/assets/app.css index eae837e55..110f0e519 100644 --- a/src/assets/app.css +++ b/src/assets/app.css @@ -37,8 +37,6 @@ body { .selected-column { background: #fff; - -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.24); - -moz-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.24); box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.24); } From df999e40fe7c2425037ce94ebf223d7c1f15a963 Mon Sep 17 00:00:00 2001 From: Maxi Date: Wed, 26 Mar 2025 14:37:23 +0100 Subject: [PATCH 046/105] docs: lazy load examples (#201) --- src/app/app-routing.module.ts | 384 +++++++++++++++++++++++----------- src/main.ts | 5 +- 2 files changed, 267 insertions(+), 122 deletions(-) diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 6ebed30df..9dfc70009 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,124 +1,268 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { BasicAutoComponent } from './basic/basic-auto.component'; -import { BasicFixedComponent } from './basic/basic-fixed.component'; -import { FullScreenComponent } from './basic/fullscreen.component'; -import { InlineEditComponent } from './basic/inline.component'; -import { VirtualScrollComponent } from './basic/virtual.component'; -import { ResponsiveComponent } from './basic/responsive.component'; -import { DynamicHeightComponent } from './basic/dynamic-height.component'; -import { PagingScrollingNoVirtualizationComponent } from './paging/paging-scrolling-novirtualization.component'; -import { ColumnFlexComponent } from './columns/column-flex.component'; -import { ColumnToggleComponent } from './columns/column-toggle.component'; -import { ColumnStandardComponent } from './columns/column-standard.component'; -import { ColumnForceComponent } from './columns/column-force.component'; -import { ColumnReorderComponent } from './columns/column-reorder.component'; -import { HorzVertScrollingComponent } from './basic/scrolling.component'; -import { MultipleTablesComponent } from './basic/multiple.component'; -import { RowDetailsComponent } from './basic/row-detail.component'; -import { LiveDataComponent } from './basic/live.component'; -import { RowCssComponent } from './basic/css.component'; -import { DragDropComponent } from './drag-drop/drag-drop.component'; -import { DisabledRowsComponent } from './basic/disabled-rows.component'; -import { FullScreenTreeComponent } from './tree/fullscreen.component'; -import { RowGroupingComponent } from './basic/row-grouping.component'; -import { ClientPagingComponent } from './paging/paging-client.component'; -import { ServerPagingComponent } from './paging/paging-server.component'; -import { ServerScrollingComponent } from './paging/scrolling-server.component'; -import { VirtualPagingComponent } from './paging/paging-virtual.component'; -import { ClientSortingComponent } from './sorting/sorting-client.component'; -import { DefaultSortingComponent } from './sorting/sorting-default.component'; -import { ServerSortingComponent } from './sorting/sorting-server.component'; -import { CellSelectionComponent } from './selection/selection-cell.component'; -import { SingleSelectionComponent } from './selection/selection-single.component'; -import { MultiSelectionComponent } from './selection/selection-multi.component'; -import { MultiClickSelectionComponent } from './selection/selection-multi-click.component'; -import { InlineTemplatesComponent } from './templates/template-dom.component'; -import { ColumnPinningComponent } from './columns/pinning.component'; -import { SummaryRowSimpleComponent } from './summary/summary-row-simple.component'; -import { SummaryRowCustomTemplateComponent } from './summary/summary-row-custom-template.component'; -import { SummaryRowServerPagingComponent } from './summary/summary-row-server-paging.component'; -import { SummaryRowInlineHtmlComponent } from './summary/summary-row-inline-html.component'; -import { ScrollingDynamicallyComponent } from './basic/scrolling-dynamically.component'; -import { FilterComponent } from './basic/filter.component'; -import { TabsDemoComponent } from './basic/tabs.component'; -import { RxDemoComponent } from './basic/rx.component'; -import { ContextMenuDemoComponent } from './basic/contextmenu.component'; -import { FooterDemoComponent } from './basic/footer.component'; -import { BasicEmptyComponent } from './basic/empty.component'; -import { DarkThemeComponent } from './basic/dark-theme.component'; -import { BootstrapThemeComponent } from './basic/bootstrap.component'; -import { ClientTreeComponent } from './tree/client-tree.component'; -import { SortingComparatorComponent } from './sorting/sorting-comparator.component'; -import { MultiDisableSelectionComponent } from './selection/selection-disabled.component'; -import { CheckboxSelectionComponent } from './selection/selection-chkbox.component'; -import { CustomCheckboxSelectionComponent } from './selection/selection-chkbox-template.component'; -import { MultiClickCheckboxSelectionComponent } from './selection/selection-multi-click-chkbox.component'; -import { TemplateRefTemplatesComponent } from './templates/template-obj.component'; +import { Routes } from '@angular/router'; -const routes: Routes = [ - { path: '', component: BasicAutoComponent }, - { path: 'basic-fixed', component: BasicFixedComponent }, - { path: 'full-screen', component: FullScreenComponent }, - { path: 'inline-edit', component: InlineEditComponent }, - { path: 'virtual-scroll', component: VirtualScrollComponent }, - { path: 'horz-vert-scrolling', component: HorzVertScrollingComponent }, - { path: 'scrolling-dynamically', component: ScrollingDynamicallyComponent }, - { path: 'multiple-tables', component: MultipleTablesComponent }, - { path: 'row-details', component: RowDetailsComponent }, - { path: 'responsive', component: ResponsiveComponent }, - { path: 'filter', component: FilterComponent }, - { path: 'hidden', component: TabsDemoComponent }, - { path: 'live', component: LiveDataComponent }, - { path: 'rx', component: RxDemoComponent }, - { path: 'contextmenu', component: ContextMenuDemoComponent }, - { path: 'css', component: RowCssComponent }, - { path: 'dynamic', component: DynamicHeightComponent }, - { path: 'footer', component: FooterDemoComponent }, - { path: 'empty', component: BasicEmptyComponent }, - { path: 'drag-drop', component: DragDropComponent }, - { path: 'disabled', component: DisabledRowsComponent }, - { path: 'dark', component: DarkThemeComponent, data: { dark: true } }, - { path: 'bootstrap', component: BootstrapThemeComponent }, - { path: 'fullscreen-tree', component: FullScreenTreeComponent }, - { path: 'client-tree', component: ClientTreeComponent }, - { path: 'row-grouping', component: RowGroupingComponent }, - { path: 'client-paging', component: ClientPagingComponent }, - { path: 'server-paging', component: ServerPagingComponent }, +export const routes: Routes = [ + { + path: '', + loadComponent: () => import('./basic/basic-auto.component').then(c => c.BasicAutoComponent) + }, + { + path: 'basic-fixed', + loadComponent: () => import('./basic/basic-fixed.component').then(c => c.BasicFixedComponent) + }, + { + path: 'full-screen', + loadComponent: () => import('./basic/fullscreen.component').then(c => c.FullScreenComponent) + }, + { + path: 'inline-edit', + loadComponent: () => import('./basic/inline.component').then(c => c.InlineEditComponent) + }, + { + path: 'virtual-scroll', + loadComponent: () => import('./basic/virtual.component').then(c => c.VirtualScrollComponent) + }, + { + path: 'horz-vert-scrolling', + loadComponent: () => + import('./basic/scrolling.component').then(c => c.HorzVertScrollingComponent) + }, + { + path: 'scrolling-dynamically', + loadComponent: () => + import('./basic/scrolling-dynamically.component').then(c => c.ScrollingDynamicallyComponent) + }, + { + path: 'multiple-tables', + loadComponent: () => import('./basic/multiple.component').then(c => c.MultipleTablesComponent) + }, + { + path: 'row-details', + loadComponent: () => import('./basic/row-detail.component').then(c => c.RowDetailsComponent) + }, + { + path: 'responsive', + loadComponent: () => import('./basic/responsive.component').then(c => c.ResponsiveComponent) + }, + { + path: 'filter', + loadComponent: () => import('./basic/filter.component').then(c => c.FilterComponent) + }, + { + path: 'hidden', + loadComponent: () => import('./basic/tabs.component').then(c => c.TabsDemoComponent) + }, + { + path: 'live', + loadComponent: () => import('./basic/live.component').then(c => c.LiveDataComponent) + }, + { path: 'rx', loadComponent: () => import('./basic/rx.component').then(c => c.RxDemoComponent) }, + { + path: 'contextmenu', + loadComponent: () => + import('./basic/contextmenu.component').then(c => c.ContextMenuDemoComponent) + }, + { + path: 'css', + loadComponent: () => import('./basic/css.component').then(c => c.RowCssComponent) + }, + { + path: 'dynamic', + loadComponent: () => + import('./basic/dynamic-height.component').then(c => c.DynamicHeightComponent) + }, + { + path: 'footer', + loadComponent: () => import('./basic/footer.component').then(c => c.FooterDemoComponent) + }, + { + path: 'empty', + loadComponent: () => import('./basic/empty.component').then(c => c.BasicEmptyComponent) + }, + { + path: 'drag-drop', + loadComponent: () => import('./drag-drop/drag-drop.component').then(c => c.DragDropComponent) + }, + { + path: 'disabled', + loadComponent: () => + import('./basic/disabled-rows.component').then(c => c.DisabledRowsComponent) + }, + { + path: 'dark', + loadComponent: () => import('./basic/dark-theme.component').then(c => c.DarkThemeComponent), + data: { dark: true } + }, + { + path: 'bootstrap', + loadComponent: () => import('./basic/bootstrap.component').then(c => c.BootstrapThemeComponent) + }, + { + path: 'fullscreen-tree', + loadComponent: () => import('./tree/fullscreen.component').then(c => c.FullScreenTreeComponent) + }, + { + path: 'client-tree', + loadComponent: () => import('./tree/client-tree.component').then(c => c.ClientTreeComponent) + }, + { + path: 'row-grouping', + loadComponent: () => import('./basic/row-grouping.component').then(c => c.RowGroupingComponent) + }, + { + path: 'client-paging', + loadComponent: () => + import('./paging/paging-client.component').then(c => c.ClientPagingComponent) + }, + { + path: 'server-paging', + loadComponent: () => + import('./paging/paging-server.component').then(c => c.ServerPagingComponent) + }, { path: 'paging-scrolling-novirtualization', - component: PagingScrollingNoVirtualizationComponent - }, - { path: 'server-scrolling', component: ServerScrollingComponent }, - { path: 'virtual-paging', component: VirtualPagingComponent }, - { path: 'client-sorting', component: ClientSortingComponent }, - { path: 'default-sorting', component: DefaultSortingComponent }, - { path: 'server-sorting', component: ServerSortingComponent }, - { path: 'comparator-sorting', component: SortingComparatorComponent }, - { path: 'cell-selection', component: CellSelectionComponent }, - { path: 'single-selection', component: SingleSelectionComponent }, - { path: 'multi-selection', component: MultiSelectionComponent }, - { path: 'multi-click-selection', component: MultiClickSelectionComponent }, - { path: 'multidisable-selection', component: MultiDisableSelectionComponent }, - { path: 'chkbox-selection', component: CheckboxSelectionComponent }, - { path: 'chkbox-selection-template', component: CustomCheckboxSelectionComponent }, - { path: 'multi-click-chkbox-selection', component: MultiClickCheckboxSelectionComponent }, - { path: 'templateref', component: TemplateRefTemplatesComponent }, - { path: 'inline', component: InlineTemplatesComponent }, - { path: 'flex', component: ColumnFlexComponent }, - { path: 'toggle', component: ColumnToggleComponent }, - { path: 'fixed', component: ColumnStandardComponent }, - { path: 'force', component: ColumnForceComponent }, - { path: 'pinning', component: ColumnPinningComponent }, - { path: 'reorder', component: ColumnReorderComponent }, - { path: 'simple-summary', component: SummaryRowSimpleComponent }, - { path: 'custom-template-summary', component: SummaryRowCustomTemplateComponent }, - { path: 'paging-summary', component: SummaryRowServerPagingComponent }, - { path: 'inline-html-summary', component: SummaryRowInlineHtmlComponent } + loadComponent: () => + import('./paging/paging-scrolling-novirtualization.component').then( + c => c.PagingScrollingNoVirtualizationComponent + ) + }, + { + path: 'server-scrolling', + loadComponent: () => + import('./paging/scrolling-server.component').then(c => c.ServerScrollingComponent) + }, + { + path: 'virtual-paging', + loadComponent: () => + import('./paging/paging-virtual.component').then(c => c.VirtualPagingComponent) + }, + { + path: 'client-sorting', + loadComponent: () => + import('./sorting/sorting-client.component').then(c => c.ClientSortingComponent) + }, + { + path: 'default-sorting', + loadComponent: () => + import('./sorting/sorting-default.component').then(c => c.DefaultSortingComponent) + }, + { + path: 'server-sorting', + loadComponent: () => + import('./sorting/sorting-server.component').then(c => c.ServerSortingComponent) + }, + { + path: 'comparator-sorting', + loadComponent: () => + import('./sorting/sorting-comparator.component').then(c => c.SortingComparatorComponent) + }, + { + path: 'cell-selection', + loadComponent: () => + import('./selection/selection-cell.component').then(c => c.CellSelectionComponent) + }, + { + path: 'single-selection', + loadComponent: () => + import('./selection/selection-single.component').then(c => c.SingleSelectionComponent) + }, + { + path: 'multi-selection', + loadComponent: () => + import('./selection/selection-multi.component').then(c => c.MultiSelectionComponent) + }, + { + path: 'multi-click-selection', + loadComponent: () => + import('./selection/selection-multi-click.component').then( + c => c.MultiClickSelectionComponent + ) + }, + { + path: 'multidisable-selection', + loadComponent: () => + import('./selection/selection-disabled.component').then(c => c.MultiDisableSelectionComponent) + }, + { + path: 'chkbox-selection', + loadComponent: () => + import('./selection/selection-chkbox.component').then(c => c.CheckboxSelectionComponent) + }, + { + path: 'chkbox-selection-template', + loadComponent: () => + import('./selection/selection-chkbox-template.component').then( + c => c.CustomCheckboxSelectionComponent + ) + }, + { + path: 'multi-click-chkbox-selection', + loadComponent: () => + import('./selection/selection-multi-click-chkbox.component').then( + c => c.MultiClickCheckboxSelectionComponent + ) + }, + { + path: 'templateref', + loadComponent: () => + import('./templates/template-obj.component').then(c => c.TemplateRefTemplatesComponent) + }, + { + path: 'inline', + loadComponent: () => + import('./templates/template-dom.component').then(c => c.InlineTemplatesComponent) + }, + { + path: 'flex', + loadComponent: () => import('./columns/column-flex.component').then(c => c.ColumnFlexComponent) + }, + { + path: 'toggle', + loadComponent: () => + import('./columns/column-toggle.component').then(c => c.ColumnToggleComponent) + }, + { + path: 'fixed', + loadComponent: () => + import('./columns/column-standard.component').then(c => c.ColumnStandardComponent) + }, + { + path: 'force', + loadComponent: () => + import('./columns/column-force.component').then(c => c.ColumnForceComponent) + }, + { + path: 'pinning', + loadComponent: () => import('./columns/pinning.component').then(c => c.ColumnPinningComponent) + }, + { + path: 'reorder', + loadComponent: () => + import('./columns/column-reorder.component').then(c => c.ColumnReorderComponent) + }, + { + path: 'simple-summary', + loadComponent: () => + import('./summary/summary-row-simple.component').then(c => c.SummaryRowSimpleComponent) + }, + { + path: 'custom-template-summary', + loadComponent: () => + import('./summary/summary-row-custom-template.component').then( + c => c.SummaryRowCustomTemplateComponent + ) + }, + { + path: 'paging-summary', + loadComponent: () => + import('./summary/summary-row-server-paging.component').then( + c => c.SummaryRowServerPagingComponent + ) + }, + { + path: 'inline-html-summary', + loadComponent: () => + import('./summary/summary-row-inline-html.component').then( + c => c.SummaryRowInlineHtmlComponent + ) + } ]; - -@NgModule({ - imports: [RouterModule.forRoot(routes, {})], - exports: [RouterModule] -}) -export class AppRoutingModule {} diff --git a/src/main.ts b/src/main.ts index 1d01c49fe..119f0dcaa 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,9 +3,10 @@ import { enableProdMode, importProvidersFrom } from '@angular/core'; import { environment } from './environments/environment'; import { provideHttpClient } from '@angular/common/http'; import { bootstrapApplication } from '@angular/platform-browser'; -import { AppRoutingModule } from './app/app-routing.module'; +import { routes } from './app/app-routing.module'; import { NgxDatatableModule } from 'projects/swimlane/ngx-datatable/src/public-api'; import { AppComponent } from './app/app.component'; +import { provideRouter, withHashLocation } from '@angular/router'; if (environment.production) { enableProdMode(); @@ -14,7 +15,6 @@ if (environment.production) { bootstrapApplication(AppComponent, { providers: [ importProvidersFrom( - AppRoutingModule, NgxDatatableModule.forRoot({ messages: { emptyMessage: 'No data to display', // Message to show when array is presented, but contains no values @@ -23,6 +23,7 @@ bootstrapApplication(AppComponent, { } }) ), + provideRouter(routes, withHashLocation()), provideHttpClient() ] }).catch(err => console.error(err)); From fb050dfc32290e459ae10a54f5eb1ec7d7cae005 Mon Sep 17 00:00:00 2001 From: Chintan Kavathia Date: Wed, 13 Nov 2024 16:33:22 +0530 Subject: [PATCH 047/105] refactor: remove column resize directive BREAKING CHANGE: removed `ResizeableDirective`. This directive was intended for internal use to handle column resizing, which is now managed directly in the `DataTableHeaderCellComponent`. --- .../header/header-cell.component.ts | 54 ++++++++++- .../lib/components/header/header.component.ts | 12 +-- .../lib/directives/resizeable.directive.ts | 96 ------------------- 3 files changed, 56 insertions(+), 106 deletions(-) delete mode 100644 projects/swimlane/ngx-datatable/src/lib/directives/resizeable.directive.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts index b779d47db..a48135273 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts @@ -2,11 +2,13 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + ElementRef, EventEmitter, HostBinding, HostListener, inject, Input, + OnDestroy, OnInit, Output, TemplateRef @@ -21,6 +23,7 @@ import { } from '../../types/public.types'; import { NgTemplateOutlet } from '@angular/common'; import { InnerSortEvent, TableColumnInternal } from '../../types/internal.types'; +import { fromEvent, Subscription, takeUntil } from 'rxjs'; @Component({ selector: 'datatable-header-cell', @@ -51,15 +54,19 @@ import { InnerSortEvent, TableColumnInternal } from '../../types/internal.types' } + @if (column.resizeable) { + + } `, host: { - class: 'datatable-header-cell' + 'class': 'datatable-header-cell', + '[attr.resizeable]': 'column.resizeable' }, styleUrl: './header-cell.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet] }) -export class DataTableHeaderCellComponent implements OnInit { +export class DataTableHeaderCellComponent implements OnInit, OnDestroy { private cd = inject(ChangeDetectorRef); @Input() sortType: SortType; @@ -116,6 +123,8 @@ export class DataTableHeaderCellComponent implements OnInit { event: MouseEvent; column: TableColumnInternal; }>(false); + @Output() resize = new EventEmitter<{ width: number; column: TableColumnInternal }>(); + @Output() resizing = new EventEmitter<{ width: number; column: TableColumnInternal }>(); @HostBinding('class') get columnCssClasses(): string { @@ -192,6 +201,8 @@ export class DataTableHeaderCellComponent implements OnInit { private _column: TableColumnInternal; private _sorts: SortPropDir[]; + private element = inject(ElementRef).nativeElement; + private subscription: Subscription; constructor() { this.cellContext = { @@ -221,6 +232,10 @@ export class DataTableHeaderCellComponent implements OnInit { } } + ngOnDestroy() { + this.destroySubscription(); + } + calcSortDir(sorts: SortPropDir[]): any { if (sorts && this.column) { const sort = sorts.find((s: any) => { @@ -265,4 +280,39 @@ export class DataTableHeaderCellComponent implements OnInit { return `sort-btn ${this.sortUnsetIcon ?? 'datatable-icon-sort-unset'}`; } } + + protected onMousedown(event: MouseEvent): void { + const initialWidth = this.element.clientWidth; + const mouseDownScreenX = event.screenX; + event.stopPropagation(); + + const mouseup = fromEvent(document, 'mouseup'); + this.subscription = mouseup.subscribe(() => this.onMouseup()); + + const mouseMoveSub = fromEvent(document, 'mousemove') + .pipe(takeUntil(mouseup)) + .subscribe((e: Event) => this.move(e, initialWidth, mouseDownScreenX)); + + this.subscription.add(mouseMoveSub); + } + + private onMouseup(): void { + if (this.subscription && !this.subscription.closed) { + this.destroySubscription(); + this.resize.emit({ width: this.element.clientWidth, column: this.column }); + } + } + + private move(event: Event, initialWidth: number, mouseDownScreenX: number): void { + const movementX = (event as MouseEvent).screenX - mouseDownScreenX; + const newWidth = initialWidth + movementX; + this.resizing.emit({ width: newWidth, column: this.column }); + } + + private destroySubscription(): void { + if (this.subscription) { + this.subscription.unsubscribe(); + this.subscription = undefined; + } + } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index e97108e24..ef10bdb10 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -32,7 +32,6 @@ import { } from '../../types/internal.types'; import { DraggableDirective } from '../../directives/draggable.directive'; import { LongPressDirective } from '../../directives/long-press.directive'; -import { ResizeableDirective } from '../../directives/resizeable.directive'; import { DataTableHeaderCellComponent } from './header-cell.component'; import { OrderableDirective } from '../../directives/orderable.directive'; @@ -52,10 +51,8 @@ import { OrderableDirective } from '../../directives/orderable.directive'; @for (column of colGroup.columns; track column.$$id) { ): void { + onColumnResized({ width, column }: { width: number; column: TableColumnInternal }): void { this.resize.emit(this.makeResizeEvent(width, column)); } - onColumnResizing(width: number, column: TableColumnInternal): void { + onColumnResizing({ width, column }: { width: number; column: TableColumnInternal }): void { this.resizing.emit(this.makeResizeEvent(width, column)); } diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/resizeable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/resizeable.directive.ts deleted file mode 100644 index 73b7ec60d..000000000 --- a/projects/swimlane/ngx-datatable/src/lib/directives/resizeable.directive.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { - AfterViewInit, - booleanAttribute, - Directive, - ElementRef, - EventEmitter, - HostBinding, - HostListener, - inject, - Input, - numberAttribute, - OnDestroy, - Output, - Renderer2 -} from '@angular/core'; -import { fromEvent, Subscription } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; - -@Directive({ - selector: '[resizeable]', - standalone: true -}) -export class ResizeableDirective implements OnDestroy, AfterViewInit { - private renderer = inject(Renderer2); - - @HostBinding('class.resizeable') @Input({ transform: booleanAttribute }) resizeEnabled = true; - @Input({ transform: numberAttribute }) minWidth: number; - @Input({ transform: numberAttribute }) maxWidth: number; - - @Output() resize: EventEmitter = new EventEmitter(); - @Output() resizing: EventEmitter = new EventEmitter(); - - element = inject(ElementRef).nativeElement; - subscription: Subscription; - private resizeHandle: HTMLElement; - - ngAfterViewInit(): void { - const renderer2 = this.renderer; - this.resizeHandle = renderer2.createElement('span'); - if (this.resizeEnabled) { - renderer2.addClass(this.resizeHandle, 'resize-handle'); - } else { - renderer2.addClass(this.resizeHandle, 'resize-handle--not-resizable'); - } - renderer2.appendChild(this.element, this.resizeHandle); - } - - ngOnDestroy(): void { - this._destroySubscription(); - if (this.renderer.destroyNode) { - this.renderer.destroyNode(this.resizeHandle); - } else if (this.resizeHandle) { - this.renderer.removeChild(this.renderer.parentNode(this.resizeHandle), this.resizeHandle); - } - } - - onMouseup(): void { - if (this.subscription && !this.subscription.closed) { - this._destroySubscription(); - this.resize.emit(this.element.clientWidth); - } - } - - @HostListener('mousedown', ['$event']) - onMousedown(event: MouseEvent): void { - const isHandle = (event.target as HTMLElement).classList.contains('resize-handle'); - const initialWidth = this.element.clientWidth; - const mouseDownScreenX = event.screenX; - - if (isHandle) { - event.stopPropagation(); - - const mouseup = fromEvent(document, 'mouseup'); - this.subscription = mouseup.subscribe(() => this.onMouseup()); - - const mouseMoveSub = fromEvent(document, 'mousemove') - .pipe(takeUntil(mouseup)) - .subscribe(e => this.move(e, initialWidth, mouseDownScreenX)); - - this.subscription.add(mouseMoveSub); - } - } - - move(event: MouseEvent, initialWidth: number, mouseDownScreenX: number): void { - const movementX = event.screenX - mouseDownScreenX; - const newWidth = initialWidth + movementX; - this.resizing.emit(newWidth); - } - - private _destroySubscription() { - if (this.subscription) { - this.subscription.unsubscribe(); - this.subscription = undefined; - } - } -} From 2243bdcb5f2f455f3f895b22d8ee17d7106a7967 Mon Sep 17 00:00:00 2001 From: Chintan Kavathia Date: Tue, 11 Mar 2025 11:23:09 +0530 Subject: [PATCH 048/105] test: unit tests for header cell --- .../header/header-cell.component.spec.ts | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts new file mode 100644 index 000000000..b73538916 --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.spec.ts @@ -0,0 +1,46 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { DataTableHeaderCellComponent } from './header-cell.component'; +import { TableColumnInternal } from '../../types/internal.types'; + +describe('DataTableHeaderCellComponent', () => { + let fixture: ComponentFixture; + let component: DataTableHeaderCellComponent; + + beforeEach(waitForAsync(() => { + fixture = TestBed.createComponent(DataTableHeaderCellComponent); + component = fixture.componentInstance; + })); + + it('should emit new width on resize', () => { + fixture.componentRef.setInput('column', { + name: 'test', + resizeable: true + }); + spyOn(component.resizing, 'emit'); + fixture.detectChanges(); + const initialWidth = fixture.nativeElement.clientWidth; + const event = new MouseEvent('mousedown'); + fixture.nativeElement.querySelector('.resize-handle').dispatchEvent(event); + const mouseMoveEvent = new MouseEvent('mousemove', { screenX: 100 }); + document.dispatchEvent(mouseMoveEvent); + const mouseUpEvent = new MouseEvent('mouseup'); + document.dispatchEvent(mouseUpEvent); + const newWidth = 100 + initialWidth; + expect(component.resizing.emit).toHaveBeenCalledWith({ + width: newWidth, + column: { name: 'test', resizeable: true } as TableColumnInternal + }); + }); + + it('should emit sort event', () => { + fixture.componentRef.setInput('column', { + prop: 'test', + sortable: true + }); + spyOn(component.sort, 'emit'); + fixture.detectChanges(); + const event = new MouseEvent('click'); + fixture.nativeElement.querySelector('.datatable-header-cell-label').dispatchEvent(event); + expect(component.sort.emit).toHaveBeenCalled(); + }); +}); From 64be85b321a8c7123f503f11819c8d668f581698 Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 27 Mar 2025 11:40:01 +0100 Subject: [PATCH 049/105] fix: apply even/odd classes correctly when rows are grouped (#111) BREAKING CHANGE: Previously `CellContext.rowIndex` was a `string` if the row was inside a group. Now `CellContext.rowIndex` is always a number. Either containing the index of the row or if the row is inside a group, the index of the group. To access the index value of a row within a group, use the new`CellContext.rowInGroupIndex`. --- .../components/body/body-cell.component.ts | 14 +++-- .../body/body-row.component.spec.ts | 61 +++++++++++++++++++ .../lib/components/body/body-row.component.ts | 18 ++++-- .../src/lib/components/body/body.component.ts | 32 +++++----- .../body/summary/summary-row.component.ts | 2 +- .../src/lib/types/internal.types.ts | 8 +++ .../src/lib/types/public.types.ts | 1 + 7 files changed, 109 insertions(+), 27 deletions(-) create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 901a7f14a..e55e9b379 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -25,7 +25,7 @@ import { } from '../../types/public.types'; import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.component'; import { NgTemplateOutlet } from '@angular/common'; -import { TableColumnInternal } from '../../types/internal.types'; +import { RowIndex, TableColumnInternal } from '../../types/internal.types'; @Component({ selector: 'datatable-body-cell', @@ -137,14 +137,15 @@ export class DataTableBodyCellComponent implements DoChe return this._expanded; } - @Input() set rowIndex(val: number) { + @Input() set rowIndex(val: RowIndex) { this._rowIndex = val; - this.cellContext.rowIndex = val; + this.cellContext.rowIndex = val?.index; + this.cellContext.rowInGroupIndex = val?.indexInGroup; this.checkValueUpdates(); this.cd.markForCheck(); } - get rowIndex(): number { + get rowIndex(): RowIndex { return this._rowIndex; } @@ -288,7 +289,7 @@ export class DataTableBodyCellComponent implements DoChe private _row: TRow; private _group: TRow[]; private _rowHeight: number; - private _rowIndex: number; + private _rowIndex: RowIndex; private _expanded: boolean; private _element = inject>(ElementRef).nativeElement; private _treeStatus: TreeStatus; @@ -304,7 +305,8 @@ export class DataTableBodyCellComponent implements DoChe column: this.column, rowHeight: this.rowHeight, isSelected: this.isSelected, - rowIndex: this.rowIndex, + rowIndex: this.rowIndex?.index, + rowInGroupIndex: this.rowIndex?.indexInGroup, treeStatus: this.treeStatus, disabled: this._disabled, onTreeAction: () => this.onTreeAction() diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts new file mode 100644 index 000000000..5d44b414b --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts @@ -0,0 +1,61 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { DataTableBodyRowComponent } from './body-row.component'; +import { Component } from '@angular/core'; +import { ScrollbarHelper } from '../../services/scrollbar-helper.service'; +import { TableColumn } from '../../types/table-column.type'; +import { By } from '@angular/platform-browser'; +import { RowIndex } from '../../types/internal.types'; +import { toInternalColumn } from '../../utils/column-helper'; + +describe('DataTableBodyRowComponent', () => { + @Component({ + template: ` `, + imports: [DataTableBodyRowComponent], + standalone: true + }) + class TestHostComponent { + rowIndex: RowIndex = { index: 0 }; + row: any = { prop: 'value' }; + columns: TableColumn[] = toInternalColumn([{ prop: 'prop' }]); + } + + let fixture: ComponentFixture; + let component: TestHostComponent; + + // provide our implementations or mocks to the dependency injector + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TestHostComponent], + providers: [ScrollbarHelper] + }); + }); + + beforeEach(waitForAsync(() => { + TestBed.compileComponents().then(() => { + fixture = TestBed.createComponent(TestHostComponent); + component = fixture.componentInstance; + }); + })); + + it('should apply odd/event without groups', () => { + component.rowIndex = { index: 0 }; + fixture.detectChanges(); + const element = fixture.debugElement.query(By.directive(DataTableBodyRowComponent)) + .nativeElement as HTMLElement; + expect(element.classList).toContain('datatable-row-even'); + component.rowIndex = { index: 3 }; + fixture.detectChanges(); + expect(element.classList).toContain('datatable-row-odd'); + }); + + it('should apply event odd/even if row is grouped', () => { + component.rowIndex = { index: 1, indexInGroup: 0 }; + fixture.detectChanges(); + const element = fixture.debugElement.query(By.directive(DataTableBodyRowComponent)) + .nativeElement as HTMLElement; + expect(element.classList).toContain('datatable-row-even'); + component.rowIndex = { index: 666, indexInGroup: 3 }; + fixture.detectChanges(); + expect(element.classList).toContain('datatable-row-odd'); + }); +}); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index 4b3520bb0..4d1c3e6f0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -19,7 +19,12 @@ import { import { columnGroupWidths, columnsByPin, columnsByPinArr } from '../../utils/column'; import { Keys } from '../../utils/keys'; import { ActivateEvent, RowOrGroup, TreeStatus } from '../../types/public.types'; -import { ColumnGroupWidth, PinnedColumns, TableColumnInternal } from '../../types/internal.types'; +import { + ColumnGroupWidth, + PinnedColumns, + RowIndex, + TableColumnInternal +} from '../../types/internal.types'; import { DataTableBodyCellComponent } from './body-cell.component'; @Component({ @@ -89,7 +94,7 @@ export class DataTableBodyRowComponent implements DoCheck, OnChanges @Input() row: TRow; @Input() group: TRow[]; @Input() isSelected: boolean; - @Input() rowIndex: number; + @Input() rowIndex: RowIndex | undefined; @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value?: any) => boolean; @Input() treeStatus?: TreeStatus = 'collapsed'; @Input() ghostLoadingIndicator = false; @@ -103,10 +108,10 @@ export class DataTableBodyRowComponent implements DoCheck, OnChanges if (this.isSelected) { cls += ' active'; } - if (this.rowIndex % 2 !== 0) { + if (this.innerRowIndex % 2 !== 0) { cls += ' datatable-row-odd'; } - if (this.rowIndex % 2 === 0) { + if (this.innerRowIndex % 2 === 0) { cls += ' datatable-row-even'; } if (this.disabled) { @@ -217,4 +222,9 @@ export class DataTableBodyRowComponent implements DoCheck, OnChanges onTreeAction() { this.treeAction.emit(); } + + /** Returns the row index, or if in a group, the index within a group. */ + private get innerRowIndex(): number { + return this.rowIndex?.indexInGroup ?? this.rowIndex?.index ?? 0; + } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 6cbac2233..eeaa95f75 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -22,7 +22,7 @@ import { NgStyle } from '@angular/common'; import { DatatableGroupHeaderDirective } from './body-group-header.directive'; import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive'; import { DataTableBodyRowComponent } from './body-row.component'; -import { ColumnGroupWidth, TableColumnInternal } from '../../types/internal.types'; +import { ColumnGroupWidth, RowIndex, TableColumnInternal } from '../../types/internal.types'; import { ActivateEvent, DragEventData, @@ -109,7 +109,7 @@ import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.compo [row]="group" [disabled]="disabled" [expanded]="getRowExpanded(group)" - [rowIndex]="getRowIndex(group && $any(group)[i])" + [rowIndex]="getRowIndex(group && $any(group)[i])?.index ?? 0" [selected]="selected" (rowContextmenu)="rowContextmenu.emit($event)" > @@ -428,7 +428,7 @@ export class DataTableBodyComponent implements OnInit, O columnGroupWidths: ColumnGroupWidth; rowTrackingFn: TrackByFunction>; listener: any; - rowIndexes = new WeakMap(); + rowIndexes = new WeakMap, RowIndex>(); rowExpansions: any[] = []; _rows: TRow[]; @@ -454,8 +454,7 @@ export class DataTableBodyComponent implements OnInit, O if (this.trackByProp) { return (row as any)[this.trackByProp]; } else { - const idx = this.getRowIndex(row); - return idx; + return this.getRowIndex(row)?.index; } }; } @@ -595,13 +594,12 @@ export class DataTableBodyComponent implements OnInit, O while (rowIndex < last && rowIndex < this.groupedRows.length) { // Add the groups into this page const group = this.groupedRows[rowIndex]; - this.rowIndexes.set(group, rowIndex); + this.rowIndexes.set(group, { index: rowIndex }); if (group.value) { // add indexes for each group item - group.value.forEach((g: any, i: number) => { - const _idx = `${rowIndex}-${i}`; - this.rowIndexes.set(g, _idx); + group.value.forEach((g: TRow, i: number) => { + this.rowIndexes.set(g, { index: rowIndex, indexInGroup: i }); }); } temp[idx] = group; @@ -616,7 +614,7 @@ export class DataTableBodyComponent implements OnInit, O if (row) { // add indexes for each row - this.rowIndexes.set(row, rowIndex); + this.rowIndexes.set(row, { index: rowIndex }); temp[idx] = row; } else if (this.ghostLoadingIndicator && this.virtualization) { temp[idx] = undefined; @@ -725,10 +723,12 @@ export class DataTableBodyComponent implements OnInit, O if (Array.isArray(rows)) { // Get the latest row rowindex in a group const row = rows[rows.length - 1]; - idx = row ? this.getRowIndex(row) : 0; + // The group row, which has always a numeric index + idx = row ? this.getRowIndex(row).index : 0; } else { if (rows) { - idx = this.getRowIndex(rows); + // normal rows always have a numeric index + idx = this.getRowIndex(rows).index; } else { // When ghost cells are enabled use index to get the position of them idx = this.indexes().first + index; @@ -867,8 +867,8 @@ export class DataTableBodyComponent implements OnInit, O // If the detailRowHeight is auto --> only in case of non-virtualized scroll if (this.scrollbarV && this.virtualization) { const detailRowHeight = this.getDetailRowHeight(row) * (expanded ? -1 : 1); - // const idx = this.rowIndexes.get(row) || 0; - const idx = this.getRowIndex(row); + // This is hopefully only called with non-grouped rows. Otherwise, the heightCache fails. + const idx = this.getRowIndex(row)?.index ?? 0; this.rowHeightsCache().update(idx, detailRowHeight); } @@ -949,8 +949,8 @@ export class DataTableBodyComponent implements OnInit, O /** * Gets the row index given a row */ - getRowIndex(row: RowOrGroup): number { - return this.rowIndexes.get(row) || 0; + getRowIndex(row: RowOrGroup): RowIndex | undefined { + return this.rowIndexes.get(row); } onTreeAction(row: TRow) { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts index d8bd84c87..1f382744d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts @@ -29,7 +29,7 @@ function noopSumFunc(cells: any[]): void { [columns]="_internalColumns" [rowHeight]="rowHeight" [row]="summaryRow" - [rowIndex]="-1" + [rowIndex]="{ index: -1 }" > } diff --git a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts index d9d81e568..54ba2c82c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts @@ -76,3 +76,11 @@ export interface TableColumnGroup { center: TableColumnInternal[]; right: TableColumnInternal[]; } + +/** Represents the index of a row. */ +export interface RowIndex { + /** Index of the row. If the row is inside a group, it will hold the index the group. */ + index: number; + /** Index of a row inside a group. Only present if the row is inside a group. */ + indexInGroup?: number; +} diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index 1e6bc5458..d0617529e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -68,6 +68,7 @@ export interface CellContext { rowHeight: number; isSelected: boolean; rowIndex: number; + rowInGroupIndex?: number; treeStatus: TreeStatus; disabled: boolean; onTreeAction: () => void; From ce7dbd8670569b86b064b20e5f8c328a4d75d1dc Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 27 Mar 2025 11:44:58 +0100 Subject: [PATCH 050/105] refactor: deprecate `PageEvent.limit` (#196) DEPRECATED: `PageEvent.limit` should no longer be used. Use the `PageEvent.pageSize` instead as this will hold the same value as `PageEvent.limit` if the table used the value of the limit input. --- .../ngx-datatable/src/lib/types/public.types.ts | 3 ++- src/app/paging/paging-virtual.component.ts | 15 ++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index d0617529e..82be4e92e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -125,7 +125,8 @@ export interface ReorderEvent { export interface PageEvent { count: number; pageSize: number; - limit: number; + /** @deprecated Use {@link pageSize} instead. */ + limit: number | undefined; offset: number; } diff --git a/src/app/paging/paging-virtual.component.ts b/src/app/paging/paging-virtual.component.ts index d08c63298..4a7d8bcaf 100644 --- a/src/app/paging/paging-virtual.component.ts +++ b/src/app/paging/paging-virtual.component.ts @@ -1,16 +1,13 @@ import { Component } from '@angular/core'; import { MockServerResultsService } from './mock-server-results-service'; import { Page } from './model/page'; -import { ColumnMode, DatatableComponent } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { + ColumnMode, + DatatableComponent, + PageEvent +} from 'projects/swimlane/ngx-datatable/src/public-api'; import { Employee } from '../data.model'; -interface PageInfo { - offset: number; - pageSize: number; - limit: number; - count: number; -} - @Component({ selector: 'virtual-paging-demo', providers: [MockServerResultsService], @@ -71,7 +68,7 @@ export class VirtualPagingComponent { this.pageNumber = 0; } - setPage(pageInfo: PageInfo) { + setPage(pageInfo: PageEvent) { // Current page number is determined by last call to setPage // This is the page the UI is currently displaying // The current page is based on the UI pagesize and scroll position From adf9d69ff6fa6e5dba5ebcc61512e5e74c9211a6 Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 27 Mar 2025 11:54:20 +0100 Subject: [PATCH 051/105] refactor: move body styles to component level (#202) --- .../body/body-row-wrapper.component.scss | 8 +++++ .../body/body-row-wrapper.component.ts | 2 ++ .../components/body/body-row.component.scss | 7 +++++ .../lib/components/body/body-row.component.ts | 1 + .../lib/components/body/body.component.scss | 10 ++++++ .../src/lib/components/body/body.component.ts | 2 ++ .../lib/components/datatable.component.scss | 31 ------------------- 7 files changed, 30 insertions(+), 31 deletions(-) create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.scss create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.scss new file mode 100644 index 000000000..b238efb90 --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.scss @@ -0,0 +1,8 @@ +:host { + display: flex; + flex-direction: column; +} + +.datatable-row-detail { + overflow-y: hidden; +} diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts index a6e6edf49..d5f31cf4d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts @@ -69,6 +69,8 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive' host: { class: 'datatable-row-wrapper' }, + styleUrl: './body-row-wrapper.component.scss', + standalone: true, imports: [NgTemplateOutlet] }) export class DataTableRowWrapperComponent implements DoCheck, OnInit, OnChanges { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss new file mode 100644 index 000000000..e94ddc3e5 --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss @@ -0,0 +1,7 @@ +:host { + outline: none; + + > div { + display: flex; + } +} diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index 4d1c3e6f0..f9afe0906 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -60,6 +60,7 @@ import { DataTableBodyCellComponent } from './body-cell.component'; } `, + styleUrl: './body-row.component.scss', standalone: true, imports: [DataTableBodyCellComponent] }) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss new file mode 100644 index 000000000..7c0cc0f0c --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss @@ -0,0 +1,10 @@ +:host { + position: relative; + z-index: 10; + display: block; + overflow: hidden; +} + +datatable-scroller { + display: inline-block; +} diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index eeaa95f75..648f9ed44 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -253,6 +253,8 @@ import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.compo host: { class: 'datatable-body' }, + styleUrl: './body.component.scss', + standalone: true, imports: [ DataTableGhostLoaderComponent, DataTableSelectionComponent, diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 100247d87..109f2ed0a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -124,35 +124,4 @@ .datatable-row-group { position: relative; } - - /** - * Body Styles - */ - .datatable-body { - position: relative; - z-index: 10; - display: block; - overflow: hidden; - - .datatable-scroll { - display: inline-block; - } - - .datatable-row-detail { - overflow-y: hidden; - } - - .datatable-row-wrapper { - display: flex; - flex-direction: column; - } - - .datatable-body-row { - outline: none; - - > div { - display: flex; - } - } - } } From ae0ad7c7a23cb49c7622cadc17af857e239352a3 Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 27 Mar 2025 12:44:13 +0100 Subject: [PATCH 052/105] refactor: simplify tree construction (#205) --- playwright/e2e/tree.spec.ts | 26 ++++++++ ...lient-tree--client-tree-chromium-linux.png | 3 + ...n-tree--fullscreen-tree-chromium-linux.png | 3 + .../ngx-datatable/src/lib/utils/tree.ts | 61 ++++++------------- 4 files changed, 51 insertions(+), 42 deletions(-) create mode 100644 playwright/e2e/tree.spec.ts create mode 100644 playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png create mode 100644 playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png diff --git a/playwright/e2e/tree.spec.ts b/playwright/e2e/tree.spec.ts new file mode 100644 index 000000000..96ffc5e6f --- /dev/null +++ b/playwright/e2e/tree.spec.ts @@ -0,0 +1,26 @@ +import { test } from '../support/test-helpers'; + +test.describe('tree', () => { + test.describe('fullscreen tree', () => { + const example = 'fullscreen-tree'; + test(example, async ({ si, page }) => { + await si.visitExample(example); + await page.getByRole('cell', { name: 'Frank Bradford' }).getByRole('button').click(); + await page.getByRole('cell', { name: 'Carrie Mcconnell' }).getByRole('button').click(); + await page.getByRole('cell', { name: 'Kathryn Rios' }).getByRole('button').click(); + await page.getByRole('cell', { name: 'Stefanie Huff' }).getByRole('button').click(); + + await si.runVisualAndA11yTests('fullscreen-tree'); + }); + }); + + test.describe('client tree', () => { + const example = 'client-tree'; + test(example, async ({ si, page }) => { + await si.visitExample(example); + await page.getByRole('cell', { name: 'Georgina Schultz ' }).getByRole('button').click(); + + await si.runVisualAndA11yTests('client-tree'); + }); + }); +}); diff --git a/playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png b/playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png new file mode 100644 index 000000000..3c3fb6806 --- /dev/null +++ b/playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e421b8bba7f879870d31fd4502183498bf0cca96f66c3d8f3eac4ad04cbba8bf +size 68919 diff --git a/playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png b/playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png new file mode 100644 index 000000000..299557199 --- /dev/null +++ b/playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a1eefc01c1cfd28d85a65d75072598235221714be0bf111a54e9da3cc5fbe07 +size 106457 diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts index 062577b82..3ef8c5685 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts @@ -49,45 +49,24 @@ export function groupRowsByParents( to?: OptionalValueGetter ): TRow[] { if (from && to) { - const nodeById: Record> = {}; - const l = rows.length; - let node: TreeNode | null = null; + const treeRows = rows.map(row => new TreeNode(row)); + const uniqIDs = new Map(treeRows.map(node => [to(node.row), node])); - nodeById[0] = new TreeNode({ - level: -1, - treeStatus: 'expanded' - } as unknown as TRow); // that's the root node, TODO: needs type that reflect this - - const uniqIDs = rows.reduce((arr, item) => { - const toValue = to(item); - if (arr.indexOf(toValue) === -1) { - arr.push(toValue); - } - return arr; - }, []); - - for (let i = 0; i < l; i++) { - // make TreeNode objects for each item - nodeById[to(rows[i])] = new TreeNode(rows[i]); - } - - for (let i = 0; i < l; i++) { - // link all TreeNode objects - node = nodeById[to(rows[i])]; - let parent = 0; + const rootNodes = treeRows.reduce((root, node) => { const fromValue = from(node.row); - if (!!fromValue && uniqIDs.indexOf(fromValue) > -1) { - parent = fromValue; + const parent = uniqIDs.get(fromValue); + if (parent) { + node.row.level = parent.row.level + 1; + node.parent = parent; + parent.children.push(node); + } else { + node.row.level = 1; + root.push(node); } - node.parent = nodeById[parent]; - node.row['level'] = node.parent.row['level'] + 1; - node.parent.children.push(node); - } + return root; + }, [] as TreeNode[]); - let resolvedRows: any[] = []; - nodeById[0].flatten(row => (resolvedRows = [...resolvedRows, row])); - - return resolvedRows; + return rootNodes.flatMap(child => child.flatten()); } else { return rows; } @@ -95,7 +74,7 @@ export function groupRowsByParents( class TreeNode { public row: TRow; - public parent: TreeNode; + public parent?: TreeNode; public children: TreeNode[]; constructor(row: TRow) { @@ -104,13 +83,11 @@ class TreeNode { this.children = []; } - flatten(f: (child: TreeNode) => void) { + flatten(): TRow[] { if (this.row.treeStatus === 'expanded') { - for (let i = 0, l = this.children.length; i < l; i++) { - const child = this.children[i]; - f(child); - child.flatten(f); - } + return [this.row, ...this.children.flatMap(child => child.flatten())]; + } else { + return [this.row]; } } } From 94fa8a835dfb2746fcdc76d7633d4b3ab52e00c8 Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 27 Mar 2025 12:52:45 +0100 Subject: [PATCH 053/105] refactor: move fixed-header styles to component level (#203) --- .../src/lib/components/datatable.component.scss | 16 ---------------- .../components/header/header-cell.component.scss | 6 ++++++ .../lib/components/header/header.component.scss | 4 ++++ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 109f2ed0a..2908fd550 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -41,22 +41,6 @@ } } - /** - * Fixed Header Height Adjustments - */ - &.fixed-header { - .datatable-header { - .datatable-header-inner { - white-space: nowrap; - .datatable-header-cell { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - } - } - } - /** * Fixed row height adjustments */ diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss index 7c270a674..29a65dc05 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss @@ -2,6 +2,12 @@ position: relative; display: inline-block; + :host-context(ngx-datatable.fixed-header) & { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + &.sortable { .datatable-header-cell-wrapper { cursor: pointer; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss index 546ab17ed..ffff3f901 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss @@ -6,4 +6,8 @@ .datatable-header-inner { align-items: stretch; -webkit-align-items: stretch; + + :host-context(ngx-datatable.fixed-header) & { + white-space: nowrap; + } } From 4df53b0a61b963b44155e3fe6d8632c9dda1d1a6 Mon Sep 17 00:00:00 2001 From: Maxi Date: Thu, 27 Mar 2025 12:57:13 +0100 Subject: [PATCH 054/105] refactor: make column resize handling typesafe (#204) --- .../src/lib/components/datatable.component.ts | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index ffad41586..c017d2926 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -1091,22 +1091,12 @@ export class DatatableComponent return; } - let idx: number; - const cols = this._internalColumns.map((c, i) => { - c = { ...c }; - - if (c.$$id === column.$$id) { - idx = i; - c.width = newValue; - - // set this so we can force the column - // width distribution to be to this value - c.$$oldWidth = newValue; - } - - return c; - }); - + const idx = this._internalColumns.indexOf(column); + const cols = this._internalColumns.map(col => ({ ...col })); + cols[idx].width = newValue; + // set this so we can force the column + // width distribution to be to this value + cols[idx].$$oldWidth = newValue; this.recalculateColumns(cols, idx); this._internalColumns = cols; From 49a8cba78f82c55d608d816a1cc0aede9fee05d0 Mon Sep 17 00:00:00 2001 From: Chintan Kavathia Date: Fri, 28 Feb 2025 16:47:25 +0530 Subject: [PATCH 055/105] refactor: remove duplicate template code --- .../components/body/body-row-def.component.ts | 10 +- .../lib/components/body/body-row.directive.ts | 20 +++ .../src/lib/components/body/body.component.ts | 167 ++++++++---------- 3 files changed, 99 insertions(+), 98 deletions(-) create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts index 5715e376a..047be265b 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts @@ -10,6 +10,7 @@ import { ViewContainerRef } from '@angular/core'; import { NgTemplateOutlet } from '@angular/common'; +import { RowOrGroup } from '../../types/public.types'; /** * This component is passed as ng-template and rendered by BodyComponent. @@ -21,13 +22,17 @@ import { NgTemplateOutlet } from '@angular/common'; template: `@if (rowDef.rowDefInternal.rowTemplate) { }`, imports: [NgTemplateOutlet] }) export class DatatableRowDefComponent { rowDef = inject(RowDefToken); + rowContext = { + ...this.rowDef.rowDefInternal, + disabled: this.rowDef.rowDefInternalDisabled + }; } @Directive({ @@ -54,6 +59,7 @@ export class DatatableRowDefInternalDirective implements OnInit { vc = inject(ViewContainerRef); @Input() rowDefInternal?: RowDefContext; + @Input() rowDefInternalDisabled?: boolean; ngOnInit(): void { this.vc.createEmbeddedView( @@ -78,6 +84,6 @@ const RowDefToken = new InjectionToken('RowDef type RowDefContext = { template: TemplateRef; rowTemplate: TemplateRef; - row: any; + row: RowOrGroup; index: number; }; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts new file mode 100644 index 000000000..e7408fb89 --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts @@ -0,0 +1,20 @@ +import { Directive } from '@angular/core'; +import { Row } from '../../types/public.types'; + +@Directive({ + selector: '[ngx-datatable-body-row]', + standalone: true +}) +export class DatatableBodyRowDirective { + static ngTemplateContextGuard( + directive: DatatableBodyRowDirective, + context: unknown + ): context is { + row: TRow; + groupedRows: TRow[]; + index: number; + disabled: boolean; + } { + return true; + } +} diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 648f9ed44..21b4d889f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -18,7 +18,7 @@ import { import { ScrollerComponent } from './scroller.component'; import { columnGroupWidths, columnsByPin } from '../../utils/column'; import { RowHeightCache } from '../../utils/row-height-cache'; -import { NgStyle } from '@angular/common'; +import { NgStyle, NgTemplateOutlet } from '@angular/common'; import { DatatableGroupHeaderDirective } from './body-group-header.directive'; import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive'; import { DataTableBodyRowComponent } from './body-row.component'; @@ -39,6 +39,7 @@ import { DataTableRowWrapperComponent } from './body-row-wrapper.component'; import { DataTableSummaryRowComponent } from './summary/summary-row.component'; import { DataTableSelectionComponent } from './selection.component'; import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.component'; +import { DatatableBodyRowDirective } from './body-row.directive'; @Component({ selector: 'datatable-body', @@ -90,6 +91,45 @@ import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.compo > } + + + + + @for (group of rowsToRender(); track rowTrackingFn(i, group); let i = $index) { @let disabled = isRow(group) && disableRowCheck && disableRowCheck(group); @@ -115,109 +155,42 @@ import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.compo > @if (rowDefTemplate) { } @else { @if (isRow(group)) { - - + } } - - @if (isRow(group)) { - - - } - - @if (isGroup(group)) { @for (row of group.value; track rowTrackingFn(i, row); let i = $index) { - @let rowInGroupDisabled = disableRowCheck && disableRowCheck(row); - - + @let disabled = disableRowCheck && disableRowCheck(row); + } } @@ -264,7 +237,9 @@ import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.compo NgStyle, DatatableRowDefInternalDirective, DataTableBodyRowComponent, - DraggableDirective + DraggableDirective, + NgTemplateOutlet, + DatatableBodyRowDirective ] }) export class DataTableBodyComponent implements OnInit, OnDestroy { From 3ed71c90d2b9b101fe369c1129afb137d551e78b Mon Sep 17 00:00:00 2001 From: Chintan Kavathia Date: Fri, 28 Mar 2025 11:24:49 +0530 Subject: [PATCH 056/105] refactor: remove custom test matchers --- .../footer/footer.component.spec.ts | 17 +++--- .../ngx-datatable/src/lib/test/index.ts | 1 - .../src/lib/test/jasmine-matchers.d.ts | 12 ---- .../src/lib/test/jasmine-matchers.ts | 59 ------------------- 4 files changed, 7 insertions(+), 82 deletions(-) delete mode 100644 projects/swimlane/ngx-datatable/src/lib/test/index.ts delete mode 100644 projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.d.ts delete mode 100644 projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts index 625e88ab5..9623e4643 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts @@ -2,7 +2,6 @@ import { Component, DebugElement, TemplateRef, ViewChild } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { addMatchers } from '../../test'; import { DataTablePagerComponent } from './pager.component'; import { DataTableFooterComponent } from './footer.component'; @@ -11,8 +10,6 @@ let component: TestFixtureComponent; let page: Page; describe('DataTableFooterComponent', () => { - beforeAll(addMatchers); - beforeEach(waitForAsync(() => { fixture = TestBed.createComponent(TestFixtureComponent); component = fixture.componentInstance; @@ -33,14 +30,14 @@ describe('DataTableFooterComponent', () => { component.selectedCount = 1; page.detectChangesAndRunQueries(); - expect(page.datatableFooterInner.nativeElement).toHaveCssClass('selected-count'); + expect(page.datatableFooterInner.nativeElement).toHaveClass('selected-count'); }); it('should not have `.selected-count` class if selectedMessage is not set', () => { component.selectedMessage = undefined; page.detectChangesAndRunQueries(); - expect(page.datatableFooterInner.nativeElement).not.toHaveCssClass('selected-count'); + expect(page.datatableFooterInner.nativeElement).not.toHaveClass('selected-count'); }); }); @@ -203,11 +200,11 @@ describe('DataTableFooterComponent', () => { page.detectChangesAndRunQueries(); const listItems = page.templateList.queryAll(By.css('li')); - expect(listItems[0].nativeElement).toHaveText('rowCount 12'); - expect(listItems[1].nativeElement).toHaveText('pageSize 1'); - expect(listItems[2].nativeElement).toHaveText('selectedCount 4'); - expect(listItems[3].nativeElement).toHaveText('curPage 1'); - expect(listItems[4].nativeElement).toHaveText('offset 0'); + expect(listItems[0].nativeElement.innerHTML).toContain('rowCount 12'); + expect(listItems[1].nativeElement.innerHTML).toContain('pageSize 1'); + expect(listItems[2].nativeElement.innerHTML).toContain('selectedCount 4'); + expect(listItems[3].nativeElement.innerHTML).toContain('curPage 1'); + expect(listItems[4].nativeElement.innerHTML).toContain('offset 0'); }); }); }); diff --git a/projects/swimlane/ngx-datatable/src/lib/test/index.ts b/projects/swimlane/ngx-datatable/src/lib/test/index.ts deleted file mode 100644 index f5dea98a0..000000000 --- a/projects/swimlane/ngx-datatable/src/lib/test/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './jasmine-matchers'; diff --git a/projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.d.ts b/projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.d.ts deleted file mode 100644 index 906f1e1fd..000000000 --- a/projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare namespace jasmine { - interface Matchers { - toHaveText(actual: any, expectationFailOutput?: any): jasmine.CustomMatcher; - toHaveCssClass(expected: any, expectationFailOutput?: any): boolean; - } -} - -/* -Copyright 2017-2018 Google Inc. All Rights Reserved. -Use of this source code is governed by an MIT-style license that -can be found in the LICENSE file at http://angular.io/license -*/ diff --git a/projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.ts b/projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.ts deleted file mode 100644 index f27defb45..000000000 --- a/projects/swimlane/ngx-datatable/src/lib/test/jasmine-matchers.ts +++ /dev/null @@ -1,59 +0,0 @@ -/// - -function elementText(n: any): string { - if (n instanceof Array) { - return n.map(elementText).join(''); - } - - if (n.nodeType === Node.COMMENT_NODE) { - return ''; - } - - if (n.nodeType === Node.ELEMENT_NODE && n.hasChildNodes()) { - return elementText(Array.prototype.slice.call(n.childNodes)); - } - - if (n.nativeElement) { - n = n.nativeElement; - } - - return n.textContent; -} - -export const addMatchers = () => - jasmine.addMatchers({ - toHaveText: function toHaveText(): jasmine.CustomMatcher { - return { - compare( - actual: any, - expectedText: string, - expectationFailOutput?: any - ): jasmine.CustomMatcherResult { - const actualText = elementText(actual); - const pass = actualText.indexOf(expectedText) > -1; - const message = pass ? '' : composeMessage(); - return { pass, message }; - - function composeMessage() { - const a = actualText.length < 100 ? actualText : actualText.substr(0, 100) + '...'; - const efo = expectationFailOutput ? ` '${expectationFailOutput}'` : ''; - return `Expected element to have text content '${expectedText}' instead of '${a}'${efo}`; - } - } - }; - }, - toHaveCssClass: function (): jasmine.CustomMatcher { - return { compare: buildError(false), negativeCompare: buildError(true) }; - - function buildError(isNot: boolean) { - return function (actual: HTMLElement, className: string) { - return { - pass: actual.classList.contains(className) === !isNot, - message: `Expected ${actual.outerHTML} ${ - isNot ? 'not ' : '' - }to contain the CSS class "${className}"` - }; - }; - } - } - }); From ebeb57dcc09b6d7e5fb76221a75d5d25827be878 Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Thu, 26 Jun 2025 13:22:47 -0500 Subject: [PATCH 057/105] update lint rules --- .eslintrc.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 5a76414ed..ec5bba0c2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,12 +30,7 @@ module.exports = { rules: { '@angular-eslint/no-attribute-decorator': 'error', '@angular-eslint/no-forward-ref': 'error', - '@angular-eslint/no-host-metadata-property': [ - 'error', - { - 'allowStatic': true - } - ], + '@angular-eslint/no-host-metadata-property': 'off', 'brace-style': 'off', 'no-bitwise': 'off', 'comma-dangle': 'off', From 51e77ad4b4f2d9526c3dfa765142642314abc471 Mon Sep 17 00:00:00 2001 From: Maxi Date: Sun, 30 Mar 2025 09:19:44 +0200 Subject: [PATCH 058/105] fix: remove unwanted space below the rows (#214) BREAKING CHANGE: The datatable body no longer has spacing below the last row. If needed for whatever reason, this must be added manually. Workarounds removing this extra space must be dropped. --- playwright/e2e/row-disabled.spec.ts | 14 ---------- playwright/e2e/tree.spec.ts | 26 ------------------- .../disabled-chromium-linux.png | 3 --- ...lient-tree--client-tree-chromium-linux.png | 3 --- ...n-tree--fullscreen-tree-chromium-linux.png | 3 --- .../lib/components/body/body.component.scss | 2 +- 6 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 playwright/e2e/row-disabled.spec.ts delete mode 100644 playwright/e2e/tree.spec.ts delete mode 100644 playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png delete mode 100644 playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png delete mode 100644 playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png diff --git a/playwright/e2e/row-disabled.spec.ts b/playwright/e2e/row-disabled.spec.ts deleted file mode 100644 index ac4eb0708..000000000 --- a/playwright/e2e/row-disabled.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { test } from '../support/test-helpers'; - -test('disabled rows', async ({ si, page }) => { - await si.visitExample('disabled'); - await page - .getByRole('row', { name: 'Merritt Booker' }) - .getByRole('button', { name: 'Disable row' }) - .click(); - await si.runVisualAndA11yTests(undefined, [ - { id: 'color-contrast', enabled: false }, - { id: 'label', enabled: false }, - { id: 'select-name', enabled: false } - ]); -}); diff --git a/playwright/e2e/tree.spec.ts b/playwright/e2e/tree.spec.ts deleted file mode 100644 index 96ffc5e6f..000000000 --- a/playwright/e2e/tree.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { test } from '../support/test-helpers'; - -test.describe('tree', () => { - test.describe('fullscreen tree', () => { - const example = 'fullscreen-tree'; - test(example, async ({ si, page }) => { - await si.visitExample(example); - await page.getByRole('cell', { name: 'Frank Bradford' }).getByRole('button').click(); - await page.getByRole('cell', { name: 'Carrie Mcconnell' }).getByRole('button').click(); - await page.getByRole('cell', { name: 'Kathryn Rios' }).getByRole('button').click(); - await page.getByRole('cell', { name: 'Stefanie Huff' }).getByRole('button').click(); - - await si.runVisualAndA11yTests('fullscreen-tree'); - }); - }); - - test.describe('client tree', () => { - const example = 'client-tree'; - test(example, async ({ si, page }) => { - await si.visitExample(example); - await page.getByRole('cell', { name: 'Georgina Schultz ' }).getByRole('button').click(); - - await si.runVisualAndA11yTests('client-tree'); - }); - }); -}); diff --git a/playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png b/playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png deleted file mode 100644 index 29b4875ab..000000000 --- a/playwright/snapshots/e2e/row-disabled.spec.ts-snapshots/disabled-chromium-linux.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:da4606a7a5aa0d295588c2955d881d989c0aa0c316af9078d91648e38867f1ca -size 73082 diff --git a/playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png b/playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png deleted file mode 100644 index 3c3fb6806..000000000 --- a/playwright/snapshots/e2e/tree.spec.ts-snapshots/client-tree--client-tree-chromium-linux.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e421b8bba7f879870d31fd4502183498bf0cca96f66c3d8f3eac4ad04cbba8bf -size 68919 diff --git a/playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png b/playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png deleted file mode 100644 index 299557199..000000000 --- a/playwright/snapshots/e2e/tree.spec.ts-snapshots/fullscreen-tree--fullscreen-tree-chromium-linux.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8a1eefc01c1cfd28d85a65d75072598235221714be0bf111a54e9da3cc5fbe07 -size 106457 diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss index 7c0cc0f0c..5d7933ad9 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss @@ -6,5 +6,5 @@ } datatable-scroller { - display: inline-block; + display: block; } From 40ac6a04edc75682d06144bc749fcbc5e162845c Mon Sep 17 00:00:00 2001 From: Maxi Date: Mon, 31 Mar 2025 08:14:47 +0200 Subject: [PATCH 059/105] refactor: move horizontal scroll styles to respective components (#211) --- .../src/lib/components/body/body.component.scss | 5 +++++ .../src/lib/components/datatable.component.scss | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss index 5d7933ad9..691a42812 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss @@ -3,6 +3,11 @@ z-index: 10; display: block; overflow: hidden; + + :host-context(ngx-datatable.scroll-horz) & { + overflow-x: auto; + -webkit-overflow-scrolling: touch; // Required for iOS optimization + } } datatable-scroller { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 2908fd550..a5bd61a4f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -31,16 +31,6 @@ } } - /** - * Horizontal Scrolling Adjustments - */ - &.scroll-horz { - .datatable-body { - overflow-x: auto; - -webkit-overflow-scrolling: touch; // Required for iOS optimization - } - } - /** * Fixed row height adjustments */ From 9215e69fc92663214c982374c28f5b4ceb21c9e7 Mon Sep 17 00:00:00 2001 From: Maxi Date: Mon, 31 Mar 2025 09:14:36 +0200 Subject: [PATCH 060/105] refactor: ensure that rows are always defined internally (#192) BREAKING CHANGE: The datatable no longer accepts `undefined` as a value of the `count` input. The TypeScript type never allowed `undefined` but it previously worked anyway. Now passing `undefined` will lead to an error. Instead of `undefined` just pass `0` which has the same effect. --- .../src/lib/components/body/body.component.ts | 9 +++------ .../body/summary/summary-row.component.spec.ts | 2 ++ .../components/body/summary/summary-row.component.ts | 2 +- .../src/lib/components/datatable.component.ts | 12 ++++-------- src/app/paging/paging-virtual.component.ts | 2 +- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 21b4d889f..814aa6d93 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -73,7 +73,7 @@ import { DatatableBodyRowDirective } from './body-row.directive'; (select)="select.emit($event)" (activate)="activate.emit($event)" > - @if (rows?.length) { + @if (rows.length) { implements OnInit, O if (val !== this._offset) { this._offset = val; if (!this.scrollbarV || (this.scrollbarV && !this.virtualization)) { - if (!isNaN(this._offset) && this.ghostLoadingIndicator) { - this.rows = []; - } this.recalcLayout(); } } @@ -730,7 +727,7 @@ export class DataTableBodyComponent implements OnInit, O * @returns the CSS3 style to be applied */ bottomSummaryRowsStyles = computed(() => { - if (!this.scrollbarV || !this.rows || !this.rows.length || !this.rowsToRender()) { + if (!this.scrollbarV || !this.rows.length || !this.rowsToRender()) { return null; } @@ -789,7 +786,7 @@ export class DataTableBodyComponent implements OnInit, O this.rowHeightsCache().clearCache(); // Initialize the tree only if there are rows inside the tree. - if (this.rows && this.rows.length) { + if (this.rows.length) { const rowExpansions = new Set(); if (this.rowDetail) { for (const row of this.rows) { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts index 21298e024..3413c88bf 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts @@ -56,6 +56,7 @@ describe('DataTableSummaryRowComponent', () => { describe('Visibility', () => { it('should not be visible when there are no columns', () => { + component.columns = []; component.rows = rows; triggerChange(); expect(element.query(By.css('datatable-body-row'))).toBeNull(); @@ -63,6 +64,7 @@ describe('DataTableSummaryRowComponent', () => { it('should not be visible when there are no rows', () => { component.columns = columns; + component.rows = []; triggerChange(); expect(element.query(By.css('datatable-body-row'))).toBeNull(); }); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts index 1f382744d..89c63e473 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts @@ -51,7 +51,7 @@ export class DataTableSummaryRowComponent implements OnChanges { summaryRow: any = {}; ngOnChanges() { - if (!this.columns || !this.rows) { + if (!this.columns.length || !this.rows.length) { return; } this.updateInternalColumns(); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index c017d2926..fba10b7b6 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -117,7 +117,7 @@ export class DatatableComponent * Rows that are displayed in the table. */ @Input() set rows(val: TRow[] | null | undefined) { - this._rows = val; + this._rows = val ?? []; // This will ensure that datatable detects changes on doing like this rows = [...rows]; this.rowDiffer.diff([] as any); if (val) { @@ -307,7 +307,7 @@ export class DatatableComponent this._ghostLoadingIndicator = val; if (val && this.scrollbarV && !this.externalPaging) { // in case where we don't have predefined total page length - this.rows = [...(this.rows ?? []), undefined]; // undefined row will render ghost cell row at the end of the page + this.rows = [...this.rows, undefined]; // undefined row will render ghost cell row at the end of the page } } get ghostLoadingIndicator(): boolean { @@ -688,9 +688,9 @@ export class DatatableComponent _limit: number | undefined; _count = 0; _offset = 0; - _rows: TRow[] | null | undefined; + _rows: TRow[]; _groupRowsBy: keyof TRow; - _internalRows: TRow[]; + _internalRows: TRow[] = []; _internalColumns: TableColumnInternal[]; _columns: TableColumn[]; _subscriptions: Subscription[] = []; @@ -1052,10 +1052,6 @@ export class DatatableComponent */ calcRowCount(): number { if (!this.externalPaging) { - if (!this.rows) { - return 0; - } - if (this.groupedRows) { return this.groupedRows.length; } else if (this.treeFromRelation != null && this.treeToRelation != null) { diff --git a/src/app/paging/paging-virtual.component.ts b/src/app/paging/paging-virtual.component.ts index 4a7d8bcaf..0951c13cc 100644 --- a/src/app/paging/paging-virtual.component.ts +++ b/src/app/paging/paging-virtual.component.ts @@ -54,7 +54,7 @@ import { Employee } from '../data.model'; imports: [DatatableComponent] }) export class VirtualPagingComponent { - totalElements: number; + totalElements = 0; pageNumber: number; rows: Employee[]; cache: Record = {}; From 7a823861a79d60587d1cbacfd7a92942aa128870 Mon Sep 17 00:00:00 2001 From: Chintan Kavathia Date: Fri, 28 Mar 2025 11:03:06 +0530 Subject: [PATCH 061/105] refactor: tree level should start from 0 --- projects/swimlane/ngx-datatable/src/lib/utils/tree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts index 3ef8c5685..9a60c934f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts @@ -60,7 +60,7 @@ export function groupRowsByParents( node.parent = parent; parent.children.push(node); } else { - node.row.level = 1; + node.row.level = 0; root.push(node); } return root; From bab00e2645408a7f6793f8eb49941b6c47925459 Mon Sep 17 00:00:00 2001 From: Maxi Date: Mon, 31 Mar 2025 12:10:11 +0200 Subject: [PATCH 062/105] refactor: remove unused styles (#217) --- .../src/lib/components/datatable.component.scss | 6 ------ .../ngx-datatable/src/lib/themes/material.scss | 10 ---------- 2 files changed, 16 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index a5bd61a4f..2f3e50615 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -46,12 +46,6 @@ white-space: nowrap; text-overflow: ellipsis; } - - .datatable-body-group-cell { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } } } } diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss index 81a365ea5..3e81ffcfc 100644 --- a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss +++ b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss @@ -309,16 +309,6 @@ $datatble-ghost-cell-animation-duration: 10s; // background: #0829e0 // } } - .datatable-body-group-cell { - text-align: left; - padding: 0.9rem 1.2rem; - vertical-align: top; - border-top: 0; - color: $datatable-body-cell-color; - transition: width 0.3s ease; - font-size: 14px; - font-weight: 400; - } } .progress-linear { From 29cafb3b5a30b9c3c8fc9736323f6d5a239a25ac Mon Sep 17 00:00:00 2001 From: Maxi Date: Wed, 2 Apr 2025 08:51:04 +0200 Subject: [PATCH 063/105] refactor: move fixed-row styles to respective components (#218) --- .../components/body/body-cell.component.scss | 5 +++++ .../components/body/body-cell.component.ts | 1 + .../components/body/body-row.component.scss | 4 ++++ .../lib/components/body/body.component.scss | 4 ++++ .../lib/components/datatable.component.scss | 19 ------------------- 5 files changed, 14 insertions(+), 19 deletions(-) create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss new file mode 100644 index 000000000..08d5fdeb5 --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss @@ -0,0 +1,5 @@ +:host-context(ngx-datatable.fixed-row) :host { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index e55e9b379..37a14ffad 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -78,6 +78,7 @@ import { RowIndex, TableColumnInternal } from '../../types/internal.types'; } } `, + styleUrl: './body-cell.component.scss', standalone: true, imports: [NgTemplateOutlet, DataTableGhostLoaderComponent] }) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss index e94ddc3e5..b28bc9d18 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss @@ -1,6 +1,10 @@ :host { outline: none; + :host-context(ngx-datatable.fixed-row) & { + white-space: nowrap; + } + > div { display: flex; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss index 691a42812..f93c5e7d1 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss @@ -12,4 +12,8 @@ datatable-scroller { display: block; + + :host-context(ngx-datatable.fixed-row) & { + white-space: nowrap; + } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 2f3e50615..871407d7b 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -31,25 +31,6 @@ } } - /** - * Fixed row height adjustments - */ - &.fixed-row { - .datatable-scroll { - white-space: nowrap; - - .datatable-body-row { - white-space: nowrap; - - .datatable-body-cell { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - } - } - } - /** * Shared Styles */ From dc2b6ba95783a9724ecf1d3fa2bfc72a503fee61 Mon Sep 17 00:00:00 2001 From: Chintan Kavathia Date: Wed, 9 Apr 2025 15:17:25 +0530 Subject: [PATCH 064/105] refactor: don't render wrapper if col group columns are empty --- .../src/lib/components/body/body-row.component.ts | 4 ++-- .../src/lib/components/header/header.component.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index f9afe0906..0246aad6b 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -31,7 +31,7 @@ import { DataTableBodyCellComponent } from './body-cell.component'; selector: 'datatable-body-row', changeDetection: ChangeDetectionStrategy.OnPush, template: ` - @for (colGroup of _columnsByPin; track colGroup.type) { + @for (colGroup of _columnsByPin; track colGroup.type) { @if (colGroup.columns.length) {
}
- } + } } `, styleUrl: './body-row.component.scss', standalone: true, diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index ef10bdb10..8ba215167 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -46,7 +46,7 @@ import { OrderableDirective } from '../../directives/orderable.directive'; [style.width.px]="_columnGroupWidths.total" class="datatable-header-inner" > - @for (colGroup of _columnsByPin; track colGroup.type) { + @for (colGroup of _columnsByPin; track colGroup.type) { @if (colGroup.columns.length) {
@for (column of colGroup.columns; track column.$$id) { }
- } + } } `, host: { From 8f35d45ff03fd21bafc5612fc707a07844750d96 Mon Sep 17 00:00:00 2001 From: chintankavathia Date: Tue, 27 May 2025 17:37:26 +0530 Subject: [PATCH 065/105] refactor: remove explicit standalone flags (#222) --- .../components/body/body-group-header-template.directive.ts | 3 +-- .../src/lib/components/body/body-group-header.directive.ts | 3 +-- .../src/lib/components/body/body-row-def.component.ts | 6 ++---- .../src/lib/components/body/body-row.directive.ts | 3 +-- .../src/lib/components/body/progress-bar.component.ts | 3 +-- .../src/lib/components/body/scroller.component.ts | 3 +-- .../src/lib/components/body/selection.component.ts | 3 +-- .../src/lib/components/columns/column-cell.directive.ts | 3 +-- .../lib/components/columns/column-ghost-cell.directive.ts | 3 +-- .../src/lib/components/columns/column-header.directive.ts | 3 +-- .../src/lib/components/columns/column.directive.ts | 3 +-- .../src/lib/components/columns/tree.directive.ts | 3 +-- .../src/lib/components/footer/footer-template.directive.ts | 3 +-- .../src/lib/components/footer/footer.directive.ts | 3 +-- .../src/lib/components/footer/pager.component.ts | 3 +-- .../components/row-detail/row-detail-template.directive.ts | 3 +-- .../src/lib/components/row-detail/row-detail.directive.ts | 3 +-- .../src/lib/directives/disable-row.directive.ts | 3 +-- .../ngx-datatable/src/lib/directives/draggable.directive.ts | 3 +-- .../src/lib/directives/long-press.directive.ts | 3 +-- .../ngx-datatable/src/lib/directives/orderable.directive.ts | 3 +-- .../src/lib/directives/visibility.directive.ts | 3 +-- 22 files changed, 23 insertions(+), 46 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header-template.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header-template.directive.ts index ea6faf58d..790949b5a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header-template.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header-template.directive.ts @@ -2,8 +2,7 @@ import { Directive } from '@angular/core'; import { GroupContext } from '../../types/public.types'; @Directive({ - selector: '[ngx-datatable-group-header-template]', - standalone: true + selector: '[ngx-datatable-group-header-template]' }) export class DatatableGroupHeaderTemplateDirective { static ngTemplateContextGuard( diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts index 1fb6ce5e4..c5deea001 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts @@ -3,8 +3,7 @@ import { DatatableGroupHeaderTemplateDirective } from './body-group-header-templ import { Group, GroupContext, GroupToggleEvents } from '../../types/public.types'; @Directive({ - selector: 'ngx-datatable-group-header', - standalone: true + selector: 'ngx-datatable-group-header' }) export class DatatableGroupHeaderDirective { /** diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts index 047be265b..1b12a2e32 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts @@ -36,8 +36,7 @@ export class DatatableRowDefComponent { } @Directive({ - selector: '[rowDef]', - standalone: true + selector: '[rowDef]' }) export class DatatableRowDefDirective { static ngTemplateContextGuard( @@ -52,8 +51,7 @@ export class DatatableRowDefDirective { * @internal To be used internally by ngx-datatable. */ @Directive({ - selector: '[rowDefInternal]', - standalone: true + selector: '[rowDefInternal]' }) export class DatatableRowDefInternalDirective implements OnInit { vc = inject(ViewContainerRef); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts index e7408fb89..1b0e64ed5 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts @@ -2,8 +2,7 @@ import { Directive } from '@angular/core'; import { Row } from '../../types/public.types'; @Directive({ - selector: '[ngx-datatable-body-row]', - standalone: true + selector: '[ngx-datatable-body-row]' }) export class DatatableBodyRowDirective { static ngTemplateContextGuard( diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/progress-bar.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/progress-bar.component.ts index aae6915a9..82d8000cf 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/progress-bar.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/progress-bar.component.ts @@ -9,7 +9,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; `, - changeDetection: ChangeDetectionStrategy.OnPush, - standalone: true + changeDetection: ChangeDetectionStrategy.OnPush }) export class ProgressBarComponent {} diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts index 7f4651155..ae3514ab4 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts @@ -18,8 +18,7 @@ import { host: { class: 'datatable-scroll' }, - changeDetection: ChangeDetectionStrategy.OnPush, - standalone: true + changeDetection: ChangeDetectionStrategy.OnPush }) export class ScrollerComponent implements OnInit, OnDestroy { private renderer = inject(Renderer2); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts index ac2023d1f..cb0837888 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts @@ -6,8 +6,7 @@ import { ActivateEvent, SelectEvent, SelectionType } from '../../types/public.ty @Component({ selector: 'datatable-selection', template: ` `, - changeDetection: ChangeDetectionStrategy.OnPush, - standalone: true + changeDetection: ChangeDetectionStrategy.OnPush }) export class DataTableSelectionComponent { @Input() rows: TRow[]; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column-cell.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column-cell.directive.ts index 6244a0edd..53f35ffac 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column-cell.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column-cell.directive.ts @@ -2,8 +2,7 @@ import { Directive, inject, TemplateRef } from '@angular/core'; import { CellContext } from '../../types/public.types'; @Directive({ - selector: '[ngx-datatable-cell-template]', - standalone: true + selector: '[ngx-datatable-cell-template]' }) export class DataTableColumnCellDirective { template = inject>(TemplateRef); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column-ghost-cell.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column-ghost-cell.directive.ts index effd6644c..2ab2d6aa0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column-ghost-cell.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column-ghost-cell.directive.ts @@ -1,8 +1,7 @@ import { Directive } from '@angular/core'; @Directive({ - selector: '[ngx-datatable-ghost-cell-template]', - standalone: true + selector: '[ngx-datatable-ghost-cell-template]' }) export class DataTableColumnGhostCellDirective { static ngTemplateContextGuard( diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column-header.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column-header.directive.ts index 3f1721e1f..b1b443b44 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column-header.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column-header.directive.ts @@ -2,8 +2,7 @@ import { Directive } from '@angular/core'; import { HeaderCellContext } from '../../types/public.types'; @Directive({ - selector: '[ngx-datatable-header-template]', - standalone: true + selector: '[ngx-datatable-header-template]' }) export class DataTableColumnHeaderDirective { static ngTemplateContextGuard( diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts index 525dfa21a..6119fd88e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts @@ -18,8 +18,7 @@ import { DataTableColumnGhostCellDirective } from './column-ghost-cell.directive import { CellContext, HeaderCellContext } from '../../types/public.types'; @Directive({ - selector: 'ngx-datatable-column', - standalone: true + selector: 'ngx-datatable-column' }) export class DataTableColumnDirective implements TableColumn, OnChanges { private columnChangesService = inject(ColumnChangesService); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/tree.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/tree.directive.ts index 3062f774a..911e76f0c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/tree.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/tree.directive.ts @@ -1,8 +1,7 @@ import { Directive, inject, TemplateRef } from '@angular/core'; @Directive({ - selector: '[ngx-datatable-tree-toggle]', - standalone: true + selector: '[ngx-datatable-tree-toggle]' }) export class DataTableColumnCellTreeToggle { template = inject>(TemplateRef); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer-template.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer-template.directive.ts index 3e77a6015..a29253d60 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer-template.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer-template.directive.ts @@ -2,8 +2,7 @@ import { Directive } from '@angular/core'; import { FooterContext } from '../../types/public.types'; @Directive({ - selector: '[ngx-datatable-footer-template]', - standalone: true + selector: '[ngx-datatable-footer-template]' }) export class DataTableFooterTemplateDirective { static ngTemplateContextGuard( diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts index e6fed6bea..c27dd8920 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts @@ -3,8 +3,7 @@ import { DataTableFooterTemplateDirective } from './footer-template.directive'; import { FooterContext } from '../../types/public.types'; @Directive({ - selector: 'ngx-datatable-footer', - standalone: true + selector: 'ngx-datatable-footer' }) export class DatatableFooterDirective { @Input({ transform: numberAttribute }) footerHeight: number; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts index 8b35fcb43..7b2c3a842 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts @@ -44,8 +44,7 @@ import { Page } from '../../types/internal.types'; class: 'datatable-pager' }, styleUrl: './pager.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, - standalone: true + changeDetection: ChangeDetectionStrategy.OnPush }) export class DataTablePagerComponent { @Input() pagerLeftArrowIcon?: string; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail-template.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail-template.directive.ts index f8d3d1ade..2ebb934ce 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail-template.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail-template.directive.ts @@ -2,8 +2,7 @@ import { Directive } from '@angular/core'; import { RowDetailContext } from '../../types/public.types'; @Directive({ - selector: '[ngx-datatable-row-detail-template]', - standalone: true + selector: '[ngx-datatable-row-detail-template]' }) export class DatatableRowDetailTemplateDirective { static ngTemplateContextGuard( diff --git a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts index 62277e57d..3acc9c568 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts @@ -3,8 +3,7 @@ import { DatatableRowDetailTemplateDirective } from './row-detail-template.direc import { DetailToggleEvents, RowDetailContext } from '../../types/public.types'; @Directive({ - selector: 'ngx-datatable-row-detail', - standalone: true + selector: 'ngx-datatable-row-detail' }) export class DatatableRowDetailDirective { /** diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts index 6c0f0f831..2455d9f43 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts @@ -12,8 +12,7 @@ import { booleanAttribute, Directive, ElementRef, inject, Input } from '@angular * */ @Directive({ - selector: '[disable-row]', - standalone: true + selector: '[disable-row]' }) export class DisableRowDirective { private element = inject(ElementRef); diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts index 3a0b6c534..b39400ba2 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts @@ -23,8 +23,7 @@ import { DraggableDragEvent, TableColumnInternal } from '../types/internal.types * */ @Directive({ - selector: '[draggable]', - standalone: true + selector: '[draggable]' }) export class DraggableDirective implements OnDestroy, OnChanges { @Input() dragEventTarget: any; diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts index 2a621f358..577abd958 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts @@ -13,8 +13,7 @@ import { fromEvent, Subscription } from 'rxjs'; import { TableColumnInternal } from '../types/internal.types'; @Directive({ - selector: '[long-press]', - standalone: true + selector: '[long-press]' }) export class LongPressDirective implements OnDestroy { @Input({ transform: booleanAttribute }) pressEnabled = true; diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts index cc51eccb3..b5259b03e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts @@ -28,8 +28,7 @@ interface OrderPosition { } @Directive({ - selector: '[orderable]', - standalone: true + selector: '[orderable]' }) export class OrderableDirective implements AfterContentInit, OnDestroy { private document = inject(DOCUMENT); diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/visibility.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/visibility.directive.ts index 7b486f961..e1940f4d5 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/visibility.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/visibility.directive.ts @@ -22,8 +22,7 @@ import { * */ @Directive({ - selector: '[visibilityObserver]', - standalone: true + selector: '[visibilityObserver]' }) export class VisibilityDirective implements OnInit, OnDestroy { private element = inject(ElementRef); From 233c6a36d1c26e85989c253697d565de8291f540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 27 May 2025 14:12:36 +0200 Subject: [PATCH 066/105] refactor: move display related styles to respective components (#221) --- .../components/body/body-row.component.scss | 8 +++-- .../lib/components/datatable.component.scss | 31 ------------------- .../components/header/header.component.scss | 3 +- 3 files changed, 6 insertions(+), 36 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss index b28bc9d18..109e5fd83 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.scss @@ -1,11 +1,13 @@ :host { + display: flex; outline: none; :host-context(ngx-datatable.fixed-row) & { white-space: nowrap; } +} - > div { - display: flex; - } +.datatable-row-group { + display: flex; + position: relative; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 871407d7b..d1ef04768 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -31,16 +31,6 @@ } } - /** - * Shared Styles - */ - .datatable-body-row, - .datatable-row-center, - .datatable-header-inner { - display: flex; - flex-flow: row; - } - .datatable-body-cell, .datatable-header-cell { overflow-x: hidden; @@ -52,25 +42,4 @@ outline: none; } } - - .datatable-row-left, - .datatable-row-right, - .datatable-group-header { - z-index: 9; - position: sticky !important; - } - - .datatable-row-left, - .datatable-group-header { - left: 0; - } - - .datatable-row-right { - right: 0; - } - - .datatable-row-center, - .datatable-row-group { - position: relative; - } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss index ffff3f901..887d6c546 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss @@ -4,8 +4,7 @@ } .datatable-header-inner { - align-items: stretch; - -webkit-align-items: stretch; + display: flex; :host-context(ngx-datatable.fixed-header) & { white-space: nowrap; From 9959fc413fce24b5afe063c83b773e409cc72bbd Mon Sep 17 00:00:00 2001 From: Colin Frick Date: Wed, 28 May 2025 09:48:50 +0200 Subject: [PATCH 067/105] feat: add touch support for reorderable and resizable features (#181) * feat: port touch events to newest version * test(draggable): use MouseEvent constructor to simulate dragging * style(draggable): run prettier --- .../header/header-cell.component.scss | 13 +++++ .../header/header-cell.component.ts | 32 +++++++++--- .../lib/components/header/header.component.ts | 10 +++- .../directives/draggable.directive.spec.ts | 6 +-- .../src/lib/directives/draggable.directive.ts | 25 +++++++--- .../lib/directives/long-press.directive.ts | 49 +++++++++---------- .../src/lib/directives/orderable.directive.ts | 8 +-- .../src/lib/types/internal.types.ts | 2 +- .../ngx-datatable/src/lib/utils/events.ts | 14 ++++++ 9 files changed, 107 insertions(+), 52 deletions(-) create mode 100644 projects/swimlane/ngx-datatable/src/lib/utils/events.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss index 29a65dc05..80183574f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss @@ -49,6 +49,19 @@ visibility: visible; } } +:host { + @media (hover: none) { + touch-action: none; + + .resize-handle { + visibility: visible; + } + + .datatable-header-cell-label.draggable { + user-select: none; + } + } +} .resize-handle--not-resizable { :host(:hover) { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts index a48135273..ddceafeff 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts @@ -24,6 +24,7 @@ import { import { NgTemplateOutlet } from '@angular/common'; import { InnerSortEvent, TableColumnInternal } from '../../types/internal.types'; import { fromEvent, Subscription, takeUntil } from 'rxjs'; +import { getPositionFromEvent } from '../../utils/events'; @Component({ selector: 'datatable-header-cell', @@ -55,7 +56,11 @@ import { fromEvent, Subscription, takeUntil } from 'rxjs'; @if (column.resizeable) { - + } `, host: { @@ -217,6 +222,9 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { @HostListener('contextmenu', ['$event']) onContextmenu($event: MouseEvent): void { this.columnContextmenu.emit({ event: $event, column: this.column }); + if (this.column.draggable) { + $event.preventDefault(); + } } @HostListener('keydown.enter') @@ -281,17 +289,21 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { } } - protected onMousedown(event: MouseEvent): void { + protected onMousedown(event: MouseEvent | TouchEvent): void { + const isMouse = event instanceof MouseEvent; const initialWidth = this.element.clientWidth; - const mouseDownScreenX = event.screenX; + const { screenX } = getPositionFromEvent(event); event.stopPropagation(); - const mouseup = fromEvent(document, 'mouseup'); + const mouseup = fromEvent(document, isMouse ? 'mouseup' : 'touchend'); this.subscription = mouseup.subscribe(() => this.onMouseup()); - const mouseMoveSub = fromEvent(document, 'mousemove') + const mouseMoveSub = fromEvent( + document, + isMouse ? 'mousemove' : 'touchmove' + ) .pipe(takeUntil(mouseup)) - .subscribe((e: Event) => this.move(e, initialWidth, mouseDownScreenX)); + .subscribe((e: MouseEvent | TouchEvent) => this.move(e, initialWidth, screenX)); this.subscription.add(mouseMoveSub); } @@ -303,8 +315,12 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { } } - private move(event: Event, initialWidth: number, mouseDownScreenX: number): void { - const movementX = (event as MouseEvent).screenX - mouseDownScreenX; + private move( + event: MouseEvent | TouchEvent, + initialWidth: number, + mouseDownScreenX: number + ): void { + const movementX = getPositionFromEvent(event).screenX - mouseDownScreenX; const newWidth = initialWidth + movementX; this.resizing.emit({ width: newWidth, column: this.column }); } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index 8ba215167..e8bfb6d4c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -133,7 +133,7 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { @Input() reorderable: boolean; @Input() verticalScrollVisible = false; - dragEventTarget?: MouseEvent; + dragEventTarget?: MouseEvent | TouchEvent; @HostBinding('style.height') @Input() @@ -212,7 +212,13 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { this.destroyed = true; } - onLongPressStart({ event, model }: { event: MouseEvent; model: TableColumnInternal }) { + onLongPressStart({ + event, + model + }: { + event: MouseEvent | TouchEvent; + model: TableColumnInternal; + }) { model.dragging = true; this.dragEventTarget = event; } diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.spec.ts b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.spec.ts index 7460f132c..649db97e0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.spec.ts @@ -44,10 +44,8 @@ describe('DraggableDirective', () => { beforeEach(() => { element.classList.add('draggable'); - mouseDown = { - target: element, - preventDefault: () => {} - }; + mouseDown = new MouseEvent('mousedown'); + Object.defineProperty(mouseDown, 'target', { value: element }); }); // or else the document:mouseup event can fire again when resizing. diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts index b39400ba2..8b710323f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts @@ -13,6 +13,7 @@ import { import { fromEvent, Subscription } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { DraggableDragEvent, TableColumnInternal } from '../types/internal.types'; +import { getPositionFromEvent } from '../utils/events'; /** * Draggable Directive for Angular2 @@ -53,7 +54,7 @@ export class DraggableDirective implements OnDestroy, OnChanges { this._destroySubscription(); } - onMouseup(event: MouseEvent): void { + onMouseup(event: MouseEvent | TouchEvent): void { if (!this.isDragging) { return; } @@ -71,7 +72,8 @@ export class DraggableDirective implements OnDestroy, OnChanges { } } - onMousedown(event: MouseEvent): void { + onMousedown(event: MouseEvent | TouchEvent): void { + const isMouse = event instanceof MouseEvent; // we only want to drag the inner header text const isDragElm = (event.target).classList.contains('draggable'); @@ -79,12 +81,18 @@ export class DraggableDirective implements OnDestroy, OnChanges { event.preventDefault(); this.isDragging = true; - const mouseDownPos = { x: event.clientX, y: event.clientY }; + const mouseDownPos = getPositionFromEvent(event); - const mouseup = fromEvent(document, 'mouseup'); + const mouseup = fromEvent( + document, + isMouse ? 'mouseup' : 'touchend' + ); this.subscription = mouseup.subscribe(ev => this.onMouseup(ev)); - const mouseMoveSub = fromEvent(document, 'mousemove') + const mouseMoveSub = fromEvent( + document, + isMouse ? 'mousemove' : 'touchmove' + ) .pipe(takeUntil(mouseup)) .subscribe(ev => this.move(ev, mouseDownPos)); @@ -98,13 +106,14 @@ export class DraggableDirective implements OnDestroy, OnChanges { } } - move(event: MouseEvent, mouseDownPos: { x: number; y: number }): void { + move(event: MouseEvent | TouchEvent, mouseDownPos: { clientX: number; clientY: number }): void { if (!this.isDragging) { return; } - const x = event.clientX - mouseDownPos.x; - const y = event.clientY - mouseDownPos.y; + const { clientX, clientY } = getPositionFromEvent(event); + const x = clientX - mouseDownPos.clientX; + const y = clientY - mouseDownPos.clientY; if (this.dragX) { this.element.style.left = `${x}px`; diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts index 577abd958..2a63a7731 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts @@ -2,47 +2,46 @@ import { booleanAttribute, Directive, EventEmitter, - HostBinding, - HostListener, Input, numberAttribute, OnDestroy, - Output + Output, + signal } from '@angular/core'; import { fromEvent, Subscription } from 'rxjs'; import { TableColumnInternal } from '../types/internal.types'; @Directive({ - selector: '[long-press]' + selector: '[long-press]', + host: { + '(touchstart)': 'onMouseDown($event)', + '(mousedown)': 'onMouseDown($event)', + '[class.press]': 'pressing()', + '[class.longpress]': 'isLongPressing()' + } }) export class LongPressDirective implements OnDestroy { @Input({ transform: booleanAttribute }) pressEnabled = true; @Input() pressModel: TableColumnInternal; @Input({ transform: numberAttribute }) duration = 500; - @Output() longPressStart = new EventEmitter<{ event: MouseEvent; model: TableColumnInternal }>(); + @Output() longPressStart = new EventEmitter<{ + event: MouseEvent | TouchEvent; + model: TableColumnInternal; + }>(); @Output() longPressEnd = new EventEmitter<{ model: TableColumnInternal }>(); - pressing: boolean; - isLongPressing: boolean; + pressing = signal(false); + isLongPressing = signal(false); timeout: any; subscription: Subscription; - @HostBinding('class.press') - get press(): boolean { - return this.pressing; - } - - @HostBinding('class.longpress') - get isLongPress(): boolean { - return this.isLongPressing; - } + onMouseDown(event: MouseEvent | TouchEvent): void { + const isMouse = event instanceof MouseEvent; - @HostListener('mousedown', ['$event']) - onMouseDown(event: MouseEvent): void { // don't do right/middle clicks - if (event.which !== 1 || !this.pressEnabled) { + if (!this.pressEnabled || (isMouse && event.button !== 0)) { return; } @@ -52,14 +51,14 @@ export class LongPressDirective implements OnDestroy { return; } - this.pressing = true; - this.isLongPressing = false; + this.pressing.set(true); + this.isLongPressing.set(false); - const mouseup = fromEvent(document, 'mouseup'); + const mouseup = fromEvent(document, isMouse ? 'mouseup' : 'touchend'); this.subscription = mouseup.subscribe(() => this.endPress()); this.timeout = setTimeout(() => { - this.isLongPressing = true; + this.isLongPressing.set(true); this.longPressStart.emit({ event, model: this.pressModel @@ -69,8 +68,8 @@ export class LongPressDirective implements OnDestroy { endPress(): void { clearTimeout(this.timeout); - this.isLongPressing = false; - this.pressing = false; + this.isLongPressing.set(false); + this.pressing.set(false); this._destroySubscription(); this.longPressEnd.emit({ diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts index b5259b03e..e828e2125 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts @@ -19,6 +19,7 @@ import { TableColumnInternal, TargetChangedEvent } from '../types/internal.types'; +import { getPositionFromEvent } from '../utils/events'; interface OrderPosition { left: number; @@ -140,11 +141,10 @@ export class OrderableDirective implements AfterContentInit, OnDestroy { element.style.left = 'auto'; } - isTarget(model: TableColumnInternal, event: MouseEvent) { + isTarget(model: TableColumnInternal, event: MouseEvent | TouchEvent) { let i = 0; - const x = event.x || event.clientX; - const y = event.y || event.clientY; - const targets = this.document.elementsFromPoint(x, y); + const { clientX, clientY } = getPositionFromEvent(event); + const targets = this.document.elementsFromPoint(clientX, clientY); for (const id in this.positions) { // current column position which throws event. diff --git a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts index 54ba2c82c..8f244fa48 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts @@ -40,7 +40,7 @@ export interface Page { } export interface DraggableDragEvent { - event: MouseEvent; + event: MouseEvent | TouchEvent; element: HTMLElement; model: TableColumnInternal; } diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/events.ts b/projects/swimlane/ngx-datatable/src/lib/utils/events.ts new file mode 100644 index 000000000..484e76e26 --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/utils/events.ts @@ -0,0 +1,14 @@ +/** + * Extracts the position (x, y coordinates) from a MouseEvent or TouchEvent. + * + * @param {MouseEvent | TouchEvent} event - The event object from which to extract the position. Can be either a MouseEvent or a TouchEvent. + * @return {{ x: number, y: number }} An object containing the x and y coordinates of the event relative to the viewport. + */ +export function getPositionFromEvent(event: MouseEvent | TouchEvent): { + clientX: number; + clientY: number; + screenX: number; + screenY: number; +} { + return event instanceof MouseEvent ? (event as MouseEvent) : (event.changedTouches[0] as Touch); +} From 59b834fea9a871b7662d2337a448bca86f903aae Mon Sep 17 00:00:00 2001 From: Robert Worgul Date: Wed, 21 May 2025 21:47:13 +0200 Subject: [PATCH 068/105] feat: include pager aria labels in text messages BREAKING CHANGE: `INgxDatatableConfig.messages` now requires new keys for the pager aria labels. --- docs/api/table/inputs.md | 18 +++- .../src/lib/components/datatable.component.ts | 7 +- .../components/footer/pager.component.spec.ts | 89 ++++++++++++++++++- .../lib/components/footer/pager.component.ts | 45 ++++++++-- .../src/lib/ngx-datatable.module.ts | 13 +++ src/main.ts | 7 +- 6 files changed, 166 insertions(+), 13 deletions(-) diff --git a/docs/api/table/inputs.md b/docs/api/table/inputs.md index 40605615c..751c8d4ef 100644 --- a/docs/api/table/inputs.md +++ b/docs/api/table/inputs.md @@ -62,7 +62,23 @@ Static messages in the table you can override for localization. totalMessage: 'total', // Footer selected message - selectedMessage: 'selected' + selectedMessage: 'selected', + + // Pager screen reader message for the first page button + ariaFirstPageMessage: 'go to first page', + + // Pager screen reader message for the previous page button + ariaPreviousPageMessage: 'go to previous page', + + // Pager screen reader message for the n-th page button. + // It will be rendered as: `{{ariaPageNMessage}} {{n}}`. + ariaPageNMessage: 'page', + + // Pager screen reader message for the next page button + ariaNextPageMessage: 'go to next page', + + // Pager screen reader message for the last page button + ariaLastPageMessage: 'go to last page' } ``` diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index fba10b7b6..4c5b0aa38 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -364,7 +364,12 @@ export class DatatableComponent * { * emptyMessage: 'No data to display', * totalMessage: 'total', - * selectedMessage: 'selected' + * selectedMessage: 'selected', + * ariaFirstPageMessage: 'go to first page', + * ariaPreviousPageMessage: 'go to previous page', + * ariaPageNMessage: 'page', + * ariaNextPageMessage: 'go to next page', + * ariaLastPageMessage: 'go to last page' * } * ``` */ diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts index 410e9273e..2afe12f98 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts @@ -1,9 +1,12 @@ -import { TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { DataTablePagerComponent } from './pager.component'; +import { By } from '@angular/platform-browser'; +import { ChangeDetectorRef, DebugElement } from '@angular/core'; +import type { DatatableComponent } from '../datatable.component'; describe('DataTablePagerComponent', () => { - let fixture; + let fixture: ComponentFixture; let pager: DataTablePagerComponent; beforeEach(waitForAsync(() => { @@ -242,4 +245,86 @@ describe('DataTablePagerComponent', () => { expect(pages.length).toEqual(0); }); }); + + describe('localisation', () => { + let firstButton: DebugElement; + let previousButton: DebugElement; + let nextButton: DebugElement; + let lastButton: DebugElement; + let pageButtons: { button: DebugElement; page: number }[]; + beforeEach(() => { + pager.size = 10; + pager.count = 100; + fixture.detectChanges(); + [firstButton, previousButton, nextButton, lastButton] = fixture.debugElement + .queryAll(By.css('a[role=button]')) + .filter(it => !it.parent.classes['pages']); + pageButtons = fixture.debugElement + .queryAll(By.css('li.pages')) + .map((button, index) => ({ button, page: index + 1 })); + }); + + function ariaLabel(element: DebugElement): string | null { + return element?.attributes['aria-label'] ?? null; + } + + describe('has default values without messages from table', () => { + it('first button', () => { + expect(ariaLabel(firstButton)).toEqual('go to first page'); + }); + + it('previous button', () => { + expect(ariaLabel(previousButton)).toEqual('go to previous page'); + }); + + it('next button', () => { + expect(ariaLabel(nextButton)).toEqual('go to next page'); + }); + + it('last button', () => { + expect(ariaLabel(lastButton)).toEqual('go to last page'); + }); + + it('page buttons', () => { + for (const { button, page } of pageButtons) { + expect(ariaLabel(button)).withContext(`${page} button`).toEqual(`page ${page}`); + } + }); + }); + + describe('takes messages-overrides from table', () => { + function setMessages(messages: DatatableComponent['messages']) { + (pager as any).dataTable = { messages }; + // do a change detection on the real changeDetectionRef + fixture.componentRef.injector.get(ChangeDetectorRef).detectChanges(); + } + + it('first button', () => { + setMessages({ ariaFirstPageMessage: 'link: first page' }); + expect(ariaLabel(firstButton)).toEqual('link: first page'); + }); + + it('previous button', () => { + setMessages({ ariaPreviousPageMessage: 'link: previous page' }); + expect(ariaLabel(previousButton)).toEqual('link: previous page'); + }); + + it('next button', () => { + setMessages({ ariaNextPageMessage: 'link: next page' }); + expect(ariaLabel(nextButton)).toEqual('link: next page'); + }); + + it('last button', () => { + setMessages({ ariaLastPageMessage: 'link: last page' }); + expect(ariaLabel(lastButton)).toEqual('link: last page'); + }); + + it('page buttons', () => { + setMessages({ ariaPageNMessage: 'link: page' }); + for (const { button, page } of pageButtons) { + expect(ariaLabel(button)).withContext(`${page} button`).toEqual(`link: page ${page}`); + } + }); + }); + }); }); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts index 7b2c3a842..562a2eb62 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.ts @@ -1,40 +1,63 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + inject, + Input, + Output +} from '@angular/core'; import { PagerPageEvent } from '../../types/public.types'; import { Page } from '../../types/internal.types'; +import { DatatableComponent } from '../datatable.component'; @Component({ selector: 'datatable-pager', template: `
  • - +
  • - +
  • @for (pg of pages; track pg.number) {
  • - + {{ pg.text }}
  • }
  • - +
  • - +
  • @@ -47,6 +70,12 @@ import { Page } from '../../types/internal.types'; changeDetection: ChangeDetectionStrategy.OnPush }) export class DataTablePagerComponent { + private dataTable = inject(DatatableComponent, { optional: true }); + + get messages(): DatatableComponent['messages'] { + return this.dataTable?.messages ?? {}; + } + @Input() pagerLeftArrowIcon?: string; @Input() pagerRightArrowIcon?: string; @Input() pagerPreviousIcon?: string; diff --git a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts index 694a27be7..b42ceece7 100644 --- a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts +++ b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts @@ -77,6 +77,19 @@ export interface INgxDatatableConfig { totalMessage: string; /** Footer selected message */ selectedMessage: string; + /** Pager screen reader message for the first page button */ + ariaFirstPageMessage: string; + /** + * Pager screen reader message for the n-th page button. + * It will be rendered as: `{{ariaPageNMessage}} {{n}}`. + */ + ariaPageNMessage: string; + /** Pager screen reader message for the previous page button */ + ariaPreviousPageMessage: string; + /** Pager screen reader message for the next page button */ + ariaNextPageMessage: string; + /** Pager screen reader message for the last page button */ + ariaLastPageMessage: string; }; cssClasses?: { sortAscending: string; diff --git a/src/main.ts b/src/main.ts index 119f0dcaa..6b65cdefe 100644 --- a/src/main.ts +++ b/src/main.ts @@ -19,7 +19,12 @@ bootstrapApplication(AppComponent, { messages: { emptyMessage: 'No data to display', // Message to show when array is presented, but contains no values totalMessage: 'total', // Footer total message - selectedMessage: 'selected' // Footer selected message + selectedMessage: 'selected', // Footer selected message + ariaFirstPageMessage: 'go to first page', // Pager screen reader message for the first page button + ariaPreviousPageMessage: 'go to previous page', // Pager screen reader message for the previous page button + ariaPageNMessage: 'page', // Pager screen reader message for the n-th page button + ariaNextPageMessage: 'go to next page', // Pager screen reader message for the next page button + ariaLastPageMessage: 'go to last page' // Pager screen reader message for the last page button } }) ), From db1b7490d629b237a51713d783215330251082b2 Mon Sep 17 00:00:00 2001 From: Robert Worgul Date: Wed, 4 Jun 2025 16:12:09 +0200 Subject: [PATCH 069/105] fix: introduce a default value for rows In #192 we introduced `rows` that are always defined internally. As other setters may use `rows` before initialization (via input), a default value is required. --- .../ngx-datatable/src/lib/components/datatable.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 4c5b0aa38..7c81edbce 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -693,7 +693,7 @@ export class DatatableComponent _limit: number | undefined; _count = 0; _offset = 0; - _rows: TRow[]; + _rows: TRow[] = []; _groupRowsBy: keyof TRow; _internalRows: TRow[] = []; _internalColumns: TableColumnInternal[]; From 69273900815fe05e1543710ac4a3a57381f34075 Mon Sep 17 00:00:00 2001 From: Robert Worgul Date: Fri, 6 Jun 2025 19:21:52 +0200 Subject: [PATCH 070/105] refactor: remove unnecessary checks Remove check for `this._rows` as it's always defined. --- .../ngx-datatable/src/lib/components/datatable.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 7c81edbce..6dcfae28f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -138,7 +138,7 @@ export class DatatableComponent @Input() set groupRowsBy(val: keyof TRow) { if (val) { this._groupRowsBy = val; - if (this._rows && this._groupRowsBy) { + if (this._groupRowsBy) { // creates a new array with the data grouped this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy); } @@ -853,7 +853,7 @@ export class DatatableComponent optionalGetterForProp(this.treeToRelation) ); - if (this._rows && this._groupRowsBy) { + if (this._groupRowsBy) { // If a column has been specified in _groupRowsBy create a new array with the data grouped by that row this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy); } From 881add34b2dfb6de1b92959ffd9eba93dc340c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 10 Jun 2025 17:51:48 +0200 Subject: [PATCH 071/105] refactor: move selection component into the body component (#213) --- .../src/lib/components/body/body.component.ts | 461 ++++++++++++------ .../lib/components/body/scroller.component.ts | 2 +- .../components/body/selection.component.ts | 186 ------- 3 files changed, 306 insertions(+), 343 deletions(-) delete mode 100644 projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 814aa6d93..024299195 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -37,9 +37,10 @@ import { DraggableDirective } from '../../directives/draggable.directive'; import { DatatableRowDefInternalDirective } from './body-row-def.component'; import { DataTableRowWrapperComponent } from './body-row-wrapper.component'; import { DataTableSummaryRowComponent } from './summary/summary-row.component'; -import { DataTableSelectionComponent } from './selection.component'; import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.component'; import { DatatableBodyRowDirective } from './body-row.directive'; +import { selectRows, selectRowsBetween } from '../../utils/selection'; +import { Keys } from '../../utils/keys'; @Component({ selector: 'datatable-body', @@ -61,166 +62,151 @@ import { DatatableBodyRowDirective } from './body-row.directive'; > } - - @if (rows.length) { - + @if (summaryRow && summaryPosition === 'top') { + + + } + - @if (summaryRow && summaryPosition === 'top') { - - - } - + + + + @for (group of rowsToRender(); track rowTrackingFn(i, group); let i = $index) { + @let disabled = isRow(group) && disableRowCheck && disableRowCheck(group); + + + - - - - - @for (group of rowsToRender(); track rowTrackingFn(i, group); let i = $index) { - @let disabled = isRow(group) && disableRowCheck && disableRowCheck(group); - - - - @if (rowDefTemplate) { + @if (rowDefTemplate) { + + } @else { + @if (isRow(group)) { - } @else { - @if (isRow(group)) { - - } + [ngTemplateOutlet]="bodyRow" + [ngTemplateOutletContext]="{ + row: group, + index: i, + disabled + }" + > } + } - @if (isGroup(group)) { - - @for (row of group.value; track rowTrackingFn(i, row); let i = $index) { - @let disabled = disableRowCheck && disableRowCheck(row); - - } + @if (isGroup(group)) { + + @for (row of group.value; track rowTrackingFn(i, row); let i = $index) { + @let disabled = disableRowCheck && disableRowCheck(row); + } - - } - @if (summaryRow && summaryPosition === 'bottom') { - - - } - - } - @if (!rows?.length && !loadingIndicator && !ghostLoadingIndicator) { - - - } - + } + + } + @if (summaryRow && summaryPosition === 'bottom') { + + + } + + } + @if (!rows?.length && !loadingIndicator && !ghostLoadingIndicator) { + + + } `, changeDetection: ChangeDetectionStrategy.OnPush, host: { @@ -230,7 +216,6 @@ import { DatatableBodyRowDirective } from './body-row.directive'; standalone: true, imports: [ DataTableGhostLoaderComponent, - DataTableSelectionComponent, ScrollerComponent, DataTableSummaryRowComponent, DataTableRowWrapperComponent, @@ -1014,6 +999,170 @@ export class DataTableBodyComponent implements OnInit, O this.columnGroupWidths = columnGroupWidths(colsByPin, this._columns); } + prevIndex: number; + + selectRow(event: Event, index: number, row: TRow): void { + if (!this.selectEnabled) { + return; + } + + const chkbox = this.selectionType === SelectionType.checkbox; + const multi = this.selectionType === SelectionType.multi; + const multiClick = this.selectionType === SelectionType.multiClick; + let selected: TRow[] = []; + + // TODO: this code needs cleanup. Casting it to KeyboardEvent is not correct as it could also be other types. + if (multi || chkbox || multiClick) { + if ((event as KeyboardEvent).shiftKey) { + selected = selectRowsBetween([], this.rows, index, this.prevIndex); + } else if ( + (event as KeyboardEvent).key === 'a' && + ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) + ) { + // select all rows except dummy rows which are added for ghostloader in case of virtual scroll + selected = this.rows.filter(rowItem => !!rowItem); + } else if ( + (event as KeyboardEvent).ctrlKey || + (event as KeyboardEvent).metaKey || + multiClick || + chkbox + ) { + selected = selectRows([...this.selected], row, this.getRowSelectedIdx.bind(this)); + } else { + selected = selectRows([], row, this.getRowSelectedIdx.bind(this)); + } + } else { + selected = selectRows([], row, this.getRowSelectedIdx.bind(this)); + } + + if (typeof this.selectCheck === 'function') { + selected = selected.filter(this.selectCheck.bind(this)); + } + + if (typeof this.disableRowCheck === 'function') { + selected = selected.filter(rowData => !this.disableRowCheck(rowData)); + } + + this.selected.splice(0, this.selected.length); + this.selected.push(...selected); + + this.prevIndex = index; + + this.select.emit({ + selected + }); + } + + onActivate(model: ActivateEvent, index: number): void { + const { type, event, row } = model; + const chkbox = this.selectionType === SelectionType.checkbox; + const select = + (!chkbox && (type === 'click' || type === 'dblclick')) || (chkbox && type === 'checkbox'); + + if (select) { + this.selectRow(event, index, row); + } else if (type === 'keydown') { + if ((event as KeyboardEvent).key === Keys.return) { + this.selectRow(event, index, row); + } else if ( + (event as KeyboardEvent).key === 'a' && + ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) + ) { + this.selectRow(event, 0, this.rows[this.rows.length - 1]); + } else { + this.onKeyboardFocus(model); + } + } + this.activate.emit(model); + } + + onKeyboardFocus(model: ActivateEvent): void { + const { key } = model.event as KeyboardEvent; + const shouldFocus = + key === Keys.up || key === Keys.down || key === Keys.right || key === Keys.left; + + if (shouldFocus) { + const isCellSelection = this.selectionType === SelectionType.cell; + if (typeof this.disableRowCheck === 'function') { + const isRowDisabled = this.disableRowCheck(model.row); + if (isRowDisabled) { + return; + } + } + if (!model.cellElement || !isCellSelection) { + this.focusRow(model.rowElement, key); + } else if (isCellSelection) { + this.focusCell(model.cellElement, model.rowElement, key, model.cellIndex); + } + } + } + + focusRow(rowElement: HTMLElement, key: Keys): void { + const nextRowElement = this.getPrevNextRow(rowElement, key); + if (nextRowElement) { + nextRowElement.focus(); + } + } + + getPrevNextRow(rowElement: HTMLElement, key: Keys): any { + const parentElement = rowElement.parentElement; + + if (parentElement) { + let focusElement: Element; + if (key === Keys.up) { + focusElement = parentElement.previousElementSibling; + } else if (key === Keys.down) { + focusElement = parentElement.nextElementSibling; + } + + if (focusElement && focusElement.children.length) { + return focusElement.children[0]; + } + } + } + + focusCell(cellElement: HTMLElement, rowElement: HTMLElement, key: Keys, cellIndex: number): void { + let nextCellElement: Element; + + if (key === Keys.left) { + nextCellElement = cellElement.previousElementSibling; + } else if (key === Keys.right) { + nextCellElement = cellElement.nextElementSibling; + } else if (key === Keys.up || key === Keys.down) { + const nextRowElement = this.getPrevNextRow(rowElement, key); + if (nextRowElement) { + const children = nextRowElement.getElementsByClassName('datatable-body-cell'); + if (children.length) { + nextCellElement = children[cellIndex]; + } + } + } + + if ( + nextCellElement && + 'focus' in nextCellElement && + typeof nextCellElement.focus === 'function' + ) { + nextCellElement.focus(); + } + } + + getRowSelected(row: TRow): boolean { + return this.getRowSelectedIdx(row, this.selected) > -1; + } + + getRowSelectedIdx(row: TRow, selected: any[]): number { + if (!selected || !selected.length) { + return -1; + } + + const rowId = this.rowIdentity(row); + return selected.findIndex(r => { + const id = this.rowIdentity(r); + return id === rowId; + }); + } + protected isGroup(row: RowOrGroup[]): row is Group[]; protected isGroup(row: RowOrGroup): row is Group; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts index ae3514ab4..0170a4686 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts @@ -49,7 +49,7 @@ export class ScrollerComponent implements OnInit, OnDestroy { // manual bind so we don't always listen if (this.scrollbarV || this.scrollbarH) { const renderer = this.renderer; - this.parentElement = renderer.parentNode(renderer.parentNode(this.element)); + this.parentElement = renderer.parentNode(this.element); this._scrollEventListener = this.onScrolled.bind(this); this.parentElement.addEventListener('scroll', this._scrollEventListener); } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts deleted file mode 100644 index cb0837888..000000000 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/selection.component.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; -import { selectRows, selectRowsBetween } from '../../utils/selection'; -import { Keys } from '../../utils/keys'; -import { ActivateEvent, SelectEvent, SelectionType } from '../../types/public.types'; - -@Component({ - selector: 'datatable-selection', - template: ` `, - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class DataTableSelectionComponent { - @Input() rows: TRow[]; - @Input() selected: TRow[]; - @Input() selectEnabled: boolean; - @Input() selectionType: SelectionType; - @Input() rowIdentity: any; - @Input() selectCheck: (value: TRow, index: number, array: TRow[]) => boolean; - @Input() disableCheck: (row: TRow) => boolean; - - @Output() activate = new EventEmitter>(); - @Output() select = new EventEmitter>(); - - prevIndex: number; - - selectRow(event: Event, index: number, row: TRow): void { - if (!this.selectEnabled) { - return; - } - - const chkbox = this.selectionType === SelectionType.checkbox; - const multi = this.selectionType === SelectionType.multi; - const multiClick = this.selectionType === SelectionType.multiClick; - let selected: TRow[] = []; - - // TODO: this code needs cleanup. Casting it to KeyboardEvent is not correct as it could also be other types. - if (multi || chkbox || multiClick) { - if ((event as KeyboardEvent).shiftKey) { - selected = selectRowsBetween([], this.rows, index, this.prevIndex); - } else if ( - (event as KeyboardEvent).key === 'a' && - ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) - ) { - // select all rows except dummy rows which are added for ghostloader in case of virtual scroll - selected = this.rows.filter(rowItem => !!rowItem); - } else if ( - (event as KeyboardEvent).ctrlKey || - (event as KeyboardEvent).metaKey || - multiClick || - chkbox - ) { - selected = selectRows([...this.selected], row, this.getRowSelectedIdx.bind(this)); - } else { - selected = selectRows([], row, this.getRowSelectedIdx.bind(this)); - } - } else { - selected = selectRows([], row, this.getRowSelectedIdx.bind(this)); - } - - if (typeof this.selectCheck === 'function') { - selected = selected.filter(this.selectCheck.bind(this)); - } - - if (typeof this.disableCheck === 'function') { - selected = selected.filter(rowData => !this.disableCheck(rowData)); - } - - this.selected.splice(0, this.selected.length); - this.selected.push(...selected); - - this.prevIndex = index; - - this.select.emit({ - selected - }); - } - - onActivate(model: ActivateEvent, index: number): void { - const { type, event, row } = model; - const chkbox = this.selectionType === SelectionType.checkbox; - const select = - (!chkbox && (type === 'click' || type === 'dblclick')) || (chkbox && type === 'checkbox'); - - if (select) { - this.selectRow(event, index, row); - } else if (type === 'keydown') { - if ((event as KeyboardEvent).key === Keys.return) { - this.selectRow(event, index, row); - } else if ( - (event as KeyboardEvent).key === 'a' && - ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) - ) { - this.selectRow(event, 0, this.rows[this.rows.length - 1]); - } else { - this.onKeyboardFocus(model); - } - } - this.activate.emit(model); - } - - onKeyboardFocus(model: ActivateEvent): void { - const { key } = model.event as KeyboardEvent; - const shouldFocus = - key === Keys.up || key === Keys.down || key === Keys.right || key === Keys.left; - - if (shouldFocus) { - const isCellSelection = this.selectionType === SelectionType.cell; - if (typeof this.disableCheck === 'function') { - const isRowDisabled = this.disableCheck(model.row); - if (isRowDisabled) { - return; - } - } - if (!model.cellElement || !isCellSelection) { - this.focusRow(model.rowElement, key); - } else if (isCellSelection) { - this.focusCell(model.cellElement, model.rowElement, key, model.cellIndex); - } - } - } - - focusRow(rowElement: HTMLElement, key: Keys): void { - const nextRowElement = this.getPrevNextRow(rowElement, key); - if (nextRowElement) { - nextRowElement.focus(); - } - } - - getPrevNextRow(rowElement: HTMLElement, key: Keys): any { - const parentElement = rowElement.parentElement; - - if (parentElement) { - let focusElement: Element; - if (key === Keys.up) { - focusElement = parentElement.previousElementSibling; - } else if (key === Keys.down) { - focusElement = parentElement.nextElementSibling; - } - - if (focusElement && focusElement.children.length) { - return focusElement.children[0]; - } - } - } - - focusCell(cellElement: HTMLElement, rowElement: HTMLElement, key: Keys, cellIndex: number): void { - let nextCellElement: Element; - - if (key === Keys.left) { - nextCellElement = cellElement.previousElementSibling; - } else if (key === Keys.right) { - nextCellElement = cellElement.nextElementSibling; - } else if (key === Keys.up || key === Keys.down) { - const nextRowElement = this.getPrevNextRow(rowElement, key); - if (nextRowElement) { - const children = nextRowElement.getElementsByClassName('datatable-body-cell'); - if (children.length) { - nextCellElement = children[cellIndex]; - } - } - } - - if ( - nextCellElement && - 'focus' in nextCellElement && - typeof nextCellElement.focus === 'function' - ) { - nextCellElement.focus(); - } - } - - getRowSelected(row: TRow): boolean { - return this.getRowSelectedIdx(row, this.selected) > -1; - } - - getRowSelectedIdx(row: TRow, selected: any[]): number { - if (!selected || !selected.length) { - return -1; - } - - const rowId = this.rowIdentity(row); - return selected.findIndex(r => { - const id = this.rowIdentity(r); - return id === rowId; - }); - } -} From 55588dffec745632975fb708f5f44071efeb7202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 10 Jun 2025 17:59:07 +0200 Subject: [PATCH 072/105] perf: only calculate render offset once for all rows (#210) --- .../components/body/body.component.spec.ts | 16 -- .../src/lib/components/body/body.component.ts | 227 +++++++----------- .../lib/components/datatable.component.scss | 7 - 3 files changed, 84 insertions(+), 166 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts index 76cb7bb67..b992c4516 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts @@ -144,20 +144,4 @@ describe('DataTableBodyComponent', () => { expect(rows[1].classes['row-disabled']).toBeTrue(); }); }); - - describe('Summary row', () => { - it('should not return custom styles for a bottom summary row if a scrollbar mode is off', () => { - const styles = component.bottomSummaryRowsStyles(); - expect(styles).toBeFalsy(); - }); - - it('should return custom styles for a bottom summary row if a scrollbar mode is on', () => { - component.rowHeight = 50; - component.scrollbarV = true; - component.virtualization = true; - component.rows = [{ num: 1 }, { num: 2 }, { num: 3 }, { num: 4 }]; - const styles = component.bottomSummaryRowsStyles(); - expect(styles).toBeDefined(); - }); - }); }); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 024299195..1cac1fb10 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -18,7 +18,7 @@ import { import { ScrollerComponent } from './scroller.component'; import { columnGroupWidths, columnsByPin } from '../../utils/column'; import { RowHeightCache } from '../../utils/row-height-cache'; -import { NgStyle, NgTemplateOutlet } from '@angular/common'; +import { NgTemplateOutlet } from '@angular/common'; import { DatatableGroupHeaderDirective } from './body-group-header.directive'; import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive'; import { DataTableBodyRowComponent } from './body-row.component'; @@ -118,83 +118,84 @@ import { Keys } from '../../utils/keys'; - @for (group of rowsToRender(); track rowTrackingFn(i, group); let i = $index) { - @let disabled = isRow(group) && disableRowCheck && disableRowCheck(group); - - - - @if (rowDefTemplate) { - - } @else { - @if (isRow(group)) { +
    + @for (group of rowsToRender(); track rowTrackingFn(i, group); let i = $index) { + @let disabled = isRow(group) && disableRowCheck && disableRowCheck(group); + + + + @if (rowDefTemplate) { + *rowDefInternal=" + { + template: rowDefTemplate, + rowTemplate: bodyRow, + row: group, + index: i + }; + disabled: disabled + " + /> + } @else { + @if (isRow(group)) { + + } } - } - @if (isGroup(group)) { - - @for (row of group.value; track rowTrackingFn(i, row); let i = $index) { - @let disabled = disableRowCheck && disableRowCheck(row); - + @if (isGroup(group)) { + + @for (row of group.value; track rowTrackingFn(i, row); let i = $index) { + @let disabled = disableRowCheck && disableRowCheck(row); + + } } - } - - } - @if (summaryRow && summaryPosition === 'bottom') { - - - } + + } +
    + @if (summaryRow && summaryPosition === 'bottom') { + + + } } @if (!rows?.length && !loadingIndicator && !ghostLoadingIndicator) { implements OnInit, O }; /** - * Calculates the styles for the row so that the rows can be moved in 2D space - * during virtual scroll inside the DOM. In the below case the Y position is - * manipulated. As an example, if the height of row 0 is 30 px and row 1 is - * 100 px then following styles are generated: - * - * transform: translate3d(0px, 0px, 0px); -> row0 - * transform: translate3d(0px, 30px, 0px); -> row1 - * transform: translate3d(0px, 130px, 0px); -> row2 - * - * Row heights have to be calculated based on the row heights cache as we wont - * be able to determine which row is of what height before hand. In the above - * case the positionY of the translate3d for row2 would be the sum of all the - * heights of the rows before it (i.e. row0 and row1). - * - * @returns the CSS3 style to be applied - */ - rowsStyles = computed(() => { - const rowsStyles: NgStyle['ngStyle'][] = []; - this.rowsToRender().forEach((rows, index) => { - const styles: NgStyle['ngStyle'] = {}; - - // only add styles for the group if there is a group - if (this.groupedRows) { - styles.width = this.columnGroupWidths.total; - } - - if (this.scrollbarV && this.virtualization) { - let idx = 0; - - if (Array.isArray(rows)) { - // Get the latest row rowindex in a group - const row = rows[rows.length - 1]; - // The group row, which has always a numeric index - idx = row ? this.getRowIndex(row).index : 0; - } else { - if (rows) { - // normal rows always have a numeric index - idx = this.getRowIndex(rows).index; - } else { - // When ghost cells are enabled use index to get the position of them - idx = this.indexes().first + index; - } - } - - // const pos = idx * rowHeight; - // The position of this row would be the sum of all row heights - // until the previous row position. - styles.transform = `translateY(${this.rowHeightsCache().query(idx - 1)}px)`; - } - rowsStyles.push(styles); - }); - return rowsStyles; - }); - - /** - * Calculate bottom summary row offset for scrollbar mode. - * For more information about cache and offset calculation - * see description for `rowsStyles` signal - * - * @returns the CSS3 style to be applied + * Calculates the offset of the rendered rows. + * As virtual rows are not shown, we have to move all rendered rows + * by the total size of previous non-rendered rows. + * If each row has a size of 10px and the first 10 rows are not rendered due to scroll, + * then we have a renderOffset of 100px. */ - bottomSummaryRowsStyles = computed(() => { - if (!this.scrollbarV || !this.rows.length || !this.rowsToRender()) { - return null; + renderOffset = computed(() => { + if (this.scrollbarV && this.virtualization) { + return `translateY(${this.rowHeightsCache().query(this.indexes().first - 1)}px)`; + } else { + return ''; } - - const pos = this.rowHeightsCache().query(this.rows.length - 1); - return { - transform: `translateY(${pos}px)`, - position: 'absolute' - }; }); /** diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index d1ef04768..88652e90c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -22,13 +22,6 @@ .datatable-body { overflow-y: auto; } - &.virtualized { - .datatable-body { - .datatable-row-wrapper { - position: absolute; - } - } - } } .datatable-body-cell, From f2f2cc1dceea6121ba87f73e69d8cdc37a7e2b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 10 Jun 2025 18:30:14 +0200 Subject: [PATCH 073/105] refactor: calculate actual index based on index offset (#212) --- .../lib/components/body/body-row.directive.ts | 1 + .../src/lib/components/body/body.component.ts | 81 +++++-------------- .../src/lib/utils/row-height-cache.ts | 4 +- 3 files changed, 22 insertions(+), 64 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts index 1b0e64ed5..a7bef986d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.directive.ts @@ -12,6 +12,7 @@ export class DatatableBodyRowDirective { row: TRow; groupedRows: TRow[]; index: number; + indexInGroup?: number; disabled: boolean; } { return true; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 1cac1fb10..40ca73164 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -22,7 +22,7 @@ import { NgTemplateOutlet } from '@angular/common'; import { DatatableGroupHeaderDirective } from './body-group-header.directive'; import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive'; import { DataTableBodyRowComponent } from './body-row.component'; -import { ColumnGroupWidth, RowIndex, TableColumnInternal } from '../../types/internal.types'; +import { ColumnGroupWidth, TableColumnInternal } from '../../types/internal.types'; import { ActivateEvent, DragEventData, @@ -83,7 +83,8 @@ import { Keys } from '../../utils/keys'; ngx-datatable-body-row #bodyRow let-row="row" - let-rowIndex="index" + let-index="index" + let-indexInGroup="indexInGroup" let-groupedRows="groupedRows" let-disabled="disabled" > @@ -98,7 +99,7 @@ import { Keys } from '../../utils/keys'; [rowHeight]="getRowHeight(row)" [row]="row" [group]="groupedRows" - [rowIndex]="getRowIndex(row)" + [rowIndex]="{ index: index, indexInGroup: indexInGroup }" [expanded]="getRowExpanded(row)" [rowClass]="rowClass" [displayCheck]="displayCheck" @@ -107,7 +108,7 @@ import { Keys } from '../../utils/keys'; [draggable]="rowDraggable" [verticalScrollVisible]="verticalScrollVisible" (treeAction)="onTreeAction(row)" - (activate)="onActivate($event, rowIndex ?? indexes().first + rowIndex)" + (activate)="onActivate($event, index)" (drop)="drop($event, row, rowElement)" (dragover)="dragOver($event, row)" (dragenter)="dragEnter($event, row, rowElement)" @@ -138,7 +139,7 @@ import { Keys } from '../../utils/keys'; [row]="group" [disabled]="disabled" [expanded]="getRowExpanded(group)" - [rowIndex]="getRowIndex(group && $any(group)[i])?.index ?? 0" + [rowIndex]="indexes().first + i" [selected]="selected" (rowContextmenu)="rowContextmenu.emit($event)" > @@ -160,7 +161,7 @@ import { Keys } from '../../utils/keys'; [ngTemplateOutlet]="bodyRow" [ngTemplateOutletContext]="{ row: group, - index: i, + index: indexes().first + i, disabled }" >
    @@ -169,14 +170,15 @@ import { Keys } from '../../utils/keys'; @if (isGroup(group)) { - @for (row of group.value; track rowTrackingFn(i, row); let i = $index) { + @for (row of group.value; track rowTrackingFn($index, row)) { @let disabled = disableRowCheck && disableRowCheck(row); @@ -387,7 +389,6 @@ export class DataTableBodyComponent implements OnInit, O columnGroupWidths: ColumnGroupWidth; rowTrackingFn: TrackByFunction>; listener: any; - rowIndexes = new WeakMap, RowIndex>(); rowExpansions: any[] = []; _rows: TRow[]; @@ -413,7 +414,7 @@ export class DataTableBodyComponent implements OnInit, O if (this.trackByProp) { return (row as any)[this.trackByProp]; } else { - return this.getRowIndex(row)?.index; + return row; } }; } @@ -542,48 +543,14 @@ export class DataTableBodyComponent implements OnInit, O */ updateRows(): RowOrGroup[] { const { first, last } = this.indexes(); - let rowIndex = first; - let idx = 0; - const temp: RowOrGroup[] = []; - // if grouprowsby has been specified treat row paging // parameters as group paging parameters ie if limit 10 has been // specified treat it as 10 groups rather than 10 rows if (this.groupedRows) { - while (rowIndex < last && rowIndex < this.groupedRows.length) { - // Add the groups into this page - const group = this.groupedRows[rowIndex]; - this.rowIndexes.set(group, { index: rowIndex }); - - if (group.value) { - // add indexes for each group item - group.value.forEach((g: TRow, i: number) => { - this.rowIndexes.set(g, { index: rowIndex, indexInGroup: i }); - }); - } - temp[idx] = group; - idx++; - - // Group index in this context - rowIndex++; - } + return this.groupedRows.slice(first, Math.min(last, this.groupedRows.length)); } else { - while (rowIndex < last && rowIndex < this.rowCount) { - const row = this.rows[rowIndex]; - - if (row) { - // add indexes for each row - this.rowIndexes.set(row, { index: rowIndex }); - temp[idx] = row; - } else if (this.ghostLoadingIndicator && this.virtualization) { - temp[idx] = undefined; - } - - idx++; - rowIndex++; - } + return this.rows.slice(first, Math.min(last, this.rowCount)); } - return temp; } /** @@ -727,8 +694,8 @@ export class DataTableBodyComponent implements OnInit, O rowHeight: this.rowHeight, detailRowHeight: this.getDetailRowHeight, externalVirtual: this.scrollbarV && this.externalPaging, + indexOffset: this.indexes().first, rowCount: this.rowCount, - rowIndexes: this.rowIndexes, rowExpansions }); this.rowHeightsCache.set(Object.create(this.rowHeightsCache())); @@ -764,14 +731,6 @@ export class DataTableBodyComponent implements OnInit, O const rowExpandedIdx = this.getRowExpandedIdx(row, this.rowExpansions); const expanded = rowExpandedIdx > -1; - // If the detailRowHeight is auto --> only in case of non-virtualized scroll - if (this.scrollbarV && this.virtualization) { - const detailRowHeight = this.getDetailRowHeight(row) * (expanded ? -1 : 1); - // This is hopefully only called with non-grouped rows. Otherwise, the heightCache fails. - const idx = this.getRowIndex(row)?.index ?? 0; - this.rowHeightsCache().update(idx, detailRowHeight); - } - // Update the toggled row and update thive nevere heights in the cache. if (expanded) { this.rowExpansions.splice(rowExpandedIdx, 1); @@ -779,6 +738,11 @@ export class DataTableBodyComponent implements OnInit, O this.rowExpansions.push(row); } + // If the detailRowHeight is auto --> only in case of non-virtualized scroll + if (this.scrollbarV && this.virtualization) { + this.refreshRowHeightCache(); + } + this.detailToggle.emit({ rows: [row], currentIndex: viewPortFirstRowIndex @@ -846,13 +810,6 @@ export class DataTableBodyComponent implements OnInit, O }); } - /** - * Gets the row index given a row - */ - getRowIndex(row: RowOrGroup): RowIndex | undefined { - return this.rowIndexes.get(row); - } - onTreeAction(row: TRow) { this.treeAction.emit({ row }); } diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/row-height-cache.ts b/projects/swimlane/ngx-datatable/src/lib/utils/row-height-cache.ts index 41f047cd2..0e214221d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/row-height-cache.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/row-height-cache.ts @@ -35,8 +35,8 @@ export class RowHeightCache { rowHeight, detailRowHeight, externalVirtual, + indexOffset, rowCount, - rowIndexes, rowExpansions } = details; const isFn = typeof rowHeight === 'function'; @@ -72,7 +72,7 @@ export class RowHeightCache { const expanded = rowExpansions.has(row); if (row && expanded) { if (isDetailFn) { - const index = rowIndexes.get(row); + const index = indexOffset + i; currentRowHeight += detailRowHeight(row, index); } else { currentRowHeight += detailRowHeight; From 436b1977c55348d98c182a228023f895fbf0ea52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Wed, 11 Jun 2025 08:53:45 +0200 Subject: [PATCH 074/105] refactor: add missing Row type for TRow (#234) --- .../lib/components/body/body-group-header.directive.ts | 4 ++-- .../lib/components/body/body-row-wrapper.component.ts | 10 ++++++---- .../src/lib/components/body/body-row.component.ts | 4 ++-- .../lib/components/row-detail/row-detail.directive.ts | 4 ++-- .../ngx-datatable/src/lib/types/internal.types.ts | 4 ++-- .../ngx-datatable/src/lib/types/public.types.ts | 6 +++--- .../ngx-datatable/src/lib/types/table-column.type.ts | 4 ++-- 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts index c5deea001..d938837aa 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts @@ -1,11 +1,11 @@ import { ContentChild, Directive, EventEmitter, Input, Output, TemplateRef } from '@angular/core'; import { DatatableGroupHeaderTemplateDirective } from './body-group-header-template.directive'; -import { Group, GroupContext, GroupToggleEvents } from '../../types/public.types'; +import { Group, GroupContext, GroupToggleEvents, Row } from '../../types/public.types'; @Directive({ selector: 'ngx-datatable-group-header' }) -export class DatatableGroupHeaderDirective { +export class DatatableGroupHeaderDirective { /** * Row height is required when virtual scroll is enabled. */ diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts index d5f31cf4d..e6a36e61c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts @@ -23,7 +23,7 @@ import { } from '@angular/core'; import { NgTemplateOutlet } from '@angular/common'; import { DatatableComponentToken } from '../../utils/table-token'; -import { Group, GroupContext, RowDetailContext, RowOrGroup } from '../../types/public.types'; +import { Group, GroupContext, Row, RowDetailContext, RowOrGroup } from '../../types/public.types'; import { DatatableGroupHeaderDirective } from './body-group-header.directive'; import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive'; @@ -73,7 +73,9 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive' standalone: true, imports: [NgTemplateOutlet] }) -export class DataTableRowWrapperComponent implements DoCheck, OnInit, OnChanges { +export class DataTableRowWrapperComponent + implements DoCheck, OnInit, OnChanges +{ @ViewChild('select') checkBoxInput!: ElementRef; @Input() innerWidth: number; @Input() rowDetail: DatatableRowDetailDirective; @@ -161,7 +163,7 @@ export class DataTableRowWrapperComponent implements DoCheck, OnInit // mark group header checkbox state as indeterminate if (this.groupHeader?.checkboxable && this.selectedRowsDiffer.diff(this.selected)) { const selectedRows = this.selected.filter(row => - this.group()?.value.find(item => item === row) + this.group()?.value.find((item: TRow) => item === row) ); if (this.checkBoxInput) { if (selectedRows.length && selectedRows.length !== this.group()?.value.length) { @@ -182,7 +184,7 @@ export class DataTableRowWrapperComponent implements DoCheck, OnInit onCheckboxChange(groupSelected: boolean): void { // First remove all rows of this group from `selected` this.selected = [ - ...this.selected.filter(row => !this.group().value.find(item => item === row)) + ...this.selected.filter(row => !this.group().value.find((item: TRow) => item === row)) ]; // If checkbox is checked then add all rows of this group in `selected` if (groupSelected) { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index 0246aad6b..71eee3e67 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -18,7 +18,7 @@ import { import { columnGroupWidths, columnsByPin, columnsByPinArr } from '../../utils/column'; import { Keys } from '../../utils/keys'; -import { ActivateEvent, RowOrGroup, TreeStatus } from '../../types/public.types'; +import { ActivateEvent, Row, RowOrGroup, TreeStatus } from '../../types/public.types'; import { ColumnGroupWidth, PinnedColumns, @@ -64,7 +64,7 @@ import { DataTableBodyCellComponent } from './body-cell.component'; standalone: true, imports: [DataTableBodyCellComponent] }) -export class DataTableBodyRowComponent implements DoCheck, OnChanges { +export class DataTableBodyRowComponent implements DoCheck, OnChanges { private cd = inject(ChangeDetectorRef); @Input() set columns(val: TableColumnInternal[]) { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts index 3acc9c568..8d5813fc7 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts @@ -1,11 +1,11 @@ import { ContentChild, Directive, EventEmitter, Input, Output, TemplateRef } from '@angular/core'; import { DatatableRowDetailTemplateDirective } from './row-detail-template.directive'; -import { DetailToggleEvents, RowDetailContext } from '../../types/public.types'; +import { DetailToggleEvents, Row, RowDetailContext } from '../../types/public.types'; @Directive({ selector: 'ngx-datatable-row-detail' }) -export class DatatableRowDetailDirective { +export class DatatableRowDetailDirective { /** * The detail row height is required especially * when virtual scroll is enabled. diff --git a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts index 8f244fa48..573b34ac8 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts @@ -1,6 +1,6 @@ import { TableColumn, TableColumnProp } from './table-column.type'; import { ValueGetter } from '../utils/column-prop-getters'; -import { SortDirection } from './public.types'; +import { Row, SortDirection } from './public.types'; export type PinDirection = 'left' | 'center' | 'right'; @@ -51,7 +51,7 @@ export interface InnerSortEvent { newValue: SortDirection; } -export interface TableColumnInternal extends TableColumn { +export interface TableColumnInternal extends TableColumn { /** Internal unique id */ $$id: string; diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index 82be4e92e..9658dcccf 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -52,13 +52,13 @@ export interface HeaderCellContext { selectFn: () => void; } -export interface GroupContext { +export interface GroupContext { group: Group; expanded: boolean; rowIndex: number; } -export interface CellContext { +export interface CellContext { onCheckboxChangeFn: (event: Event) => void; activateFn: (event: ActivateEvent) => void; row: TRow; @@ -99,7 +99,7 @@ export interface Group { /** Type for either a row or a group */ export type RowOrGroup = TRow | Group; -export interface RowDetailContext { +export interface RowDetailContext { row: TRow; expanded: boolean; rowIndex: number; diff --git a/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts b/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts index d5312cebf..8ffa02866 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts @@ -1,5 +1,5 @@ import { PipeTransform, TemplateRef } from '@angular/core'; -import { CellContext, HeaderCellContext } from './public.types'; +import { CellContext, HeaderCellContext, Row } from './public.types'; /** * Column property that indicates how to retrieve this column's @@ -11,7 +11,7 @@ export type TableColumnProp = string | number; /** * Column Type */ -export interface TableColumn { +export interface TableColumn { /** * Determines if column is checkbox */ From c82c33dab25ddf0664f81570d04b74920bcdffa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Wed, 11 Jun 2025 08:59:16 +0200 Subject: [PATCH 075/105] refactor: add missing null and declaration (#237) --- .../ngx-datatable/src/lib/components/body/body.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 40ca73164..bdf61c7dd 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -1006,7 +1006,7 @@ export class DataTableBodyComponent implements OnInit, O const parentElement = rowElement.parentElement; if (parentElement) { - let focusElement: Element; + let focusElement: Element | null = null; if (key === Keys.up) { focusElement = parentElement.previousElementSibling; } else if (key === Keys.down) { @@ -1020,7 +1020,7 @@ export class DataTableBodyComponent implements OnInit, O } focusCell(cellElement: HTMLElement, rowElement: HTMLElement, key: Keys, cellIndex: number): void { - let nextCellElement: Element; + let nextCellElement: Element | null = null; if (key === Keys.left) { nextCellElement = cellElement.previousElementSibling; From d251668371183cf3c96c3d6a818e142f76b909f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Wed, 11 Jun 2025 09:37:44 +0200 Subject: [PATCH 076/105] refactor: merge contexts into one object to avoid type issues (#235) --- .../body/body-row-wrapper.component.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts index e6a36e61c..73af1cad2 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts @@ -50,16 +50,20 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive' } - + } @if ((groupHeader?.template && expanded) || !groupHeader || !groupHeader.template) { } @if (rowDetail?.template && expanded) { +
    + + +
    + } @if ((groupHeader?.template && expanded) || !groupHeader || !groupHeader.template) { + + } @if (rowDetail?.template && expanded) {
    @@ -98,8 +102,7 @@ export class DataTableRowWrapperComponent @Input({ transform: booleanAttribute }) expanded = false; - groupContext?: GroupContext; - rowContext?: RowDetailContext; + context: RowDetailContext | GroupContext; private rowDiffer: KeyValueDiffer, any> = inject(KeyValueDiffers) .find({}) @@ -123,13 +126,13 @@ export class DataTableRowWrapperComponent if (changes['row']) { // this component renders either a group header or a row. Never both. if (this.isGroup(this.row)) { - this.groupContext = { + this.context = { group: this.row, expanded: this.expanded, rowIndex: this.rowIndex }; } else { - this.rowContext = { + this.context = { row: this.row, expanded: this.expanded, rowIndex: this.rowIndex, @@ -138,22 +141,19 @@ export class DataTableRowWrapperComponent } } if (changes['rowIndex']) { - (this.rowContext ?? this.groupContext).rowIndex = this.rowIndex; + this.context.rowIndex = this.rowIndex; } if (changes['expanded']) { - (this.groupContext ?? this.rowContext)!.expanded = this.expanded; - if (this.rowContext) { - this.rowContext.expanded = this.expanded; - } + this.context.expanded = this.expanded; } } ngDoCheck(): void { if (this.rowDiffer.diff(this.row)) { - if (this.isGroup(this.row)) { - this.groupContext.group = this.row; + if ('group' in this.context) { + this.context.group = this.row as Group; } else { - this.rowContext.row = this.row; + this.context.row = this.row as TRow; } this.cd.markForCheck(); } From df8379eb0e880c6c279b960790f00eec7bbd2359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Wed, 11 Jun 2025 16:57:23 +0200 Subject: [PATCH 077/105] refactor: drop useless group signal (#236) --- .../body/body-row-wrapper.component.ts | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts index 73af1cad2..312e1e8d5 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts @@ -3,7 +3,6 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - computed, DoCheck, ElementRef, EventEmitter, @@ -31,7 +30,7 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive' selector: 'datatable-row-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, template: ` - @if (groupHeader?.template) { + @if (isGroup(row) && groupHeader?.template) {
    @@ -61,13 +60,6 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive'
    - } @if ((groupHeader?.template && expanded) || !groupHeader || !groupHeader.template) { - - } @if (rowDetail?.template && expanded) { -
    - - -
    } `, host: { @@ -112,12 +104,6 @@ export class DataTableRowWrapperComponent private tableComponent = inject(DatatableComponentToken); private cd = inject(ChangeDetectorRef); - protected group = computed(() => { - if (typeof this.row === 'object' && 'value' in this.row) { - return this.row; - } - }); - ngOnInit(): void { this.selectedRowsDiffer = this.iterableDiffers.find(this.selected ?? []).create(); } @@ -161,12 +147,17 @@ export class DataTableRowWrapperComponent // on currently selected rows to check if it is modified // if any of the row of this group is not present in `selected` rows array // mark group header checkbox state as indeterminate - if (this.groupHeader?.checkboxable && this.selectedRowsDiffer.diff(this.selected)) { + if ( + this.isGroup(this.row) && + this.groupHeader?.checkboxable && + this.selectedRowsDiffer.diff(this.selected) + ) { + const thisRow = this.row; const selectedRows = this.selected.filter(row => - this.group()?.value.find((item: TRow) => item === row) + thisRow.value.find((item: TRow) => item === row) ); if (this.checkBoxInput) { - if (selectedRows.length && selectedRows.length !== this.group()?.value.length) { + if (selectedRows.length && selectedRows.length !== this.row.value.length) { this.checkBoxInput.nativeElement.indeterminate = true; } else { this.checkBoxInput.nativeElement.indeterminate = false; @@ -181,14 +172,14 @@ export class DataTableRowWrapperComponent this.rowContextmenu.emit({ event: $event, row: this.row }); } - onCheckboxChange(groupSelected: boolean): void { + onCheckboxChange(groupSelected: boolean, group: Group): void { // First remove all rows of this group from `selected` this.selected = [ - ...this.selected.filter(row => !this.group().value.find((item: TRow) => item === row)) + ...this.selected.filter(row => !group.value.find((item: TRow) => item === row)) ]; // If checkbox is checked then add all rows of this group in `selected` if (groupSelected) { - this.selected = [...this.selected, ...this.group().value]; + this.selected = [...this.selected, ...group.value]; } // Update `selected` of DatatableComponent with newly evaluated `selected` this.tableComponent.selected = [...this.selected]; From 4a30874225defc547f9e077bc72241bd7554bac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Fri, 13 Jun 2025 13:05:19 +0200 Subject: [PATCH 078/105] fix: prevent errors with row-specific ghost in combination with grouping, selection and trees (#241) This is just preventing runtime errors and not supporting the combination. Since we use `undefined` to mark loading rows, we do not have access to group keys and alike. So it is not possible yet to have loading rows inside a group or a tree structure. To solve this, we need to enhance the API. --- .../src/lib/components/body/body.component.ts | 14 +++++----- .../src/lib/components/datatable.component.ts | 27 ++++++++++++------- .../ngx-datatable/src/lib/utils/selection.ts | 9 +++++-- .../ngx-datatable/src/lib/utils/tree.ts | 6 ++--- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index bdf61c7dd..73124e284 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -277,14 +277,14 @@ export class DataTableBodyComponent implements OnInit, O return this._pageSize; } - @Input() set rows(val: TRow[]) { + @Input() set rows(val: (TRow | undefined)[]) { if (val !== this._rows) { this._rows = val; this.recalcLayout(); } } - get rows(): TRow[] { + get rows(): (TRow | undefined)[] { return this._rows; } @@ -387,11 +387,11 @@ export class DataTableBodyComponent implements OnInit, O offsetY = 0; indexes = signal<{ first: number; last: number }>({ first: 0, last: 0 }); columnGroupWidths: ColumnGroupWidth; - rowTrackingFn: TrackByFunction>; + rowTrackingFn: TrackByFunction | undefined>; listener: any; rowExpansions: any[] = []; - _rows: TRow[]; + _rows: (TRow | undefined)[]; _bodyHeight: string; _columns: TableColumnInternal[]; _rowCount: number; @@ -541,7 +541,7 @@ export class DataTableBodyComponent implements OnInit, O /** * Updates the rows in the view port */ - updateRows(): RowOrGroup[] { + updateRows(): (RowOrGroup | undefined)[] { const { first, last } = this.indexes(); // if grouprowsby has been specified treat row paging // parameters as group paging parameters ie if limit 10 has been @@ -683,7 +683,7 @@ export class DataTableBodyComponent implements OnInit, O const rowExpansions = new Set(); if (this.rowDetail) { for (const row of this.rows) { - if (this.getRowExpanded(row)) { + if (row && this.getRowExpanded(row)) { rowExpansions.add(row); } } @@ -1068,7 +1068,7 @@ export class DataTableBodyComponent implements OnInit, O return !!this.groupedRows; } - protected isRow(row: RowOrGroup): row is TRow { + protected isRow(row: RowOrGroup | undefined): row is TRow { return !this.groupedRows; } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 6dcfae28f..10915bb1c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -116,7 +116,7 @@ export class DatatableComponent /** * Rows that are displayed in the table. */ - @Input() set rows(val: TRow[] | null | undefined) { + @Input() set rows(val: (TRow | undefined)[] | null | undefined) { this._rows = val ?? []; // This will ensure that datatable detects changes on doing like this rows = [...rows]; this.rowDiffer.diff([] as any); @@ -128,7 +128,7 @@ export class DatatableComponent /** * Gets the rows. */ - get rows(): TRow[] { + get rows(): (TRow | undefined)[] { return this._rows; } @@ -693,9 +693,9 @@ export class DatatableComponent _limit: number | undefined; _count = 0; _offset = 0; - _rows: TRow[] = []; + _rows: (TRow | undefined)[] = []; _groupRowsBy: keyof TRow; - _internalRows: TRow[] = []; + _internalRows: (TRow | undefined)[] = []; _internalColumns: TableColumnInternal[]; _columns: TableColumn[]; _subscriptions: Subscription[] = []; @@ -811,12 +811,17 @@ export class DatatableComponent * @param originalArray the original array passed via parameter * @param groupBy the key of the column to group the data by */ - groupArrayBy(originalArray: TRow[], groupBy: keyof TRow) { + groupArrayBy(originalArray: (TRow | undefined)[], groupBy: keyof TRow) { // create a map to hold groups with their corresponding results const map = new Map(); let i = 0; originalArray.forEach(item => { + if (!item) { + // skip undefined items + return; + } + const key = item[groupBy]; const value = map.get(key); if (!value) { @@ -1206,14 +1211,16 @@ export class DatatableComponent // do the opposite here if (!allSelected) { - this.selected.push(...this._internalRows.slice(first, last)); + this.selected.push(...this._internalRows.slice(first, last).filter(row => !!row)); } } else { - let relevantRows; + let relevantRows: TRow[]; if (this.disableRowCheck) { - relevantRows = this.rows.filter(row => !this.disableRowCheck!(row)); + relevantRows = this.rows.filter( + (row => row && !this.disableRowCheck!(row)) as (row: TRow | undefined) => row is TRow + ); } else { - relevantRows = this.rows; + relevantRows = this.rows.filter(row => !!row); } // before we splice, chk if we currently have all selected const allSelected = this.selected.length === relevantRows.length; @@ -1244,7 +1251,7 @@ export class DatatableComponent const row = event.row; // TODO: For duplicated items this will not work const rowIndex = this._rows.findIndex( - r => r[this.treeToRelation] === event.row[this.treeToRelation] + r => r && r[this.treeToRelation] === event.row[this.treeToRelation] ); this.treeAction.emit({ row, rowIndex }); } diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/selection.ts b/projects/swimlane/ngx-datatable/src/lib/utils/selection.ts index 0adbf46f9..3ac2fa269 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/selection.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/selection.ts @@ -10,7 +10,12 @@ export function selectRows(selected: TRow[], row: TRow, comparefn: any) { return selected; } -export function selectRowsBetween(selected: TRow[], rows: TRow[], index: number, prevIndex: number): TRow[] { +export function selectRowsBetween( + selected: TRow[], + rows: (TRow | undefined)[], + index: number, + prevIndex: number +): TRow[] { const reverse = index < prevIndex; for (let i = 0; i < rows.length; i++) { @@ -34,7 +39,7 @@ export function selectRowsBetween(selected: TRow[], rows: TRow[], index: n if ((reverse && lesser) || (!reverse && greater)) { // if in the positive range to be added to `selected`, and // not already in the selected array, add it - if (i >= range.start && i <= range.end) { + if (i >= range.start && i <= range.end && row) { selected.push(row); } } diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts index 9a60c934f..936653298 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts @@ -44,12 +44,12 @@ export function optionalGetterForProp(prop: TableColumnProp): OptionalValueGette * */ export function groupRowsByParents( - rows: TRow[], + rows: (TRow | undefined)[], from?: OptionalValueGetter, to?: OptionalValueGetter -): TRow[] { +): (TRow | undefined)[] { if (from && to) { - const treeRows = rows.map(row => new TreeNode(row)); + const treeRows = rows.filter(row => !!row).map(row => new TreeNode(row)); const uniqIDs = new Map(treeRows.map(node => [to(node.row), node])); const rootNodes = treeRows.reduce((root, node) => { From ebd9afe3e5d87a931aff88da46ce653451e67727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Mon, 16 Jun 2025 10:36:59 +0200 Subject: [PATCH 079/105] refactor: move ghost loading out of cells (#239) --- .../components/body/body-cell.component.ts | 8 +- .../src/lib/components/body/body.component.ts | 130 +++++++++--------- .../ghost-loader/ghost-loader.component.html | 18 +-- .../ghost-loader/ghost-loader.component.scss | 7 +- .../ghost-loader/ghost-loader.component.ts | 11 +- 5 files changed, 91 insertions(+), 83 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 37a14ffad..32d7c32ed 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -23,7 +23,6 @@ import { SortPropDir, TreeStatus } from '../../types/public.types'; -import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.component'; import { NgTemplateOutlet } from '@angular/common'; import { RowIndex, TableColumnInternal } from '../../types/internal.types'; @@ -31,7 +30,6 @@ import { RowIndex, TableColumnInternal } from '../../types/internal.types'; selector: 'datatable-body-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: ` - @if (row) {
    @if (column.checkboxable && (!displayCheck || displayCheck(row, column, value))) {
    - } @else { @if (ghostLoadingIndicator) { - - } } `, styleUrl: './body-cell.component.scss', - standalone: true, - imports: [NgTemplateOutlet, DataTableGhostLoaderComponent] + imports: [NgTemplateOutlet] }) export class DataTableBodyCellComponent implements DoCheck { private cd = inject(ChangeDetectorRef); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 73124e284..91a1f9ff9 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -121,70 +121,76 @@ import { Keys } from '../../utils/keys';
    @for (group of rowsToRender(); track rowTrackingFn(i, group); let i = $index) { - @let disabled = isRow(group) && disableRowCheck && disableRowCheck(group); - - - - @if (rowDefTemplate) { - - } @else { - @if (isRow(group)) { + @if (!group && ghostLoadingIndicator) { + + } @else if (group) { + @let disabled = isRow(group) && disableRowCheck && disableRowCheck(group); + + + + @if (rowDefTemplate) { + *rowDefInternal=" + { + template: rowDefTemplate, + rowTemplate: bodyRow, + row: group, + index: i + }; + disabled: disabled + " + /> + } @else { + @if (isRow(group)) { + + } } - } - @if (isGroup(group)) { - - @for (row of group.value; track rowTrackingFn($index, row)) { - @let disabled = disableRowCheck && disableRowCheck(row); - + @if (isGroup(group)) { + + @for (row of group.value; track rowTrackingFn($index, row)) { + @let disabled = disableRowCheck && disableRowCheck(row); + + } } - } - + + } }
    @@ -207,8 +213,8 @@ import { Keys } from '../../utils/keys'; [style.width]="scrollbarH ? columnGroupWidths?.total + 'px' : '100%'" (scroll)="onBodyScroll($event)" > - + + } `, changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.html b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.html index 55fb44a53..69e67622b 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.html +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.html @@ -1,13 +1,15 @@ -
    +
    @for (item of [].constructor(pageSize); track item) { -
    - @for (col of columns; track col) { - @if (!col.ghostCellTemplate) { -
    - } @else { - - } +
    + @for (col of columns; track col) { +
    + @if (!col.ghostCellTemplate) { +
    + } @else { + }
    + } +
    }
    diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.scss index ef7e44bb8..322125c33 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.scss @@ -23,6 +23,7 @@ .ghost-element { display: flex; + align-items: center; } } @@ -30,9 +31,7 @@ position: sticky; top: 20px; - .ghost-loader { - .line { - margin: 0.9rem 1.2rem; - } + .ghost-cell { + padding-inline: 1.2rem; } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts index 6d2be2b6b..ba5f816e3 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts @@ -1,4 +1,10 @@ -import { ChangeDetectionStrategy, Component, Input, numberAttribute } from '@angular/core'; +import { + booleanAttribute, + ChangeDetectionStrategy, + Component, + Input, + numberAttribute +} from '@angular/core'; import { NgTemplateOutlet } from '@angular/common'; import { TableColumnInternal } from '../../../types/internal.types'; @@ -13,5 +19,6 @@ export class DataTableGhostLoaderComponent { @Input() columns: TableColumnInternal[]; @Input({ transform: numberAttribute }) pageSize: number; @Input() rowHeight: number | 'auto' | ((row?: any) => number); - @Input({ transform: numberAttribute }) ghostBodyHeight: number; + @Input({ transform: numberAttribute }) ghostBodyHeight?: number; + @Input({ transform: booleanAttribute }) cellMode = false; } From 659ecd5a9c83b99e7f1cb48cd9c6371d35099d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Mon, 16 Jun 2025 14:52:52 +0200 Subject: [PATCH 080/105] refactor: remove unused internal event (#206) --- docs/api/table/outputs.md | 11 ------- .../src/lib/components/body/body.component.ts | 33 ------------------- 2 files changed, 44 deletions(-) diff --git a/docs/api/table/outputs.md b/docs/api/table/outputs.md index a7ff5ada4..d6335c32e 100644 --- a/docs/api/table/outputs.md +++ b/docs/api/table/outputs.md @@ -18,17 +18,6 @@ A cell or row was focused via keyboard or mouse click. } ``` -### `detailToggle` - -Row detail row was toggled. - -``` -{ - rows - currentIndex -} -``` - ### `page` The table was paged either triggered by the pager or the body scroll. diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 91a1f9ff9..f12d66bfa 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -360,7 +360,6 @@ export class DataTableBodyComponent implements OnInit, O @Output() page = new EventEmitter(); @Output() activate = new EventEmitter>(); @Output() select = new EventEmitter>(); - @Output() detailToggle = new EventEmitter(); @Output() rowContextmenu = new EventEmitter<{ event: MouseEvent; row: RowOrGroup }>(false); @Output() treeAction: EventEmitter<{ row: TRow }> = new EventEmitter(); @@ -708,23 +707,6 @@ export class DataTableBodyComponent implements OnInit, O } } - /** - * Gets the index for the view port - */ - getAdjustedViewPortIndex(): number { - // Capture the row index of the first row that is visible on the viewport. - // If the scroll bar is just below the row which is highlighted then make that as the - // first index. - const viewPortFirstRowIndex = this.indexes().first; - - if (this.scrollbarV && this.virtualization) { - const offsetScroll = this.rowHeightsCache().query(viewPortFirstRowIndex - 1); - return offsetScroll <= this.offsetY ? viewPortFirstRowIndex - 1 : viewPortFirstRowIndex; - } - - return viewPortFirstRowIndex; - } - /** * Toggle the Expansion of the row i.e. if the row is expanded then it will * collapse and vice versa. Note that the expanded status is stored as @@ -732,8 +714,6 @@ export class DataTableBodyComponent implements OnInit, O * status in case of sorting and filtering of the row set. */ toggleRowExpansion(row: TRow): void { - // Capture the row index of the first row that is visible on the viewport. - const viewPortFirstRowIndex = this.getAdjustedViewPortIndex(); const rowExpandedIdx = this.getRowExpandedIdx(row, this.rowExpansions); const expanded = rowExpandedIdx > -1; @@ -748,11 +728,6 @@ export class DataTableBodyComponent implements OnInit, O if (this.scrollbarV && this.virtualization) { this.refreshRowHeightCache(); } - - this.detailToggle.emit({ - rows: [row], - currentIndex: viewPortFirstRowIndex - }); } /** @@ -762,8 +737,6 @@ export class DataTableBodyComponent implements OnInit, O // clear prev expansions this.rowExpansions = []; - // Capture the row index of the first row that is visible on the viewport. - const viewPortFirstRowIndex = this.getAdjustedViewPortIndex(); const rows = this.groupedRows ?? this.rows; if (expanded) { for (const row of rows) { @@ -775,12 +748,6 @@ export class DataTableBodyComponent implements OnInit, O // Refresh the full row heights cache since every row was affected. this.recalcLayout(); } - - // Emit all rows that have been expanded. - this.detailToggle.emit({ - rows: rows, - currentIndex: viewPortFirstRowIndex - }); } /** From 3939475ed0792642930e398fb84c047545ddf187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Mon, 16 Jun 2025 14:58:23 +0200 Subject: [PATCH 081/105] refactor: drop useless stable sort code (#244) Since ES2019 Array.sort is guaranteed to be stable. --- .../swimlane/ngx-datatable/src/lib/utils/sort.ts | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts index a6f5b5bfb..5310f7a4c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts @@ -83,13 +83,6 @@ export function sortRows(rows: TRow[], columns: TableColumn[], dirs: SortP return [...rows]; } - /** - * record the row ordering of results from prior sort operations (if applicable) - * this is necessary to guarantee stable sorting behavior - */ - const rowToIndexMap = new Map(); - rows.forEach((row, index) => rowToIndexMap.set(row, index)); - const temp = [...rows]; const cols = columns.reduce((obj, col) => { if (col.comparator && typeof col.comparator === 'function') { @@ -136,14 +129,7 @@ export function sortRows(rows: TRow[], columns: TableColumn[], dirs: SortP } } - if (!(rowToIndexMap.has(rowA) && rowToIndexMap.has(rowB))) { - return 0; - } - - /** - * all else being equal, preserve original order of the rows (stable sort) - */ - return rowToIndexMap.get(rowA) < rowToIndexMap.get(rowB) ? -1 : 1; + return 0; }); } From 4a4f64428158b70ffda7b539b66e424d5aff62e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Mon, 16 Jun 2025 15:03:16 +0200 Subject: [PATCH 082/105] refactor: allow undefined on internal prop (#243) * refactor: allow undefined on internal prop * refactor: add missing Row type * refactor: add new internal type for sortable rows Sortable rows require a prop attribute. This should be reflected in the type to avoid unnecessary casting. --- .../src/lib/types/internal.types.ts | 14 ++++++++++++-- .../src/lib/utils/column-helper.ts | 5 ++++- .../src/lib/utils/column-prop-getters.ts | 2 +- .../ngx-datatable/src/lib/utils/sort.ts | 19 ++++++++++++------- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts index 573b34ac8..7bcdbcfbe 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts @@ -51,7 +51,7 @@ export interface InnerSortEvent { newValue: SortDirection; } -export interface TableColumnInternal extends TableColumn { +export interface BaseTableColumnInternal extends TableColumn { /** Internal unique id */ $$id: string; @@ -66,11 +66,21 @@ export interface TableColumnInternal extends TableColumn targetMarkerContext?: any; // Those properties are never null on the internal type: - prop: TableColumnProp; name: string; width: number; } +export interface SortableTableColumnInternal + extends BaseTableColumnInternal { + comparator: Exclude; + prop: TableColumnProp; + sortable: true; +} + +export type TableColumnInternal = + | BaseTableColumnInternal + | SortableTableColumnInternal; + export interface TableColumnGroup { left: TableColumnInternal[]; center: TableColumnInternal[]; diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts b/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts index 891f89bf0..d255a0d0c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts @@ -5,8 +5,10 @@ import { TableColumn } from '../types/table-column.type'; import { QueryList } from '@angular/core'; import { DataTableColumnDirective } from '../components/columns/column.directive'; import { TableColumnInternal } from '../types/internal.types'; +import { Row } from '../types/public.types'; +import { orderByComparator } from './sort'; -export function toInternalColumn( +export function toInternalColumn( columns: TableColumn[] | QueryList>, defaultColumnWidth = 150 ): TableColumnInternal[] { @@ -27,6 +29,7 @@ export function toInternalColumn( name: column.name ?? (prop ? deCamelCase(String(prop)) : ''), resizeable: column.resizeable ?? true, sortable: column.sortable ?? true, + comparator: column.comparator ?? orderByComparator, draggable: column.draggable ?? true, canAutoResize: column.canAutoResize ?? true, width: column.width ?? defaultColumnWidth, diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/column-prop-getters.ts b/projects/swimlane/ngx-datatable/src/lib/utils/column-prop-getters.ts index 5f5c13bff..4f1fbf804 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/column-prop-getters.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/column-prop-getters.ts @@ -15,7 +15,7 @@ export function emptyStringGetter(): string { * Returns the appropriate getter function for this kind of prop. * If prop == null, returns the emptyStringGetter. */ -export function getterForProp(prop: TableColumnProp): ValueGetter { +export function getterForProp(prop: TableColumnProp | undefined): ValueGetter { // TODO requires better typing which will also involve adjust TableColum. So postponing it. if (prop == null) { return emptyStringGetter; diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts index 5310f7a4c..4af0ad256 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts @@ -1,6 +1,7 @@ import { getterForProp } from './column-prop-getters'; import { Group, SortDirection, SortPropDir, SortType } from '../types/public.types'; -import { TableColumn, TableColumnProp } from '../types/table-column.type'; +import { TableColumnProp } from '../types/table-column.type'; +import { SortableTableColumnInternal, TableColumnInternal } from '../types/internal.types'; /** * Gets the next sort direction @@ -75,7 +76,11 @@ export function orderByComparator(a: any, b: any): number { * creates a shallow copy of the `rows` input and returns the sorted copy. this function * does not sort the `rows` argument in place */ -export function sortRows(rows: TRow[], columns: TableColumn[], dirs: SortPropDir[]): TRow[] { +export function sortRows( + rows: TRow[], + columns: TableColumnInternal[], + dirs: SortPropDir[] +): TRow[] { if (!rows) { return []; } @@ -85,11 +90,11 @@ export function sortRows(rows: TRow[], columns: TableColumn[], dirs: SortP const temp = [...rows]; const cols = columns.reduce((obj, col) => { - if (col.comparator && typeof col.comparator === 'function') { + if (col.sortable) { obj[col.prop] = col.comparator; } return obj; - }, {} as Record); + }, {} as Record); // cache valueGetter and compareFn so that they // do not need to be looked-up in the sort function body @@ -99,11 +104,11 @@ export function sortRows(rows: TRow[], columns: TableColumn[], dirs: SortP prop, dir: dir.dir, valueGetter: getterForProp(prop), - compareFn: cols[prop] || orderByComparator + compareFn: cols[prop] }; }); - return temp.sort(function (rowA: any, rowB: any) { + return temp.sort((rowA: TRow, rowB: TRow) => { for (const cachedDir of cachedDirs) { // Get property and valuegetters for column to be sorted const { prop, valueGetter } = cachedDir; @@ -135,7 +140,7 @@ export function sortRows(rows: TRow[], columns: TableColumn[], dirs: SortP export function sortGroupedRows( groupedRows: Group[], - columns: TableColumn[], + columns: TableColumnInternal[], dirs: SortPropDir[], sortOnGroupHeader: SortPropDir ): Group[] { From 9bea63ba348f8309bf1c5beadd4cd1ef8449e8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 17 Jun 2025 08:18:40 +0200 Subject: [PATCH 083/105] refactor: split activation event (#245) --- .../src/lib/components/body/body-cell.component.ts | 4 ++-- .../src/lib/components/body/body-row.component.ts | 7 +++---- .../src/lib/components/body/body.component.ts | 2 +- .../ngx-datatable/src/lib/types/internal.types.ts | 14 +++++++++++++- .../ngx-datatable/src/lib/types/public.types.ts | 2 +- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 32d7c32ed..8e1a4e770 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -24,7 +24,7 @@ import { TreeStatus } from '../../types/public.types'; import { NgTemplateOutlet } from '@angular/common'; -import { RowIndex, TableColumnInternal } from '../../types/internal.types'; +import { CellActiveEvent, RowIndex, TableColumnInternal } from '../../types/internal.types'; @Component({ selector: 'datatable-body-cell', @@ -197,7 +197,7 @@ export class DataTableBodyCellComponent implements DoChe @Input() ghostLoadingIndicator = false; - @Output() activate: EventEmitter> = new EventEmitter(); + @Output() activate = new EventEmitter>(); @Output() treeAction: EventEmitter = new EventEmitter(); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index 71eee3e67..225eb5d32 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -20,6 +20,7 @@ import { columnGroupWidths, columnsByPin, columnsByPinArr } from '../../utils/co import { Keys } from '../../utils/keys'; import { ActivateEvent, Row, RowOrGroup, TreeStatus } from '../../types/public.types'; import { + CellActiveEvent, ColumnGroupWidth, PinnedColumns, RowIndex, @@ -170,10 +171,8 @@ export class DataTableBodyRowComponent implements DoChec } } - onActivate(event: ActivateEvent, index: number): void { - event.cellIndex = index; - event.rowElement = this._element; - this.activate.emit(event); + onActivate(event: CellActiveEvent, index: number): void { + this.activate.emit({ ...event, rowElement: this._element, cellIndex: index }); } @HostListener('keydown', ['$event']) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index f12d66bfa..e62417658 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -962,7 +962,7 @@ export class DataTableBodyComponent implements OnInit, O } if (!model.cellElement || !isCellSelection) { this.focusRow(model.rowElement, key); - } else if (isCellSelection) { + } else if (isCellSelection && model.cellIndex) { this.focusCell(model.cellElement, model.rowElement, key, model.cellIndex); } } diff --git a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts index 7bcdbcfbe..ca8cfe3ea 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts @@ -1,6 +1,6 @@ import { TableColumn, TableColumnProp } from './table-column.type'; import { ValueGetter } from '../utils/column-prop-getters'; -import { Row, SortDirection } from './public.types'; +import { Row, SortDirection, TreeStatus } from './public.types'; export type PinDirection = 'left' | 'center' | 'right'; @@ -51,6 +51,18 @@ export interface InnerSortEvent { newValue: SortDirection; } +export interface CellActiveEvent { + type: 'checkbox' | 'click' | 'dblclick' | 'keydown' | 'mouseenter'; + event: Event; + row: TRow; + group?: TRow[]; + rowHeight?: number; + column?: TableColumn; + value?: any; + cellElement?: HTMLElement; + treeStatus?: TreeStatus; +} + export interface BaseTableColumnInternal extends TableColumn { /** Internal unique id */ $$id: string; diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index 9658dcccf..8c4ac5a53 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -41,7 +41,7 @@ export interface ActivateEvent { cellElement?: HTMLElement; treeStatus?: TreeStatus; cellIndex?: number; - rowElement?: HTMLElement; + rowElement: HTMLElement; } export interface HeaderCellContext { From 02dcc7d674871e2c61515aaa60968b72517f5adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 17 Jun 2025 08:28:05 +0200 Subject: [PATCH 084/105] Refactor/fine tune api (#246) * refactor: mark all inputs on the table-column directive as optional The interface should be assignable to directive. Every field in the interface is optional, so it has to be in the directive as well. * refactor: mark row param of rowHeight function as always defined --- .../components/columns/column.directive.ts | 64 +++++++++---------- .../src/lib/components/datatable.component.ts | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts index 6119fd88e..243c9cdb0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts @@ -22,14 +22,14 @@ import { CellContext, HeaderCellContext } from '../../types/public.types'; }) export class DataTableColumnDirective implements TableColumn, OnChanges { private columnChangesService = inject(ColumnChangesService); - @Input() name: string; - @Input() prop: TableColumnProp; + @Input() name?: string; + @Input() prop?: TableColumnProp; @Input({ transform: booleanAttribute }) bindAsUnsafeHtml?: boolean; - @Input({ transform: booleanAttribute }) frozenLeft: boolean; - @Input({ transform: booleanAttribute }) frozenRight: boolean; - @Input({ transform: numberAttribute }) flexGrow: number; - @Input({ transform: booleanAttribute }) resizeable: boolean; - @Input() comparator: ( + @Input({ transform: booleanAttribute }) frozenLeft?: boolean; + @Input({ transform: booleanAttribute }) frozenRight?: boolean; + @Input({ transform: numberAttribute }) flexGrow?: number; + @Input({ transform: booleanAttribute }) resizeable?: boolean; + @Input() comparator?: ( valueA: any, valueB: any, rowA: TRow, @@ -37,15 +37,15 @@ export class DataTableColumnDirective implements TableColumn, OnChanges { sortDir: 'desc' | 'asc' ) => number; @Input() pipe: PipeTransform; - @Input({ transform: booleanAttribute }) sortable: boolean; - @Input({ transform: booleanAttribute }) draggable: boolean; - @Input({ transform: booleanAttribute }) canAutoResize: boolean; - @Input({ transform: numberAttribute }) minWidth: number; - @Input({ transform: numberAttribute }) width: number; - @Input({ transform: numberAttribute }) maxWidth: number; - @Input({ transform: booleanAttribute }) checkboxable: boolean; - @Input({ transform: booleanAttribute }) headerCheckboxable: boolean; - @Input() headerClass: + @Input({ transform: booleanAttribute }) sortable?: boolean; + @Input({ transform: booleanAttribute }) draggable?: boolean; + @Input({ transform: booleanAttribute }) canAutoResize?: boolean; + @Input({ transform: numberAttribute }) minWidth?: number; + @Input({ transform: numberAttribute }) width?: number; + @Input({ transform: numberAttribute }) maxWidth?: number; + @Input({ transform: booleanAttribute }) checkboxable?: boolean; + @Input({ transform: booleanAttribute }) headerCheckboxable?: boolean; + @Input() headerClass?: | string | ((data: { column: TableColumn }) => string | Record); @Input() cellClass?: @@ -57,48 +57,48 @@ export class DataTableColumnDirective implements TableColumn, OnChanges { value: any; rowHeight: number; }) => string | Record); - @Input({ transform: booleanAttribute }) isTreeColumn: boolean; - @Input() treeLevelIndent: number; - @Input() summaryFunc: (cells: any[]) => any; - @Input() summaryTemplate: TemplateRef; + @Input({ transform: booleanAttribute }) isTreeColumn?: boolean; + @Input() treeLevelIndent?: number; + @Input() summaryFunc?: (cells: any[]) => any; + @Input() summaryTemplate?: TemplateRef; @Input('cellTemplate') - _cellTemplateInput: TemplateRef>; + _cellTemplateInput?: TemplateRef>; @ContentChild(DataTableColumnCellDirective, { read: TemplateRef, static: true }) - _cellTemplateQuery: TemplateRef>; + _cellTemplateQuery?: TemplateRef>; - get cellTemplate(): TemplateRef> { + get cellTemplate(): TemplateRef> | undefined { return this._cellTemplateInput || this._cellTemplateQuery; } @Input('headerTemplate') - _headerTemplateInput: TemplateRef; + _headerTemplateInput?: TemplateRef; @ContentChild(DataTableColumnHeaderDirective, { read: TemplateRef, static: true }) - _headerTemplateQuery: TemplateRef; + _headerTemplateQuery?: TemplateRef; - get headerTemplate(): TemplateRef { + get headerTemplate(): TemplateRef | undefined { return this._headerTemplateInput || this._headerTemplateQuery; } @Input('treeToggleTemplate') - _treeToggleTemplateInput: TemplateRef; + _treeToggleTemplateInput?: TemplateRef; @ContentChild(DataTableColumnCellTreeToggle, { read: TemplateRef, static: true }) - _treeToggleTemplateQuery: TemplateRef; + _treeToggleTemplateQuery?: TemplateRef; - get treeToggleTemplate(): TemplateRef { + get treeToggleTemplate(): TemplateRef | undefined { return this._treeToggleTemplateInput || this._treeToggleTemplateQuery; } @Input('ghostCellTemplate') - _ghostCellTemplateInput: TemplateRef; + _ghostCellTemplateInput?: TemplateRef; @ContentChild(DataTableColumnGhostCellDirective, { read: TemplateRef, static: true }) - _ghostCellTemplateQuery: TemplateRef; + _ghostCellTemplateQuery?: TemplateRef; - get ghostCellTemplate(): TemplateRef { + get ghostCellTemplate(): TemplateRef | undefined { return this._ghostCellTemplateInput || this._ghostCellTemplateQuery; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 10915bb1c..053790399 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -214,7 +214,7 @@ export class DatatableComponent * The row height; which is necessary * to calculate the height for the lazy rendering. */ - @Input() rowHeight: number | 'auto' | ((row?: TRow) => number) = 30; + @Input() rowHeight: number | 'auto' | ((row: TRow) => number) = 30; /** * Type of column width distribution formula. From 610986f5a140e13f035514800049e6443e8e4a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 17 Jun 2025 15:38:32 +0200 Subject: [PATCH 085/105] feat: include sorts in page event (#248) --- .../src/lib/components/datatable.component.ts | 12 ++++++++---- .../ngx-datatable/src/lib/types/public.types.ts | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 053790399..da75e972a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -755,7 +755,8 @@ export class DatatableComponent count: this.count, pageSize: this.pageSize, limit: this.limit, - offset: 0 + offset: 0, + sorts: this.sorts }); } }); @@ -996,7 +997,8 @@ export class DatatableComponent count: this.count, pageSize: this.pageSize, limit: this.limit, - offset: this.offset + offset: this.offset, + sorts: this.sorts }); } } @@ -1020,7 +1022,8 @@ export class DatatableComponent count: this.count, pageSize: this.pageSize, limit: this.limit, - offset: this.offset + offset: this.offset, + sorts: this.sorts }); if (this.selectAllRowsOnPage) { @@ -1191,7 +1194,8 @@ export class DatatableComponent count: this.count, pageSize: this.pageSize, limit: this.limit, - offset: this.offset + offset: this.offset, + sorts: this.sorts }); this.sort.emit(event); } diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index 8c4ac5a53..2814d749c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -128,6 +128,7 @@ export interface PageEvent { /** @deprecated Use {@link pageSize} instead. */ limit: number | undefined; offset: number; + sorts: SortPropDir[]; } export interface PagerPageEvent { From f5cb3eadb9239db8435d3cc36b0bd5a1c5c8f6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 17 Jun 2025 15:43:58 +0200 Subject: [PATCH 086/105] Refactor/enable strict null checks (#247) * refactor: improve typing related to null checks * docs: improve typing related to null checks * test: improve typing related to null checks * build: enable strict null checks --- .../lib/components/body/body-cell.component.ts | 9 ++++----- .../components/body/body-row-def.component.ts | 2 +- .../body/body-row-wrapper.component.ts | 4 ++-- .../lib/components/body/body-row.component.ts | 2 +- .../src/lib/components/body/body.component.ts | 16 ++++++++-------- .../body/summary/summary-row.component.spec.ts | 2 +- .../body/summary/summary-row.component.ts | 8 ++++---- .../components/columns/column.directive.spec.ts | 5 +++-- .../lib/components/columns/column.directive.ts | 4 ++-- .../components/footer/footer.component.spec.ts | 6 +++--- .../lib/components/footer/footer.component.ts | 6 +++--- .../components/footer/pager.component.spec.ts | 2 +- .../components/header/header-cell.component.ts | 2 +- .../lib/components/header/header.component.ts | 12 +++++++----- .../src/lib/directives/draggable.directive.ts | 2 +- .../src/lib/directives/long-press.directive.ts | 2 +- .../src/lib/directives/orderable.directive.ts | 6 +++--- .../src/lib/services/scrollbar-helper.service.ts | 2 +- .../src/lib/types/internal.types.ts | 11 ++++++++--- .../ngx-datatable/src/lib/types/public.types.ts | 4 ++-- .../src/lib/types/table-column.type.ts | 6 +++++- .../ngx-datatable/src/lib/utils/column-helper.ts | 6 ++++-- .../ngx-datatable/src/lib/utils/column.ts | 8 +++++--- .../ngx-datatable/src/lib/utils/math.spec.ts | 2 +- .../swimlane/ngx-datatable/src/lib/utils/math.ts | 2 +- .../swimlane/ngx-datatable/src/lib/utils/sort.ts | 2 +- .../swimlane/ngx-datatable/src/lib/utils/tree.ts | 7 +++---- src/app/basic/row-grouping.component.ts | 4 ++-- .../selection-chkbox-template.component.ts | 4 ++-- src/app/selection/selection-chkbox.component.ts | 4 ++-- .../selection-multi-click-chkbox.component.ts | 4 ++-- src/app/summary/summary-row-simple.component.ts | 2 +- 32 files changed, 86 insertions(+), 72 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 8e1a4e770..a40f22579 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -9,8 +9,7 @@ import { HostListener, inject, Input, - Output, - PipeTransform + Output } from '@angular/core'; import { Keys } from '../../utils/keys'; @@ -315,11 +314,11 @@ export class DataTableBodyCellComponent implements DoChe checkValueUpdates(): void { let value = ''; - if (!this.row || !this.column) { + if (!this.row || !this.column || this.column.prop == undefined) { value = ''; } else { const val = this.column.$$valueGetter(this.row, this.column.prop); - const userPipe: PipeTransform = this.column.pipe; + const userPipe = this.column.pipe; if (userPipe) { value = userPipe.transform(val); @@ -441,6 +440,6 @@ export class DataTableBodyCellComponent implements DoChe calcLeftMargin(column: TableColumnInternal, row: RowOrGroup): number { const levelIndent = column.treeLevelIndent != null ? column.treeLevelIndent : 50; - return column.isTreeColumn ? (row as TRow).level * levelIndent : 0; + return column.isTreeColumn ? (row as TRow).level! * levelIndent : 0; } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts index 1b12a2e32..d0f424e49 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts @@ -56,7 +56,7 @@ export class DatatableRowDefDirective { export class DatatableRowDefInternalDirective implements OnInit { vc = inject(ViewContainerRef); - @Input() rowDefInternal?: RowDefContext; + @Input() rowDefInternal: RowDefContext; @Input() rowDefInternalDisabled?: boolean; ngOnInit(): void { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts index 312e1e8d5..33f9d72c3 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts @@ -82,13 +82,13 @@ export class DataTableRowWrapperComponent @Input() row: RowOrGroup; @Input() groupedRows: Group[]; @Input() selected: TRow[]; - @Input() disabled: boolean; + @Input() disabled?: boolean; @Output() rowContextmenu = new EventEmitter<{ event: MouseEvent; row: RowOrGroup; }>(false); - @Input() rowIndex?: number; + @Input() rowIndex: number; selectedGroupRows = signal([]); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index 225eb5d32..b31a191f8 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -96,7 +96,7 @@ export class DataTableBodyRowComponent implements DoChec @Input() row: TRow; @Input() group: TRow[]; @Input() isSelected: boolean; - @Input() rowIndex: RowIndex | undefined; + @Input() rowIndex: RowIndex; @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value?: any) => boolean; @Input() treeStatus?: TreeStatus = 'collapsed'; @Input() ghostLoadingIndicator = false; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index e62417658..20661a342 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -265,7 +265,7 @@ export class DataTableBodyComponent implements OnInit, O @Input() summaryHeight: number; @Input() rowDraggable: boolean; @Input() rowDragEvents: EventEmitter; - @Input() disableRowCheck: (row: TRow) => boolean; + @Input() disableRowCheck?: (row: TRow) => boolean | undefined; @Input() set pageSize(val: number) { if (val !== this._pageSize) { @@ -791,7 +791,7 @@ export class DataTableBodyComponent implements OnInit, O event.preventDefault(); this.rowDragEvents.emit({ event, - srcElement: this._draggedRowElement, + srcElement: this._draggedRowElement!, eventType: 'dragover', dragRow: this._draggedRow, dropRow @@ -813,7 +813,7 @@ export class DataTableBodyComponent implements OnInit, O event.preventDefault(); this.rowDragEvents.emit({ event, - srcElement: this._draggedRowElement, + srcElement: this._draggedRowElement!, targetElement: rowComponent._element, eventType: 'drop', dragRow: this._draggedRow, @@ -829,7 +829,7 @@ export class DataTableBodyComponent implements OnInit, O event.preventDefault(); this.rowDragEvents.emit({ event, - srcElement: this._draggedRowElement, + srcElement: this._draggedRowElement!, targetElement: rowComponent._element, eventType: 'dragenter', dragRow: this._draggedRow, @@ -845,7 +845,7 @@ export class DataTableBodyComponent implements OnInit, O event.preventDefault(); this.rowDragEvents.emit({ event, - srcElement: this._draggedRowElement, + srcElement: this._draggedRowElement!, targetElement: rowComponent._element, eventType: 'dragleave', dragRow: this._draggedRow, @@ -857,7 +857,7 @@ export class DataTableBodyComponent implements OnInit, O event.preventDefault(); this.rowDragEvents.emit({ event, - srcElement: this._draggedRowElement, + srcElement: this._draggedRowElement!, eventType: 'dragend', dragRow }); @@ -911,7 +911,7 @@ export class DataTableBodyComponent implements OnInit, O } if (typeof this.disableRowCheck === 'function') { - selected = selected.filter(rowData => !this.disableRowCheck(rowData)); + selected = selected.filter(rowData => !this.disableRowCheck!(rowData)); } this.selected.splice(0, this.selected.length); @@ -939,7 +939,7 @@ export class DataTableBodyComponent implements OnInit, O (event as KeyboardEvent).key === 'a' && ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) ) { - this.selectRow(event, 0, this.rows[this.rows.length - 1]); + this.selectRow(event, 0, row); // The row property is ignored in this case. So we can pass anything. } else { this.onKeyboardFocus(model); } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts index 3413c88bf..aaf378c69 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.spec.ts @@ -116,7 +116,7 @@ describe('DataTableSummaryRowComponent', () => { triggerChange(); - expect(component.summaryRow.col1).toEqual(null); + expect(component.summaryRow.col1).toEqual(undefined); }); it('should use provided summary function', () => { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts index 89c63e473..87746e936 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts @@ -16,7 +16,7 @@ function defaultSumFunc(cells: any[]): any { } function noopSumFunc(cells: any[]): void { - return null; + return; } @Component({ @@ -69,12 +69,12 @@ export class DataTableSummaryRowComponent implements OnChanges { this.summaryRow = {}; this.columns - .filter(col => !col.summaryTemplate) + .filter(col => !col.summaryTemplate && col.prop) .forEach(col => { - const cellsFromSingleColumn = this.rows.map(row => row[col.prop]); + const cellsFromSingleColumn = this.rows.map(row => row[col.prop!]); const sumFunc = this.getSummaryFunction(col); - this.summaryRow[col.prop] = col.pipe + this.summaryRow[col.prop!] = col.pipe ? col.pipe.transform(sumFunc(cellsFromSingleColumn)) : sumFunc(cellsFromSingleColumn); }); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts index ab91736bb..492b5e0c3 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts @@ -4,6 +4,7 @@ import { By } from '@angular/platform-browser'; import { ColumnChangesService } from '../../services/column-changes.service'; import { DataTableColumnDirective } from './column.directive'; +import { Row } from '../../types/public.types'; import Spy = jasmine.Spy; @Component({ @@ -33,7 +34,7 @@ describe('DataTableColumnDirective', () => { })); describe('fixture', () => { - let directive: DataTableColumnDirective; + let directive: DataTableColumnDirective; beforeEach(() => { directive = fixture.debugElement @@ -51,7 +52,7 @@ describe('DataTableColumnDirective', () => { }); describe('directive #1', () => { - let directive: DataTableColumnDirective; + let directive: DataTableColumnDirective; beforeEach(() => { directive = fixture.debugElement.query(By.css('#t1')).injector.get(DataTableColumnDirective); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts index 243c9cdb0..4b2396fa7 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts @@ -15,12 +15,12 @@ import { DataTableColumnCellTreeToggle } from './tree.directive'; import { ColumnChangesService } from '../../services/column-changes.service'; import { TableColumn, TableColumnProp } from '../../types/table-column.type'; import { DataTableColumnGhostCellDirective } from './column-ghost-cell.directive'; -import { CellContext, HeaderCellContext } from '../../types/public.types'; +import { CellContext, HeaderCellContext, Row } from '../../types/public.types'; @Directive({ selector: 'ngx-datatable-column' }) -export class DataTableColumnDirective implements TableColumn, OnChanges { +export class DataTableColumnDirective implements TableColumn, OnChanges { private columnChangesService = inject(ColumnChangesService); @Input() name?: string; @Input() prop?: TableColumnProp; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts index 9623e4643..51686221f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts @@ -228,7 +228,7 @@ describe('DataTableFooterComponent', () => { [selectedCount]="selectedCount" [selectedMessage]="selectedMessage" [pagerNextIcon]="pagerNextIcon" - (page)="onPageEvent($event)" + (page)="onPageEvent()" > @@ -261,9 +261,9 @@ class TestFixtureComponent { pagerPreviousIcon: string; pagerNextIcon: string; totalMessage: string; - footerTemplate: { template: TemplateRef }; + footerTemplate?: { template: TemplateRef }; selectedCount: number; - selectedMessage: string; + selectedMessage?: string; /** * establishes a reference to a test template that can diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts index 89ae2dea8..709be3be1 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts @@ -62,10 +62,10 @@ export class DataTableFooterComponent { @Input() pagerPreviousIcon?: string; @Input() pagerNextIcon?: string; @Input() totalMessage: string; - @Input() footerTemplate: DatatableFooterDirective; + @Input() footerTemplate?: DatatableFooterDirective; - @Input() selectedCount: number = 0; - @Input() selectedMessage: string | boolean; + @Input() selectedCount = 0; + @Input() selectedMessage?: string | boolean; @Output() page: EventEmitter = new EventEmitter(); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts index 2afe12f98..48f5c8b31 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/pager.component.spec.ts @@ -258,7 +258,7 @@ describe('DataTablePagerComponent', () => { fixture.detectChanges(); [firstButton, previousButton, nextButton, lastButton] = fixture.debugElement .queryAll(By.css('a[role=button]')) - .filter(it => !it.parent.classes['pages']); + .filter(it => !it.parent!.classes['pages']); pageButtons = fixture.debugElement .queryAll(By.css('li.pages')) .map((button, index) => ({ button, page: index + 1 })); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts index ddceafeff..3c73a1118 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.ts @@ -207,7 +207,7 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { private _column: TableColumnInternal; private _sorts: SortPropDir[]; private element = inject(ElementRef).nativeElement; - private subscription: Subscription; + private subscription?: Subscription; constructor() { this.cellContext = { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index e8bfb6d4c..9a551a5e7 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -14,6 +14,7 @@ import { } from '@angular/core'; import { columnGroupWidths, columnsByPin, columnsByPinArr } from '../../utils/column'; import { + Row, SelectionType, SortDirection, SortEvent, @@ -27,6 +28,7 @@ import { InnerSortEvent, PinnedColumns, ReorderEventInternal, + SortableTableColumnInternal, TableColumnInternal, TargetChangedEvent } from '../../types/internal.types'; @@ -217,13 +219,13 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { model }: { event: MouseEvent | TouchEvent; - model: TableColumnInternal; + model: TableColumnInternal; }) { model.dragging = true; this.dragEventTarget = event; } - onLongPressEnd({ model }: { model: TableColumnInternal }) { + onLongPressEnd({ model }: { model: TableColumnInternal }) { this.dragEventTarget = undefined; // delay resetting so sort can be @@ -260,7 +262,7 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { private makeResizeEvent( width: number, - column: TableColumnInternal + column: TableColumnInternal ): ColumnResizeEventInternal { if (column.minWidth && width <= column.minWidth) { width = column.minWidth; @@ -329,9 +331,9 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { } calcNewSorts( - column: TableColumnInternal, + column: SortableTableColumnInternal, prevValue: SortDirection, - newValue: SortDirection + newValue: SortDirection | undefined ): SortPropDir[] { let idx = 0; diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts index 8b710323f..fc8191652 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts @@ -38,7 +38,7 @@ export class DraggableDirective implements OnDestroy, OnChanges { element = inject(ElementRef).nativeElement; isDragging = false; - subscription: Subscription; + subscription?: Subscription; ngOnChanges(changes: SimpleChanges): void { if ( diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts index 2a63a7731..b87431943 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts @@ -35,7 +35,7 @@ export class LongPressDirective implements OnDestroy { isLongPressing = signal(false); timeout: any; - subscription: Subscription; + subscription?: Subscription; onMouseDown(event: MouseEvent | TouchEvent): void { const isMouse = event instanceof MouseEvent; diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts index e828e2125..e70845ff2 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts @@ -42,7 +42,7 @@ export class OrderableDirective implements AfterContentInit, OnDestroy { positions: Record; differ: KeyValueDiffer = inject(KeyValueDiffers).find({}).create(); - lastDraggingIndex: number; + lastDraggingIndex?: number; ngAfterContentInit(): void { // HACK: Investigate Better Way @@ -110,7 +110,7 @@ export class OrderableDirective implements AfterContentInit, OnDestroy { if (target) { if (this.lastDraggingIndex !== target.i) { this.targetChanged.emit({ - prevIndex: this.lastDraggingIndex, + prevIndex: this.lastDraggingIndex!, newIndex: target.i, initialIndex: prevPos.index }); @@ -118,7 +118,7 @@ export class OrderableDirective implements AfterContentInit, OnDestroy { } } else if (this.lastDraggingIndex !== prevPos.index) { this.targetChanged.emit({ - prevIndex: this.lastDraggingIndex, + prevIndex: this.lastDraggingIndex!, initialIndex: prevPos.index }); this.lastDraggingIndex = prevPos.index; diff --git a/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts b/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts index 25446d1cf..11d201688 100644 --- a/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts +++ b/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts @@ -25,7 +25,7 @@ export class ScrollbarHelper { outer.appendChild(inner); const widthWithScroll = inner.offsetWidth; - outer.parentNode.removeChild(outer); + this.document.body.removeChild(outer); return widthNoScroll - widthWithScroll; } diff --git a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts index ca8cfe3ea..5a8b869ab 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts @@ -46,9 +46,9 @@ export interface DraggableDragEvent { } export interface InnerSortEvent { - column: TableColumnInternal; + column: SortableTableColumnInternal; prevValue: SortDirection; - newValue: SortDirection; + newValue: SortDirection | undefined; } export interface CellActiveEvent { @@ -82,6 +82,11 @@ export interface BaseTableColumnInternal extends TableCo width: number; } +export interface StandardTableColumnInternal + extends BaseTableColumnInternal { + sortable?: false; +} + export interface SortableTableColumnInternal extends BaseTableColumnInternal { comparator: Exclude; @@ -90,7 +95,7 @@ export interface SortableTableColumnInternal } export type TableColumnInternal = - | BaseTableColumnInternal + | StandardTableColumnInternal | SortableTableColumnInternal; export interface TableColumnGroup { diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index 2814d749c..c25346171 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -13,7 +13,7 @@ export enum SortDirection { export interface SortEvent { column: TableColumn; prevValue: SortDirection; - newValue: SortDirection; + newValue: SortDirection | undefined; sorts: SortPropDir[]; } @@ -103,7 +103,7 @@ export interface RowDetailContext { row: TRow; expanded: boolean; rowIndex: number; - disabled: boolean; + disabled?: boolean; } /** diff --git a/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts b/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts index 8ffa02866..63bc4eb8e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/table-column.type.ts @@ -163,8 +163,12 @@ export interface TableColumn { /** * Summary function + * + * Null and undefined have different meanings: + * - undefined will use the default summary function + * - null will not compute a summary */ - summaryFunc?: (cells: any[]) => any; + summaryFunc?: ((cells: any[]) => any) | null; /** * Summary cell template ref diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts b/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts index d255a0d0c..62638efa4 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/column-helper.ts @@ -19,8 +19,10 @@ export function toInternalColumn( // Only one column should hold the tree view, // Thus if multiple columns are provided with // isTreeColumn as true, we take only the first one - const isTreeColumn = column.isTreeColumn && !hasTreeColumn; + const isTreeColumn = !!column.isTreeColumn && !hasTreeColumn; hasTreeColumn = hasTreeColumn || isTreeColumn; + // TODO: add check if prop or name is provided if sorting is enabled. + return { ...column, $$id: id(), @@ -39,6 +41,6 @@ export function toInternalColumn( cellTemplate: column.cellTemplate, summaryTemplate: column.summaryTemplate, ghostCellTemplate: column.ghostCellTemplate - }; + } as TableColumnInternal; // TS cannot cast here }); } diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/column.ts b/projects/swimlane/ngx-datatable/src/lib/utils/column.ts index 07eae0760..ec0d2d799 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/column.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/column.ts @@ -1,4 +1,3 @@ -import { TableColumn } from '../types/table-column.type'; import { ColumnGroupWidth, PinnedColumns, @@ -34,7 +33,10 @@ export function columnsByPin(cols: TableColumnInternal[]) { /** * Returns the widths of all group sets of a column */ -export function columnGroupWidths(groups: TableColumnGroup, all: TableColumn[]): ColumnGroupWidth { +export function columnGroupWidths( + groups: TableColumnGroup, + all: TableColumnInternal[] +): ColumnGroupWidth { return { left: columnTotalWidth(groups.left), center: columnTotalWidth(groups.center), @@ -46,7 +48,7 @@ export function columnGroupWidths(groups: TableColumnGroup, all: TableColumn[]): /** * Calculates the total width of all columns */ -export function columnTotalWidth(columns?: TableColumn[]) { +export function columnTotalWidth(columns?: TableColumnInternal[]) { return columns?.reduce((total, column) => total + column.width, 0) ?? 0; } diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/math.spec.ts b/projects/swimlane/ngx-datatable/src/lib/utils/math.spec.ts index 8af3f0daf..ff5ab873c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/math.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/math.spec.ts @@ -141,7 +141,7 @@ describe('Math function', () => { adjustColumnWidths(cols, 40); for (const col of cols) { - expect(col.width - col.minWidth).toBeGreaterThanOrEqual(0); + expect(col.width - col.minWidth!).toBeGreaterThanOrEqual(0); } }); }); diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/math.ts b/projects/swimlane/ngx-datatable/src/lib/utils/math.ts index 82ff63d1e..6e28c02bc 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/math.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/math.ts @@ -71,7 +71,7 @@ function scaleColumns(colsByGroup: TableColumnGroup, maxWidth: number, totalFlex } while (remainingWidth !== 0); // Adjust for any remaining offset in computed widths vs maxWidth - const columns: TableColumn[] = Object.values(colsByGroup).reduce( + const columns: TableColumnInternal[] = Object.values(colsByGroup).reduce( (acc, col) => acc.concat(col), [] ); diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts index 4af0ad256..92d004a95 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts @@ -142,7 +142,7 @@ export function sortGroupedRows( groupedRows: Group[], columns: TableColumnInternal[], dirs: SortPropDir[], - sortOnGroupHeader: SortPropDir + sortOnGroupHeader: SortPropDir | undefined ): Group[] { if (sortOnGroupHeader) { groupedRows = sortRows(groupedRows, columns, [ diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts index 936653298..3e5c52edf 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts @@ -2,9 +2,9 @@ import { getterForProp } from './column-prop-getters'; import { TableColumnProp } from '../types/table-column.type'; import { Row } from '../types/public.types'; -export type OptionalValueGetter = (row: any) => any | undefined; +export type OptionalValueGetter = ((row: any) => any) | undefined; export function optionalGetterForProp(prop: TableColumnProp): OptionalValueGetter { - return prop && (row => getterForProp(prop)(row, prop)); + return prop ? row => getterForProp(prop)(row, prop) : undefined; } /** @@ -56,7 +56,7 @@ export function groupRowsByParents( const fromValue = from(node.row); const parent = uniqIDs.get(fromValue); if (parent) { - node.row.level = parent.row.level + 1; + node.row.level = parent.row.level! + 1; // TODO: should be reflected by type, that level is defined node.parent = parent; parent.children.push(node); } else { @@ -79,7 +79,6 @@ class TreeNode { constructor(row: TRow) { this.row = row; - this.parent = null; this.children = []; } diff --git a/src/app/basic/row-grouping.component.ts b/src/app/basic/row-grouping.component.ts index 6c01fcd30..ca306cac6 100644 --- a/src/app/basic/row-grouping.component.ts +++ b/src/app/basic/row-grouping.component.ts @@ -201,8 +201,8 @@ export class RowGroupingComponent { if (group.length === 2) { // There are only 2 lines in a group if ( - ['Calculated', 'Funder'].indexOf(group[0].source) > -1 && - ['Calculated', 'Funder'].indexOf(group[1].source) > -1 + ['Calculated', 'Funder'].indexOf(group[0].source!) > -1 && + ['Calculated', 'Funder'].indexOf(group[1].source!) > -1 ) { // Sources are funder and calculated if (group[0].startdate === group[1].startdate && group[0].enddate === group[1].enddate) { diff --git a/src/app/selection/selection-chkbox-template.component.ts b/src/app/selection/selection-chkbox-template.component.ts index c9cfa1601..376668ec4 100644 --- a/src/app/selection/selection-chkbox-template.component.ts +++ b/src/app/selection/selection-chkbox-template.component.ts @@ -78,14 +78,14 @@ import { DataService } from '../data.service';

    - Selections ({{ selected?.length }}) + Selections ({{ selected.length }})

      @for (sel of selected; track sel) {
    • {{ sel.name }}
    • - } @if (!selected?.length) { + } @if (!selected.length) {
    • No Selections
    • }
    diff --git a/src/app/selection/selection-chkbox.component.ts b/src/app/selection/selection-chkbox.component.ts index 22c2e2864..e2ea2dbff 100644 --- a/src/app/selection/selection-chkbox.component.ts +++ b/src/app/selection/selection-chkbox.component.ts @@ -65,14 +65,14 @@ import { DataService } from '../data.service';

    - Selections ({{ selected?.length }}) + Selections ({{ selected.length }})

      @for (sel of selected; track sel) {
    • {{ sel.name }}
    • - } @if (!selected?.length) { + } @if (!selected.length) {
    • No Selections
    • }
    diff --git a/src/app/selection/selection-multi-click-chkbox.component.ts b/src/app/selection/selection-multi-click-chkbox.component.ts index 99194dd1d..63557d750 100644 --- a/src/app/selection/selection-multi-click-chkbox.component.ts +++ b/src/app/selection/selection-multi-click-chkbox.component.ts @@ -66,14 +66,14 @@ import { DataService } from '../data.service';

    - Selections ({{ selected?.length }}) + Selections ({{ selected.length }})

      @for (sel of selected; track sel) {
    • {{ sel.name }}
    • - } @if (!selected?.length) { + } @if (!selected.length) {
    • No Selections
    • }
    diff --git a/src/app/summary/summary-row-simple.component.ts b/src/app/summary/summary-row-simple.component.ts index 8e09d7765..519f2ccdd 100644 --- a/src/app/summary/summary-row-simple.component.ts +++ b/src/app/summary/summary-row-simple.component.ts @@ -61,7 +61,7 @@ export class SummaryRowSimpleComponent { rows: Employee[] = []; columns: TableColumn[] = [ - { prop: 'name', summaryFunc: null }, + { prop: 'name' }, { name: 'Gender', summaryFunc: cells => this.summaryForGender(cells) }, { prop: 'age', summaryFunc: cells => this.avgAge(cells) } ]; From 27084510904629fd6f12a0be856e32180251cd39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Tue, 17 Jun 2025 17:09:29 +0200 Subject: [PATCH 087/105] refactor: drop unused inputs of footer directive (#249) BREAKING CHANGE: All inputs except `template` of `DatatableFooterDirective` have been dropped. Those were unused. Remove any usages without replacement. --- .../src/lib/components/footer/footer.directive.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts index c27dd8920..e8692455d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts @@ -1,4 +1,4 @@ -import { ContentChild, Directive, Input, numberAttribute, TemplateRef } from '@angular/core'; +import { ContentChild, Directive, Input, TemplateRef } from '@angular/core'; import { DataTableFooterTemplateDirective } from './footer-template.directive'; import { FooterContext } from '../../types/public.types'; @@ -6,14 +6,6 @@ import { FooterContext } from '../../types/public.types'; selector: 'ngx-datatable-footer' }) export class DatatableFooterDirective { - @Input({ transform: numberAttribute }) footerHeight: number; - @Input() totalMessage: string; - @Input() selectedMessage: string | boolean; - @Input() pagerLeftArrowIcon: string; - @Input() pagerRightArrowIcon: string; - @Input() pagerPreviousIcon: string; - @Input() pagerNextIcon: string; - @Input('template') _templateInput: TemplateRef; From 38800ace0335168ab6667bdc57da65463a0bfff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Wed, 18 Jun 2025 10:52:04 +0200 Subject: [PATCH 088/105] refactor: remove unused ghost loading input internally (#251) --- .../src/lib/components/body/body-cell.component.ts | 2 -- .../ngx-datatable/src/lib/components/body/body-row.component.ts | 2 -- .../ngx-datatable/src/lib/components/body/body.component.ts | 1 - 3 files changed, 5 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index a40f22579..6a4ae4d43 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -194,8 +194,6 @@ export class DataTableBodyCellComponent implements DoChe return this._treeStatus; } - @Input() ghostLoadingIndicator = false; - @Output() activate = new EventEmitter>(); @Output() treeAction: EventEmitter = new EventEmitter(); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index b31a191f8..dd04d4cf3 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -52,7 +52,6 @@ import { DataTableBodyCellComponent } from './body-cell.component'; [displayCheck]="displayCheck" [disabled]="disabled" [treeStatus]="treeStatus" - [ghostLoadingIndicator]="ghostLoadingIndicator" (activate)="onActivate($event, ii)" (treeAction)="onTreeAction()" > @@ -99,7 +98,6 @@ export class DataTableBodyRowComponent implements DoChec @Input() rowIndex: RowIndex; @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value?: any) => boolean; @Input() treeStatus?: TreeStatus = 'collapsed'; - @Input() ghostLoadingIndicator = false; @Input() verticalScrollVisible = false; @Input() disabled: boolean; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 20661a342..292b1bcd5 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -104,7 +104,6 @@ import { Keys } from '../../utils/keys'; [rowClass]="rowClass" [displayCheck]="displayCheck" [treeStatus]="row?.treeStatus" - [ghostLoadingIndicator]="ghostLoadingIndicator" [draggable]="rowDraggable" [verticalScrollVisible]="verticalScrollVisible" (treeAction)="onTreeAction(row)" From 34087546ba4be90ff139e407a885bf81f045245b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Wed, 18 Jun 2025 11:15:32 +0200 Subject: [PATCH 089/105] Refactor/enable strict init checks (#250) * refactor: improve typing related to strict property init checks * docs: improve typing related to strict property init checks * test: improve typing related to strict property init checks * build: enable strict mode --- .../components/body/body-cell.component.ts | 38 +++++----- .../body/body-group-header.directive.ts | 6 +- .../components/body/body-row-def.component.ts | 2 +- .../body/body-row-wrapper.component.ts | 33 +++++---- .../lib/components/body/body-row.component.ts | 22 +++--- .../src/lib/components/body/body.component.ts | 72 +++++++++---------- .../ghost-loader/ghost-loader.component.ts | 6 +- .../lib/components/body/scroller.component.ts | 10 +-- .../body/summary/summary-row.component.ts | 11 ++- .../columns/column.directive.spec.ts | 2 +- .../components/columns/column.directive.ts | 2 +- .../components/datatable.component.spec.ts | 4 +- .../src/lib/components/datatable.component.ts | 44 ++++++------ .../footer/footer.component.spec.ts | 26 +++---- .../lib/components/footer/footer.component.ts | 14 ++-- .../lib/components/footer/footer.directive.ts | 6 +- .../lib/components/footer/pager.component.ts | 2 +- .../header/header-cell.component.ts | 20 +++--- .../lib/components/header/header.component.ts | 28 ++++---- .../row-detail/row-detail.directive.ts | 6 +- .../src/lib/directives/draggable.directive.ts | 2 +- .../lib/directives/long-press.directive.ts | 2 +- .../src/lib/directives/orderable.directive.ts | 8 +-- .../src/lib/types/internal.types.ts | 2 +- .../src/lib/types/public.types.ts | 14 ++-- .../ngx-datatable/src/lib/utils/sort.ts | 2 +- .../ngx-datatable/src/lib/utils/tree.ts | 2 +- src/app/basic/filter.component.ts | 2 +- src/app/basic/live.component.ts | 2 +- src/app/basic/responsive.component.ts | 4 +- src/app/basic/row-detail.component.ts | 8 +-- src/app/basic/row-grouping.component.ts | 13 ++-- src/app/basic/virtual.component.ts | 2 +- src/app/paging/paging-virtual.component.ts | 2 +- src/app/paging/scrolling-server.component.ts | 4 +- .../sorting/sorting-comparator.component.ts | 2 + .../summary-row-custom-template.component.ts | 2 +- src/app/templates/template-obj.component.ts | 8 +-- 38 files changed, 221 insertions(+), 214 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts index 6a4ae4d43..edfac2fb6 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.ts @@ -80,16 +80,16 @@ export class DataTableBodyCellComponent implements DoChe @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value: any) => boolean; - @Input() set disabled(value: boolean) { + @Input() set disabled(value: boolean | undefined) { this.cellContext.disabled = value; this._disabled = value; } - get disabled(): boolean { + get disabled(): boolean | undefined { return this._disabled; } - @Input() set group(group: TRow[]) { + @Input() set group(group: TRow[] | undefined) { this._group = group; this.cellContext.group = group; this.checkValueUpdates(); @@ -111,23 +111,23 @@ export class DataTableBodyCellComponent implements DoChe return this._rowHeight; } - @Input() set isSelected(val: boolean) { + @Input() set isSelected(val: boolean | undefined) { this._isSelected = val; this.cellContext.isSelected = val; this.cd.markForCheck(); } - get isSelected(): boolean { + get isSelected(): boolean | undefined { return this._isSelected; } - @Input() set expanded(val: boolean) { + @Input() set expanded(val: boolean | undefined) { this._expanded = val; this.cellContext.expanded = val; this.cd.markForCheck(); } - get expanded(): boolean { + get expanded(): boolean | undefined { return this._expanded; } @@ -190,7 +190,7 @@ export class DataTableBodyCellComponent implements DoChe this.cd.markForCheck(); } - get treeStatus(): TreeStatus { + get treeStatus(): TreeStatus | undefined { return this._treeStatus; } @@ -268,24 +268,24 @@ export class DataTableBodyCellComponent implements DoChe return height + 'px'; } - sanitizedValue: string; + sanitizedValue!: string; value: any; sortDir?: SortDirection; isFocused = false; cellContext: CellContext; - private _isSelected: boolean; - private _sorts: SortPropDir[]; - private _column: TableColumnInternal; - private _row: TRow; - private _group: TRow[]; - private _rowHeight: number; - private _rowIndex: RowIndex; - private _expanded: boolean; + private _isSelected?: boolean; + private _sorts!: SortPropDir[]; + private _column!: TableColumnInternal; + private _row!: TRow; + private _group?: TRow[]; + private _rowHeight!: number; + private _rowIndex!: RowIndex; + private _expanded?: boolean; private _element = inject>(ElementRef).nativeElement; - private _treeStatus: TreeStatus; - private _disabled: boolean; + private _treeStatus?: TreeStatus; + private _disabled?: boolean; constructor() { this.cellContext = { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts index d938837aa..7bdfa376d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-group-header.directive.ts @@ -17,12 +17,12 @@ export class DatatableGroupHeaderDirective { @Input() checkboxable = false; @Input('template') - _templateInput: TemplateRef>; + _templateInput?: TemplateRef>; @ContentChild(DatatableGroupHeaderTemplateDirective, { read: TemplateRef, static: true }) - _templateQuery: TemplateRef>; + _templateQuery?: TemplateRef>; - get template(): TemplateRef> { + get template(): TemplateRef> | undefined { return this._templateInput || this._templateQuery; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts index d0f424e49..1e294ffcc 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-def.component.ts @@ -56,7 +56,7 @@ export class DatatableRowDefDirective { export class DatatableRowDefInternalDirective implements OnInit { vc = inject(ViewContainerRef); - @Input() rowDefInternal: RowDefContext; + @Input() rowDefInternal!: RowDefContext; @Input() rowDefInternalDisabled?: boolean; ngOnInit(): void { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts index 33f9d72c3..f632ef5bf 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts @@ -37,7 +37,7 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive' [style.width.px]="innerWidth" >
    - @if (groupHeader.checkboxable) { + @if (groupHeader!.checkboxable) {
    } - +
    @@ -57,7 +60,7 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive' } @if (rowDetail?.template && expanded) {
    - +
    } @@ -73,34 +76,34 @@ export class DataTableRowWrapperComponent implements DoCheck, OnInit, OnChanges { @ViewChild('select') checkBoxInput!: ElementRef; - @Input() innerWidth: number; - @Input() rowDetail: DatatableRowDetailDirective; - @Input() groupHeader: DatatableGroupHeaderDirective; - @Input() offsetX: number; - @Input() detailRowHeight: number; - @Input() groupHeaderRowHeight: number; - @Input() row: RowOrGroup; - @Input() groupedRows: Group[]; - @Input() selected: TRow[]; + @Input() innerWidth!: number; + @Input() rowDetail?: DatatableRowDetailDirective; + @Input() groupHeader?: DatatableGroupHeaderDirective; + @Input() offsetX!: number; + @Input() detailRowHeight!: number; + @Input() groupHeaderRowHeight!: number; + @Input() row!: RowOrGroup; + @Input() groupedRows?: Group[]; + @Input() selected!: TRow[]; @Input() disabled?: boolean; @Output() rowContextmenu = new EventEmitter<{ event: MouseEvent; row: RowOrGroup; }>(false); - @Input() rowIndex: number; + @Input() rowIndex!: number; selectedGroupRows = signal([]); @Input({ transform: booleanAttribute }) expanded = false; - context: RowDetailContext | GroupContext; + context!: RowDetailContext | GroupContext; private rowDiffer: KeyValueDiffer, any> = inject(KeyValueDiffers) .find({}) .create(); private iterableDiffers = inject(IterableDiffers); - private selectedRowsDiffer: IterableDiffer; + private selectedRowsDiffer!: IterableDiffer; private tableComponent = inject(DatatableComponentToken); private cd = inject(ChangeDetectorRef); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index dd04d4cf3..b06212612 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -90,17 +90,17 @@ export class DataTableBodyRowComponent implements DoChec return this._innerWidth; } - @Input() expanded: boolean; + @Input() expanded?: boolean; @Input() rowClass?: (row: TRow) => string | Record; - @Input() row: TRow; - @Input() group: TRow[]; - @Input() isSelected: boolean; - @Input() rowIndex: RowIndex; + @Input() row!: TRow; + @Input() group?: TRow[]; + @Input() isSelected?: boolean; + @Input() rowIndex!: RowIndex; @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value?: any) => boolean; @Input() treeStatus?: TreeStatus = 'collapsed'; @Input() verticalScrollVisible = false; - @Input() disabled: boolean; + @Input() disabled?: boolean; @HostBinding('class') get cssClass() { @@ -137,7 +137,7 @@ export class DataTableBodyRowComponent implements DoChec @HostBinding('style.height.px') @Input() - rowHeight: number; + rowHeight!: number; @HostBinding('style.width.px') get columnsTotalWidths(): number { @@ -148,10 +148,10 @@ export class DataTableBodyRowComponent implements DoChec @Output() treeAction: EventEmitter = new EventEmitter(); _element = inject>(ElementRef).nativeElement; - _columnGroupWidths: ColumnGroupWidth; - _columnsByPin: PinnedColumns[]; - _columns: TableColumnInternal[]; - _innerWidth: number; + _columnGroupWidths!: ColumnGroupWidth; + _columnsByPin!: PinnedColumns[]; + _columns!: TableColumnInternal[]; + _innerWidth!: number; private _rowDiffer: KeyValueDiffer, any> = inject(KeyValueDiffers) .find({}) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 292b1bcd5..6f5318105 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -238,32 +238,32 @@ export class DataTableBodyComponent implements OnInit, O cd = inject(ChangeDetectorRef); @Input() rowDefTemplate?: TemplateRef; - @Input() scrollbarV: boolean; - @Input() scrollbarH: boolean; - @Input() loadingIndicator: boolean; - @Input() ghostLoadingIndicator: boolean; - @Input() externalPaging: boolean; - @Input() rowHeight: number | 'auto' | ((row?: any) => number); - @Input() offsetX: number; - @Input() selectionType: SelectionType; + @Input() scrollbarV?: boolean; + @Input() scrollbarH?: boolean; + @Input() loadingIndicator?: boolean; + @Input() ghostLoadingIndicator?: boolean; + @Input() externalPaging?: boolean; + @Input() rowHeight!: number | 'auto' | ((row?: any) => number); + @Input() offsetX!: number; + @Input() selectionType?: SelectionType; @Input() selected: any[] = []; - @Input() rowIdentity: any; - @Input() rowDetail: DatatableRowDetailDirective; - @Input() groupHeader: DatatableGroupHeaderDirective; - @Input() selectCheck: (value: TRow, index: number, array: TRow[]) => boolean; - @Input() displayCheck: (row: TRow, column: TableColumnInternal, value?: any) => boolean; - @Input() trackByProp: string; - @Input() rowClass: (row: TRow) => string | Record; - @Input() groupedRows: Group[]; - @Input() groupExpansionDefault: boolean; - @Input() innerWidth: number; - @Input() groupRowsBy: keyof TRow; - @Input() virtualization: boolean; - @Input() summaryRow: boolean; - @Input() summaryPosition: string; - @Input() summaryHeight: number; - @Input() rowDraggable: boolean; - @Input() rowDragEvents: EventEmitter; + @Input() rowIdentity!: (x: RowOrGroup) => unknown; + @Input() rowDetail?: DatatableRowDetailDirective; + @Input() groupHeader?: DatatableGroupHeaderDirective; + @Input() selectCheck?: (value: TRow, index: number, array: TRow[]) => boolean; + @Input() displayCheck?: (row: TRow, column: TableColumnInternal, value?: any) => boolean; + @Input() trackByProp?: string; + @Input() rowClass?: (row: TRow) => string | Record; + @Input() groupedRows?: Group[]; + @Input() groupExpansionDefault?: boolean; + @Input() innerWidth!: number; + @Input() groupRowsBy?: keyof TRow; + @Input() virtualization?: boolean; + @Input() summaryRow?: boolean; + @Input() summaryPosition!: string; + @Input() summaryHeight!: number; + @Input() rowDraggable?: boolean; + @Input() rowDragEvents!: EventEmitter; @Input() disableRowCheck?: (row: TRow) => boolean | undefined; @Input() set pageSize(val: number) { @@ -362,7 +362,7 @@ export class DataTableBodyComponent implements OnInit, O @Output() rowContextmenu = new EventEmitter<{ event: MouseEvent; row: RowOrGroup }>(false); @Output() treeAction: EventEmitter<{ row: TRow }> = new EventEmitter(); - @ViewChild(ScrollerComponent) scroller: ScrollerComponent; + @ViewChild(ScrollerComponent) scroller!: ScrollerComponent; /** * Returns if selection is enabled. @@ -390,17 +390,17 @@ export class DataTableBodyComponent implements OnInit, O rowHeightsCache = signal(new RowHeightCache()); offsetY = 0; indexes = signal<{ first: number; last: number }>({ first: 0, last: 0 }); - columnGroupWidths: ColumnGroupWidth; + columnGroupWidths!: ColumnGroupWidth; rowTrackingFn: TrackByFunction | undefined>; listener: any; rowExpansions: any[] = []; - _rows: (TRow | undefined)[]; - _bodyHeight: string; - _columns: TableColumnInternal[]; - _rowCount: number; - _offset: number; - _pageSize: number; + _rows!: (TRow | undefined)[]; + _bodyHeight!: string; + _columns!: TableColumnInternal[]; + _rowCount!: number; + _offset!: number; + _pageSize!: number; _offsetEvent = -1; private _draggedRow?: RowOrGroup; @@ -762,7 +762,7 @@ export class DataTableBodyComponent implements OnInit, O */ getRowExpanded(row: RowOrGroup): boolean { if (this.rowExpansions.length === 0 && this.groupExpansionDefault) { - for (const group of this.groupedRows) { + for (const group of this.groupedRows!) { this.rowExpansions.push(group); } } @@ -869,7 +869,7 @@ export class DataTableBodyComponent implements OnInit, O this.columnGroupWidths = columnGroupWidths(colsByPin, this._columns); } - prevIndex: number; + prevIndex?: number; selectRow(event: Event, index: number, row: TRow): void { if (!this.selectEnabled) { @@ -884,7 +884,7 @@ export class DataTableBodyComponent implements OnInit, O // TODO: this code needs cleanup. Casting it to KeyboardEvent is not correct as it could also be other types. if (multi || chkbox || multiClick) { if ((event as KeyboardEvent).shiftKey) { - selected = selectRowsBetween([], this.rows, index, this.prevIndex); + selected = selectRowsBetween([], this.rows, index, this.prevIndex!); } else if ( (event as KeyboardEvent).key === 'a' && ((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts index ba5f816e3..2b00f4f66 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/ghost-loader/ghost-loader.component.ts @@ -16,9 +16,9 @@ import { TableColumnInternal } from '../../../types/internal.types'; imports: [NgTemplateOutlet] }) export class DataTableGhostLoaderComponent { - @Input() columns: TableColumnInternal[]; - @Input({ transform: numberAttribute }) pageSize: number; - @Input() rowHeight: number | 'auto' | ((row?: any) => number); + @Input() columns!: TableColumnInternal[]; + @Input({ transform: numberAttribute }) pageSize!: number; + @Input() rowHeight!: number | 'auto' | ((row?: any) => number); @Input({ transform: numberAttribute }) ghostBodyHeight?: number; @Input({ transform: booleanAttribute }) cellMode = false; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts index 0170a4686..39f2c99b4 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/scroller.component.ts @@ -23,8 +23,8 @@ import { export class ScrollerComponent implements OnInit, OnDestroy { private renderer = inject(Renderer2); - @Input() scrollbarV = false; - @Input() scrollbarH = false; + @Input() scrollbarV?: boolean; + @Input() scrollbarH?: boolean; @HostBinding('style.height.px') @Input() @@ -41,7 +41,7 @@ export class ScrollerComponent implements OnInit, OnDestroy { prevScrollYPos = 0; prevScrollXPos = 0; element = inject>(ElementRef).nativeElement; - parentElement: HTMLElement; + parentElement?: HTMLElement; private _scrollEventListener: any = null; @@ -51,13 +51,13 @@ export class ScrollerComponent implements OnInit, OnDestroy { const renderer = this.renderer; this.parentElement = renderer.parentNode(this.element); this._scrollEventListener = this.onScrolled.bind(this); - this.parentElement.addEventListener('scroll', this._scrollEventListener); + this.parentElement?.addEventListener('scroll', this._scrollEventListener); } } ngOnDestroy(): void { if (this._scrollEventListener) { - this.parentElement.removeEventListener('scroll', this._scrollEventListener); + this.parentElement?.removeEventListener('scroll', this._scrollEventListener); this._scrollEventListener = null; } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts index 87746e936..a7f3a3a3a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/summary/summary-row.component.ts @@ -40,14 +40,13 @@ function noopSumFunc(cells: any[]): void { imports: [DataTableBodyRowComponent] }) export class DataTableSummaryRowComponent implements OnChanges { - @Input() rows: any[]; - @Input() columns: TableColumnInternal[]; + @Input() rows!: any[]; + @Input() columns!: TableColumnInternal[]; - @Input() rowHeight: number; - @Input() offsetX: number; - @Input() innerWidth: number; + @Input() rowHeight!: number; + @Input() innerWidth!: number; - _internalColumns: TableColumnInternal[]; + _internalColumns!: TableColumnInternal[]; summaryRow: any = {}; ngOnChanges() { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts index 492b5e0c3..9b4523dff 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts @@ -21,7 +21,7 @@ import Spy = jasmine.Spy; standalone: true }) class TestFixtureComponent { - columnName: string; + columnName?: string; } describe('DataTableColumnDirective', () => { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts index 4b2396fa7..d180a88d3 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.ts @@ -36,7 +36,7 @@ export class DataTableColumnDirective implements TableColumn, rowB: TRow, sortDir: 'desc' | 'asc' ) => number; - @Input() pipe: PipeTransform; + @Input() pipe?: PipeTransform; @Input({ transform: booleanAttribute }) sortable?: boolean; @Input({ transform: booleanAttribute }) draggable?: boolean; @Input({ transform: booleanAttribute }) canAutoResize?: boolean; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts index bf8616625..045d2e1ae 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts @@ -379,7 +379,7 @@ describe('DatatableComponent With Custom Templates', () => { {{ column.name }} - {{ row[column.prop] }} + {{ row[column.prop!] }} @@ -396,7 +396,7 @@ describe('DatatableComponent With Custom Templates', () => { class TestFixtureComponentWithCustomTemplates { rows: Record[] = []; sorts: SortPropDir[] = []; - columnTwoProp: string; + columnTwoProp?: string; } let fixture: ComponentFixture; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index da75e972a..97a77ada0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -111,7 +111,7 @@ export class DatatableComponent /** * Template for the target marker of drag target columns. */ - @Input() targetMarkerTemplate: TemplateRef; + @Input() targetMarkerTemplate?: TemplateRef; /** * Rows that are displayed in the table. @@ -135,7 +135,7 @@ export class DatatableComponent /** * This attribute allows the user to set the name of the column to group the data with */ - @Input() set groupRowsBy(val: keyof TRow) { + @Input() set groupRowsBy(val: keyof TRow | undefined) { if (val) { this._groupRowsBy = val; if (this._groupRowsBy) { @@ -164,7 +164,7 @@ export class DatatableComponent * ]} * ] */ - @Input() groupedRows: Group[]; + @Input() groupedRows?: Group[]; /** * Columns to be displayed. @@ -326,7 +326,7 @@ export class DatatableComponent * For no selection pass a `falsey`. * Default value: `undefined` */ - @Input() selectionType: SelectionType; + @Input() selectionType?: SelectionType; /** * Enable/Disable ability to re-order columns @@ -380,7 +380,7 @@ export class DatatableComponent * - a string: `"class-1 class-2` * - a Record: `{ 'class-1': true, 'class-2': false }` */ - @Input() rowClass: (row: TRow) => string | Record; + @Input() rowClass?: (row: TRow) => string | Record; /** * A boolean/function you can use to check whether you want @@ -390,7 +390,7 @@ export class DatatableComponent * return selection !== 'Ethel Price'; * } */ - @Input() selectCheck: (value: TRow, index: number, array: TRow[]) => boolean; + @Input() selectCheck?: (value: TRow, index: number, array: TRow[]) => boolean; /** * A function you can use to check whether you want @@ -400,7 +400,7 @@ export class DatatableComponent * return row.name !== 'Ethel Price'; * } */ - @Input() displayCheck: (row: TRow, column: TableColumn, value?: any) => boolean; + @Input() displayCheck?: (row: TRow, column: TableColumn, value?: any) => boolean; /** * A boolean you can use to set the detault behaviour of rows and groups @@ -413,7 +413,7 @@ export class DatatableComponent * Property to which you can use for custom tracking of rows. * Example: 'name' */ - @Input() trackByProp: string; + @Input() trackByProp?: string; /** * Property to which you can use for determining select all @@ -429,12 +429,12 @@ export class DatatableComponent /** * Tree from relation */ - @Input() treeFromRelation: string; + @Input() treeFromRelation?: string; /** * Tree to relation */ - @Input() treeToRelation: string; + @Input() treeToRelation?: string; /** * A flag for switching summary row on / off @@ -632,36 +632,36 @@ export class DatatableComponent * Row Detail templates gathered from the ContentChild */ @ContentChild(DatatableRowDetailDirective) - rowDetail: DatatableRowDetailDirective; + rowDetail?: DatatableRowDetailDirective; /** * Group Header templates gathered from the ContentChild */ @ContentChild(DatatableGroupHeaderDirective) - groupHeader: DatatableGroupHeaderDirective; + groupHeader?: DatatableGroupHeaderDirective; /** * Footer template gathered from the ContentChild */ @ContentChild(DatatableFooterDirective) - footer: DatatableFooterDirective; + footer?: DatatableFooterDirective; /** * Reference to the body component for manually * invoking functions on the body. */ @ViewChild(DataTableBodyComponent) - bodyComponent: DataTableBodyComponent; + bodyComponent!: DataTableBodyComponent; /** * Reference to the header component for manually * invoking functions on the header. */ @ViewChild(DataTableHeaderComponent) - headerComponent: DataTableHeaderComponent; + headerComponent!: DataTableHeaderComponent; @ViewChild(DataTableBodyComponent, { read: ElementRef }) - private bodyElement: ElementRef; + private bodyElement!: ElementRef; @ContentChild(DatatableRowDefDirective, { read: TemplateRef }) @@ -694,10 +694,10 @@ export class DatatableComponent _count = 0; _offset = 0; _rows: (TRow | undefined)[] = []; - _groupRowsBy: keyof TRow; + _groupRowsBy?: keyof TRow; _internalRows: (TRow | undefined)[] = []; - _internalColumns: TableColumnInternal[]; - _columns: TableColumn[]; + _internalColumns!: TableColumnInternal[]; + _columns!: TableColumn[]; _subscriptions: Subscription[] = []; _ghostLoadingIndicator = false; _defaultColumnWidth?: number; @@ -780,7 +780,7 @@ export class DatatableComponent * * (`fn(x) === fn(y)` instead of `x === y`) */ - @Input() rowIdentity: (x: TRow | Group) => unknown = x => { + @Input() rowIdentity: (x: RowOrGroup) => unknown = x => { if (this._groupRowsBy) { // each group in groupedRows are stored as {key, value: [rows]}, // where key is the groupRowsBy index @@ -1255,7 +1255,7 @@ export class DatatableComponent const row = event.row; // TODO: For duplicated items this will not work const rowIndex = this._rows.findIndex( - r => r && r[this.treeToRelation] === event.row[this.treeToRelation] + r => r && r[this.treeToRelation!] === event.row[this.treeToRelation!] ); this.treeAction.emit({ row, rowIndex }); } @@ -1295,7 +1295,7 @@ export class DatatableComponent const sortOnGroupHeader = this.sorts?.find( sortColumns => sortColumns.prop === this._groupRowsBy ); - this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy); + this.groupedRows = this.groupArrayBy(this._rows, this._groupRowsBy!); this.groupedRows = sortGroupedRows( this.groupedRows, this._internalColumns, diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts index 51686221f..4c800186f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts @@ -252,17 +252,17 @@ describe('DataTableFooterComponent', () => { imports: [DataTableFooterComponent] }) class TestFixtureComponent { - footerHeight: number; + footerHeight = 0; rowCount = 100; pageSize = 1; offset = 0; - pagerLeftArrowIcon: string; - pagerRightArrowIcon: string; - pagerPreviousIcon: string; - pagerNextIcon: string; - totalMessage: string; + pagerLeftArrowIcon = ''; + pagerRightArrowIcon = ''; + pagerPreviousIcon = ''; + pagerNextIcon = ''; + totalMessage = ''; footerTemplate?: { template: TemplateRef }; - selectedCount: number; + selectedCount = 0; selectedMessage?: string; /** @@ -271,7 +271,7 @@ class TestFixtureComponent { * in these unit tests */ @ViewChild('testTemplate', { read: TemplateRef, static: true }) - testTemplate: TemplateRef; + testTemplate!: TemplateRef; onPageEvent() { return; @@ -283,11 +283,11 @@ class TestFixtureComponent { * makes for cleaner testing */ class Page { - datatableFooter: DebugElement; - datatableFooterInner: DebugElement; - templateList: DebugElement; - pageCount: DebugElement; - datatablePager: DebugElement; + datatableFooter!: DebugElement; + datatableFooterInner!: DebugElement; + templateList!: DebugElement; + pageCount!: DebugElement; + datatablePager!: DebugElement; detectChangesAndRunQueries() { fixture.detectChanges(); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts index 709be3be1..a23ce99c3 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts @@ -11,9 +11,9 @@ import { NgClass, NgTemplateOutlet } from '@angular/common'; [ngClass]="{ 'selected-count': selectedMessage }" [style.height.px]="footerHeight" > - @if (footerTemplate) { + @if (footerTemplate?.template) { @if (isTarget) { @@ -74,17 +74,17 @@ import { getPositionFromEvent } from '../../utils/events'; export class DataTableHeaderCellComponent implements OnInit, OnDestroy { private cd = inject(ChangeDetectorRef); - @Input() sortType: SortType; + @Input() sortType!: SortType; @Input() sortAscendingIcon?: string; @Input() sortDescendingIcon?: string; @Input() sortUnsetIcon?: string; @Input() isTarget?: boolean; - @Input() targetMarkerTemplate: TemplateRef; + @Input() targetMarkerTemplate?: TemplateRef; @Input() targetMarkerContext: any; @Input() enableClearingSortState = false; - _allRowsSelected: boolean; + _allRowsSelected?: boolean; @Input() set allRowsSelected(value) { this._allRowsSelected = value; @@ -94,7 +94,7 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { return this._allRowsSelected; } - @Input() selectionType: SelectionType; + @Input() selectionType?: SelectionType; @Input() set column(column: TableColumnInternal) { this._column = column; @@ -108,7 +108,7 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { @HostBinding('style.height.px') @Input() - headerHeight: number; + headerHeight!: number; @Input() set sorts(val: SortPropDir[]) { this._sorts = val; @@ -200,12 +200,12 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { } sortClass?: string; - sortDir: SortDirection; + sortDir?: SortDirection; cellContext: HeaderCellContext; - private _column: TableColumnInternal; - private _sorts: SortPropDir[]; + private _column!: TableColumnInternal; + private _sorts!: SortPropDir[]; private element = inject(ElementRef).nativeElement; private subscription?: Subscription; @@ -276,7 +276,7 @@ export class DataTableHeaderCellComponent implements OnInit, OnDestroy { }); } - calcSortClass(sortDir: SortDirection): string | undefined { + calcSortClass(sortDir: SortDirection | undefined): string | undefined { if (!this.cellContext.column.sortable) { return undefined; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index 9a551a5e7..f1019afb6 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -108,9 +108,9 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { @Input() sortAscendingIcon?: string; @Input() sortDescendingIcon?: string; @Input() sortUnsetIcon?: string; - @Input() scrollbarH: boolean; - @Input() dealsWithGroup: boolean; - @Input() targetMarkerTemplate: TemplateRef; + @Input() scrollbarH?: boolean; + @Input() dealsWithGroup?: boolean; + @Input() targetMarkerTemplate?: TemplateRef; @Input() enableClearingSortState = false; @Input() set innerWidth(val: number) { @@ -128,11 +128,11 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { return this._innerWidth; } - @Input() sorts: SortPropDir[]; - @Input() sortType: SortType; - @Input() allRowsSelected: boolean; - @Input() selectionType: SelectionType; - @Input() reorderable: boolean; + @Input() sorts!: SortPropDir[]; + @Input() sortType!: SortType; + @Input() allRowsSelected?: boolean; + @Input() selectionType?: SelectionType; + @Input() reorderable?: boolean; @Input() verticalScrollVisible = false; dragEventTarget?: MouseEvent | TouchEvent; @@ -185,14 +185,14 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { column: TableColumnInternal; }>(false); - _columnsByPin: PinnedColumns[]; + _columnsByPin!: PinnedColumns[]; _columnGroupWidths: any = { total: 100 }; - _innerWidth: number; - _offsetX: number; - _columns: TableColumnInternal[]; - _headerHeight: string; + _innerWidth!: number; + _offsetX!: number; + _columns!: TableColumnInternal[]; + _headerHeight!: string; _styleByGroup: { left: NgStyle['ngStyle']; center: NgStyle['ngStyle']; @@ -332,7 +332,7 @@ export class DataTableHeaderComponent implements OnDestroy, OnChanges { calcNewSorts( column: SortableTableColumnInternal, - prevValue: SortDirection, + prevValue: SortDirection | undefined, newValue: SortDirection | undefined ): SortPropDir[] { let idx = 0; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts index 8d5813fc7..415ab5134 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/row-detail/row-detail.directive.ts @@ -13,12 +13,12 @@ export class DatatableRowDetailDirective { @Input() rowHeight: number | ((row?: TRow, index?: number) => number) = 0; @Input('template') - _templateInput: TemplateRef>; + _templateInput?: TemplateRef>; @ContentChild(DatatableRowDetailTemplateDirective, { read: TemplateRef, static: true }) - _templateQuery: TemplateRef>; + _templateQuery?: TemplateRef>; - get template(): TemplateRef> { + get template(): TemplateRef> | undefined { return this._templateInput || this._templateQuery; } diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts index fc8191652..9f54640d6 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/draggable.directive.ts @@ -28,7 +28,7 @@ import { getPositionFromEvent } from '../utils/events'; }) export class DraggableDirective implements OnDestroy, OnChanges { @Input() dragEventTarget: any; - @Input() dragModel: TableColumnInternal; + @Input() dragModel!: TableColumnInternal; @Input({ transform: booleanAttribute }) dragX = true; @Input({ transform: booleanAttribute }) dragY = true; diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts index b87431943..1b1908056 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/long-press.directive.ts @@ -22,7 +22,7 @@ import { TableColumnInternal } from '../types/internal.types'; }) export class LongPressDirective implements OnDestroy { @Input({ transform: booleanAttribute }) pressEnabled = true; - @Input() pressModel: TableColumnInternal; + @Input() pressModel!: TableColumnInternal; @Input({ transform: numberAttribute }) duration = 500; @Output() longPressStart = new EventEmitter<{ diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts index e70845ff2..10d82270a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts @@ -38,9 +38,9 @@ export class OrderableDirective implements AfterContentInit, OnDestroy { @Output() targetChanged = new EventEmitter(); @ContentChildren(DraggableDirective, { descendants: true }) - draggables: QueryList; + draggables!: QueryList; - positions: Record; + positions?: Record; differ: KeyValueDiffer = inject(KeyValueDiffers).find({}).create(); lastDraggingIndex?: number; @@ -104,7 +104,7 @@ export class OrderableDirective implements AfterContentInit, OnDestroy { } onDragging({ element, model, event }: DraggableDragEvent): void { - const prevPos = this.positions[model.$$id]; + const prevPos = this.positions![model.$$id]; const target = this.isTarget(model, event); if (target) { @@ -126,7 +126,7 @@ export class OrderableDirective implements AfterContentInit, OnDestroy { } onDragEnd({ element, model, event }: DraggableDragEvent): void { - const prevPos = this.positions[model.$$id]; + const prevPos = this.positions![model.$$id]; const target = this.isTarget(model, event); if (target) { diff --git a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts index 5a8b869ab..b74a11289 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/internal.types.ts @@ -47,7 +47,7 @@ export interface DraggableDragEvent { export interface InnerSortEvent { column: SortableTableColumnInternal; - prevValue: SortDirection; + prevValue: SortDirection | undefined; newValue: SortDirection | undefined; } diff --git a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts index c25346171..6bac248bf 100644 --- a/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts +++ b/projects/swimlane/ngx-datatable/src/lib/types/public.types.ts @@ -12,7 +12,7 @@ export enum SortDirection { export interface SortEvent { column: TableColumn; - prevValue: SortDirection; + prevValue: SortDirection | undefined; newValue: SortDirection | undefined; sorts: SortPropDir[]; } @@ -46,9 +46,9 @@ export interface ActivateEvent { export interface HeaderCellContext { column: TableColumn; - sortDir: SortDirection | 'asc' | 'desc'; + sortDir: SortDirection | 'asc' | 'desc' | undefined; sortFn: () => void; - allRowsSelected: boolean; + allRowsSelected?: boolean; selectFn: () => void; } @@ -62,15 +62,15 @@ export interface CellContext { onCheckboxChangeFn: (event: Event) => void; activateFn: (event: ActivateEvent) => void; row: TRow; - group: TRow[]; + group?: TRow[]; value: any; column: TableColumn; rowHeight: number; - isSelected: boolean; + isSelected?: boolean; rowIndex: number; rowInGroupIndex?: number; - treeStatus: TreeStatus; - disabled: boolean; + treeStatus?: TreeStatus; + disabled?: boolean; onTreeAction: () => void; expanded?: boolean; } diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts index 92d004a95..9ee575e59 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/sort.ts @@ -8,7 +8,7 @@ import { SortableTableColumnInternal, TableColumnInternal } from '../types/inter */ export function nextSortDir( sortType: SortType, - current: SortDirection | 'desc' | 'asc' + current: SortDirection | 'desc' | 'asc' | undefined ): SortDirection | undefined { if (sortType === SortType.single) { if (current === SortDirection.asc) { diff --git a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts index 3e5c52edf..b81ba9668 100644 --- a/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts +++ b/projects/swimlane/ngx-datatable/src/lib/utils/tree.ts @@ -3,7 +3,7 @@ import { TableColumnProp } from '../types/table-column.type'; import { Row } from '../types/public.types'; export type OptionalValueGetter = ((row: any) => any) | undefined; -export function optionalGetterForProp(prop: TableColumnProp): OptionalValueGetter { +export function optionalGetterForProp(prop: TableColumnProp | undefined): OptionalValueGetter { return prop ? row => getterForProp(prop)(row, prop) : undefined; } diff --git a/src/app/basic/filter.component.ts b/src/app/basic/filter.component.ts index b89bb4b0d..13e1b7d38 100644 --- a/src/app/basic/filter.component.ts +++ b/src/app/basic/filter.component.ts @@ -51,7 +51,7 @@ export class FilterComponent { temp: Employee[] = []; columns: TableColumn[] = [{ prop: 'name' }, { name: 'Company' }, { name: 'Gender' }]; - @ViewChild(DatatableComponent) table: DatatableComponent; + @ViewChild(DatatableComponent) table!: DatatableComponent; ColumnMode = ColumnMode; diff --git a/src/app/basic/live.component.ts b/src/app/basic/live.component.ts index 8843db03c..011114127 100644 --- a/src/app/basic/live.component.ts +++ b/src/app/basic/live.component.ts @@ -49,7 +49,7 @@ import { DataService } from '../data.service'; imports: [DatatableComponent, DataTableColumnDirective] }) export class LiveDataComponent { - @ViewChild('mydatatable') mydatatable: DatatableComponent; + @ViewChild('mydatatable') mydatatable!: DatatableComponent; count = 50; rows: (Employee & { updated: string })[] = []; diff --git a/src/app/basic/responsive.component.ts b/src/app/basic/responsive.component.ts index ec2649b4e..92c8ad947 100644 --- a/src/app/basic/responsive.component.ts +++ b/src/app/basic/responsive.component.ts @@ -136,7 +136,7 @@ import { DataService } from '../data.service'; ] }) export class ResponsiveComponent { - @ViewChild('myTable') table: DatatableComponent; + @ViewChild('myTable') table!: DatatableComponent; rows: FullEmployee[] = []; expanded: any = {}; @@ -161,7 +161,7 @@ export class ResponsiveComponent { toggleExpandRow(row: FullEmployee) { console.log('Toggled Expand Row!', row); - this.table.rowDetail.toggleExpandRow(row); + this.table.rowDetail!.toggleExpandRow(row); } onDetailToggle(event: DetailToggleEvents) { diff --git a/src/app/basic/row-detail.component.ts b/src/app/basic/row-detail.component.ts index 543528354..19fceb77d 100644 --- a/src/app/basic/row-detail.component.ts +++ b/src/app/basic/row-detail.component.ts @@ -27,9 +27,9 @@ import { DataService } from '../data.service'; - Expand All + Expand All | - Collapse All + Collapse All ; + @ViewChild('myTable') table!: DatatableComponent; rows: FullEmployee[] = []; expanded: any = {}; @@ -133,7 +133,7 @@ export class RowDetailsComponent { toggleExpandRow(row: FullEmployee) { console.log('Toggled Expand Row!', row); - this.table.rowDetail.toggleExpandRow(row); + this.table.rowDetail!.toggleExpandRow(row); } onDetailToggle(event: DetailToggleEvents) { diff --git a/src/app/basic/row-grouping.component.ts b/src/app/basic/row-grouping.component.ts index ca306cac6..e01ec2fe1 100644 --- a/src/app/basic/row-grouping.component.ts +++ b/src/app/basic/row-grouping.component.ts @@ -92,7 +92,8 @@ import { DataService } from '../data.service'; name="{{ rowIndex }}" value="0" class="expectedpayment" - (change)="checkGroup($event, row, rowIndex, group)" + [attr.aria-label]="'ex pay1' + rowIndex" + (change)="checkGroup($event, row, rowIndex, group!)" [checked]="row.exppayyes === 1" /> @@ -103,7 +104,8 @@ import { DataService } from '../data.service'; name="{{ rowIndex }}" value="1" class="expectedpayment2" - (change)="checkGroup($event, row, rowIndex, group)" + [attr.aria-label]="'ex pay2' + rowIndex" + (change)="checkGroup($event, row, rowIndex, group!)" [checked]="row.exppayno === 1" /> @@ -114,7 +116,8 @@ import { DataService } from '../data.service'; name="{{ rowIndex }}" value="2" class="expectedpayment3" - (change)="checkGroup($event, row, rowIndex, group)" + [attr.aria-label]="'ex pay3' + rowIndex" + (change)="checkGroup($event, row, rowIndex, group!)" [checked]="row.exppaypending === 1" /> @@ -160,7 +163,7 @@ import { DataService } from '../data.service'; ] }) export class RowGroupingComponent { - @ViewChild('myTable') table: DatatableComponent; + @ViewChild('myTable') table!: DatatableComponent; editing: Record = {}; rows: GroupedEmployee[] = []; @@ -292,7 +295,7 @@ export class RowGroupingComponent { toggleExpandGroup(group: Group) { console.log('Toggled Expand Group!', group); - this.table.groupHeader.toggleExpandGroup(group); + this.table.groupHeader!.toggleExpandGroup(group); } onDetailToggle(event: GroupToggleEvents) { diff --git a/src/app/basic/virtual.component.ts b/src/app/basic/virtual.component.ts index a1fab2db2..eb402d5a5 100644 --- a/src/app/basic/virtual.component.ts +++ b/src/app/basic/virtual.component.ts @@ -52,7 +52,7 @@ import { DataService } from '../data.service'; imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class VirtualScrollComponent { - rows: (FullEmployee & { height: number })[]; + rows: (FullEmployee & { height: number })[] = []; expanded = {}; timeout: any; diff --git a/src/app/paging/paging-virtual.component.ts b/src/app/paging/paging-virtual.component.ts index 0951c13cc..78e0f3468 100644 --- a/src/app/paging/paging-virtual.component.ts +++ b/src/app/paging/paging-virtual.component.ts @@ -56,7 +56,7 @@ import { Employee } from '../data.model'; export class VirtualPagingComponent { totalElements = 0; pageNumber: number; - rows: Employee[]; + rows?: Employee[]; cache: Record = {}; cachePageSize = 0; diff --git a/src/app/paging/scrolling-server.component.ts b/src/app/paging/scrolling-server.component.ts index f185f0f7e..627479cb3 100644 --- a/src/app/paging/scrolling-server.component.ts +++ b/src/app/paging/scrolling-server.component.ts @@ -8,7 +8,7 @@ import { Employee } from '../data.model'; const companyData = data as any[]; -class PagedData { +interface PagedData { data: T[]; } @@ -65,7 +65,7 @@ export class ServerScrollingComponent { readonly pageLimit = 10; rows: Employee[] = []; - isLoading: boolean; + isLoading?: boolean; ColumnMode = ColumnMode; diff --git a/src/app/sorting/sorting-comparator.component.ts b/src/app/sorting/sorting-comparator.component.ts index cb079a7a8..86a02fe37 100644 --- a/src/app/sorting/sorting-comparator.component.ts +++ b/src/app/sorting/sorting-comparator.component.ts @@ -66,5 +66,7 @@ export class SortingComparatorComponent { if (propA.toLowerCase() > propB.toLowerCase()) { return 1; } + + return 0; } } diff --git a/src/app/summary/summary-row-custom-template.component.ts b/src/app/summary/summary-row-custom-template.component.ts index e6414d6b1..4763c7063 100644 --- a/src/app/summary/summary-row-custom-template.component.ts +++ b/src/app/summary/summary-row-custom-template.component.ts @@ -50,7 +50,7 @@ import { DataService } from '../data.service'; export class SummaryRowCustomTemplateComponent implements OnInit { rows: Employee[] = []; - @ViewChild('nameSummaryCell') nameSummaryCell: TemplateRef; + @ViewChild('nameSummaryCell') nameSummaryCell!: TemplateRef; columns: TableColumn[] = []; diff --git a/src/app/templates/template-obj.component.ts b/src/app/templates/template-obj.component.ts index a4727e305..fdcbc5f07 100644 --- a/src/app/templates/template-obj.component.ts +++ b/src/app/templates/template-obj.component.ts @@ -1,4 +1,4 @@ -import { Component, inject, TemplateRef, ViewChild } from '@angular/core'; +import { Component, inject, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { ColumnMode, DatatableComponent, @@ -49,9 +49,9 @@ import { DataService } from '../data.service'; standalone: true, imports: [DatatableComponent] }) -export class TemplateRefTemplatesComponent { - @ViewChild('editTmpl', { static: true }) editTmpl: TemplateRef; - @ViewChild('hdrTpl', { static: true }) hdrTpl: TemplateRef; +export class TemplateRefTemplatesComponent implements OnInit { + @ViewChild('editTmpl', { static: true }) editTmpl!: TemplateRef; + @ViewChild('hdrTpl', { static: true }) hdrTpl!: TemplateRef; rows: Employee[] = []; columns: TableColumn[] = []; From 3bf8f4ac00bb43df41ebe8801fc080b15bc7ef20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Fri, 20 Jun 2025 16:26:49 +0200 Subject: [PATCH 090/105] refactor: move cell styles into respective components (#254) --- .../components/body/body-cell.component.scss | 6 +++++ .../lib/components/datatable.component.scss | 12 --------- .../header/header-cell.component.scss | 4 +++ .../src/lib/components/shared.scss | 26 +++++++++++++++++++ 4 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 projects/swimlane/ngx-datatable/src/lib/components/shared.scss diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss index 08d5fdeb5..8634aa322 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-cell.component.scss @@ -1,3 +1,9 @@ +@use '../shared'; + +:host { + @include shared.cell-styles(); +} + :host-context(ngx-datatable.fixed-row) :host { overflow: hidden; white-space: nowrap; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 88652e90c..c8f26b154 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -23,16 +23,4 @@ overflow-y: auto; } } - - .datatable-body-cell, - .datatable-header-cell { - overflow-x: hidden; - vertical-align: top; - display: inline-block; - line-height: 1.625; - - &:focus { - outline: none; - } - } } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss index 80183574f..0b7a0909c 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header-cell.component.scss @@ -1,4 +1,8 @@ +@use '../shared'; + :host { + @include shared.cell-styles(); + position: relative; display: inline-block; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/shared.scss b/projects/swimlane/ngx-datatable/src/lib/components/shared.scss new file mode 100644 index 000000000..649a86510 --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/components/shared.scss @@ -0,0 +1,26 @@ +@mixin pinned-columns() { + .datatable-row-left, + .datatable-row-right { + position: sticky; + z-index: 9; + } + + .datatable-row-left { + left: 0; + } + + .datatable-row-right { + right: 0; + } +} + +@mixin cell-styles() { + overflow-x: hidden; + vertical-align: top; + display: inline-block; + line-height: 1.625; + + &:focus { + outline: none; + } +} From 59b1f48f1fde73518e6eb976d1d76f5838039f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Sun, 22 Jun 2025 13:45:56 +0200 Subject: [PATCH 091/105] refactor: move or replace `[hidden]` style to drop in from global styles (#257) --- .../src/lib/components/body/body.component.scss | 4 ++++ .../src/lib/components/datatable.component.scss | 4 ---- .../src/lib/components/footer/footer.component.spec.ts | 10 ++-------- .../src/lib/components/footer/footer.component.ts | 4 ++-- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss index f93c5e7d1..d478c8945 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss @@ -17,3 +17,7 @@ datatable-scroller { white-space: nowrap; } } + +[hidden] { + display: none !important; +} diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index c8f26b154..6c8b0558e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -5,10 +5,6 @@ position: relative; transform: translate3d(0, 0, 0); - [hidden] { - display: none !important; - } - *, *:before, *:after { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts index 4c800186f..8bcb76117 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts @@ -158,19 +158,13 @@ describe('DataTableFooterComponent', () => { component.pageSize = 5; page.detectChangesAndRunQueries(); - expect(page.datatablePager.nativeElement.hidden).toBe( - false, - 'DataTablePagerComponent should be hidden' - ); + expect(page.datatablePager).toBeTruthy(); component.rowCount = 1; component.pageSize = 2; page.detectChangesAndRunQueries(); - expect(page.datatablePager.nativeElement.hidden).toBe( - true, - 'DataTablePagerComponent should not be hidden' - ); + expect(page.datatablePager).toBeFalsy(); }); }); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts index a23ce99c3..8add706fd 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts @@ -30,6 +30,7 @@ import { NgClass, NgTemplateOutlet } from '@angular/common'; } {{ rowCount?.toLocaleString() }} {{ totalMessage }}
    + @if (isVisible) { - } + } }
    `, host: { From 952670b3299c8e08eb5d2f9a6a43b6803e7ff14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Sun, 22 Jun 2025 13:51:40 +0200 Subject: [PATCH 092/105] refactor: move scroll-vertical style to the body component (#258) --- .../src/lib/components/body/body.component.scss | 4 ++++ .../src/lib/components/datatable.component.scss | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss index d478c8945..5b47784e0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.scss @@ -18,6 +18,10 @@ datatable-scroller { } } +:host-context(ngx-datatable.scroll-vertical) :host { + overflow-y: auto; +} + [hidden] { display: none !important; } diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 6c8b0558e..df01fdf15 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -10,13 +10,4 @@ *:after { box-sizing: border-box; } - - /** - * Vertical Scrolling Adjustments - */ - &.scroll-vertical { - .datatable-body { - overflow-y: auto; - } - } } From 3ac908e981eff0d743b35eee51b8f31f5d1d936f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Sun, 22 Jun 2025 14:02:21 +0200 Subject: [PATCH 093/105] refactor: remove general `box-sizing: border-box` (#256) BREAKING CHANGE: Previously the datatable applied `box-sizing: border-box` to all its elements. This is no longer the case. Custom themes that depend on this must set this behavior manually, using: ```css *, *:before, *:after { box-sizing: border-box; } ``` --- .../src/lib/components/datatable.component.scss | 6 ------ .../swimlane/ngx-datatable/src/lib/themes/bootstrap.scss | 7 +++++++ projects/swimlane/ngx-datatable/src/lib/themes/dark.scss | 6 ++++++ .../swimlane/ngx-datatable/src/lib/themes/material.scss | 6 ++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index df01fdf15..16fc5590a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -4,10 +4,4 @@ justify-content: center; position: relative; transform: translate3d(0, 0, 0); - - *, - *:before, - *:after { - box-sizing: border-box; - } } diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss b/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss index 43212f1de..31061e369 100644 --- a/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss +++ b/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss @@ -17,6 +17,13 @@ $datatble-ghost-cell-animation-duration: 10s; .ngx-datatable.bootstrap { box-shadow: none; font-size: 13px; + + *, + *:before, + *:after { + box-sizing: border-box; + } + .datatable-header { height: unset !important; .datatable-header-cell { diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss b/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss index 2a428da8a..5136c5f32 100644 --- a/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss +++ b/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss @@ -5,6 +5,12 @@ color: #fff; font-size: 13px; + *, + *:before, + *:after { + box-sizing: border-box; + } + .datatable-header { background: #181b24; color: #72809b; diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss index 3e81ffcfc..fb7a15d8a 100644 --- a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss +++ b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss @@ -86,6 +86,12 @@ $datatble-ghost-cell-animation-duration: 10s; background: $ngx-datatable-background; box-shadow: $ngx-datatable-box-shadow; + *, + *:before, + *:after { + box-sizing: border-box; + } + &.striped { .datatable-row-odd { background: $ngx-datatable-row-odd-background; From 4a4155c6a076c0648429cc056c0631506ff60b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Sun, 22 Jun 2025 14:41:05 +0200 Subject: [PATCH 094/105] feat: introduce a new `providedNgxDatatableConfig` for a standalone way to configure the datatable. (#259) This also removes the previous breaking change of requiring new messages. Since all messages are now optional. --- .../src/lib/components/datatable.component.ts | 11 ++- .../src/lib/ngx-datatable.config.ts | 76 +++++++++++++++++++ .../src/lib/ngx-datatable.module.ts | 47 ++---------- .../swimlane/ngx-datatable/src/public-api.ts | 7 ++ src/main.ts | 30 ++++---- 5 files changed, 109 insertions(+), 62 deletions(-) create mode 100644 projects/swimlane/ngx-datatable/src/lib/ngx-datatable.config.ts diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 97a77ada0..618555aa4 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -30,7 +30,6 @@ import { import { DatatableGroupHeaderDirective } from './body/body-group-header.directive'; import { Subscription } from 'rxjs'; -import { INgxDatatableConfig } from '../ngx-datatable.module'; import { groupRowsByParents, optionalGetterForProp } from '../utils/tree'; import { TableColumn } from '../types/table-column.type'; import { DataTableColumnDirective } from './columns/column.directive'; @@ -75,6 +74,7 @@ import { ReorderEventInternal, TableColumnInternal } from '../types/internal.types'; +import { NGX_DATATABLE_CONFIG, NgxDatatableConfig } from '../ngx-datatable.config'; @Component({ selector: 'ngx-datatable', @@ -106,7 +106,10 @@ export class DatatableComponent private scrollbarHelper = inject(ScrollbarHelper); private cd = inject(ChangeDetectorRef); private columnChangesService = inject(ColumnChangesService); - private configuration = inject('configuration' as any, { optional: true }); + private configuration = + inject(NGX_DATATABLE_CONFIG, { optional: true }) ?? + // This is the old injection token for backward compatibility. + inject('configuration' as any, { optional: true }); /** * Template for the target marker of drag target columns. @@ -354,7 +357,7 @@ export class DatatableComponent /** * Css class overrides */ - @Input() cssClasses: Partial['cssClasses']> = {}; + @Input() cssClasses: Partial['cssClasses']> = {}; /** * Message overrides for localization @@ -373,7 +376,7 @@ export class DatatableComponent * } * ``` */ - @Input() messages: Partial['messages']> = {}; + @Input() messages: Partial['messages']> = {}; /** * A function which is called with the row and should return either: diff --git a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.config.ts b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.config.ts new file mode 100644 index 000000000..92d3960fb --- /dev/null +++ b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.config.ts @@ -0,0 +1,76 @@ +import { InjectionToken, Provider } from '@angular/core'; + +/** Interface for messages to override default table texts. */ +export interface NgxDatatableMessages { + /** Message to show when the array is present but empty */ + emptyMessage: string; + /** Footer total message */ + totalMessage: string; + /** Footer selected message */ + selectedMessage: string; + /** Pager screen reader message for the first page button */ + ariaFirstPageMessage: string; + /** + * Pager screen reader message for the n-th page button. + * It will be rendered as: `{{ariaPageNMessage}} {{n}}`. + */ + ariaPageNMessage: string; + /** Pager screen reader message for the previous page button */ + ariaPreviousPageMessage: string; + /** Pager screen reader message for the next page button */ + ariaNextPageMessage: string; + /** Pager screen reader message for the last page button */ + ariaLastPageMessage: string; +} + +/** CSS classes for icons that override the default table icons. */ +export interface NgxDatatableCssClasses { + sortAscending: string; + sortDescending: string; + sortUnset: string; + pagerLeftArrow: string; + pagerRightArrow: string; + pagerPrevious: string; + pagerNext: string; +} + +/** + * Interface definition for ngx-datatable global configuration + */ +// TODO those properties should all be required in the interface. Should be changed with signal migration. +export interface NgxDatatableConfig { + messages?: NgxDatatableMessages; + cssClasses?: NgxDatatableCssClasses; + headerHeight?: number; + footerHeight?: number; + rowHeight?: number; + defaultColumnWidth?: number; +} + +export const NGX_DATATABLE_CONFIG = new InjectionToken('ngx-datatable.config'); + +/** + * This makes all properties recursively optional. + * + * @internal + */ +export type AllPartial = { [K in keyof T]?: AllPartial }; + +/** + * Interface definition for INgxDatatableConfig global configuration. + * + * @deprecated Use {@link NgxDatatableConfig} instead. + */ +export type INgxDatatableConfig = NgxDatatableConfig; + +/** + * Provides a global configuration for ngx-datatable. + * + * @param overrides The overrides of the table configuration. + */ +export function providedNgxDatatableConfig(overrides: AllPartial): Provider { + return { + provide: NGX_DATATABLE_CONFIG, + useValue: overrides + }; +} diff --git a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts index b42ceece7..8292f6dae 100644 --- a/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts +++ b/projects/swimlane/ngx-datatable/src/lib/ngx-datatable.module.ts @@ -16,6 +16,7 @@ import { DatatableRowDefComponent, DatatableRowDefDirective } from './components/body/body-row-def.component'; +import { AllPartial, NgxDatatableConfig, providedNgxDatatableConfig } from './ngx-datatable.config'; @NgModule({ imports: [ @@ -58,50 +59,12 @@ export class NgxDatatableModule { * Configure global configuration via INgxDatatableConfig * @param configuration */ - static forRoot(configuration: INgxDatatableConfig): ModuleWithProviders { + static forRoot( + configuration: AllPartial + ): ModuleWithProviders { return { ngModule: NgxDatatableModule, - providers: [{ provide: 'configuration', useValue: configuration }] + providers: [providedNgxDatatableConfig(configuration)] }; } } - -/** - * Interface definition for INgxDatatableConfig global configuration - */ -export interface INgxDatatableConfig { - messages?: { - /** Message to show when the array is present but empty */ - emptyMessage: string; - /** Footer total message */ - totalMessage: string; - /** Footer selected message */ - selectedMessage: string; - /** Pager screen reader message for the first page button */ - ariaFirstPageMessage: string; - /** - * Pager screen reader message for the n-th page button. - * It will be rendered as: `{{ariaPageNMessage}} {{n}}`. - */ - ariaPageNMessage: string; - /** Pager screen reader message for the previous page button */ - ariaPreviousPageMessage: string; - /** Pager screen reader message for the next page button */ - ariaNextPageMessage: string; - /** Pager screen reader message for the last page button */ - ariaLastPageMessage: string; - }; - cssClasses?: { - sortAscending: string; - sortDescending: string; - sortUnset: string; - pagerLeftArrow: string; - pagerRightArrow: string; - pagerPrevious: string; - pagerNext: string; - }; - headerHeight?: number; - footerHeight?: number; - rowHeight?: number; - defaultColumnWidth?: number; -} diff --git a/projects/swimlane/ngx-datatable/src/public-api.ts b/projects/swimlane/ngx-datatable/src/public-api.ts index 6969d6e21..115d4aa41 100644 --- a/projects/swimlane/ngx-datatable/src/public-api.ts +++ b/projects/swimlane/ngx-datatable/src/public-api.ts @@ -24,3 +24,10 @@ export * from './lib/directives/disable-row.directive'; // types export * from './lib/types/public.types'; export * from './lib/types/table-column.type'; + +export { + providedNgxDatatableConfig, + NgxDatatableConfig, + NgxDatatableMessages, + NgxDatatableCssClasses +} from './lib/ngx-datatable.config'; diff --git a/src/main.ts b/src/main.ts index 6b65cdefe..285a2e6b8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,10 @@ -import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { enableProdMode } from '@angular/core'; import { environment } from './environments/environment'; import { provideHttpClient } from '@angular/common/http'; import { bootstrapApplication } from '@angular/platform-browser'; import { routes } from './app/app-routing.module'; -import { NgxDatatableModule } from 'projects/swimlane/ngx-datatable/src/public-api'; +import { providedNgxDatatableConfig } from 'projects/swimlane/ngx-datatable/src/public-api'; import { AppComponent } from './app/app.component'; import { provideRouter, withHashLocation } from '@angular/router'; @@ -14,20 +14,18 @@ if (environment.production) { bootstrapApplication(AppComponent, { providers: [ - importProvidersFrom( - NgxDatatableModule.forRoot({ - messages: { - emptyMessage: 'No data to display', // Message to show when array is presented, but contains no values - totalMessage: 'total', // Footer total message - selectedMessage: 'selected', // Footer selected message - ariaFirstPageMessage: 'go to first page', // Pager screen reader message for the first page button - ariaPreviousPageMessage: 'go to previous page', // Pager screen reader message for the previous page button - ariaPageNMessage: 'page', // Pager screen reader message for the n-th page button - ariaNextPageMessage: 'go to next page', // Pager screen reader message for the next page button - ariaLastPageMessage: 'go to last page' // Pager screen reader message for the last page button - } - }) - ), + providedNgxDatatableConfig({ + messages: { + emptyMessage: 'No data to display', // Message to show when array is presented, but contains no values + totalMessage: 'total', // Footer total message + selectedMessage: 'selected', // Footer selected message + ariaFirstPageMessage: 'go to first page', // Pager screen reader message for the first page button + ariaPreviousPageMessage: 'go to previous page', // Pager screen reader message for the previous page button + ariaPageNMessage: 'page', // Pager screen reader message for the n-th page button + ariaNextPageMessage: 'go to next page', // Pager screen reader message for the next page button + ariaLastPageMessage: 'go to last page' // Pager screen reader message for the last page button + } + }), provideRouter(routes, withHashLocation()), provideHttpClient() ] From 86c21d22d5a28e18f78fffbccbb847dc7eecc4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20K=C3=B6ller?= Date: Sun, 22 Jun 2025 14:56:39 +0200 Subject: [PATCH 095/105] refactor: all header pinned columns should be flex (#253) We accidentally removed the flex container on column groups for pinning. Please note that we have the same in body rows where we kept the container as flex. --- .../src/lib/components/header/header.component.scss | 8 ++++++++ .../src/lib/components/header/header.component.ts | 11 ++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss index 887d6c546..9e3c036f4 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.scss @@ -1,3 +1,5 @@ +@use '../shared'; + :host { display: block; overflow: hidden; @@ -10,3 +12,9 @@ white-space: nowrap; } } + +.datatable-row-group { + display: flex; +} + +@include shared.pinned-columns(); diff --git a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts index f1019afb6..ab806803f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/header/header.component.ts @@ -21,7 +21,7 @@ import { SortPropDir, SortType } from '../../types/public.types'; -import { NgStyle } from '@angular/common'; +import { NgClass, NgStyle } from '@angular/common'; import { ScrollbarHelper } from '../../services/scrollbar-helper.service'; import { ColumnResizeEventInternal, @@ -49,7 +49,11 @@ import { OrderableDirective } from '../../directives/orderable.directive'; class="datatable-header-inner" > @for (colGroup of _columnsByPin; track colGroup.type) { @if (colGroup.columns.length) { -
    +
    @for (column of colGroup.columns; track column.$$id) { Date: Tue, 24 Jun 2025 08:49:12 +0200 Subject: [PATCH 096/105] refactor: base internal row length on rowCount property (#261) The number of potentially rendered rows should be based on the `rowCount` property which can be supplied externally for server paging. This is needed for ghost loading as apps may provide rows which are shorter than the `rowCount` and thus than the rendered rows. By filling up the internal rows with `undefined` the ghost loading works even though the rows provided are too short. --- .../components/body/body.component.spec.ts | 26 +++++++++++++++++++ .../src/lib/components/body/body.component.ts | 13 +++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts index b992c4516..efa8e9c1d 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.spec.ts @@ -5,6 +5,8 @@ import { DatatableComponentToken } from '../../utils/table-token'; import { By } from '@angular/platform-browser'; import { DataTableBodyRowComponent } from './body-row.component'; import { toInternalColumn } from '../../utils/column-helper'; +import { ScrollerComponent } from './scroller.component'; +import { DataTableGhostLoaderComponent } from './ghost-loader/ghost-loader.component'; describe('DataTableBodyComponent', () => { let fixture: ComponentFixture; @@ -92,6 +94,30 @@ describe('DataTableBodyComponent', () => { component.updateIndexes(); expect(component.indexes()).toEqual(expectedIndexes); }); + + it('should render ghost rows based rowCount', () => { + component.trackByProp = 'num'; + component.rows = [{ num: 1 }, { num: 2 }, { num: 3 }, { num: 4 }]; + component.externalPaging = true; + component.scrollbarV = true; + component.virtualization = true; + component.rowHeight = 50; + component.ghostLoadingIndicator = true; + component.bodyHeight = 200; + component.pageSize = 5; + component.rowCount = 10; + component.offset = 0; + fixture.detectChanges(); + expect(component.indexes()).toEqual({ first: 0, last: 5 }); + fixture.debugElement + .query(By.directive(ScrollerComponent)) + .triggerEventHandler('scroll', { scrollYPos: 250, scrollXPos: 0 }); + fixture.detectChanges(); + expect(component.indexes()).toEqual({ first: 5, last: 10 }); + expect(fixture.debugElement.queryAll(By.directive(DataTableGhostLoaderComponent))).toHaveSize( + 5 + ); + }); }); describe('with disableCheck', () => { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 6f5318105..d9430d877 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -415,7 +415,7 @@ export class DataTableBodyComponent implements OnInit, O if (this.ghostLoadingIndicator) { return index; } - if (this.trackByProp) { + if (this.trackByProp && row) { return (row as any)[this.trackByProp]; } else { return row; @@ -550,11 +550,12 @@ export class DataTableBodyComponent implements OnInit, O // if grouprowsby has been specified treat row paging // parameters as group paging parameters ie if limit 10 has been // specified treat it as 10 groups rather than 10 rows - if (this.groupedRows) { - return this.groupedRows.slice(first, Math.min(last, this.groupedRows.length)); - } else { - return this.rows.slice(first, Math.min(last, this.rowCount)); - } + const rows = this.groupedRows + ? this.groupedRows.slice(first, Math.min(last, this.groupedRows.length)) + : this.rows.slice(first, Math.min(last, this.rowCount)); + + rows.length = last - first; + return rows; } /** From d3ddab35c9824f007df651c7cfda09d0eafd929c Mon Sep 17 00:00:00 2001 From: Maximilian Koeller Date: Tue, 24 Jun 2025 08:56:12 +0200 Subject: [PATCH 097/105] refactor: enable view encapsulation on root component --- .../ngx-datatable/src/lib/components/datatable.component.scss | 2 +- .../ngx-datatable/src/lib/components/datatable.component.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss index 16fc5590a..74f943397 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.scss @@ -1,4 +1,4 @@ -.ngx-datatable { +:host { display: block; overflow: hidden; justify-content: center; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts index 618555aa4..7d4e49cfb 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts @@ -23,8 +23,7 @@ import { QueryList, signal, TemplateRef, - ViewChild, - ViewEncapsulation + ViewChild } from '@angular/core'; import { DatatableGroupHeaderDirective } from './body/body-group-header.directive'; @@ -80,7 +79,6 @@ import { NGX_DATATABLE_CONFIG, NgxDatatableConfig } from '../ngx-datatable.confi selector: 'ngx-datatable', templateUrl: './datatable.component.html', changeDetection: ChangeDetectionStrategy.OnPush, - encapsulation: ViewEncapsulation.None, styleUrls: ['./datatable.component.scss'], host: { class: 'ngx-datatable' From 28a7470b09f36a8115810a756e00c5daf4ba9a7d Mon Sep 17 00:00:00 2001 From: Linus Schlumberger Date: Tue, 24 Jun 2025 15:55:07 +0200 Subject: [PATCH 098/105] fix: fix keyboard interaction for cell selection mode --- .../ngx-datatable/src/lib/components/body/body.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index d9430d877..50bea30a0 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -962,7 +962,7 @@ export class DataTableBodyComponent implements OnInit, O } if (!model.cellElement || !isCellSelection) { this.focusRow(model.rowElement, key); - } else if (isCellSelection && model.cellIndex) { + } else if (isCellSelection && model.cellIndex !== undefined) { this.focusCell(model.cellElement, model.rowElement, key, model.cellIndex); } } From 23ab901e9a046db8344f7153c643cc211a47f897 Mon Sep 17 00:00:00 2001 From: Colin Frick Date: Tue, 24 Jun 2025 08:58:04 +0200 Subject: [PATCH 099/105] refactor: migrate to input signals --- .../lib/directives/disable-row.directive.ts | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts index 2455d9f43..8e69ba2e2 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/disable-row.directive.ts @@ -1,4 +1,4 @@ -import { booleanAttribute, Directive, ElementRef, inject, Input } from '@angular/core'; +import { booleanAttribute, Directive, effect, ElementRef, inject, input } from '@angular/core'; /** * Row Disable Directive @@ -15,26 +15,27 @@ import { booleanAttribute, Directive, ElementRef, inject, Input } from '@angular selector: '[disable-row]' }) export class DisableRowDirective { - private element = inject(ElementRef); - private _disabled = false; - @Input({ transform: booleanAttribute }) set disabled(val: boolean) { - this._disabled = val; - if (val) { - this.disableAllElements(); - } - } + private readonly elementRef = inject>(ElementRef); - get disabled() { - return this._disabled; + readonly disabled = input(false, { + transform: booleanAttribute + }); + + constructor() { + effect(() => { + if (this.disabled()) { + this.disableAllElements(); + } + }); } - disableAllElements() { - const el = this.element?.nativeElement; - if (!el) { + private disableAllElements() { + const hostElement = this.elementRef?.nativeElement; + if (!hostElement) { return; } - Array.from(el.querySelectorAll('*') as HTMLAllCollection).forEach(child => { - child?.setAttribute('disabled', ''); + Array.from(hostElement.querySelectorAll('*')).forEach(child => { + child.setAttribute('disabled', ''); }); } } From 11ddc36d866fce4d5f3f3176870afc9ccbf060ce Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Thu, 26 Jun 2025 14:58:27 -0500 Subject: [PATCH 100/105] upgrade angular cli to v20 --- package.json | 2 +- yarn.lock | 417 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 289 insertions(+), 130 deletions(-) diff --git a/package.json b/package.json index a4fac4fec..1e0864d37 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@angular-eslint/eslint-plugin-template": "^18.0.0", "@angular-eslint/schematics": "^18.0.0", "@angular-eslint/template-parser": "^18.0.0", - "@angular/cli": "^19.1.6", + "@angular/cli": "^20.0.4", "@angular/compiler-cli": "^19.1.4", "@angular/language-service": "^19.1.4", "@swimlane/eslint-config": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index e9002f881..2ffac1d20 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,6 +25,16 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/architect@npm:0.2000.4": + version: 0.2000.4 + resolution: "@angular-devkit/architect@npm:0.2000.4" + dependencies: + "@angular-devkit/core": "npm:20.0.4" + rxjs: "npm:7.8.2" + checksum: 10c0/ebca373f9c09309c13172c2cbf563b925518690cb516db63d1a4de075893516e25f0ad1c9a39628b239923669bb6e37c60c008d67a616609a43792e0932664fc + languageName: node + linkType: hard + "@angular-devkit/architect@npm:>= 0.1800.0 < 0.1900.0": version: 0.1802.19 resolution: "@angular-devkit/architect@npm:0.1802.19" @@ -232,16 +242,35 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/schematics@npm:19.2.10, @angular-devkit/schematics@npm:^19.1.4": - version: 19.2.10 - resolution: "@angular-devkit/schematics@npm:19.2.10" +"@angular-devkit/core@npm:20.0.4": + version: 20.0.4 + resolution: "@angular-devkit/core@npm:20.0.4" dependencies: - "@angular-devkit/core": "npm:19.2.10" + ajv: "npm:8.17.1" + ajv-formats: "npm:3.0.1" + jsonc-parser: "npm:3.3.1" + picomatch: "npm:4.0.2" + rxjs: "npm:7.8.2" + source-map: "npm:0.7.4" + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + checksum: 10c0/1d3919f8911f36d800346a01e950a7dc2969b605493945a4338f0a9bc17e427be7ac3025cbcd6b7282643df42ef0a89ea016319b6bb85fc96a5273dd7696725e + languageName: node + linkType: hard + +"@angular-devkit/schematics@npm:20.0.4": + version: 20.0.4 + resolution: "@angular-devkit/schematics@npm:20.0.4" + dependencies: + "@angular-devkit/core": "npm:20.0.4" jsonc-parser: "npm:3.3.1" magic-string: "npm:0.30.17" - ora: "npm:5.4.1" - rxjs: "npm:7.8.1" - checksum: 10c0/ea4fb356b78b5e9b0cb07a764f3bca6fab5a7eb5204d71c877351ed18910f34d569aecb9aa9ea2e85cfa8d3a3c68803f47eeb2d565284ca53acb3c6f1556052a + ora: "npm:8.2.0" + rxjs: "npm:7.8.2" + checksum: 10c0/574e24144dba760dc29b93061b3f1f9cae649531f50c6c62ba90d46b2d53ca20d15173f645a40174f28c9e096f35726a1aebae48a6c46257f6e4a8cf1f534d8f languageName: node linkType: hard @@ -263,6 +292,19 @@ __metadata: languageName: node linkType: hard +"@angular-devkit/schematics@npm:^19.1.4": + version: 19.2.10 + resolution: "@angular-devkit/schematics@npm:19.2.10" + dependencies: + "@angular-devkit/core": "npm:19.2.10" + jsonc-parser: "npm:3.3.1" + magic-string: "npm:0.30.17" + ora: "npm:5.4.1" + rxjs: "npm:7.8.1" + checksum: 10c0/ea4fb356b78b5e9b0cb07a764f3bca6fab5a7eb5204d71c877351ed18910f34d569aecb9aa9ea2e85cfa8d3a3c68803f47eeb2d565284ca53acb3c6f1556052a + languageName: node + linkType: hard + "@angular-eslint/builder@npm:^18.0.0": version: 18.4.3 resolution: "@angular-eslint/builder@npm:18.4.3" @@ -454,30 +496,29 @@ __metadata: languageName: node linkType: hard -"@angular/cli@npm:^19.1.6": - version: 19.2.10 - resolution: "@angular/cli@npm:19.2.10" +"@angular/cli@npm:^20.0.4": + version: 20.0.4 + resolution: "@angular/cli@npm:20.0.4" dependencies: - "@angular-devkit/architect": "npm:0.1902.10" - "@angular-devkit/core": "npm:19.2.10" - "@angular-devkit/schematics": "npm:19.2.10" - "@inquirer/prompts": "npm:7.3.2" - "@listr2/prompt-adapter-inquirer": "npm:2.0.18" - "@schematics/angular": "npm:19.2.10" + "@angular-devkit/architect": "npm:0.2000.4" + "@angular-devkit/core": "npm:20.0.4" + "@angular-devkit/schematics": "npm:20.0.4" + "@inquirer/prompts": "npm:7.5.1" + "@listr2/prompt-adapter-inquirer": "npm:2.0.22" + "@schematics/angular": "npm:20.0.4" "@yarnpkg/lockfile": "npm:1.1.0" ini: "npm:5.0.0" jsonc-parser: "npm:3.3.1" - listr2: "npm:8.2.5" + listr2: "npm:8.3.3" npm-package-arg: "npm:12.0.2" npm-pick-manifest: "npm:10.0.0" - pacote: "npm:20.0.0" + pacote: "npm:21.0.0" resolve: "npm:1.22.10" - semver: "npm:7.7.1" - symbol-observable: "npm:4.0.0" + semver: "npm:7.7.2" yargs: "npm:17.7.2" bin: ng: bin/ng.js - checksum: 10c0/5f276697832ae901c8766ba9157ac7aade886c0cf901a9882719f67b2fbdcbf71961cab9670418beef4427d6b71ea65d814307691cfb6b191333f7a082e8df2b + checksum: 10c0/16f94b7e52a0710b878746fd1b260a24aec0aa89850f40d398722e4dcc0dd3e314edba31b6f15aa99270b6af4833c4057a4cbb953f481961314e9bd7b67b1449 languageName: node linkType: hard @@ -2275,13 +2316,13 @@ __metadata: languageName: node linkType: hard -"@inquirer/checkbox@npm:^4.1.2": - version: 4.1.5 - resolution: "@inquirer/checkbox@npm:4.1.5" +"@inquirer/checkbox@npm:^4.1.6": + version: 4.1.8 + resolution: "@inquirer/checkbox@npm:4.1.8" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/figures": "npm:^1.0.11" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/figures": "npm:^1.0.12" + "@inquirer/type": "npm:^3.0.7" ansi-escapes: "npm:^4.3.2" yoctocolors-cjs: "npm:^2.1.2" peerDependencies: @@ -2289,7 +2330,7 @@ __metadata: peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/b984fb3ce8af34c327f3a85adcfe9fbd9eaac0c689bb9af79a5d55d508acb01de329747e8c923c9f4962e4006c353ed2dbe79e3fc9ae0f85f5851427dbed75ed + checksum: 10c0/6d726420b179c55b2f0001aaf6e339fa56e9e939afcbda31c386ab2e5d029ef6f2d392ec99c6a6950af1776a399791bbb88a635e4d047f1170b2ed8c5bba1e4c languageName: node linkType: hard @@ -2308,22 +2349,43 @@ __metadata: languageName: node linkType: hard -"@inquirer/confirm@npm:^5.1.6": - version: 5.1.9 - resolution: "@inquirer/confirm@npm:5.1.9" +"@inquirer/confirm@npm:^5.1.10": + version: 5.1.12 + resolution: "@inquirer/confirm@npm:5.1.12" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/type": "npm:^3.0.7" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/e35c134303f8151074479d6704c048676b2684debfde18a46ff0fb7585a3ee31dea551899ddcb48169fbef5dfe64c1948d2d8ac17a6939bedd31bb54c39bbea4 + checksum: 10c0/581aedfe8ce45e177fb4470a12f874f5162a4396636bf4140edc5812ffc8ed0d1fa7e9bbc3a7af618203089a084f489e0b32112947eedc6930a766fad992449e languageName: node linkType: hard -"@inquirer/core@npm:^10.1.10, @inquirer/core@npm:^10.1.7": +"@inquirer/core@npm:^10.1.13": + version: 10.1.13 + resolution: "@inquirer/core@npm:10.1.13" + dependencies: + "@inquirer/figures": "npm:^1.0.12" + "@inquirer/type": "npm:^3.0.7" + ansi-escapes: "npm:^4.3.2" + cli-width: "npm:^4.1.0" + mute-stream: "npm:^2.0.0" + signal-exit: "npm:^4.1.0" + wrap-ansi: "npm:^6.2.0" + yoctocolors-cjs: "npm:^2.1.2" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/919208a31307297d5a07a44b9ebe69a999ce1470b31a2e1b5a04538bc36624d2053808cd6c677637a61690af09bdbdd635bd7031b64e3dd86c5b18df3ca7c3f9 + languageName: node + linkType: hard + +"@inquirer/core@npm:^10.1.7": version: 10.1.10 resolution: "@inquirer/core@npm:10.1.10" dependencies: @@ -2344,35 +2406,35 @@ __metadata: languageName: node linkType: hard -"@inquirer/editor@npm:^4.2.7": - version: 4.2.10 - resolution: "@inquirer/editor@npm:4.2.10" +"@inquirer/editor@npm:^4.2.11": + version: 4.2.13 + resolution: "@inquirer/editor@npm:4.2.13" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/type": "npm:^3.0.7" external-editor: "npm:^3.1.0" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/b0213ad3ef45bc30427def4742db22126a1e6a59923033d21cae216276d8cf85d2af8abe432e5567ea24a7f6a31e23e7014e31308405cde684060b974e454a22 + checksum: 10c0/e1a27d75f737d7847905c14cf04d66d864eeb0f3e4cb2d36e34b51993741c5b70c22754171820c5d880a740765471455a8a98874285fd4a10b162342898f6c6b languageName: node linkType: hard -"@inquirer/expand@npm:^4.0.9": - version: 4.0.12 - resolution: "@inquirer/expand@npm:4.0.12" +"@inquirer/expand@npm:^4.0.13": + version: 4.0.15 + resolution: "@inquirer/expand@npm:4.0.15" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/type": "npm:^3.0.7" yoctocolors-cjs: "npm:^2.1.2" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/f7abfc09ef942b63504677be5cf6fc443fb8090b5d43f7d2fe09983215cc01c6d82351cd1b596e90723b382a0931c9344d3280d54acf47d898782f4af2030b2e + checksum: 10c0/d558e367995a38a31d830de45d1e6831b73a798d6076c7fc8bdb639d3fac947a5d15810f7336b45c7712fc0e21fe8a2728f7f594550a20b6b4a839a18f9086cb languageName: node linkType: hard @@ -2383,115 +2445,122 @@ __metadata: languageName: node linkType: hard -"@inquirer/input@npm:^4.1.6": - version: 4.1.9 - resolution: "@inquirer/input@npm:4.1.9" +"@inquirer/figures@npm:^1.0.12": + version: 1.0.12 + resolution: "@inquirer/figures@npm:1.0.12" + checksum: 10c0/08694288bdf9aa474571ca94272113a5ac443229519ce71447eba9eb7d5a2007901bdc3e92216d929a69746dcbac29683886c20e67b7864a7c7f6c59b99d3269 + languageName: node + linkType: hard + +"@inquirer/input@npm:^4.1.10": + version: 4.1.12 + resolution: "@inquirer/input@npm:4.1.12" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/type": "npm:^3.0.7" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/db2e661ee482f3f27bf8cb77f054f99aba30291bd24d63b28db62204c4c5efc496199a9ddc03d01e0f6e6455d6967efb3ef92d2cd91e672905948c8c978c67a1 + checksum: 10c0/17b59547432f54a18ec573fde96c2c13c827f04faf694fc58239ec97e993ac6af151ed2a0521029c9199a4f422742dbe5dc23c20705748eafdc7dd26c7adca3a languageName: node linkType: hard -"@inquirer/number@npm:^3.0.9": - version: 3.0.12 - resolution: "@inquirer/number@npm:3.0.12" +"@inquirer/number@npm:^3.0.13": + version: 3.0.15 + resolution: "@inquirer/number@npm:3.0.15" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/type": "npm:^3.0.7" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/e40726e1c60ba48a374b4867d212bd5e14cb12daae97a6536095906246ba6af91ec7fa68e347ba52607ba5bd84f9e804768d12fbc1250b2cac814187fb5e9628 + checksum: 10c0/724fc0d10611a0a9ea43280a94ed9194b8bb22d9a2af940eb37592d0cebc9e6e219edc4f79d8c176f53fd1b078543a9e4773037c7bde4b8d929a3034406eec90 languageName: node linkType: hard -"@inquirer/password@npm:^4.0.9": - version: 4.0.12 - resolution: "@inquirer/password@npm:4.0.12" +"@inquirer/password@npm:^4.0.13": + version: 4.0.15 + resolution: "@inquirer/password@npm:4.0.15" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/type": "npm:^3.0.7" ansi-escapes: "npm:^4.3.2" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/03257985bbbd813c4f0c412effb691737517e348ca2590558864fe09877080daf90eb9910a60d097048fce9cf0c56a900e8f099854a9ae21512ceaadbd986e01 + checksum: 10c0/673d7c33dd0ee951c96f349d4fb66f8762f31c62188546da4d7af544202b638eecef6b8c78e62f43a46c72a5fa0712d94a56ed56f12e1badbb1001128bc991bd languageName: node linkType: hard -"@inquirer/prompts@npm:7.3.2": - version: 7.3.2 - resolution: "@inquirer/prompts@npm:7.3.2" +"@inquirer/prompts@npm:7.5.1": + version: 7.5.1 + resolution: "@inquirer/prompts@npm:7.5.1" dependencies: - "@inquirer/checkbox": "npm:^4.1.2" - "@inquirer/confirm": "npm:^5.1.6" - "@inquirer/editor": "npm:^4.2.7" - "@inquirer/expand": "npm:^4.0.9" - "@inquirer/input": "npm:^4.1.6" - "@inquirer/number": "npm:^3.0.9" - "@inquirer/password": "npm:^4.0.9" - "@inquirer/rawlist": "npm:^4.0.9" - "@inquirer/search": "npm:^3.0.9" - "@inquirer/select": "npm:^4.0.9" + "@inquirer/checkbox": "npm:^4.1.6" + "@inquirer/confirm": "npm:^5.1.10" + "@inquirer/editor": "npm:^4.2.11" + "@inquirer/expand": "npm:^4.0.13" + "@inquirer/input": "npm:^4.1.10" + "@inquirer/number": "npm:^3.0.13" + "@inquirer/password": "npm:^4.0.13" + "@inquirer/rawlist": "npm:^4.1.1" + "@inquirer/search": "npm:^3.0.13" + "@inquirer/select": "npm:^4.2.1" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/a318d7c2a963f753f4868151f2ce5673e214f3a6597430e712bc59ef9605c831b71a6b52a9c5ea2f312b23063d2ee9fd633e127cdc9e4999e95ef15a5e90c7e1 + checksum: 10c0/7f9cf44e1caff3eb61939f8abc9906acfec0d955c25e860212dc9e0e7bd6b9fb046415731e2407eb8a0745d282bb73c03587481090720255c4b828d85b830a08 languageName: node linkType: hard -"@inquirer/rawlist@npm:^4.0.9": - version: 4.1.0 - resolution: "@inquirer/rawlist@npm:4.1.0" +"@inquirer/rawlist@npm:^4.1.1": + version: 4.1.3 + resolution: "@inquirer/rawlist@npm:4.1.3" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/type": "npm:^3.0.7" yoctocolors-cjs: "npm:^2.1.2" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/0e92e8ee7eebd6b6ba7a81d968701f398dd372638f51dd8e3cb1fd3a03520bc0f713e112488d37fdb813f18928f338d82527c575e18a9bebde7ac3273045898c + checksum: 10c0/d653e730188e6849df540186cf7cb0f37f06c64d03f075b5a617145671fb015c27aeb60adb003d1a05a925795968efff0a3ae5a737a8d04c5679aa6fdc423662 languageName: node linkType: hard -"@inquirer/search@npm:^3.0.9": - version: 3.0.12 - resolution: "@inquirer/search@npm:3.0.12" +"@inquirer/search@npm:^3.0.13": + version: 3.0.15 + resolution: "@inquirer/search@npm:3.0.15" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/figures": "npm:^1.0.11" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/figures": "npm:^1.0.12" + "@inquirer/type": "npm:^3.0.7" yoctocolors-cjs: "npm:^2.1.2" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/ef764f96b561b48e4d9a99716789d1fc0941d40884d1c9fea715c304360b46ec8c6e3edf603f7425a27d7743915564f405a3ccd1a72f0379a714be22887fe6ff + checksum: 10c0/32b29789e72e53a7b6cfdbc1803bd9e466c424d9f0368a145bef9e25c6fbde72af29cdd4667a785fee79de213f11fa76453f8120ea02ac5158dce259565ce7fd languageName: node linkType: hard -"@inquirer/select@npm:^4.0.9": - version: 4.2.0 - resolution: "@inquirer/select@npm:4.2.0" +"@inquirer/select@npm:^4.2.1": + version: 4.2.3 + resolution: "@inquirer/select@npm:4.2.3" dependencies: - "@inquirer/core": "npm:^10.1.10" - "@inquirer/figures": "npm:^1.0.11" - "@inquirer/type": "npm:^3.0.6" + "@inquirer/core": "npm:^10.1.13" + "@inquirer/figures": "npm:^1.0.12" + "@inquirer/type": "npm:^3.0.7" ansi-escapes: "npm:^4.3.2" yoctocolors-cjs: "npm:^2.1.2" peerDependencies: @@ -2499,7 +2568,7 @@ __metadata: peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/b3cfab393d54e48012336710b8e9267a0dd5551878a7727800da3d78602398720aab8777d5687b2138261fb731b0079d1c3ec0f4d0fee194bb1c4496c97b340b + checksum: 10c0/376535f50a9c2e19e27a5c81930cd1b5afa0b7d86228e5789782955a2d0a89bf5a8890a97943042e1b393094fe236ce97c9ff4bb777c9b44b22c1424f883b063 languageName: node linkType: hard @@ -2524,6 +2593,18 @@ __metadata: languageName: node linkType: hard +"@inquirer/type@npm:^3.0.7": + version: 3.0.7 + resolution: "@inquirer/type@npm:3.0.7" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/bbaa33c274a10f70d3a587264e1db6dbfcd8c1458d595c54870d1d5b3fc113ab5063203ec12a098485bb9e2fcef1a87d8c6ecd2a6d44ddc575f5c4715379be5e + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -2655,14 +2736,14 @@ __metadata: languageName: node linkType: hard -"@listr2/prompt-adapter-inquirer@npm:2.0.18": - version: 2.0.18 - resolution: "@listr2/prompt-adapter-inquirer@npm:2.0.18" +"@listr2/prompt-adapter-inquirer@npm:2.0.22": + version: 2.0.22 + resolution: "@listr2/prompt-adapter-inquirer@npm:2.0.22" dependencies: "@inquirer/type": "npm:^1.5.5" peerDependencies: "@inquirer/prompts": ">= 3 < 8" - checksum: 10c0/580d2f0ae414cf3090c2fbfe4623649e448d930b3ff24b0211e64e0e037f1a3ffff5307bc36c10cdc0c4a35fc12f04190585e864c4ce05fbf5f062b41ff29e40 + checksum: 10c0/861fd7c66122551d078b10bfaf8927255be1e9169ed4b6b8844c323bfa1a6da7628dc0b0eb15c6830741d1d87f3b137131388a4f57bcc896b37a68e40cebe615 languageName: node linkType: hard @@ -3564,14 +3645,14 @@ __metadata: languageName: node linkType: hard -"@schematics/angular@npm:19.2.10": - version: 19.2.10 - resolution: "@schematics/angular@npm:19.2.10" +"@schematics/angular@npm:20.0.4": + version: 20.0.4 + resolution: "@schematics/angular@npm:20.0.4" dependencies: - "@angular-devkit/core": "npm:19.2.10" - "@angular-devkit/schematics": "npm:19.2.10" + "@angular-devkit/core": "npm:20.0.4" + "@angular-devkit/schematics": "npm:20.0.4" jsonc-parser: "npm:3.3.1" - checksum: 10c0/dd6bc6aaf762ee58ec1675b088464c9b45b4734f18ed53179a95ed3be5fb7e1792c6e858c635de85d42143882bfb8df5f2f238d408cd0967e7de02f07a7b10be + checksum: 10c0/446d1eafcee89cf6fcd4ae881dbafe7d5e47a32925dcf84eda94200be0c1d433eaa825e704a39007912265b3816cabd67b3752fa20d449d12df992ec82ee6703 languageName: node linkType: hard @@ -5951,6 +6032,13 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^5.3.0": + version: 5.4.1 + resolution: "chalk@npm:5.4.1" + checksum: 10c0/b23e88132c702f4855ca6d25cb5538b1114343e41472d5263ee8a37cccfccd9c4216d111e1097c6a27830407a1dc81fecdf2a56f2c63033d4dbbd88c10b0dcef + languageName: node + linkType: hard + "chardet@npm:^0.7.0": version: 0.7.0 resolution: "chardet@npm:0.7.0" @@ -6090,7 +6178,7 @@ __metadata: languageName: node linkType: hard -"cli-spinners@npm:^2.5.0": +"cli-spinners@npm:^2.5.0, cli-spinners@npm:^2.9.2": version: 2.9.2 resolution: "cli-spinners@npm:2.9.2" checksum: 10c0/907a1c227ddf0d7a101e7ab8b300affc742ead4b4ebe920a5bf1bc6d45dce2958fcd195eb28fa25275062fe6fa9b109b93b63bc8033396ed3bcb50297008b3a3 @@ -9954,6 +10042,13 @@ __metadata: languageName: node linkType: hard +"is-interactive@npm:^2.0.0": + version: 2.0.0 + resolution: "is-interactive@npm:2.0.0" + checksum: 10c0/801c8f6064f85199dc6bf99b5dd98db3282e930c3bc197b32f2c5b89313bb578a07d1b8a01365c4348c2927229234f3681eb861b9c2c92bee72ff397390fa600 + languageName: node + linkType: hard + "is-ip@npm:^3.1.0": version: 3.1.0 resolution: "is-ip@npm:3.1.0" @@ -10174,6 +10269,20 @@ __metadata: languageName: node linkType: hard +"is-unicode-supported@npm:^1.3.0": + version: 1.3.0 + resolution: "is-unicode-supported@npm:1.3.0" + checksum: 10c0/b8674ea95d869f6faabddc6a484767207058b91aea0250803cbf1221345cb0c56f466d4ecea375dc77f6633d248d33c47bd296fb8f4cdba0b4edba8917e83d8a + languageName: node + linkType: hard + +"is-unicode-supported@npm:^2.0.0": + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 + languageName: node + linkType: hard + "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -11076,6 +11185,20 @@ __metadata: languageName: node linkType: hard +"listr2@npm:8.3.3": + version: 8.3.3 + resolution: "listr2@npm:8.3.3" + dependencies: + cli-truncate: "npm:^4.0.0" + colorette: "npm:^2.0.20" + eventemitter3: "npm:^5.0.1" + log-update: "npm:^6.1.0" + rfdc: "npm:^1.4.1" + wrap-ansi: "npm:^9.0.0" + checksum: 10c0/0792f8a7fd482fa516e21689e012e07081cab3653172ca606090622cfa0024c784a1eba8095a17948a0e9a4aa98a80f7c9c90f78a0dd35173d6802f9cc123a82 + languageName: node + linkType: hard + "lmdb@npm:3.2.6": version: 3.2.6 resolution: "lmdb@npm:3.2.6" @@ -11213,6 +11336,16 @@ __metadata: languageName: node linkType: hard +"log-symbols@npm:^6.0.0": + version: 6.0.0 + resolution: "log-symbols@npm:6.0.0" + dependencies: + chalk: "npm:^5.3.0" + is-unicode-supported: "npm:^1.3.0" + checksum: 10c0/36636cacedba8f067d2deb4aad44e91a89d9efb3ead27e1846e7b82c9a10ea2e3a7bd6ce28a7ca616bebc60954ff25c67b0f92d20a6a746bb3cc52c3701891f6 + languageName: node + linkType: hard + "log-update@npm:^4.0.0": version: 4.0.0 resolution: "log-update@npm:4.0.0" @@ -12012,7 +12145,7 @@ __metadata: "@angular-eslint/template-parser": "npm:^18.0.0" "@angular/animations": "npm:^19.1.4" "@angular/cdk": "npm:^18.2.14" - "@angular/cli": "npm:^19.1.6" + "@angular/cli": "npm:^20.0.4" "@angular/common": "npm:^19.1.4" "@angular/compiler": "npm:^19.1.4" "@angular/compiler-cli": "npm:^19.1.4" @@ -12223,12 +12356,12 @@ __metadata: languageName: node linkType: hard -"npm-packlist@npm:^9.0.0": - version: 9.0.0 - resolution: "npm-packlist@npm:9.0.0" +"npm-packlist@npm:^10.0.0": + version: 10.0.0 + resolution: "npm-packlist@npm:10.0.0" dependencies: ignore-walk: "npm:^7.0.0" - checksum: 10c0/3eb9e877fff81ed1f97b86a387a13a7d0136a26c4c21d8fab7e49be653e71d604ba63091ec80e3a0b1d1fd879639eab91ddda1a8df45d7631795b83911f2f9b8 + checksum: 10c0/be8cb82c4f9b6fdfba2e3379c538949d3ea7aeb303436db013aaccd8ad1ff49d9f894d7fa4684f9d3016b7944dcc3f0bfc8c3d10c535fa7cd29314a8aad4b80f languageName: node linkType: hard @@ -12556,6 +12689,23 @@ __metadata: languageName: node linkType: hard +"ora@npm:8.2.0": + version: 8.2.0 + resolution: "ora@npm:8.2.0" + dependencies: + chalk: "npm:^5.3.0" + cli-cursor: "npm:^5.0.0" + cli-spinners: "npm:^2.9.2" + is-interactive: "npm:^2.0.0" + is-unicode-supported: "npm:^2.0.0" + log-symbols: "npm:^6.0.0" + stdin-discarder: "npm:^0.2.2" + string-width: "npm:^7.2.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/7d9291255db22e293ea164f520b6042a3e906576ab06c9cf408bf9ef5664ba0a9f3bd258baa4ada058cfcc2163ef9b6696d51237a866682ce33295349ba02c3a + languageName: node + linkType: hard + "ordered-binary@npm:^1.5.3": version: 1.5.3 resolution: "ordered-binary@npm:1.5.3" @@ -12718,9 +12868,9 @@ __metadata: languageName: node linkType: hard -"pacote@npm:20.0.0": - version: 20.0.0 - resolution: "pacote@npm:20.0.0" +"pacote@npm:21.0.0": + version: 21.0.0 + resolution: "pacote@npm:21.0.0" dependencies: "@npmcli/git": "npm:^6.0.0" "@npmcli/installed-package-contents": "npm:^3.0.0" @@ -12731,7 +12881,7 @@ __metadata: fs-minipass: "npm:^3.0.0" minipass: "npm:^7.0.2" npm-package-arg: "npm:^12.0.0" - npm-packlist: "npm:^9.0.0" + npm-packlist: "npm:^10.0.0" npm-pick-manifest: "npm:^10.0.0" npm-registry-fetch: "npm:^18.0.0" proc-log: "npm:^5.0.0" @@ -12741,7 +12891,7 @@ __metadata: tar: "npm:^6.1.11" bin: pacote: bin/index.js - checksum: 10c0/435c385446ecc81b1eb1584f4fa3cb102e630a22877f39b5c1a92eddfeaf222bd027b205e32632be2801e3bcbe525165cdffb5ceca5c13bbc81f8132fe1ba49e + checksum: 10c0/406eabb2185f87526f07b2b7540a96c91f07c8782f9d1651ef022844f021922ee1507161c43dd16616ab3f15a2d13a1bfe217bfd79731020c725373c4e713022 languageName: node linkType: hard @@ -14087,7 +14237,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.8.1, rxjs@npm:~7.8.1": +"rxjs@npm:7.8.2, rxjs@npm:^7.8.1, rxjs@npm:~7.8.1": version: 7.8.2 resolution: "rxjs@npm:7.8.2" dependencies: @@ -14355,6 +14505,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:7.7.2": + version: 7.7.2 + resolution: "semver@npm:7.7.2" + bin: + semver: bin/semver.js + checksum: 10c0/aca305edfbf2383c22571cb7714f48cadc7ac95371b4b52362fb8eeffdfbc0de0669368b82b2b15978f8848f01d7114da65697e56cd8c37b0dab8c58e543f9ea + languageName: node + linkType: hard + "semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -14987,6 +15146,13 @@ __metadata: languageName: node linkType: hard +"stdin-discarder@npm:^0.2.2": + version: 0.2.2 + resolution: "stdin-discarder@npm:0.2.2" + checksum: 10c0/c78375e82e956d7a64be6e63c809c7f058f5303efcaf62ea48350af072bacdb99c06cba39209b45a071c1acbd49116af30df1df9abb448df78a6005b72f10537 + languageName: node + linkType: hard + "streamroller@npm:^3.1.5": version: 3.1.5 resolution: "streamroller@npm:3.1.5" @@ -15034,7 +15200,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^7.0.0": +"string-width@npm:^7.0.0, string-width@npm:^7.2.0": version: 7.2.0 resolution: "string-width@npm:7.2.0" dependencies: @@ -15220,13 +15386,6 @@ __metadata: languageName: node linkType: hard -"symbol-observable@npm:4.0.0": - version: 4.0.0 - resolution: "symbol-observable@npm:4.0.0" - checksum: 10c0/5e9a3ab08263a6be8cbee76587ad5880dcc62a47002787ed5ebea56b1eb30dc87da6f0183d67e88286806799fbe21c69077fbd677be4be2188e92318d6c6f31d - languageName: node - linkType: hard - "table-layout@npm:^4.1.0": version: 4.1.1 resolution: "table-layout@npm:4.1.1" From 71ecabbfa5152be6a7594a50c16b69cf439d6ae7 Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Thu, 26 Jun 2025 14:59:20 -0500 Subject: [PATCH 101/105] upgrade node and yarn --- .github/workflows/test_and_deploy.yml | 4 ++-- package.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index 6537d72aa..e104e032e 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -12,13 +12,13 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: 20.17.0 + node-version: 22.16.0 - name: Enable Corepack run: corepack enable - name: Install Yarn - run: corepack prepare yarn@4.5.1 --activate + run: corepack prepare yarn@4.9.2 --activate - name: Install dependencies run: yarn install --immutable diff --git a/package.json b/package.json index 1e0864d37..f3992f2cf 100644 --- a/package.json +++ b/package.json @@ -103,8 +103,8 @@ } }, "volta": { - "node": "20.14.0", - "yarn": "4.5.1" + "node": "22.16.0", + "yarn": "4.9.2" }, - "packageManager": "yarn@4.5.1" + "packageManager": "yarn@4.9.2" } From b3319760fe5847e58024c90bc2cea8db50a3bea9 Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Thu, 26 Jun 2025 15:01:11 -0500 Subject: [PATCH 102/105] upgraded angular packages to v20 --- package.json | 22 +- .../src/lib/directives/orderable.directive.ts | 5 +- .../lib/services/scrollbar-helper.service.ts | 3 +- yarn.lock | 312 ++++++++++++------ 4 files changed, 227 insertions(+), 115 deletions(-) diff --git a/package.json b/package.json index f3992f2cf..fa80f7310 100644 --- a/package.json +++ b/package.json @@ -31,15 +31,15 @@ }, "private": true, "dependencies": { - "@angular/animations": "^19.1.4", + "@angular/animations": "^20.0.5", "@angular/cdk": "^18.2.14", - "@angular/common": "^19.1.4", - "@angular/compiler": "^19.1.4", - "@angular/core": "^19.1.4", - "@angular/forms": "^19.1.4", - "@angular/platform-browser": "^19.1.4", - "@angular/platform-browser-dynamic": "^19.1.4", - "@angular/router": "^19.1.4", + "@angular/common": "^20.0.5", + "@angular/compiler": "^20.0.5", + "@angular/core": "^20.0.5", + "@angular/forms": "^20.0.5", + "@angular/platform-browser": "^20.0.5", + "@angular/platform-browser-dynamic": "^20.0.5", + "@angular/router": "^20.0.5", "rxjs": "~7.8.1", "tslib": "~2.4.0", "zone.js": "~0.15.0" @@ -54,8 +54,8 @@ "@angular-eslint/schematics": "^18.0.0", "@angular-eslint/template-parser": "^18.0.0", "@angular/cli": "^20.0.4", - "@angular/compiler-cli": "^19.1.4", - "@angular/language-service": "^19.1.4", + "@angular/compiler-cli": "^20.0.5", + "@angular/language-service": "^20.0.5", "@swimlane/eslint-config": "^2.0.0", "@swimlane/prettier-config-swimlane": "^3.0.2", "@types/jasmine": "4.3.0", @@ -95,7 +95,7 @@ "sass": "^1.77.6", "scss-bundle": "^3.1.1", "ts-node": "10.9.1", - "typescript": "5.7.3" + "typescript": "5.8.3" }, "husky": { "hooks": { diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts index 10d82270a..61dda470f 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts @@ -9,10 +9,11 @@ import { KeyValueDiffers, OnDestroy, Output, - QueryList + QueryList, + DOCUMENT } from '@angular/core'; import { DraggableDirective } from './draggable.directive'; -import { DOCUMENT } from '@angular/common'; + import { DraggableDragEvent, ReorderEventInternal, diff --git a/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts b/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts index 11d201688..65cfe804e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts +++ b/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts @@ -1,5 +1,4 @@ -import { inject, Injectable } from '@angular/core'; -import { DOCUMENT } from '@angular/common'; +import { inject, Injectable, DOCUMENT } from '@angular/core'; /** * Gets the width of the scrollbar. Nesc for windows diff --git a/yarn.lock b/yarn.lock index 2ffac1d20..435dc46d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -397,15 +397,15 @@ __metadata: languageName: node linkType: hard -"@angular/animations@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/animations@npm:19.2.9" +"@angular/animations@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/animations@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 19.2.9 - "@angular/core": 19.2.9 - checksum: 10c0/b58683994612ef0a44cd6f4f3c9d0cc4d2ea517d997f5e25dc45d812a7dddc00ee2a59f8dd152d0229c3036df4e1d30a1812c9fc27ee262d5904e9269c49157b + "@angular/common": 20.0.5 + "@angular/core": 20.0.5 + checksum: 10c0/2a28ad56cceadfeb023fad774f0e970135435f17ef53d963f273d5f3eb6b7b547c6913a5108b2b6544395c3a24c50d66226aa66c58de9443547715d4dedd9541 languageName: node linkType: hard @@ -522,124 +522,132 @@ __metadata: languageName: node linkType: hard -"@angular/common@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/common@npm:19.2.9" +"@angular/common@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/common@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/core": 19.2.9 + "@angular/core": 20.0.5 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/5f5367b1ca81f1c346cebec5cf4e5ba0b1187b8b0a0638bea7030e4d6d82339d852651c011c8a527e0864db334829a294c747d1a3828bdd530fdf7dccffd5e4f + checksum: 10c0/0e496406f734797b8858432671e8d8843e0308b545ea99cada67cf325741340069efc2ca83c34499d154181f053b0852736a66aa9484e6e66bd4c860641f49f1 languageName: node linkType: hard -"@angular/compiler-cli@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/compiler-cli@npm:19.2.9" +"@angular/compiler-cli@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/compiler-cli@npm:20.0.5" dependencies: - "@babel/core": "npm:7.26.9" + "@babel/core": "npm:7.27.4" "@jridgewell/sourcemap-codec": "npm:^1.4.14" chokidar: "npm:^4.0.0" convert-source-map: "npm:^1.5.1" reflect-metadata: "npm:^0.2.0" semver: "npm:^7.0.0" tslib: "npm:^2.3.0" - yargs: "npm:^17.2.1" + yargs: "npm:^18.0.0" peerDependencies: - "@angular/compiler": 19.2.9 - typescript: ">=5.5 <5.9" + "@angular/compiler": 20.0.5 + typescript: ">=5.8 <5.9" + peerDependenciesMeta: + typescript: + optional: true bin: ng-xi18n: bundles/src/bin/ng_xi18n.js ngc: bundles/src/bin/ngc.js - ngcc: bundles/ngcc/index.js - checksum: 10c0/2edd9bad1fe6dda2c1b214ac1942695c6e2818c0d2d8f296153ebb5f94fc5b477627002892e73e5b384e059953c19263504964c5850c4f7626f6106239e1c612 + checksum: 10c0/219a1a5db601507af59b335c0ccb37fabbdd389b64ddc1a835414a87a9dc10b30827e0c76b86121b03f96b38d46db86c876d544d53f6e442dba4632d2ddd42b0 languageName: node linkType: hard -"@angular/compiler@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/compiler@npm:19.2.9" +"@angular/compiler@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/compiler@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" - checksum: 10c0/63fe1e3f9f9ce81c79ae674bfbb15b4391d90fba9a19f26c424c6cdbb6d075e71fc48c6ba8cedeab3fe4aa8a6138f1a6ff63a0290d8b0e3af0744a0dc45f4fbe + checksum: 10c0/fcf106f28c29b262f4e0a9774c00a4ad9a671df0e55abcfa9a40f27327d85aca13093e52ba3ed5f68aa962a1aa6aa08792e34a43f5088a65bd5cf0f52986a510 languageName: node linkType: hard -"@angular/core@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/core@npm:19.2.9" +"@angular/core@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/core@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" peerDependencies: + "@angular/compiler": 20.0.5 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 - checksum: 10c0/c53fe99fed7cd5317d7c1cbe493a18fb7f09f04962119d74d1f924029d8ba924150563aa188bc08404810d167e08b71ab023bfa81d0af1f2b608956cd2a4219e + peerDependenciesMeta: + "@angular/compiler": + optional: true + zone.js: + optional: true + checksum: 10c0/0c77d18163335253687f1ea885789657ed818f1ff81a9a776153ee60601674c332a27f733ddcd7ac7bea511d38dd5ee43f12de91f14f2635ff9c1b905e5b4ce9 languageName: node linkType: hard -"@angular/forms@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/forms@npm:19.2.9" +"@angular/forms@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/forms@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 19.2.9 - "@angular/core": 19.2.9 - "@angular/platform-browser": 19.2.9 + "@angular/common": 20.0.5 + "@angular/core": 20.0.5 + "@angular/platform-browser": 20.0.5 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/d45fb669066af1285cc79b42d84158271222ea653c70176387d72bd62b87dbd3fc82ed6449ee1ad5cbeeebdb1f35dda5ef27580f53874ddf58ce991f64270c65 + checksum: 10c0/544704c95009218d464aea803ffc750963c7fab1e69c1f49a328240f8a2a8323d0c3af0da3d4ee4c895398a24cc30e653b7cace56226add1435342def0b76e1c languageName: node linkType: hard -"@angular/language-service@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/language-service@npm:19.2.9" - checksum: 10c0/81886eabedeedc106a5311e4bfa8a4802411023f3225e27bc54081517b57b1cebdb84794f8857243a8a3c41b3ee1895ff0ff51be1407edf6f37cb4c489529d62 +"@angular/language-service@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/language-service@npm:20.0.5" + checksum: 10c0/478d713ccfb6d571b037b43a8d0b6a0721a6f3ef09a1b2d69709bac0c552ee9a49c9b3c6d682d94ebe2a90b32f93d0755c7b80658434742dc398895b66921505 languageName: node linkType: hard -"@angular/platform-browser-dynamic@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/platform-browser-dynamic@npm:19.2.9" +"@angular/platform-browser-dynamic@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/platform-browser-dynamic@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 19.2.9 - "@angular/compiler": 19.2.9 - "@angular/core": 19.2.9 - "@angular/platform-browser": 19.2.9 - checksum: 10c0/39ef227907fe169fee370521aab97077183948099edb7117067038a33ed72be32dfc84058afb90ca713752cec7be7282a60b17d4a684febf62fbe204c4604684 + "@angular/common": 20.0.5 + "@angular/compiler": 20.0.5 + "@angular/core": 20.0.5 + "@angular/platform-browser": 20.0.5 + checksum: 10c0/ad0b7a39799592bc33f4511c38d0b03629c4536e3bd1f7dc7d7e550548858bf4509b7260c9f1f604f68400ed303c43e3e50c23a947c318c390621bbbaa851b29 languageName: node linkType: hard -"@angular/platform-browser@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/platform-browser@npm:19.2.9" +"@angular/platform-browser@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/platform-browser@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/animations": 19.2.9 - "@angular/common": 19.2.9 - "@angular/core": 19.2.9 + "@angular/animations": 20.0.5 + "@angular/common": 20.0.5 + "@angular/core": 20.0.5 peerDependenciesMeta: "@angular/animations": optional: true - checksum: 10c0/069597039feb51be3ec3dd18f48432cd47a612400e16937b2e93483ecf6daa0d89fab573d55daf220c8d878f8d822d5e9c1bf5bdb7824bd2df3f43785405d209 + checksum: 10c0/44c1add8d39e738906cecd5e0efa9a84033b17dc452b44ed076aab2850d0024a5771e9fc4e00b558a2947ae3a2ad9660e7fd2ba35d35a4944d76d87403e28743 languageName: node linkType: hard -"@angular/router@npm:^19.1.4": - version: 19.2.9 - resolution: "@angular/router@npm:19.2.9" +"@angular/router@npm:^20.0.5": + version: 20.0.5 + resolution: "@angular/router@npm:20.0.5" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 19.2.9 - "@angular/core": 19.2.9 - "@angular/platform-browser": 19.2.9 + "@angular/common": 20.0.5 + "@angular/core": 20.0.5 + "@angular/platform-browser": 20.0.5 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/78d906af2d3c6a26d853a349f33922f9e68c08174bf7acce3f7c84b9f3635c46b658500f49f630d762455c6b006e58500ae54df5224c661d47e9193405494f8e + checksum: 10c0/746bf7e9ee0ca112b4b0364fb5f0d39329df164f4adf68bddf1181a4f1d8e3062af4689adb1903ea59e0e51cad7c18fd7b4b251ab20e8c8ea50b426077ac9892 languageName: node linkType: hard @@ -684,26 +692,26 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:7.26.9": - version: 7.26.9 - resolution: "@babel/core@npm:7.26.9" +"@babel/core@npm:7.27.4": + version: 7.27.4 + resolution: "@babel/core@npm:7.27.4" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.9" - "@babel/helper-compilation-targets": "npm:^7.26.5" - "@babel/helper-module-transforms": "npm:^7.26.0" - "@babel/helpers": "npm:^7.26.9" - "@babel/parser": "npm:^7.26.9" - "@babel/template": "npm:^7.26.9" - "@babel/traverse": "npm:^7.26.9" - "@babel/types": "npm:^7.26.9" + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.27.3" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-module-transforms": "npm:^7.27.3" + "@babel/helpers": "npm:^7.27.4" + "@babel/parser": "npm:^7.27.4" + "@babel/template": "npm:^7.27.2" + "@babel/traverse": "npm:^7.27.4" + "@babel/types": "npm:^7.27.3" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/ed7212ff42a9453765787019b7d191b167afcacd4bd8fec10b055344ef53fa0cc648c9a80159ae4ecf870016a6318731e087042dcb68d1a2a9d34eb290dc014b + checksum: 10c0/d2d17b106a8d91d3eda754bb3f26b53a12eb7646df73c2b2d2e9b08d90529186bc69e3823f70a96ec6e5719dc2372fb54e14ad499da47ceeb172d2f7008787b5 languageName: node linkType: hard @@ -743,7 +751,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.26.10, @babel/generator@npm:^7.26.9, @babel/generator@npm:^7.27.1": +"@babel/generator@npm:^7.26.10, @babel/generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/generator@npm:7.27.1" dependencies: @@ -756,6 +764,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.27.3, @babel/generator@npm:^7.27.5": + version: 7.27.5 + resolution: "@babel/generator@npm:7.27.5" + dependencies: + "@babel/parser": "npm:^7.27.5" + "@babel/types": "npm:^7.27.3" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^3.0.2" + checksum: 10c0/8f649ef4cd81765c832bb11de4d6064b035ffebdecde668ba7abee68a7b0bce5c9feabb5dc5bb8aeba5bd9e5c2afa3899d852d2bd9ca77a711ba8c8379f416f0 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:7.25.9": version: 7.25.9 resolution: "@babel/helper-annotate-as-pure@npm:7.25.9" @@ -865,6 +886,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helper-module-transforms@npm:7.27.3" + dependencies: + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.3" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/fccb4f512a13b4c069af51e1b56b20f54024bcf1591e31e978a30f3502567f34f90a80da6a19a6148c249216292a8074a0121f9e52602510ef0f32dbce95ca01 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" @@ -958,7 +992,7 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.26.10, @babel/helpers@npm:^7.26.9, @babel/helpers@npm:^7.27.1": +"@babel/helpers@npm:^7.26.10, @babel/helpers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helpers@npm:7.27.1" dependencies: @@ -968,7 +1002,17 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.14.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.26.9, @babel/parser@npm:^7.27.1, @babel/parser@npm:^7.27.2": +"@babel/helpers@npm:^7.27.4": + version: 7.27.6 + resolution: "@babel/helpers@npm:7.27.6" + dependencies: + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.27.6" + checksum: 10c0/448bac96ef8b0f21f2294a826df9de6bf4026fd023f8a6bb6c782fe3e61946801ca24381490b8e58d861fee75cd695a1882921afbf1f53b0275ee68c938bd6d3 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.14.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.27.1, @babel/parser@npm:^7.27.2": version: 7.27.2 resolution: "@babel/parser@npm:7.27.2" dependencies: @@ -979,6 +1023,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.27.4, @babel/parser@npm:^7.27.5, @babel/parser@npm:^7.27.7": + version: 7.27.7 + resolution: "@babel/parser@npm:7.27.7" + dependencies: + "@babel/types": "npm:^7.27.7" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/f6202faeb873f0b3083022e50a5046fe07266d337c0a3bd80a491f8435ba6d9e383d49725e3dcd666b3b52c0dccb4e0f1f1004915762345f7eeed5ba54ea9fd2 + languageName: node + linkType: hard + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.9": version: 7.27.1 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.27.1" @@ -1822,7 +1877,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.26.9, @babel/template@npm:^7.27.1": +"@babel/template@npm:^7.26.9, @babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2": version: 7.27.2 resolution: "@babel/template@npm:7.27.2" dependencies: @@ -1833,7 +1888,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.26.8, @babel/traverse@npm:^7.26.9, @babel/traverse@npm:^7.27.1": +"@babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.26.8, @babel/traverse@npm:^7.27.1": version: 7.27.1 resolution: "@babel/traverse@npm:7.27.1" dependencies: @@ -1848,7 +1903,22 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.26.9, @babel/types@npm:^7.27.1, @babel/types@npm:^7.4.4": +"@babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.27.4": + version: 7.27.7 + resolution: "@babel/traverse@npm:7.27.7" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.27.5" + "@babel/parser": "npm:^7.27.7" + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.27.7" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10c0/941fecd0248546f059d58230590a2765d128ef072c8521c9e0bcf6037abf28a0ea4736003d0d695513128d07fe00a7bc57acaada2ed905941d44619b9f49cf0c + languageName: node + linkType: hard + +"@babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.4.4": version: 7.27.1 resolution: "@babel/types@npm:7.27.1" dependencies: @@ -1858,6 +1928,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.27.3, @babel/types@npm:^7.27.6, @babel/types@npm:^7.27.7": + version: 7.27.7 + resolution: "@babel/types@npm:7.27.7" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + checksum: 10c0/1d1dcb5fa7cfba2b4034a3ab99ba17049bfc4af9e170935575246cdb1cee68b04329a0111506d9ae83fb917c47dbd4394a6db5e32fbd041b7834ffbb17ca086b + languageName: node + linkType: hard + "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -6235,6 +6315,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^9.0.1": + version: 9.0.1 + resolution: "cliui@npm:9.0.1" + dependencies: + string-width: "npm:^7.2.0" + strip-ansi: "npm:^7.1.0" + wrap-ansi: "npm:^9.0.0" + checksum: 10c0/13441832e9efe7c7a76bd2b8e683555c478d461a9f249dc5db9b17fe8d4b47fa9277b503914b90bd00e4a151abb6b9b02b2288972ffe2e5e3ca40bcb1c2330d3 + languageName: node + linkType: hard + "clone-deep@npm:^4.0.1": version: 4.0.1 resolution: "clone-deep@npm:4.0.1" @@ -12143,18 +12234,18 @@ __metadata: "@angular-eslint/eslint-plugin-template": "npm:^18.0.0" "@angular-eslint/schematics": "npm:^18.0.0" "@angular-eslint/template-parser": "npm:^18.0.0" - "@angular/animations": "npm:^19.1.4" + "@angular/animations": "npm:^20.0.5" "@angular/cdk": "npm:^18.2.14" "@angular/cli": "npm:^20.0.4" - "@angular/common": "npm:^19.1.4" - "@angular/compiler": "npm:^19.1.4" - "@angular/compiler-cli": "npm:^19.1.4" - "@angular/core": "npm:^19.1.4" - "@angular/forms": "npm:^19.1.4" - "@angular/language-service": "npm:^19.1.4" - "@angular/platform-browser": "npm:^19.1.4" - "@angular/platform-browser-dynamic": "npm:^19.1.4" - "@angular/router": "npm:^19.1.4" + "@angular/common": "npm:^20.0.5" + "@angular/compiler": "npm:^20.0.5" + "@angular/compiler-cli": "npm:^20.0.5" + "@angular/core": "npm:^20.0.5" + "@angular/forms": "npm:^20.0.5" + "@angular/language-service": "npm:^20.0.5" + "@angular/platform-browser": "npm:^20.0.5" + "@angular/platform-browser-dynamic": "npm:^20.0.5" + "@angular/router": "npm:^20.0.5" "@swimlane/eslint-config": "npm:^2.0.0" "@swimlane/prettier-config-swimlane": "npm:^3.0.2" "@types/jasmine": "npm:4.3.0" @@ -12196,7 +12287,7 @@ __metadata: scss-bundle: "npm:^3.1.1" ts-node: "npm:10.9.1" tslib: "npm:~2.4.0" - typescript: "npm:5.7.3" + typescript: "npm:5.8.3" zone.js: "npm:~0.15.0" languageName: unknown linkType: soft @@ -15876,23 +15967,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.7.3": - version: 5.7.3 - resolution: "typescript@npm:5.7.3" +"typescript@npm:5.8.3": + version: 5.8.3 + resolution: "typescript@npm:5.8.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa + checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.7.3#optional!builtin": - version: 5.7.3 - resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin::version=5.7.3&hash=cef18b" +"typescript@patch:typescript@npm%3A5.8.3#optional!builtin": + version: 5.8.3 + resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/3b56d6afa03d9f6172d0b9cdb10e6b1efc9abc1608efd7a3d2f38773d5d8cfb9bbc68dfb72f0a7de5e8db04fc847f4e4baeddcd5ad9c9feda072234f0d788896 + checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb languageName: node linkType: hard @@ -16769,7 +16860,14 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.2.1, yargs@npm:^17.7.2": +"yargs-parser@npm:^22.0.0": + version: 22.0.0 + resolution: "yargs-parser@npm:22.0.0" + checksum: 10c0/cb7ef81759c4271cb1d96b9351dbbc9a9ce35d3e1122d2b739bf6c432603824fa02c67cc12dcef6ea80283379d63495686e8f41cc7b06c6576e792aba4d33e1c + languageName: node + linkType: hard + +"yargs@npm:17.7.2, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -16818,6 +16916,20 @@ __metadata: languageName: node linkType: hard +"yargs@npm:^18.0.0": + version: 18.0.0 + resolution: "yargs@npm:18.0.0" + dependencies: + cliui: "npm:^9.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + string-width: "npm:^7.2.0" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^22.0.0" + checksum: 10c0/bf290e4723876ea9c638c786a5c42ac28e03c9ca2325e1424bf43b94e5876456292d3ed905b853ebbba6daf43ed29e772ac2a6b3c5fb1b16533245d6211778f3 + languageName: node + linkType: hard + "yauzl@npm:^2.10.0": version: 2.10.0 resolution: "yauzl@npm:2.10.0" From 9b25059d0b5cfe0b3e9d95d031d70864bb9433ae Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Thu, 26 Jun 2025 15:09:37 -0500 Subject: [PATCH 103/105] upgraded the rest of the angular packages and removed support for angular 17 and earlier versions --- package.json | 20 +- projects/swimlane/ngx-datatable/package.json | 6 +- yarn.lock | 2003 ++++++++---------- 3 files changed, 899 insertions(+), 1130 deletions(-) diff --git a/package.json b/package.json index fa80f7310..4f633e306 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "private": true, "dependencies": { "@angular/animations": "^20.0.5", - "@angular/cdk": "^18.2.14", + "@angular/cdk": "^20.0.4", "@angular/common": "^20.0.5", "@angular/compiler": "^20.0.5", "@angular/core": "^20.0.5", @@ -45,14 +45,14 @@ "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.1.4", - "@angular-devkit/core": "^19.1.4", - "@angular-devkit/schematics": "^19.1.4", - "@angular-eslint/builder": "^18.0.0", - "@angular-eslint/eslint-plugin": "^18.0.0", - "@angular-eslint/eslint-plugin-template": "^18.0.0", - "@angular-eslint/schematics": "^18.0.0", - "@angular-eslint/template-parser": "^18.0.0", + "@angular-devkit/build-angular": "^20.0.4", + "@angular-devkit/core": "^20.0.4", + "@angular-devkit/schematics": "^20.0.4", + "@angular-eslint/builder": "^20.1.1", + "@angular-eslint/eslint-plugin": "^20.1.1", + "@angular-eslint/eslint-plugin-template": "^20.1.1", + "@angular-eslint/schematics": "^20.1.1", + "@angular-eslint/template-parser": "^20.1.1", "@angular/cli": "^20.0.4", "@angular/compiler-cli": "^20.0.5", "@angular/language-service": "^20.0.5", @@ -87,7 +87,7 @@ "karma-coverage-istanbul-reporter": "^3.0.3", "karma-jasmine": "5.1.0", "karma-jasmine-html-reporter": "2.0.0", - "ng-packagr": "^19.0.0", + "ng-packagr": "^20.0.1", "npm-run-all": "^4.1.5", "prettier": "2.7.1", "pretty-quick": "3.1.3", diff --git a/projects/swimlane/ngx-datatable/package.json b/projects/swimlane/ngx-datatable/package.json index f877c8cc8..2d4e2c6f2 100644 --- a/projects/swimlane/ngx-datatable/package.json +++ b/projects/swimlane/ngx-datatable/package.json @@ -3,9 +3,9 @@ "version": "21.1.0", "description": "ngx-datatable is an Angular table grid component for presenting large and complex data.", "peerDependencies": { - "@angular/common": "17.x || 18.x || 19.x", - "@angular/core": "17.x || 18.x || 19.x", - "@angular/platform-browser": "17.x || 18.x || 19.x", + "@angular/common": "18.x || 19.x || 20.x", + "@angular/core": "18.x || 19.x || 20.x", + "@angular/platform-browser": "18.x || 19.x || 20.x", "rxjs": "7.x" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index 435dc46d1..1fad1face 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,7 +5,7 @@ __metadata: version: 8 cacheKey: 10c0 -"@ampproject/remapping@npm:2.3.0, @ampproject/remapping@npm:^2.2.0": +"@ampproject/remapping@npm:2.3.0, @ampproject/remapping@npm:^2.2.0, @ampproject/remapping@npm:^2.3.0": version: 2.3.0 resolution: "@ampproject/remapping@npm:2.3.0" dependencies: @@ -15,17 +15,7 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/architect@npm:0.1902.10": - version: 0.1902.10 - resolution: "@angular-devkit/architect@npm:0.1902.10" - dependencies: - "@angular-devkit/core": "npm:19.2.10" - rxjs: "npm:7.8.1" - checksum: 10c0/4ce187452618041674ea9b3533183a580a3c0c11c4bc25985801a82b6f02d55e4ab21e25a26f8394deced831accf586225bcd02ed40227f818f2b1636fe00f92 - languageName: node - linkType: hard - -"@angular-devkit/architect@npm:0.2000.4": +"@angular-devkit/architect@npm:0.2000.4, @angular-devkit/architect@npm:>= 0.2000.0 < 0.2100.0": version: 0.2000.4 resolution: "@angular-devkit/architect@npm:0.2000.4" dependencies: @@ -35,21 +25,6 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/architect@npm:>= 0.1800.0 < 0.1900.0": - version: 0.1802.19 - resolution: "@angular-devkit/architect@npm:0.1802.19" - dependencies: - "@angular-devkit/core": "npm:18.2.19" - rxjs: "npm:7.8.1" - dependenciesMeta: - esbuild: - built: true - puppeteer: - built: true - checksum: 10c0/9a81e1e5357ddd6160eedf4ed40ca01b6092f377ef5969e67f0a4c577764a3a52b23011c8a85b5374dcf48ec23fe5cb8ca3577696476cd1838751e492259afcd - languageName: node - linkType: hard - "@angular-devkit/architect@npm:~0.1800.0": version: 0.1800.7 resolution: "@angular-devkit/architect@npm:0.1800.7" @@ -60,87 +35,93 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/build-angular@npm:^19.1.4": - version: 19.2.10 - resolution: "@angular-devkit/build-angular@npm:19.2.10" +"@angular-devkit/build-angular@npm:^20.0.4": + version: 20.0.4 + resolution: "@angular-devkit/build-angular@npm:20.0.4" dependencies: "@ampproject/remapping": "npm:2.3.0" - "@angular-devkit/architect": "npm:0.1902.10" - "@angular-devkit/build-webpack": "npm:0.1902.10" - "@angular-devkit/core": "npm:19.2.10" - "@angular/build": "npm:19.2.10" - "@babel/core": "npm:7.26.10" - "@babel/generator": "npm:7.26.10" - "@babel/helper-annotate-as-pure": "npm:7.25.9" + "@angular-devkit/architect": "npm:0.2000.4" + "@angular-devkit/build-webpack": "npm:0.2000.4" + "@angular-devkit/core": "npm:20.0.4" + "@angular/build": "npm:20.0.4" + "@babel/core": "npm:7.27.1" + "@babel/generator": "npm:7.27.1" + "@babel/helper-annotate-as-pure": "npm:7.27.1" "@babel/helper-split-export-declaration": "npm:7.24.7" - "@babel/plugin-transform-async-generator-functions": "npm:7.26.8" - "@babel/plugin-transform-async-to-generator": "npm:7.25.9" - "@babel/plugin-transform-runtime": "npm:7.26.10" - "@babel/preset-env": "npm:7.26.9" - "@babel/runtime": "npm:7.26.10" + "@babel/plugin-transform-async-generator-functions": "npm:7.27.1" + "@babel/plugin-transform-async-to-generator": "npm:7.27.1" + "@babel/plugin-transform-runtime": "npm:7.27.1" + "@babel/preset-env": "npm:7.27.2" + "@babel/runtime": "npm:7.27.1" "@discoveryjs/json-ext": "npm:0.6.3" - "@ngtools/webpack": "npm:19.2.10" - "@vitejs/plugin-basic-ssl": "npm:1.2.0" + "@ngtools/webpack": "npm:20.0.4" + "@vitejs/plugin-basic-ssl": "npm:2.0.0" ansi-colors: "npm:4.1.3" - autoprefixer: "npm:10.4.20" - babel-loader: "npm:9.2.1" + autoprefixer: "npm:10.4.21" + babel-loader: "npm:10.0.0" browserslist: "npm:^4.21.5" - copy-webpack-plugin: "npm:12.0.2" + copy-webpack-plugin: "npm:13.0.0" css-loader: "npm:7.1.2" - esbuild: "npm:0.25.1" - esbuild-wasm: "npm:0.25.1" + esbuild: "npm:0.25.5" + esbuild-wasm: "npm:0.25.5" fast-glob: "npm:3.3.3" http-proxy-middleware: "npm:3.0.5" istanbul-lib-instrument: "npm:6.0.3" jsonc-parser: "npm:3.3.1" karma-source-map-support: "npm:1.4.0" - less: "npm:4.2.2" - less-loader: "npm:12.2.0" + less: "npm:4.3.0" + less-loader: "npm:12.3.0" license-webpack-plugin: "npm:4.0.2" loader-utils: "npm:3.3.1" mini-css-extract-plugin: "npm:2.9.2" - open: "npm:10.1.0" - ora: "npm:5.4.1" + open: "npm:10.1.2" + ora: "npm:8.2.0" picomatch: "npm:4.0.2" - piscina: "npm:4.8.0" - postcss: "npm:8.5.2" + piscina: "npm:5.1.1" + postcss: "npm:8.5.3" postcss-loader: "npm:8.1.1" resolve-url-loader: "npm:5.0.0" - rxjs: "npm:7.8.1" - sass: "npm:1.85.0" + rxjs: "npm:7.8.2" + sass: "npm:1.88.0" sass-loader: "npm:16.0.5" - semver: "npm:7.7.1" + semver: "npm:7.7.2" source-map-loader: "npm:5.0.0" source-map-support: "npm:0.5.21" - terser: "npm:5.39.0" + terser: "npm:5.39.1" tree-kill: "npm:1.2.2" tslib: "npm:2.8.1" - webpack: "npm:5.98.0" + webpack: "npm:5.99.8" webpack-dev-middleware: "npm:7.4.2" - webpack-dev-server: "npm:5.2.0" + webpack-dev-server: "npm:5.2.1" webpack-merge: "npm:6.0.1" webpack-subresource-integrity: "npm:5.1.0" peerDependencies: - "@angular/compiler-cli": ^19.0.0 || ^19.2.0-next.0 - "@angular/localize": ^19.0.0 || ^19.2.0-next.0 - "@angular/platform-server": ^19.0.0 || ^19.2.0-next.0 - "@angular/service-worker": ^19.0.0 || ^19.2.0-next.0 - "@angular/ssr": ^19.2.10 + "@angular/compiler-cli": ^20.0.0 + "@angular/core": ^20.0.0 + "@angular/localize": ^20.0.0 + "@angular/platform-browser": ^20.0.0 + "@angular/platform-server": ^20.0.0 + "@angular/service-worker": ^20.0.0 + "@angular/ssr": ^20.0.4 "@web/test-runner": ^0.20.0 browser-sync: ^3.0.2 jest: ^29.5.0 jest-environment-jsdom: ^29.5.0 karma: ^6.3.0 - ng-packagr: ^19.0.0 || ^19.2.0-next.0 + ng-packagr: ^20.0.0 protractor: ^7.0.0 tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 - typescript: ">=5.5 <5.9" + typescript: ">=5.8 <5.9" dependenciesMeta: esbuild: optional: true peerDependenciesMeta: + "@angular/core": + optional: true "@angular/localize": optional: true + "@angular/platform-browser": + optional: true "@angular/platform-server": optional: true "@angular/service-worker": @@ -163,20 +144,20 @@ __metadata: optional: true tailwindcss: optional: true - checksum: 10c0/c853722cf9e916083441d60e742eda2ea3f348f5bddd0c1e8da37836db6f36aec59712fbd388a88057f83fa18a6c1465c04e9602b1f1218d49037565c9472eda + checksum: 10c0/6fd9faa11743439367b5cbfcb33050978d54fe4e68c1c6acc1f62794591a82024a0b62ff38818aa86eef1ece2efd21b64bcaeb790841465616d859147fde937f languageName: node linkType: hard -"@angular-devkit/build-webpack@npm:0.1902.10": - version: 0.1902.10 - resolution: "@angular-devkit/build-webpack@npm:0.1902.10" +"@angular-devkit/build-webpack@npm:0.2000.4": + version: 0.2000.4 + resolution: "@angular-devkit/build-webpack@npm:0.2000.4" dependencies: - "@angular-devkit/architect": "npm:0.1902.10" - rxjs: "npm:7.8.1" + "@angular-devkit/architect": "npm:0.2000.4" + rxjs: "npm:7.8.2" peerDependencies: webpack: ^5.30.0 webpack-dev-server: ^5.0.2 - checksum: 10c0/193d42127b4a27c502ee888ab97c3a60fd2a81a73bb76b418dd32fe3ac1f4ac91d5507ba2cdd37816716e43d68f4cf203a114c52646faf811169ced750480e42 + checksum: 10c0/c3a48218055ceb91945727562879b56a0c68f6c68c26dc2edc876893e67a338a56bc95eb74c0cf8e06d73099ec478b67dc1a4247c7f54ccc38a942a2e971eee4 languageName: node linkType: hard @@ -199,7 +180,7 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/core@npm:18.2.19, @angular-devkit/core@npm:>= 18.0.0 < 19.0.0, @angular-devkit/core@npm:^18.0.0": +"@angular-devkit/core@npm:18.2.19, @angular-devkit/core@npm:^18.0.0": version: 18.2.19 resolution: "@angular-devkit/core@npm:18.2.19" dependencies: @@ -223,26 +204,7 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/core@npm:19.2.10, @angular-devkit/core@npm:^19.1.4": - version: 19.2.10 - resolution: "@angular-devkit/core@npm:19.2.10" - dependencies: - ajv: "npm:8.17.1" - ajv-formats: "npm:3.0.1" - jsonc-parser: "npm:3.3.1" - picomatch: "npm:4.0.2" - rxjs: "npm:7.8.1" - source-map: "npm:0.7.4" - peerDependencies: - chokidar: ^4.0.0 - peerDependenciesMeta: - chokidar: - optional: true - checksum: 10c0/a095df28d41f920650bfaf3dbd6de712519f6335abf503f2b7315966abcb2df4e625bf2c26765b03296e06bcc21aafb96271da7f0338b26fba277d08158f4904 - languageName: node - linkType: hard - -"@angular-devkit/core@npm:20.0.4": +"@angular-devkit/core@npm:20.0.4, @angular-devkit/core@npm:>= 20.0.0 < 21.0.0, @angular-devkit/core@npm:^20.0.4": version: 20.0.4 resolution: "@angular-devkit/core@npm:20.0.4" dependencies: @@ -261,7 +223,7 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/schematics@npm:20.0.4": +"@angular-devkit/schematics@npm:20.0.4, @angular-devkit/schematics@npm:>= 20.0.0 < 21.0.0, @angular-devkit/schematics@npm:^20.0.4": version: 20.0.4 resolution: "@angular-devkit/schematics@npm:20.0.4" dependencies: @@ -274,7 +236,7 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/schematics@npm:>= 18.0.0 < 19.0.0, @angular-devkit/schematics@npm:^18.0.0": +"@angular-devkit/schematics@npm:^18.0.0": version: 18.2.19 resolution: "@angular-devkit/schematics@npm:18.2.19" dependencies: @@ -292,108 +254,97 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/schematics@npm:^19.1.4": - version: 19.2.10 - resolution: "@angular-devkit/schematics@npm:19.2.10" - dependencies: - "@angular-devkit/core": "npm:19.2.10" - jsonc-parser: "npm:3.3.1" - magic-string: "npm:0.30.17" - ora: "npm:5.4.1" - rxjs: "npm:7.8.1" - checksum: 10c0/ea4fb356b78b5e9b0cb07a764f3bca6fab5a7eb5204d71c877351ed18910f34d569aecb9aa9ea2e85cfa8d3a3c68803f47eeb2d565284ca53acb3c6f1556052a - languageName: node - linkType: hard - -"@angular-eslint/builder@npm:^18.0.0": - version: 18.4.3 - resolution: "@angular-eslint/builder@npm:18.4.3" +"@angular-eslint/builder@npm:^20.1.1": + version: 20.1.1 + resolution: "@angular-eslint/builder@npm:20.1.1" dependencies: - "@angular-devkit/architect": "npm:>= 0.1800.0 < 0.1900.0" - "@angular-devkit/core": "npm:>= 18.0.0 < 19.0.0" + "@angular-devkit/architect": "npm:>= 0.2000.0 < 0.2100.0" + "@angular-devkit/core": "npm:>= 20.0.0 < 21.0.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/649eb002a3baeae27d395836a52e19b5f4d1f8c39066554447cd34640c95d4fa6f7ff746a21b6f4da68e257495682e5c731cd40121029d62bf41b9eebee847e1 + checksum: 10c0/fd266276a583005f030dd98fae50fa735a3e64cfc33ee2dd02f0e55f241dcd9f6145db57851d9b8ed5e7985bbf7d0651de2b1f00593d9c96f2b7093802f58f83 languageName: node linkType: hard -"@angular-eslint/bundled-angular-compiler@npm:18.4.3": - version: 18.4.3 - resolution: "@angular-eslint/bundled-angular-compiler@npm:18.4.3" - checksum: 10c0/da11e3a2ec0f46504b4bed7c3e1af94d118b52b9b59b07152ae5f102e09f4fbef790694b52b6e5260d08b4403de2497192abfa1c879431fbff10adbc558ebac4 +"@angular-eslint/bundled-angular-compiler@npm:20.1.1": + version: 20.1.1 + resolution: "@angular-eslint/bundled-angular-compiler@npm:20.1.1" + checksum: 10c0/a62c2264b8d159c8787d081705b1362f592ae5d7025d6feaf9a7bc845a16d770f598772644bb22f122efd833068958c1c00239982428ad200fc5ef4fe17011eb languageName: node linkType: hard -"@angular-eslint/eslint-plugin-template@npm:18.4.3, @angular-eslint/eslint-plugin-template@npm:^18.0.0": - version: 18.4.3 - resolution: "@angular-eslint/eslint-plugin-template@npm:18.4.3" +"@angular-eslint/eslint-plugin-template@npm:20.1.1, @angular-eslint/eslint-plugin-template@npm:^20.1.1": + version: 20.1.1 + resolution: "@angular-eslint/eslint-plugin-template@npm:20.1.1" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.4.3" - "@angular-eslint/utils": "npm:18.4.3" + "@angular-eslint/bundled-angular-compiler": "npm:20.1.1" + "@angular-eslint/utils": "npm:20.1.1" aria-query: "npm:5.3.2" axobject-query: "npm:4.1.0" peerDependencies: + "@angular-eslint/template-parser": 20.1.1 "@typescript-eslint/types": ^7.11.0 || ^8.0.0 "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/31de5fe38040b5cd8b96674b183dd950aa4f07367c2499185f5687106c3f9944c81cbf3583430fae69849fcd6d430149428138bf69fa84b786777b0c9817393e + checksum: 10c0/57bcabbfb8c3327a4fa22aaf7239cd087fd7f3782c68d85e56d3c8e29e68078c3f2b3f262daf221ecc3053173655dc0a4857832b150852cf90c498d77d4ef99e languageName: node linkType: hard -"@angular-eslint/eslint-plugin@npm:18.4.3, @angular-eslint/eslint-plugin@npm:^18.0.0": - version: 18.4.3 - resolution: "@angular-eslint/eslint-plugin@npm:18.4.3" +"@angular-eslint/eslint-plugin@npm:20.1.1, @angular-eslint/eslint-plugin@npm:^20.1.1": + version: 20.1.1 + resolution: "@angular-eslint/eslint-plugin@npm:20.1.1" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.4.3" - "@angular-eslint/utils": "npm:18.4.3" + "@angular-eslint/bundled-angular-compiler": "npm:20.1.1" + "@angular-eslint/utils": "npm:20.1.1" + ts-api-utils: "npm:^2.1.0" peerDependencies: "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/79c497b1d924c440c62d4d79d736b722bbd8ff8813dda53c68e23211b6130d3d83b5e01716809e1139f27b24ac8703217bb2dc04404ccd1e58f070f845a2bbe6 + checksum: 10c0/ff3d195765c2fdc0b9af9c61d119e029237208043951d6369a50e9e5e3b4e0da2ba2d892cda703dfb659c92ec6289ba8cc686977ec4a6c0dcebb03419701b821 languageName: node linkType: hard -"@angular-eslint/schematics@npm:^18.0.0": - version: 18.4.3 - resolution: "@angular-eslint/schematics@npm:18.4.3" +"@angular-eslint/schematics@npm:^20.1.1": + version: 20.1.1 + resolution: "@angular-eslint/schematics@npm:20.1.1" dependencies: - "@angular-devkit/core": "npm:>= 18.0.0 < 19.0.0" - "@angular-devkit/schematics": "npm:>= 18.0.0 < 19.0.0" - "@angular-eslint/eslint-plugin": "npm:18.4.3" - "@angular-eslint/eslint-plugin-template": "npm:18.4.3" - ignore: "npm:6.0.2" - semver: "npm:7.6.3" + "@angular-devkit/core": "npm:>= 20.0.0 < 21.0.0" + "@angular-devkit/schematics": "npm:>= 20.0.0 < 21.0.0" + "@angular-eslint/eslint-plugin": "npm:20.1.1" + "@angular-eslint/eslint-plugin-template": "npm:20.1.1" + ignore: "npm:7.0.5" + semver: "npm:7.7.2" strip-json-comments: "npm:3.1.1" - checksum: 10c0/eba9185745f5de5feb283952e307725ec4702f4762fa1a975f98b4dd4d19893bc4764414ef4239c71727b194252ec07ff540c70ad99fc7d5165160d6d83c8f98 + checksum: 10c0/c690f0c9691309c4da7017696814b62d2d23a10ebf5e23fb81f0fd68b3d2e049c48323b95ad534ba3e2751e0118754f96611eaaf829e83d214474560aa045737 languageName: node linkType: hard -"@angular-eslint/template-parser@npm:^18.0.0": - version: 18.4.3 - resolution: "@angular-eslint/template-parser@npm:18.4.3" +"@angular-eslint/template-parser@npm:^20.1.1": + version: 20.1.1 + resolution: "@angular-eslint/template-parser@npm:20.1.1" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.4.3" + "@angular-eslint/bundled-angular-compiler": "npm:20.1.1" eslint-scope: "npm:^8.0.2" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/0d045243a57f9a821fba9482bf3ea098d4f8a84172b69002f8d2587eb551085a64562dba1fb6368a18ad54e242ba47fba0c8b1a3505619fea7a4b4cb1ffe835f + checksum: 10c0/8594aacdba2ae82191744790f1b711dd6feef3941c29a337a1a5cf296eff451cb47c5c20434fa7a3e6f76c07187e02dc1ad43d3db4fabc66fe17941fb929c571 languageName: node linkType: hard -"@angular-eslint/utils@npm:18.4.3": - version: 18.4.3 - resolution: "@angular-eslint/utils@npm:18.4.3" +"@angular-eslint/utils@npm:20.1.1": + version: 20.1.1 + resolution: "@angular-eslint/utils@npm:20.1.1" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.4.3" + "@angular-eslint/bundled-angular-compiler": "npm:20.1.1" peerDependencies: "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/3291b3ecc4214fe93b70272317bb45fa836e41a103eff4335aa2385bcbe0196196185b89d214287107ef234ded808d7ffd59290cdb91877dae7f9608ec70aedd + checksum: 10c0/85c65c70330bae9355854a4982dfb85f41c620be06b77ecf7cca760febc3d884ea17026cfdbdcafeb4b520f0fa7f9ceb2888b5e59a8ef60fe45c49d28b7edca8 languageName: node linkType: hard @@ -409,56 +360,64 @@ __metadata: languageName: node linkType: hard -"@angular/build@npm:19.2.10": - version: 19.2.10 - resolution: "@angular/build@npm:19.2.10" +"@angular/build@npm:20.0.4": + version: 20.0.4 + resolution: "@angular/build@npm:20.0.4" dependencies: "@ampproject/remapping": "npm:2.3.0" - "@angular-devkit/architect": "npm:0.1902.10" - "@babel/core": "npm:7.26.10" - "@babel/helper-annotate-as-pure": "npm:7.25.9" + "@angular-devkit/architect": "npm:0.2000.4" + "@babel/core": "npm:7.27.1" + "@babel/helper-annotate-as-pure": "npm:7.27.1" "@babel/helper-split-export-declaration": "npm:7.24.7" - "@babel/plugin-syntax-import-attributes": "npm:7.26.0" - "@inquirer/confirm": "npm:5.1.6" - "@vitejs/plugin-basic-ssl": "npm:1.2.0" - beasties: "npm:0.3.2" + "@inquirer/confirm": "npm:5.1.10" + "@vitejs/plugin-basic-ssl": "npm:2.0.0" + beasties: "npm:0.3.4" browserslist: "npm:^4.23.0" - esbuild: "npm:0.25.1" - fast-glob: "npm:3.3.3" + esbuild: "npm:0.25.5" https-proxy-agent: "npm:7.0.6" istanbul-lib-instrument: "npm:6.0.3" - listr2: "npm:8.2.5" - lmdb: "npm:3.2.6" + jsonc-parser: "npm:3.3.1" + listr2: "npm:8.3.3" + lmdb: "npm:3.3.0" magic-string: "npm:0.30.17" mrmime: "npm:2.0.1" - parse5-html-rewriting-stream: "npm:7.0.0" + parse5-html-rewriting-stream: "npm:7.1.0" picomatch: "npm:4.0.2" - piscina: "npm:4.8.0" - rollup: "npm:4.34.8" - sass: "npm:1.85.0" - semver: "npm:7.7.1" + piscina: "npm:5.1.1" + rollup: "npm:4.40.2" + sass: "npm:1.88.0" + semver: "npm:7.7.2" source-map-support: "npm:0.5.21" - vite: "npm:6.2.7" + tinyglobby: "npm:0.2.13" + vite: "npm:6.3.5" watchpack: "npm:2.4.2" peerDependencies: - "@angular/compiler": ^19.0.0 || ^19.2.0-next.0 - "@angular/compiler-cli": ^19.0.0 || ^19.2.0-next.0 - "@angular/localize": ^19.0.0 || ^19.2.0-next.0 - "@angular/platform-server": ^19.0.0 || ^19.2.0-next.0 - "@angular/service-worker": ^19.0.0 || ^19.2.0-next.0 - "@angular/ssr": ^19.2.10 + "@angular/compiler": ^20.0.0 + "@angular/compiler-cli": ^20.0.0 + "@angular/core": ^20.0.0 + "@angular/localize": ^20.0.0 + "@angular/platform-browser": ^20.0.0 + "@angular/platform-server": ^20.0.0 + "@angular/service-worker": ^20.0.0 + "@angular/ssr": ^20.0.4 karma: ^6.4.0 less: ^4.2.0 - ng-packagr: ^19.0.0 || ^19.2.0-next.0 + ng-packagr: ^20.0.0 postcss: ^8.4.0 tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 - typescript: ">=5.5 <5.9" + tslib: ^2.3.0 + typescript: ">=5.8 <5.9" + vitest: ^3.1.1 dependenciesMeta: lmdb: optional: true peerDependenciesMeta: + "@angular/core": + optional: true "@angular/localize": optional: true + "@angular/platform-browser": + optional: true "@angular/platform-server": optional: true "@angular/service-worker": @@ -475,24 +434,23 @@ __metadata: optional: true tailwindcss: optional: true - checksum: 10c0/416411d5f2c40a5e91d80372b474cd0eabbb03e56e48ef9bdc02342373ed37b65feeb3824ed2fd278d3ac57f42fc765d29921f7910a1dfa11d045c58939dfb84 + vitest: + optional: true + checksum: 10c0/381154d51663a290346308129677f2f330cca45e8b8b8d6e39387dbf70018163cf048b041b2f2a5c8b7ae801e9bb9d049b1accd23fd2fb35be8b11d5b51fe180 languageName: node linkType: hard -"@angular/cdk@npm:^18.2.14": - version: 18.2.14 - resolution: "@angular/cdk@npm:18.2.14" +"@angular/cdk@npm:^20.0.4": + version: 20.0.4 + resolution: "@angular/cdk@npm:20.0.4" dependencies: parse5: "npm:^7.1.2" tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": ^18.0.0 || ^19.0.0 - "@angular/core": ^18.0.0 || ^19.0.0 + "@angular/common": ^20.0.0 || ^21.0.0 + "@angular/core": ^20.0.0 || ^21.0.0 rxjs: ^6.5.3 || ^7.4.0 - dependenciesMeta: - parse5: - optional: true - checksum: 10c0/d5fb364044b1bc2fb36ac4158586f6ac74f94c9e7c74b20a295671105bf92266bcd8f710132c57569d0174b21438dbfc250bd2649ebff544b38ac3e03ada02ac + checksum: 10c0/5e46962dcfe41605377a7f59b991c79c73b78cc50d087c0fb8bc849d76e114a0d7f4a9d15e8e0a3bc609fa1e842743d360c693a973df0cba5167e21b3da4a310 languageName: node linkType: hard @@ -662,33 +620,33 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.26.8, @babel/compat-data@npm:^7.27.2": +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.27.2": version: 7.27.2 resolution: "@babel/compat-data@npm:7.27.2" checksum: 10c0/077c9e01af3b90decee384a6a44dcf353898e980cee22ec7941f9074655dbbe97ec317345536cdc7ef7391521e1497930c522a3816af473076dd524be7fccd32 languageName: node linkType: hard -"@babel/core@npm:7.26.10": - version: 7.26.10 - resolution: "@babel/core@npm:7.26.10" +"@babel/core@npm:7.27.1, @babel/core@npm:^7.12.3, @babel/core@npm:^7.23.9": + version: 7.27.1 + resolution: "@babel/core@npm:7.27.1" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.26.2" - "@babel/generator": "npm:^7.26.10" - "@babel/helper-compilation-targets": "npm:^7.26.5" - "@babel/helper-module-transforms": "npm:^7.26.0" - "@babel/helpers": "npm:^7.26.10" - "@babel/parser": "npm:^7.26.10" - "@babel/template": "npm:^7.26.9" - "@babel/traverse": "npm:^7.26.10" - "@babel/types": "npm:^7.26.10" + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.27.1" + "@babel/helper-compilation-targets": "npm:^7.27.1" + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helpers": "npm:^7.27.1" + "@babel/parser": "npm:^7.27.1" + "@babel/template": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/e046e0e988ab53841b512ee9d263ca409f6c46e2a999fe53024688b92db394346fa3aeae5ea0866331f62133982eee05a675d22922a4603c3f603aa09a581d62 + checksum: 10c0/0fc31f87f5401ac5d375528cb009f4ea5527fc8c5bb5b64b5b22c033b60fd0ad723388933a5f3f5db14e1edd13c958e9dd7e5c68f9b68c767aeb496199c8a4bb languageName: node linkType: hard @@ -715,43 +673,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.12.3, @babel/core@npm:^7.23.9": - version: 7.27.1 - resolution: "@babel/core@npm:7.27.1" - dependencies: - "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.27.1" - "@babel/generator": "npm:^7.27.1" - "@babel/helper-compilation-targets": "npm:^7.27.1" - "@babel/helper-module-transforms": "npm:^7.27.1" - "@babel/helpers": "npm:^7.27.1" - "@babel/parser": "npm:^7.27.1" - "@babel/template": "npm:^7.27.1" - "@babel/traverse": "npm:^7.27.1" - "@babel/types": "npm:^7.27.1" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10c0/0fc31f87f5401ac5d375528cb009f4ea5527fc8c5bb5b64b5b22c033b60fd0ad723388933a5f3f5db14e1edd13c958e9dd7e5c68f9b68c767aeb496199c8a4bb - languageName: node - linkType: hard - -"@babel/generator@npm:7.26.10": - version: 7.26.10 - resolution: "@babel/generator@npm:7.26.10" - dependencies: - "@babel/parser": "npm:^7.26.10" - "@babel/types": "npm:^7.26.10" - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^3.0.2" - checksum: 10c0/88b3b3ea80592fc89349c4e1a145e1386e4042866d2507298adf452bf972f68d13bf699a845e6ab8c028bd52c2247013eb1221b86e1db5c9779faacba9c4b10e - languageName: node - linkType: hard - -"@babel/generator@npm:^7.26.10, @babel/generator@npm:^7.27.1": +"@babel/generator@npm:7.27.1, @babel/generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/generator@npm:7.27.1" dependencies: @@ -777,16 +699,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:7.25.9": - version: 7.25.9 - resolution: "@babel/helper-annotate-as-pure@npm:7.25.9" - dependencies: - "@babel/types": "npm:^7.25.9" - checksum: 10c0/095b6ba50489d797733abebc4596a81918316a99e3632755c9f02508882912b00c2ae5e468532a25a5c2108d109ddbe9b7da78333ee7cc13817fc50c00cf06fe - languageName: node - linkType: hard - -"@babel/helper-annotate-as-pure@npm:^7.27.1": +"@babel/helper-annotate-as-pure@npm:7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-annotate-as-pure@npm:7.27.1" dependencies: @@ -795,7 +708,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.26.5, @babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": +"@babel/helper-annotate-as-pure@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" + dependencies: + "@babel/types": "npm:^7.27.3" + checksum: 10c0/94996ce0a05b7229f956033e6dcd69393db2b0886d0db6aff41e704390402b8cdcca11f61449cb4f86cfd9e61b5ad3a73e4fa661eeed7846b125bd1c33dbc633 + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": version: 7.27.2 resolution: "@babel/helper-compilation-targets@npm:7.27.2" dependencies: @@ -863,7 +785,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.25.9, @babel/helper-module-imports@npm:^7.27.1": +"@babel/helper-module-imports@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-module-imports@npm:7.27.1" dependencies: @@ -873,7 +795,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.26.0, @babel/helper-module-transforms@npm:^7.27.1": +"@babel/helper-module-transforms@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-module-transforms@npm:7.27.1" dependencies: @@ -908,14 +830,14 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.25.9, @babel/helper-plugin-utils@npm:^7.26.5, @babel/helper-plugin-utils@npm:^7.27.1": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-plugin-utils@npm:7.27.1" checksum: 10c0/94cf22c81a0c11a09b197b41ab488d416ff62254ce13c57e62912c85700dc2e99e555225787a4099ff6bae7a1812d622c80fbaeda824b79baa10a6c5ac4cf69b languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.25.9, @babel/helper-remap-async-to-generator@npm:^7.27.1": +"@babel/helper-remap-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" dependencies: @@ -974,7 +896,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.25.9, @babel/helper-validator-option@npm:^7.27.1": +"@babel/helper-validator-option@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-validator-option@npm:7.27.1" checksum: 10c0/6fec5f006eba40001a20f26b1ef5dbbda377b7b68c8ad518c05baa9af3f396e780bdfded24c4eef95d14bb7b8fd56192a6ed38d5d439b97d10efc5f1a191d148 @@ -992,7 +914,7 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.26.10, @babel/helpers@npm:^7.27.1": +"@babel/helpers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helpers@npm:7.27.1" dependencies: @@ -1012,7 +934,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.14.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.26.10, @babel/parser@npm:^7.27.1, @babel/parser@npm:^7.27.2": +"@babel/parser@npm:^7.14.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.27.1, @babel/parser@npm:^7.27.2": version: 7.27.2 resolution: "@babel/parser@npm:7.27.2" dependencies: @@ -1034,7 +956,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.9": +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.27.1" dependencies: @@ -1046,7 +968,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.9": +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.27.1" dependencies: @@ -1057,7 +979,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.9": +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.27.1" dependencies: @@ -1068,7 +990,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.25.9": +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.27.1" dependencies: @@ -1081,7 +1003,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.9": +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.27.1" dependencies: @@ -1102,7 +1024,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.26.0": +"@babel/plugin-syntax-import-assertions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-syntax-import-assertions@npm:7.27.1" dependencies: @@ -1113,18 +1035,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:7.26.0": - version: 7.26.0 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.26.0" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.25.9" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/e594c185b12bfe0bbe7ca78dfeebe870e6d569a12128cac86f3164a075fe0ff70e25ddbd97fd0782906b91f65560c9dc6957716b7b4a68aba2516c9b7455e352 - languageName: node - linkType: hard - -"@babel/plugin-syntax-import-attributes@npm:^7.26.0": +"@babel/plugin-syntax-import-attributes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1" dependencies: @@ -1147,7 +1058,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.25.9": +"@babel/plugin-transform-arrow-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" dependencies: @@ -1158,20 +1069,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:7.26.8": - version: 7.26.8 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.26.8" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.26.5" - "@babel/helper-remap-async-to-generator": "npm:^7.25.9" - "@babel/traverse": "npm:^7.26.8" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/f6fefce963fe2e6268dde1958975d7adbce65fba94ca6f4bc554c90da03104ad1dd2e66d03bc0462da46868498428646e30b03a218ef0e5a84bfc87a7e375cec - languageName: node - linkType: hard - -"@babel/plugin-transform-async-generator-functions@npm:^7.26.8": +"@babel/plugin-transform-async-generator-functions@npm:7.27.1, @babel/plugin-transform-async-generator-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-async-generator-functions@npm:7.27.1" dependencies: @@ -1184,20 +1082,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:7.25.9": - version: 7.25.9 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.25.9" - dependencies: - "@babel/helper-module-imports": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.25.9" - "@babel/helper-remap-async-to-generator": "npm:^7.25.9" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/c443d9e462ddef733ae56360064f32fc800105803d892e4ff32d7d6a6922b3765fa97b9ddc9f7f1d3f9d8c2d95721d85bef9dbf507804214c6cf6466b105c168 - languageName: node - linkType: hard - -"@babel/plugin-transform-async-to-generator@npm:^7.25.9": +"@babel/plugin-transform-async-to-generator@npm:7.27.1, @babel/plugin-transform-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-async-to-generator@npm:7.27.1" dependencies: @@ -1210,7 +1095,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.26.5": +"@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" dependencies: @@ -1221,18 +1106,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.25.9": - version: 7.27.1 - resolution: "@babel/plugin-transform-block-scoping@npm:7.27.1" +"@babel/plugin-transform-block-scoping@npm:^7.27.1": + version: 7.27.5 + resolution: "@babel/plugin-transform-block-scoping@npm:7.27.5" dependencies: "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/d3f357beeb92fbdf3045aea2ba286a60dafc9c2d2a9f89065bb3c4bea9cc48934ee6689df3db0439d9ec518eda5e684f3156cab792b7c38c33ece2f8204ddee8 + checksum: 10c0/5c1a61f312f18d3807c4df25868161301a7bd0807092b86951fa6b9918e07ee382d58d61a204c3f9ad0b72b8f6f1d18586f8e485c355a3e959c26a070397e95e languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.25.9": +"@babel/plugin-transform-class-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" dependencies: @@ -1244,7 +1129,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.26.0": +"@babel/plugin-transform-class-static-block@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-class-static-block@npm:7.27.1" dependencies: @@ -1256,23 +1141,23 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.25.9": - version: 7.27.1 - resolution: "@babel/plugin-transform-classes@npm:7.27.1" +"@babel/plugin-transform-classes@npm:^7.27.1": + version: 7.27.7 + resolution: "@babel/plugin-transform-classes@npm:7.27.7" dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.27.1" - "@babel/helper-compilation-targets": "npm:^7.27.1" + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-compilation-targets": "npm:^7.27.2" "@babel/helper-plugin-utils": "npm:^7.27.1" "@babel/helper-replace-supers": "npm:^7.27.1" - "@babel/traverse": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.7" globals: "npm:^11.1.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/1071f4cb1ed5deb5e6f8d0442f2293a540cac5caa5ab3c25ad0571aadcbf961f61e26d367a67894976165a543e02f3a19e40b63b909afbed6e710801a590635c + checksum: 10c0/188131e30543e9726c1f7f80df111f9b2f8a05b476627190444970f26dc392d9bd42070b47e91a0ece1afcbb7e7e672b9d12f7572ce4bcffa9c70b1fb31554b8 languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.25.9": +"@babel/plugin-transform-computed-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" dependencies: @@ -1284,7 +1169,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.25.9, @babel/plugin-transform-destructuring@npm:^7.27.1": +"@babel/plugin-transform-destructuring@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-destructuring@npm:7.27.1" dependencies: @@ -1295,7 +1180,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.25.9": +"@babel/plugin-transform-destructuring@npm:^7.27.7": + version: 7.27.7 + resolution: "@babel/plugin-transform-destructuring@npm:7.27.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/0439b47c193c2e1c55994d27c61e1c3762856833d166eb1d43a3cd9825cdafa40766e7830446d98723f1ce0db218374083ab064cb93d80b824c494ac6642422c + languageName: node + linkType: hard + +"@babel/plugin-transform-dotall-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-dotall-regex@npm:7.27.1" dependencies: @@ -1307,7 +1204,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.25.9": +"@babel/plugin-transform-duplicate-keys@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" dependencies: @@ -1318,7 +1215,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.9": +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.27.1" dependencies: @@ -1330,7 +1227,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.25.9": +"@babel/plugin-transform-dynamic-import@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" dependencies: @@ -1341,7 +1238,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.26.3": +"@babel/plugin-transform-exponentiation-operator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.27.1" dependencies: @@ -1352,7 +1249,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.25.9": +"@babel/plugin-transform-export-namespace-from@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" dependencies: @@ -1363,7 +1260,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.26.9": +"@babel/plugin-transform-for-of@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-for-of@npm:7.27.1" dependencies: @@ -1375,7 +1272,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.25.9": +"@babel/plugin-transform-function-name@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-function-name@npm:7.27.1" dependencies: @@ -1388,7 +1285,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.25.9": +"@babel/plugin-transform-json-strings@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-json-strings@npm:7.27.1" dependencies: @@ -1399,7 +1296,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.25.9": +"@babel/plugin-transform-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-literals@npm:7.27.1" dependencies: @@ -1410,7 +1307,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.25.9": +"@babel/plugin-transform-logical-assignment-operators@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.27.1" dependencies: @@ -1421,7 +1318,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.25.9": +"@babel/plugin-transform-member-expression-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" dependencies: @@ -1432,7 +1329,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.25.9": +"@babel/plugin-transform-modules-amd@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-amd@npm:7.27.1" dependencies: @@ -1444,7 +1341,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.26.3": +"@babel/plugin-transform-modules-commonjs@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.27.1" dependencies: @@ -1456,7 +1353,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.25.9": +"@babel/plugin-transform-modules-systemjs@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.27.1" dependencies: @@ -1470,7 +1367,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.25.9": +"@babel/plugin-transform-modules-umd@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-umd@npm:7.27.1" dependencies: @@ -1482,7 +1379,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.25.9": +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.27.1" dependencies: @@ -1494,7 +1391,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.25.9": +"@babel/plugin-transform-new-target@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-new-target@npm:7.27.1" dependencies: @@ -1505,7 +1402,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.26.6": +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1" dependencies: @@ -1516,7 +1413,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.25.9": +"@babel/plugin-transform-numeric-separator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" dependencies: @@ -1527,21 +1424,22 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.25.9": - version: 7.27.2 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.27.2" +"@babel/plugin-transform-object-rest-spread@npm:^7.27.2": + version: 7.27.7 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.27.7" dependencies: "@babel/helper-compilation-targets": "npm:^7.27.2" "@babel/helper-plugin-utils": "npm:^7.27.1" - "@babel/plugin-transform-destructuring": "npm:^7.27.1" - "@babel/plugin-transform-parameters": "npm:^7.27.1" + "@babel/plugin-transform-destructuring": "npm:^7.27.7" + "@babel/plugin-transform-parameters": "npm:^7.27.7" + "@babel/traverse": "npm:^7.27.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5e255b262dd65c8700078d9f6ed87bd45f951a905dda6b3414be28d7b2781b18e6b812e9d71421e61360c9cf51e1e619c1d48348593bb7399496f61f5f221446 + checksum: 10c0/8902c97849f2f8368295610d084fe783c31d1c7c4cab65b0a144d617ddd4c0ff9bf073c55846dc118ced140fed1f4c64345a2dfca82999a65bf0c099f060eae7 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.25.9": +"@babel/plugin-transform-object-super@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-object-super@npm:7.27.1" dependencies: @@ -1553,7 +1451,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.25.9": +"@babel/plugin-transform-optional-catch-binding@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.27.1" dependencies: @@ -1564,7 +1462,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.25.9, @babel/plugin-transform-optional-chaining@npm:^7.27.1": +"@babel/plugin-transform-optional-chaining@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-optional-chaining@npm:7.27.1" dependencies: @@ -1576,7 +1474,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.25.9, @babel/plugin-transform-parameters@npm:^7.27.1": +"@babel/plugin-transform-parameters@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-parameters@npm:7.27.1" dependencies: @@ -1587,7 +1485,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.25.9": +"@babel/plugin-transform-parameters@npm:^7.27.7": + version: 7.27.7 + resolution: "@babel/plugin-transform-parameters@npm:7.27.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/f2da3804e047d9f1cfb27be6c014e2c7f6cf5e1e38290d1cb3cb2607859e3d6facb4ee8c8c1e336e9fbb440091a174ce95ce156582d7e8bf9c0e735d11681f0f + languageName: node + linkType: hard + +"@babel/plugin-transform-private-methods@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-private-methods@npm:7.27.1" dependencies: @@ -1599,7 +1508,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.25.9": +"@babel/plugin-transform-private-property-in-object@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-private-property-in-object@npm:7.27.1" dependencies: @@ -1612,7 +1521,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.25.9": +"@babel/plugin-transform-property-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" dependencies: @@ -1623,18 +1532,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.25.9": - version: 7.27.1 - resolution: "@babel/plugin-transform-regenerator@npm:7.27.1" +"@babel/plugin-transform-regenerator@npm:^7.27.1": + version: 7.27.5 + resolution: "@babel/plugin-transform-regenerator@npm:7.27.5" dependencies: "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/42395908899310bb107d9ca31ebd4c302e14c582e3ad3ebfe1498fabafc43155c8f10850265c1e686a2afcf50d1f402cc5c5218fba72e167852607a4d8d6492e + checksum: 10c0/4ace8ced76b421cd44dd9fa08bebc2f3fd76ec84e532cd1027738f411afdbc239789edd6c96dd1db412fc4a42cead5c1ac98a8aef94f35102f5de1049e64c07a languageName: node linkType: hard -"@babel/plugin-transform-regexp-modifiers@npm:^7.26.0": +"@babel/plugin-transform-regexp-modifiers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.27.1" dependencies: @@ -1646,7 +1555,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.25.9": +"@babel/plugin-transform-reserved-words@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" dependencies: @@ -1657,23 +1566,23 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-runtime@npm:7.26.10": - version: 7.26.10 - resolution: "@babel/plugin-transform-runtime@npm:7.26.10" +"@babel/plugin-transform-runtime@npm:7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-runtime@npm:7.27.1" dependencies: - "@babel/helper-module-imports": "npm:^7.25.9" - "@babel/helper-plugin-utils": "npm:^7.26.5" + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.11.0" babel-plugin-polyfill-regenerator: "npm:^0.6.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/4b70a63b904a3f7faa6ca95f9034d2f29330764820b06cf1814dda4ab0482b233a28241e98d8497bc1690dd31972e72861d8534ae0e37f26e04637e7d615e43d + checksum: 10c0/7abbae60a6441ba8546dee3fcbc00b38038304250ba2419adaf0c76267bff43420ff75b7049003a24a829e01d9fde2ac8a422352af6d88aebd31996a83f04c2f languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.25.9": +"@babel/plugin-transform-shorthand-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" dependencies: @@ -1684,7 +1593,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.25.9": +"@babel/plugin-transform-spread@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-spread@npm:7.27.1" dependencies: @@ -1696,7 +1605,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.25.9": +"@babel/plugin-transform-sticky-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" dependencies: @@ -1707,7 +1616,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.26.8": +"@babel/plugin-transform-template-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" dependencies: @@ -1718,7 +1627,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.26.7": +"@babel/plugin-transform-typeof-symbol@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-typeof-symbol@npm:7.27.1" dependencies: @@ -1729,7 +1638,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.25.9": +"@babel/plugin-transform-unicode-escapes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" dependencies: @@ -1740,7 +1649,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.25.9": +"@babel/plugin-transform-unicode-property-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.27.1" dependencies: @@ -1752,7 +1661,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.25.9": +"@babel/plugin-transform-unicode-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" dependencies: @@ -1764,7 +1673,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.9": +"@babel/plugin-transform-unicode-sets-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.27.1" dependencies: @@ -1776,73 +1685,73 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:7.26.9": - version: 7.26.9 - resolution: "@babel/preset-env@npm:7.26.9" +"@babel/preset-env@npm:7.27.2": + version: 7.27.2 + resolution: "@babel/preset-env@npm:7.27.2" dependencies: - "@babel/compat-data": "npm:^7.26.8" - "@babel/helper-compilation-targets": "npm:^7.26.5" - "@babel/helper-plugin-utils": "npm:^7.26.5" - "@babel/helper-validator-option": "npm:^7.25.9" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.9" - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.9" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.9" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.25.9" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.9" + "@babel/compat-data": "npm:^7.27.2" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.27.1" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.27.1" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions": "npm:^7.26.0" - "@babel/plugin-syntax-import-attributes": "npm:^7.26.0" + "@babel/plugin-syntax-import-assertions": "npm:^7.27.1" + "@babel/plugin-syntax-import-attributes": "npm:^7.27.1" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" - "@babel/plugin-transform-arrow-functions": "npm:^7.25.9" - "@babel/plugin-transform-async-generator-functions": "npm:^7.26.8" - "@babel/plugin-transform-async-to-generator": "npm:^7.25.9" - "@babel/plugin-transform-block-scoped-functions": "npm:^7.26.5" - "@babel/plugin-transform-block-scoping": "npm:^7.25.9" - "@babel/plugin-transform-class-properties": "npm:^7.25.9" - "@babel/plugin-transform-class-static-block": "npm:^7.26.0" - "@babel/plugin-transform-classes": "npm:^7.25.9" - "@babel/plugin-transform-computed-properties": "npm:^7.25.9" - "@babel/plugin-transform-destructuring": "npm:^7.25.9" - "@babel/plugin-transform-dotall-regex": "npm:^7.25.9" - "@babel/plugin-transform-duplicate-keys": "npm:^7.25.9" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.9" - "@babel/plugin-transform-dynamic-import": "npm:^7.25.9" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.26.3" - "@babel/plugin-transform-export-namespace-from": "npm:^7.25.9" - "@babel/plugin-transform-for-of": "npm:^7.26.9" - "@babel/plugin-transform-function-name": "npm:^7.25.9" - "@babel/plugin-transform-json-strings": "npm:^7.25.9" - "@babel/plugin-transform-literals": "npm:^7.25.9" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.25.9" - "@babel/plugin-transform-member-expression-literals": "npm:^7.25.9" - "@babel/plugin-transform-modules-amd": "npm:^7.25.9" - "@babel/plugin-transform-modules-commonjs": "npm:^7.26.3" - "@babel/plugin-transform-modules-systemjs": "npm:^7.25.9" - "@babel/plugin-transform-modules-umd": "npm:^7.25.9" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.25.9" - "@babel/plugin-transform-new-target": "npm:^7.25.9" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.26.6" - "@babel/plugin-transform-numeric-separator": "npm:^7.25.9" - "@babel/plugin-transform-object-rest-spread": "npm:^7.25.9" - "@babel/plugin-transform-object-super": "npm:^7.25.9" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.25.9" - "@babel/plugin-transform-optional-chaining": "npm:^7.25.9" - "@babel/plugin-transform-parameters": "npm:^7.25.9" - "@babel/plugin-transform-private-methods": "npm:^7.25.9" - "@babel/plugin-transform-private-property-in-object": "npm:^7.25.9" - "@babel/plugin-transform-property-literals": "npm:^7.25.9" - "@babel/plugin-transform-regenerator": "npm:^7.25.9" - "@babel/plugin-transform-regexp-modifiers": "npm:^7.26.0" - "@babel/plugin-transform-reserved-words": "npm:^7.25.9" - "@babel/plugin-transform-shorthand-properties": "npm:^7.25.9" - "@babel/plugin-transform-spread": "npm:^7.25.9" - "@babel/plugin-transform-sticky-regex": "npm:^7.25.9" - "@babel/plugin-transform-template-literals": "npm:^7.26.8" - "@babel/plugin-transform-typeof-symbol": "npm:^7.26.7" - "@babel/plugin-transform-unicode-escapes": "npm:^7.25.9" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.25.9" - "@babel/plugin-transform-unicode-regex": "npm:^7.25.9" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.25.9" + "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" + "@babel/plugin-transform-async-generator-functions": "npm:^7.27.1" + "@babel/plugin-transform-async-to-generator": "npm:^7.27.1" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.27.1" + "@babel/plugin-transform-block-scoping": "npm:^7.27.1" + "@babel/plugin-transform-class-properties": "npm:^7.27.1" + "@babel/plugin-transform-class-static-block": "npm:^7.27.1" + "@babel/plugin-transform-classes": "npm:^7.27.1" + "@babel/plugin-transform-computed-properties": "npm:^7.27.1" + "@babel/plugin-transform-destructuring": "npm:^7.27.1" + "@babel/plugin-transform-dotall-regex": "npm:^7.27.1" + "@babel/plugin-transform-duplicate-keys": "npm:^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.27.1" + "@babel/plugin-transform-dynamic-import": "npm:^7.27.1" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.27.1" + "@babel/plugin-transform-export-namespace-from": "npm:^7.27.1" + "@babel/plugin-transform-for-of": "npm:^7.27.1" + "@babel/plugin-transform-function-name": "npm:^7.27.1" + "@babel/plugin-transform-json-strings": "npm:^7.27.1" + "@babel/plugin-transform-literals": "npm:^7.27.1" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.27.1" + "@babel/plugin-transform-member-expression-literals": "npm:^7.27.1" + "@babel/plugin-transform-modules-amd": "npm:^7.27.1" + "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" + "@babel/plugin-transform-modules-systemjs": "npm:^7.27.1" + "@babel/plugin-transform-modules-umd": "npm:^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.27.1" + "@babel/plugin-transform-new-target": "npm:^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.27.1" + "@babel/plugin-transform-numeric-separator": "npm:^7.27.1" + "@babel/plugin-transform-object-rest-spread": "npm:^7.27.2" + "@babel/plugin-transform-object-super": "npm:^7.27.1" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.27.1" + "@babel/plugin-transform-optional-chaining": "npm:^7.27.1" + "@babel/plugin-transform-parameters": "npm:^7.27.1" + "@babel/plugin-transform-private-methods": "npm:^7.27.1" + "@babel/plugin-transform-private-property-in-object": "npm:^7.27.1" + "@babel/plugin-transform-property-literals": "npm:^7.27.1" + "@babel/plugin-transform-regenerator": "npm:^7.27.1" + "@babel/plugin-transform-regexp-modifiers": "npm:^7.27.1" + "@babel/plugin-transform-reserved-words": "npm:^7.27.1" + "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" + "@babel/plugin-transform-spread": "npm:^7.27.1" + "@babel/plugin-transform-sticky-regex": "npm:^7.27.1" + "@babel/plugin-transform-template-literals": "npm:^7.27.1" + "@babel/plugin-transform-typeof-symbol": "npm:^7.27.1" + "@babel/plugin-transform-unicode-escapes": "npm:^7.27.1" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.27.1" "@babel/preset-modules": "npm:0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.11.0" @@ -1851,7 +1760,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6812ca76bd38165a58fe8354bab5e7204e1aa17d8b9270bd8f8babb08cc7fa94cd29525fe41b553f2ba0e84033d566f10da26012b8ee0f81897005c5225d0051 + checksum: 10c0/fd7ec310832a9ff26ed8d56bc0832cdbdb3a188e022050b74790796650649fb8373568af05b320b58b3ff922507979bad50ff95a4d504ab0081134480103504e languageName: node linkType: hard @@ -1868,16 +1777,14 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:7.26.10": - version: 7.26.10 - resolution: "@babel/runtime@npm:7.26.10" - dependencies: - regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/6dc6d88c7908f505c4f7770fb4677dfa61f68f659b943c2be1f2a99cb6680343462867abf2d49822adc435932919b36c77ac60125793e719ea8745f2073d3745 +"@babel/runtime@npm:7.27.1": + version: 7.27.1 + resolution: "@babel/runtime@npm:7.27.1" + checksum: 10c0/530a7332f86ac5a7442250456823a930906911d895c0b743bf1852efc88a20a016ed4cd26d442d0ca40ae6d5448111e02a08dd638a4f1064b47d080e2875dc05 languageName: node linkType: hard -"@babel/template@npm:^7.26.9, @babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2": +"@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2": version: 7.27.2 resolution: "@babel/template@npm:7.27.2" dependencies: @@ -1888,7 +1795,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.26.8, @babel/traverse@npm:^7.27.1": +"@babel/traverse@npm:^7.27.1": version: 7.27.1 resolution: "@babel/traverse@npm:7.27.1" dependencies: @@ -1903,7 +1810,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.27.4": +"@babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.27.4, @babel/traverse@npm:^7.27.7": version: 7.27.7 resolution: "@babel/traverse@npm:7.27.7" dependencies: @@ -1918,7 +1825,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.4.4": +"@babel/types@npm:^7.24.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.4.4": version: 7.27.1 resolution: "@babel/types@npm:7.27.1" dependencies: @@ -1972,13 +1879,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/aix-ppc64@npm:0.25.1" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/aix-ppc64@npm:0.25.4": version: 0.25.4 resolution: "@esbuild/aix-ppc64@npm:0.25.4" @@ -1986,10 +1886,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/android-arm64@npm:0.25.1" - conditions: os=android & cpu=arm64 +"@esbuild/aix-ppc64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/aix-ppc64@npm:0.25.5" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -2000,10 +1900,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/android-arm@npm:0.25.1" - conditions: os=android & cpu=arm +"@esbuild/android-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-arm64@npm:0.25.5" + conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2014,10 +1914,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/android-x64@npm:0.25.1" - conditions: os=android & cpu=x64 +"@esbuild/android-arm@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-arm@npm:0.25.5" + conditions: os=android & cpu=arm languageName: node linkType: hard @@ -2028,10 +1928,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/darwin-arm64@npm:0.25.1" - conditions: os=darwin & cpu=arm64 +"@esbuild/android-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-x64@npm:0.25.5" + conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -2042,10 +1942,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/darwin-x64@npm:0.25.1" - conditions: os=darwin & cpu=x64 +"@esbuild/darwin-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/darwin-arm64@npm:0.25.5" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -2056,10 +1956,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/freebsd-arm64@npm:0.25.1" - conditions: os=freebsd & cpu=arm64 +"@esbuild/darwin-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/darwin-x64@npm:0.25.5" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2070,10 +1970,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/freebsd-x64@npm:0.25.1" - conditions: os=freebsd & cpu=x64 +"@esbuild/freebsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/freebsd-arm64@npm:0.25.5" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2084,10 +1984,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-arm64@npm:0.25.1" - conditions: os=linux & cpu=arm64 +"@esbuild/freebsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/freebsd-x64@npm:0.25.5" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2098,10 +1998,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-arm@npm:0.25.1" - conditions: os=linux & cpu=arm +"@esbuild/linux-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-arm64@npm:0.25.5" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2112,10 +2012,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-ia32@npm:0.25.1" - conditions: os=linux & cpu=ia32 +"@esbuild/linux-arm@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-arm@npm:0.25.5" + conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2126,10 +2026,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-loong64@npm:0.25.1" - conditions: os=linux & cpu=loong64 +"@esbuild/linux-ia32@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-ia32@npm:0.25.5" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2140,10 +2040,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-mips64el@npm:0.25.1" - conditions: os=linux & cpu=mips64el +"@esbuild/linux-loong64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-loong64@npm:0.25.5" + conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2154,10 +2054,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-ppc64@npm:0.25.1" - conditions: os=linux & cpu=ppc64 +"@esbuild/linux-mips64el@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-mips64el@npm:0.25.5" + conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2168,10 +2068,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-riscv64@npm:0.25.1" - conditions: os=linux & cpu=riscv64 +"@esbuild/linux-ppc64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-ppc64@npm:0.25.5" + conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2182,10 +2082,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-s390x@npm:0.25.1" - conditions: os=linux & cpu=s390x +"@esbuild/linux-riscv64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-riscv64@npm:0.25.5" + conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2196,10 +2096,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/linux-x64@npm:0.25.1" - conditions: os=linux & cpu=x64 +"@esbuild/linux-s390x@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-s390x@npm:0.25.5" + conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2210,10 +2110,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/netbsd-arm64@npm:0.25.1" - conditions: os=netbsd & cpu=arm64 +"@esbuild/linux-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-x64@npm:0.25.5" + conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2224,10 +2124,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/netbsd-x64@npm:0.25.1" - conditions: os=netbsd & cpu=x64 +"@esbuild/netbsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/netbsd-arm64@npm:0.25.5" + conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard @@ -2238,10 +2138,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/openbsd-arm64@npm:0.25.1" - conditions: os=openbsd & cpu=arm64 +"@esbuild/netbsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/netbsd-x64@npm:0.25.5" + conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2252,10 +2152,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/openbsd-x64@npm:0.25.1" - conditions: os=openbsd & cpu=x64 +"@esbuild/openbsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/openbsd-arm64@npm:0.25.5" + conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -2266,10 +2166,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/sunos-x64@npm:0.25.1" - conditions: os=sunos & cpu=x64 +"@esbuild/openbsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/openbsd-x64@npm:0.25.5" + conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -2280,10 +2180,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/win32-arm64@npm:0.25.1" - conditions: os=win32 & cpu=arm64 +"@esbuild/sunos-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/sunos-x64@npm:0.25.5" + conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -2294,10 +2194,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/win32-ia32@npm:0.25.1" - conditions: os=win32 & cpu=ia32 +"@esbuild/win32-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-arm64@npm:0.25.5" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -2308,10 +2208,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.1": - version: 0.25.1 - resolution: "@esbuild/win32-x64@npm:0.25.1" - conditions: os=win32 & cpu=x64 +"@esbuild/win32-ia32@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-ia32@npm:0.25.5" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -2322,6 +2222,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-x64@npm:0.25.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.7.0 resolution: "@eslint-community/eslint-utils@npm:4.7.0" @@ -2414,18 +2321,18 @@ __metadata: languageName: node linkType: hard -"@inquirer/confirm@npm:5.1.6": - version: 5.1.6 - resolution: "@inquirer/confirm@npm:5.1.6" +"@inquirer/confirm@npm:5.1.10": + version: 5.1.10 + resolution: "@inquirer/confirm@npm:5.1.10" dependencies: - "@inquirer/core": "npm:^10.1.7" - "@inquirer/type": "npm:^3.0.4" + "@inquirer/core": "npm:^10.1.11" + "@inquirer/type": "npm:^3.0.6" peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 10c0/57b667f8096ec261504b613656e7b7718a238a73e059870a2b8e97c3127bc50085251100ed371250733b7cc5cd68122d8694d6a04a46de95d08bb590a8437b11 + checksum: 10c0/71a1b1c1007b0edd06984c356a9e13764ca917bdbf947a59ce0f55084d36e653daffe56b3806fc9959337aae80ff7b37eeaf01a40746e5f60de86475fdf0502a languageName: node linkType: hard @@ -2444,7 +2351,7 @@ __metadata: languageName: node linkType: hard -"@inquirer/core@npm:^10.1.13": +"@inquirer/core@npm:^10.1.11, @inquirer/core@npm:^10.1.13": version: 10.1.13 resolution: "@inquirer/core@npm:10.1.13" dependencies: @@ -2465,27 +2372,6 @@ __metadata: languageName: node linkType: hard -"@inquirer/core@npm:^10.1.7": - version: 10.1.10 - resolution: "@inquirer/core@npm:10.1.10" - dependencies: - "@inquirer/figures": "npm:^1.0.11" - "@inquirer/type": "npm:^3.0.6" - ansi-escapes: "npm:^4.3.2" - cli-width: "npm:^4.1.0" - mute-stream: "npm:^2.0.0" - signal-exit: "npm:^4.1.0" - wrap-ansi: "npm:^6.2.0" - yoctocolors-cjs: "npm:^2.1.2" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 10c0/8d0a3b725e42e40efbdc6ed087283795f1e36e642b119dd7dd3cbf31fce74bdbdb1b987da16159cd2475f45b2ede7e33293ae92bad3ac481832889c230df3fc0 - languageName: node - linkType: hard - "@inquirer/editor@npm:^4.2.11": version: 4.2.13 resolution: "@inquirer/editor@npm:4.2.13" @@ -2518,13 +2404,6 @@ __metadata: languageName: node linkType: hard -"@inquirer/figures@npm:^1.0.11": - version: 1.0.11 - resolution: "@inquirer/figures@npm:1.0.11" - checksum: 10c0/6270e24eebbe42bbc4e7f8e761e906be66b4896787f31ab3e7484ad271c8edc90bce4ec20e232a5da447aee4fc73803397b2dda8cf645f4f7eea83e773b44e1e - languageName: node - linkType: hard - "@inquirer/figures@npm:^1.0.12": version: 1.0.12 resolution: "@inquirer/figures@npm:1.0.12" @@ -2661,7 +2540,7 @@ __metadata: languageName: node linkType: hard -"@inquirer/type@npm:^3.0.4, @inquirer/type@npm:^3.0.6": +"@inquirer/type@npm:^3.0.6": version: 3.0.6 resolution: "@inquirer/type@npm:3.0.6" peerDependencies: @@ -2827,44 +2706,51 @@ __metadata: languageName: node linkType: hard -"@lmdb/lmdb-darwin-arm64@npm:3.2.6": - version: 3.2.6 - resolution: "@lmdb/lmdb-darwin-arm64@npm:3.2.6" +"@lmdb/lmdb-darwin-arm64@npm:3.3.0": + version: 3.3.0 + resolution: "@lmdb/lmdb-darwin-arm64@npm:3.3.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@lmdb/lmdb-darwin-x64@npm:3.2.6": - version: 3.2.6 - resolution: "@lmdb/lmdb-darwin-x64@npm:3.2.6" +"@lmdb/lmdb-darwin-x64@npm:3.3.0": + version: 3.3.0 + resolution: "@lmdb/lmdb-darwin-x64@npm:3.3.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@lmdb/lmdb-linux-arm64@npm:3.2.6": - version: 3.2.6 - resolution: "@lmdb/lmdb-linux-arm64@npm:3.2.6" +"@lmdb/lmdb-linux-arm64@npm:3.3.0": + version: 3.3.0 + resolution: "@lmdb/lmdb-linux-arm64@npm:3.3.0" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@lmdb/lmdb-linux-arm@npm:3.2.6": - version: 3.2.6 - resolution: "@lmdb/lmdb-linux-arm@npm:3.2.6" +"@lmdb/lmdb-linux-arm@npm:3.3.0": + version: 3.3.0 + resolution: "@lmdb/lmdb-linux-arm@npm:3.3.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@lmdb/lmdb-linux-x64@npm:3.2.6": - version: 3.2.6 - resolution: "@lmdb/lmdb-linux-x64@npm:3.2.6" +"@lmdb/lmdb-linux-x64@npm:3.3.0": + version: 3.3.0 + resolution: "@lmdb/lmdb-linux-x64@npm:3.3.0" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@lmdb/lmdb-win32-x64@npm:3.2.6": - version: 3.2.6 - resolution: "@lmdb/lmdb-win32-x64@npm:3.2.6" +"@lmdb/lmdb-win32-arm64@npm:3.3.0": + version: 3.3.0 + resolution: "@lmdb/lmdb-win32-arm64@npm:3.3.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@lmdb/lmdb-win32-x64@npm:3.3.0": + version: 3.3.0 + resolution: "@lmdb/lmdb-win32-x64@npm:3.3.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3080,14 +2966,14 @@ __metadata: languageName: node linkType: hard -"@ngtools/webpack@npm:19.2.10": - version: 19.2.10 - resolution: "@ngtools/webpack@npm:19.2.10" +"@ngtools/webpack@npm:20.0.4": + version: 20.0.4 + resolution: "@ngtools/webpack@npm:20.0.4" peerDependencies: - "@angular/compiler-cli": ^19.0.0 || ^19.2.0-next.0 - typescript: ">=5.5 <5.9" + "@angular/compiler-cli": ^20.0.0 + typescript: ">=5.8 <5.9" webpack: ^5.54.0 - checksum: 10c0/0b9c43df6c19baf61af16272d73ad915174d87109436f6d96ba807adc3b94c1767cf83f679ec79dbc9eb913767fb3ef521dee948f7bb6ec996224445f3cfb6f9 + checksum: 10c0/52a692495ebf92687786b4231e1bf27c9af553c21be12a18939cdc2b0afec6a902170647f2a2642ecc45d4d7737b4139eafd518fb7cccf970b7fd207a8a858c4 languageName: node linkType: hard @@ -3437,13 +3323,6 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.34.8" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@rollup/rollup-android-arm-eabi@npm:4.40.2": version: 4.40.2 resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.2" @@ -3451,10 +3330,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-android-arm64@npm:4.34.8" - conditions: os=android & cpu=arm64 +"@rollup/rollup-android-arm-eabi@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.44.1" + conditions: os=android & cpu=arm languageName: node linkType: hard @@ -3465,10 +3344,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-darwin-arm64@npm:4.34.8" - conditions: os=darwin & cpu=arm64 +"@rollup/rollup-android-arm64@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-android-arm64@npm:4.44.1" + conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -3479,10 +3358,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-darwin-x64@npm:4.34.8" - conditions: os=darwin & cpu=x64 +"@rollup/rollup-darwin-arm64@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.44.1" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -3493,10 +3372,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.34.8" - conditions: os=freebsd & cpu=arm64 +"@rollup/rollup-darwin-x64@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.44.1" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -3507,10 +3386,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-freebsd-x64@npm:4.34.8" - conditions: os=freebsd & cpu=x64 +"@rollup/rollup-freebsd-arm64@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.44.1" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -3521,10 +3400,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.34.8" - conditions: os=linux & cpu=arm & libc=glibc +"@rollup/rollup-freebsd-x64@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-freebsd-x64@npm:4.44.1" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -3535,10 +3414,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.34.8" - conditions: os=linux & cpu=arm & libc=musl +"@rollup/rollup-linux-arm-gnueabihf@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.44.1" + conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard @@ -3549,10 +3428,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.34.8" - conditions: os=linux & cpu=arm64 & libc=glibc +"@rollup/rollup-linux-arm-musleabihf@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.44.1" + conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard @@ -3563,10 +3442,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.34.8" - conditions: os=linux & cpu=arm64 & libc=musl +"@rollup/rollup-linux-arm64-gnu@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.44.1" + conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -3577,10 +3456,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.34.8" - conditions: os=linux & cpu=loong64 & libc=glibc +"@rollup/rollup-linux-arm64-musl@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.44.1" + conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -3591,10 +3470,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.8" - conditions: os=linux & cpu=ppc64 & libc=glibc +"@rollup/rollup-linux-loongarch64-gnu@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.44.1" + conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard @@ -3605,10 +3484,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.34.8" - conditions: os=linux & cpu=riscv64 & libc=glibc +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.44.1" + conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard @@ -3619,6 +3498,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.44.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-musl@npm:4.40.2": version: 4.40.2 resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.40.2" @@ -3626,10 +3512,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.34.8" - conditions: os=linux & cpu=s390x & libc=glibc +"@rollup/rollup-linux-riscv64-musl@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.44.1" + conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard @@ -3640,10 +3526,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.34.8" - conditions: os=linux & cpu=x64 & libc=glibc +"@rollup/rollup-linux-s390x-gnu@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.44.1" + conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard @@ -3654,10 +3540,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.34.8" - conditions: os=linux & cpu=x64 & libc=musl +"@rollup/rollup-linux-x64-gnu@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.44.1" + conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -3668,10 +3554,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.34.8" - conditions: os=win32 & cpu=arm64 +"@rollup/rollup-linux-x64-musl@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.44.1" + conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -3682,10 +3568,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.34.8" - conditions: os=win32 & cpu=ia32 +"@rollup/rollup-win32-arm64-msvc@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.44.1" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -3696,10 +3582,10 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.34.8": - version: 4.34.8 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.34.8" - conditions: os=win32 & cpu=x64 +"@rollup/rollup-win32-ia32-msvc@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.44.1" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -3710,6 +3596,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.44.1": + version: 4.44.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.44.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rollup/wasm-node@npm:^4.24.0": version: 4.40.2 resolution: "@rollup/wasm-node@npm:4.40.2" @@ -3794,13 +3687,6 @@ __metadata: languageName: node linkType: hard -"@sindresorhus/merge-streams@npm:^2.1.0": - version: 2.3.0 - resolution: "@sindresorhus/merge-streams@npm:2.3.0" - checksum: 10c0/69ee906f3125fb2c6bb6ec5cdd84e8827d93b49b3892bce8b62267116cc7e197b5cccf20c160a1d32c26014ecd14470a72a5e3ee37a58f1d6dadc0db1ccf3894 - languageName: node - linkType: hard - "@socket.io/component-emitter@npm:~3.1.0": version: 3.1.2 resolution: "@socket.io/component-emitter@npm:3.1.2" @@ -4035,10 +3921,10 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:1.0.6": - version: 1.0.6 - resolution: "@types/estree@npm:1.0.6" - checksum: 10c0/cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a +"@types/estree@npm:1.0.8": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 languageName: node linkType: hard @@ -4054,7 +3940,7 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:^4.17.33": +"@types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33": version: 4.19.6 resolution: "@types/express-serve-static-core@npm:4.19.6" dependencies: @@ -4163,7 +4049,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db @@ -4528,12 +4414,12 @@ __metadata: languageName: node linkType: hard -"@vitejs/plugin-basic-ssl@npm:1.2.0": - version: 1.2.0 - resolution: "@vitejs/plugin-basic-ssl@npm:1.2.0" +"@vitejs/plugin-basic-ssl@npm:2.0.0": + version: 2.0.0 + resolution: "@vitejs/plugin-basic-ssl@npm:2.0.0" peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - checksum: 10c0/0d360fcca01f91ade6e451edbea09a107ff9e95cd3c3766c7a069d1a168709df92d96c0bd1eccc66e2739a153e07c75a45321ec487450c0da942606200d8441d + vite: ^6.0.0 + checksum: 10c0/673f46dc5ee042f6fcfa7ecf514e717e770085f8979d4608cab952f3e9003fe7aed589cc812a67f3dcd5e80655975c6490ce8a07a4b6feef98766003256d4283 languageName: node linkType: hard @@ -5491,21 +5377,21 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:10.4.20": - version: 10.4.20 - resolution: "autoprefixer@npm:10.4.20" +"autoprefixer@npm:10.4.21": + version: 10.4.21 + resolution: "autoprefixer@npm:10.4.21" dependencies: - browserslist: "npm:^4.23.3" - caniuse-lite: "npm:^1.0.30001646" + browserslist: "npm:^4.24.4" + caniuse-lite: "npm:^1.0.30001702" fraction.js: "npm:^4.3.7" normalize-range: "npm:^0.1.2" - picocolors: "npm:^1.0.1" + picocolors: "npm:^1.1.1" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.1.0 bin: autoprefixer: bin/autoprefixer - checksum: 10c0/e1f00978a26e7c5b54ab12036d8c13833fad7222828fc90914771b1263f51b28c7ddb5803049de4e77696cbd02bb25cfc3634e80533025bb26c26aacdf938940 + checksum: 10c0/de5b71d26d0baff4bbfb3d59f7cf7114a6030c9eeb66167acf49a32c5b61c68e308f1e0f869d92334436a221035d08b51cd1b2f2c4689b8d955149423c16d4d4 languageName: node linkType: hard @@ -5546,16 +5432,15 @@ __metadata: languageName: node linkType: hard -"babel-loader@npm:9.2.1": - version: 9.2.1 - resolution: "babel-loader@npm:9.2.1" +"babel-loader@npm:10.0.0": + version: 10.0.0 + resolution: "babel-loader@npm:10.0.0" dependencies: - find-cache-dir: "npm:^4.0.0" - schema-utils: "npm:^4.0.0" + find-up: "npm:^5.0.0" peerDependencies: "@babel/core": ^7.12.0 - webpack: ">=5" - checksum: 10c0/efb82faff4c7c27e9c15bb28bf11c73200e61cf365118a9514e8d74dd489d0afc2a0d5aaa62cb4254eefc2ab631579224d95a03fd245410f28ea75e24de54ba4 + webpack: ">=5.61.0" + checksum: 10c0/882dfacde3ee24b432ad57e468832cd0821e2a410f6c5b75ff945f069a8956592b28c6c357df5bb03db73d2741ec3db5febb106ac0bb3591c3d4288f2cf4df0e languageName: node linkType: hard @@ -5720,9 +5605,9 @@ __metadata: languageName: node linkType: hard -"beasties@npm:0.3.2": - version: 0.3.2 - resolution: "beasties@npm:0.3.2" +"beasties@npm:0.3.4": + version: 0.3.4 + resolution: "beasties@npm:0.3.4" dependencies: css-select: "npm:^5.1.0" css-what: "npm:^6.1.0" @@ -5732,7 +5617,7 @@ __metadata: picocolors: "npm:^1.1.1" postcss: "npm:^8.4.49" postcss-media-query-parser: "npm:^0.2.3" - checksum: 10c0/ed6d4356f8b0448ce360eabfba80bd3d9f8d6592a6dc2fa78467e6522da62fee87d8116d7b94aa695dc51bef18f332b3962435a414b759939264a8754702faa3 + checksum: 10c0/e87d6eac3c2bb370789ae50a6e0818451694979bef05383283119fe2098ba6b92ab8210d68437adfb816d24b87b91a4716691e6d604e8876d5330ecc0e1c8c35 languageName: node linkType: hard @@ -5882,7 +5767,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.21.5, browserslist@npm:^4.22.1, browserslist@npm:^4.23.0, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4": +"browserslist@npm:^4.21.5, browserslist@npm:^4.22.1, browserslist@npm:^4.23.0, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4": version: 4.24.5 resolution: "browserslist@npm:4.24.5" dependencies: @@ -6045,7 +5930,14 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001716": +"caniuse-lite@npm:^1.0.30001702": + version: 1.0.30001726 + resolution: "caniuse-lite@npm:1.0.30001726" + checksum: 10c0/2c5f91da7fd9ebf8c6b432818b1498ea28aca8de22b30dafabe2a2a6da1e014f10e67e14f8e68e872a0867b6b4cd6001558dde04e3ab9770c9252ca5c8849d0e + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001716": version: 1.0.30001717 resolution: "caniuse-lite@npm:1.0.30001717" checksum: 10c0/6c0bb1e5182fd578ebe97ee2203250849754a4e17d985839fab527ad27e125a4c4ffce3ece5505217fedf30ea0bbc17ac9f93e9ac525c0389ccba61c6e8345dc @@ -6460,10 +6352,10 @@ __metadata: languageName: node linkType: hard -"commander@npm:^13.0.0": - version: 13.1.0 - resolution: "commander@npm:13.1.0" - checksum: 10c0/7b8c5544bba704fbe84b7cab2e043df8586d5c114a4c5b607f83ae5060708940ed0b5bd5838cf8ce27539cde265c1cbd59ce3c8c6b017ed3eec8943e3a415164 +"commander@npm:^14.0.0": + version: 14.0.0 + resolution: "commander@npm:14.0.0" + checksum: 10c0/73c4babfa558077868d84522b11ef56834165d472b9e86a634cd4c3ae7fc72d59af6377d8878e06bd570fe8f3161eced3cbe383c38f7093272bb65bd242b595b languageName: node linkType: hard @@ -6650,19 +6542,18 @@ __metadata: languageName: node linkType: hard -"copy-webpack-plugin@npm:12.0.2": - version: 12.0.2 - resolution: "copy-webpack-plugin@npm:12.0.2" +"copy-webpack-plugin@npm:13.0.0": + version: 13.0.0 + resolution: "copy-webpack-plugin@npm:13.0.0" dependencies: - fast-glob: "npm:^3.3.2" glob-parent: "npm:^6.0.1" - globby: "npm:^14.0.0" normalize-path: "npm:^3.0.0" schema-utils: "npm:^4.2.0" serialize-javascript: "npm:^6.0.2" + tinyglobby: "npm:^0.2.12" peerDependencies: webpack: ^5.1.0 - checksum: 10c0/1a2715a1280a37b81b7040b89ed962db4aa75475b164f84f266fa4e81f209269b13f8bff10b104dff7558854bafedcdd4f30c40fd23ecd8fa28af45516b459cd + checksum: 10c0/955037f77c6beb249b690710c35bacceb03b61bb5b7c5fc59ac7dff122c706eb794ef601bc3d9bbdb1350bda3e2615e0b43bf33f1ce2ca14ed934d9a89f43637 languageName: node linkType: hard @@ -7473,7 +7364,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^4.2.0, entities@npm:^4.3.0": +"entities@npm:^4.2.0": version: 4.5.0 resolution: "entities@npm:4.5.0" checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 @@ -7672,44 +7563,44 @@ __metadata: languageName: node linkType: hard -"esbuild-wasm@npm:0.25.1": - version: 0.25.1 - resolution: "esbuild-wasm@npm:0.25.1" +"esbuild-wasm@npm:0.25.5": + version: 0.25.5 + resolution: "esbuild-wasm@npm:0.25.5" bin: esbuild: bin/esbuild - checksum: 10c0/9cc20c0f1c31c686f26202b86279a80307225ac82e52f1713d2971638baf7afd7e89ab5602648f53e1b9c331b7bfea99a76a75e38bb310ecb18c655fa7a9fd63 - languageName: node - linkType: hard - -"esbuild@npm:0.25.1": - version: 0.25.1 - resolution: "esbuild@npm:0.25.1" - dependencies: - "@esbuild/aix-ppc64": "npm:0.25.1" - "@esbuild/android-arm": "npm:0.25.1" - "@esbuild/android-arm64": "npm:0.25.1" - "@esbuild/android-x64": "npm:0.25.1" - "@esbuild/darwin-arm64": "npm:0.25.1" - "@esbuild/darwin-x64": "npm:0.25.1" - "@esbuild/freebsd-arm64": "npm:0.25.1" - "@esbuild/freebsd-x64": "npm:0.25.1" - "@esbuild/linux-arm": "npm:0.25.1" - "@esbuild/linux-arm64": "npm:0.25.1" - "@esbuild/linux-ia32": "npm:0.25.1" - "@esbuild/linux-loong64": "npm:0.25.1" - "@esbuild/linux-mips64el": "npm:0.25.1" - "@esbuild/linux-ppc64": "npm:0.25.1" - "@esbuild/linux-riscv64": "npm:0.25.1" - "@esbuild/linux-s390x": "npm:0.25.1" - "@esbuild/linux-x64": "npm:0.25.1" - "@esbuild/netbsd-arm64": "npm:0.25.1" - "@esbuild/netbsd-x64": "npm:0.25.1" - "@esbuild/openbsd-arm64": "npm:0.25.1" - "@esbuild/openbsd-x64": "npm:0.25.1" - "@esbuild/sunos-x64": "npm:0.25.1" - "@esbuild/win32-arm64": "npm:0.25.1" - "@esbuild/win32-ia32": "npm:0.25.1" - "@esbuild/win32-x64": "npm:0.25.1" + checksum: 10c0/5893a8e09ec576154a2144989708998ec6081f2c6b6353cdba7df1d0ca9f12db8292302391ba04decdde45119a384cfbba19307c15c05991da826202f7357129 + languageName: node + linkType: hard + +"esbuild@npm:0.25.5": + version: 0.25.5 + resolution: "esbuild@npm:0.25.5" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.5" + "@esbuild/android-arm": "npm:0.25.5" + "@esbuild/android-arm64": "npm:0.25.5" + "@esbuild/android-x64": "npm:0.25.5" + "@esbuild/darwin-arm64": "npm:0.25.5" + "@esbuild/darwin-x64": "npm:0.25.5" + "@esbuild/freebsd-arm64": "npm:0.25.5" + "@esbuild/freebsd-x64": "npm:0.25.5" + "@esbuild/linux-arm": "npm:0.25.5" + "@esbuild/linux-arm64": "npm:0.25.5" + "@esbuild/linux-ia32": "npm:0.25.5" + "@esbuild/linux-loong64": "npm:0.25.5" + "@esbuild/linux-mips64el": "npm:0.25.5" + "@esbuild/linux-ppc64": "npm:0.25.5" + "@esbuild/linux-riscv64": "npm:0.25.5" + "@esbuild/linux-s390x": "npm:0.25.5" + "@esbuild/linux-x64": "npm:0.25.5" + "@esbuild/netbsd-arm64": "npm:0.25.5" + "@esbuild/netbsd-x64": "npm:0.25.5" + "@esbuild/openbsd-arm64": "npm:0.25.5" + "@esbuild/openbsd-x64": "npm:0.25.5" + "@esbuild/sunos-x64": "npm:0.25.5" + "@esbuild/win32-arm64": "npm:0.25.5" + "@esbuild/win32-ia32": "npm:0.25.5" + "@esbuild/win32-x64": "npm:0.25.5" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -7763,7 +7654,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10c0/80fca30dd0f21aec23fdfab34f0a8d5f55df5097dd7f475f2ab561d45662c32ee306f5649071cd1a0ba0614b164c48ca3dc3ee1551a4daf204b8af90e4d893f5 + checksum: 10c0/aba8cbc11927fa77562722ed5e95541ce2853f67ad7bdc40382b558abc2e0ec57d92ffb820f082ba2047b4ef9f3bc3da068cdebe30dfd3850cfa3827a78d604e languageName: node linkType: hard @@ -8445,7 +8336,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:3.3.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2, fast-glob@npm:^3.3.3": +"fast-glob@npm:3.3.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -8623,7 +8514,7 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^3.3.1, find-cache-dir@npm:^3.3.2": +"find-cache-dir@npm:^3.3.1": version: 3.3.2 resolution: "find-cache-dir@npm:3.3.2" dependencies: @@ -8634,13 +8525,13 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^4.0.0": - version: 4.0.0 - resolution: "find-cache-dir@npm:4.0.0" +"find-cache-directory@npm:^6.0.0": + version: 6.0.0 + resolution: "find-cache-directory@npm:6.0.0" dependencies: common-path-prefix: "npm:^3.0.0" - pkg-dir: "npm:^7.0.0" - checksum: 10c0/0faa7956974726c8769671de696d24c643ca1e5b8f7a2401283caa9e07a5da093293e0a0f4bd18c920ec981d2ef945c7f5b946cde268dfc9077d833ad0293cff + pkg-dir: "npm:^8.0.0" + checksum: 10c0/a4ac657f63bc3aac120f71d90dde0fe471b80d8d7572f2cd2c38499a27f30d87526b4590d217fb3732f5bf4a2d11e15d85e39ea12965731824e3e4da0e01b246 languageName: node linkType: hard @@ -8660,6 +8551,13 @@ __metadata: languageName: node linkType: hard +"find-up-simple@npm:^1.0.0": + version: 1.0.1 + resolution: "find-up-simple@npm:1.0.1" + checksum: 10c0/ad34de157b7db925d50ff78302fefb28e309f3bc947c93ffca0f9b0bccf9cf1a2dc57d805d5c94ec9fc60f4838f5dbdfd2a48ecd77c23015fa44c6dd5f60bc40 + languageName: node + linkType: hard + "find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -8680,16 +8578,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^6.3.0": - version: 6.3.0 - resolution: "find-up@npm:6.3.0" - dependencies: - locate-path: "npm:^7.1.0" - path-exists: "npm:^5.0.0" - checksum: 10c0/07e0314362d316b2b13f7f11ea4692d5191e718ca3f7264110127520f3347996349bf9e16805abae3e196805814bc66ef4bff2b8904dc4a6476085fc9b0eba07 - languageName: node - linkType: hard - "find-versions@npm:^4.0.0": version: 4.0.0 resolution: "find-versions@npm:4.0.0" @@ -9178,20 +9066,6 @@ __metadata: languageName: node linkType: hard -"globby@npm:^14.0.0": - version: 14.1.0 - resolution: "globby@npm:14.1.0" - dependencies: - "@sindresorhus/merge-streams": "npm:^2.1.0" - fast-glob: "npm:^3.3.3" - ignore: "npm:^7.0.3" - path-type: "npm:^6.0.0" - slash: "npm:^5.1.0" - unicorn-magic: "npm:^0.3.0" - checksum: 10c0/527a1063c5958255969620c6fa4444a2b2e9278caddd571d46dfbfa307cb15977afb746e84d682ba5b6c94fc081e8997f80ff05dd235441ba1cb16f86153e58e - languageName: node - linkType: hard - "globby@npm:^5.0.0": version: 5.0.0 resolution: "globby@npm:5.0.0" @@ -9670,10 +9544,10 @@ __metadata: languageName: node linkType: hard -"ignore@npm:6.0.2": - version: 6.0.2 - resolution: "ignore@npm:6.0.2" - checksum: 10c0/9a38feac1861906a78ba0f03e8ef3cd6b0526dce2a1a84e1009324b557763afeb9c3ebcc04666b21f7bbf71adda45e76781bb9e2eaa0903d45dcaded634454f5 +"ignore@npm:7.0.5": + version: 7.0.5 + resolution: "ignore@npm:7.0.5" + checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d languageName: node linkType: hard @@ -9684,13 +9558,6 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^7.0.3": - version: 7.0.4 - resolution: "ignore@npm:7.0.4" - checksum: 10c0/90e1f69ce352b9555caecd9cbfd07abe7626d312a6f90efbbb52c7edca6ea8df065d66303863b30154ab1502afb2da8bc59d5b04e1719a52ef75bbf675c488eb - languageName: node - linkType: hard - "image-size@npm:~0.5.0": version: 0.5.5 resolution: "image-size@npm:0.5.5" @@ -11126,9 +10993,9 @@ __metadata: languageName: node linkType: hard -"less-loader@npm:12.2.0": - version: 12.2.0 - resolution: "less-loader@npm:12.2.0" +"less-loader@npm:12.3.0": + version: 12.3.0 + resolution: "less-loader@npm:12.3.0" peerDependencies: "@rspack/core": 0.x || 1.x less: ^3.5.0 || ^4.0.0 @@ -11138,46 +11005,11 @@ __metadata: optional: true webpack: optional: true - checksum: 10c0/54eea545727930801d2ccc0b586332cd07d0f922b14ab7c8b3f03199944d770ac363081081ed2fda5f23da904336367cb2bb40007c033970dce25f7f9c906ba2 - languageName: node - linkType: hard - -"less@npm:4.2.2": - version: 4.2.2 - resolution: "less@npm:4.2.2" - dependencies: - copy-anything: "npm:^2.0.1" - errno: "npm:^0.1.1" - graceful-fs: "npm:^4.1.2" - image-size: "npm:~0.5.0" - make-dir: "npm:^2.1.0" - mime: "npm:^1.4.1" - needle: "npm:^3.1.0" - parse-node-version: "npm:^1.0.1" - source-map: "npm:~0.6.0" - tslib: "npm:^2.3.0" - dependenciesMeta: - errno: - optional: true - graceful-fs: - optional: true - image-size: - optional: true - make-dir: - optional: true - mime: - optional: true - needle: - optional: true - source-map: - optional: true - bin: - lessc: bin/lessc - checksum: 10c0/d472c203a41fb3722a9bf5677f5348e59d8b6589bf2e3933a77c305b42b2ebbe1e3accf145f05b6d2415ba1dad08add7803646947bf867eec7a2a279d758d99a + checksum: 10c0/11814ce601fe9a9a148f28643ffcb6041939b1142b21538c2c0a7a220f79e35f7eeffd4ac5f4d9495e41f1f25aabb98652fa18792d22eebb1d151716d8297332 languageName: node linkType: hard -"less@npm:^4.2.0": +"less@npm:4.3.0, less@npm:^4.2.0": version: 4.3.0 resolution: "less@npm:4.3.0" dependencies: @@ -11262,20 +11094,6 @@ __metadata: languageName: node linkType: hard -"listr2@npm:8.2.5": - version: 8.2.5 - resolution: "listr2@npm:8.2.5" - dependencies: - cli-truncate: "npm:^4.0.0" - colorette: "npm:^2.0.20" - eventemitter3: "npm:^5.0.1" - log-update: "npm:^6.1.0" - rfdc: "npm:^1.4.1" - wrap-ansi: "npm:^9.0.0" - checksum: 10c0/f5a9599514b00c27d7eb32d1117c83c61394b2a985ec20e542c798bf91cf42b19340215701522736f5b7b42f557e544afeadec47866e35e5d4f268f552729671 - languageName: node - linkType: hard - "listr2@npm:8.3.3": version: 8.3.3 resolution: "listr2@npm:8.3.3" @@ -11290,16 +11108,17 @@ __metadata: languageName: node linkType: hard -"lmdb@npm:3.2.6": - version: 3.2.6 - resolution: "lmdb@npm:3.2.6" - dependencies: - "@lmdb/lmdb-darwin-arm64": "npm:3.2.6" - "@lmdb/lmdb-darwin-x64": "npm:3.2.6" - "@lmdb/lmdb-linux-arm": "npm:3.2.6" - "@lmdb/lmdb-linux-arm64": "npm:3.2.6" - "@lmdb/lmdb-linux-x64": "npm:3.2.6" - "@lmdb/lmdb-win32-x64": "npm:3.2.6" +"lmdb@npm:3.3.0": + version: 3.3.0 + resolution: "lmdb@npm:3.3.0" + dependencies: + "@lmdb/lmdb-darwin-arm64": "npm:3.3.0" + "@lmdb/lmdb-darwin-x64": "npm:3.3.0" + "@lmdb/lmdb-linux-arm": "npm:3.3.0" + "@lmdb/lmdb-linux-arm64": "npm:3.3.0" + "@lmdb/lmdb-linux-x64": "npm:3.3.0" + "@lmdb/lmdb-win32-arm64": "npm:3.3.0" + "@lmdb/lmdb-win32-x64": "npm:3.3.0" msgpackr: "npm:^1.11.2" node-addon-api: "npm:^6.1.0" node-gyp: "npm:latest" @@ -11317,11 +11136,13 @@ __metadata: optional: true "@lmdb/lmdb-linux-x64": optional: true + "@lmdb/lmdb-win32-arm64": + optional: true "@lmdb/lmdb-win32-x64": optional: true bin: download-lmdb-prebuilds: bin/download-prebuilds.js - checksum: 10c0/1b7a4e17351f41ae5cbe79a8db7782f34f24484ffbcba6614b91c7d5d4431284c55d8912065e50d05598de0d6dcd0417608d3705d930a207fbf76019219cc43d + checksum: 10c0/91b22b552ad79ce39d05dc0025613fa9edd61762fadbac280c400fb0d7b680e3880833d7067e1f537ed3ef4376ea58c2a4b1ec79b83425866f2bce116e56f910 languageName: node linkType: hard @@ -11380,15 +11201,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^7.1.0": - version: 7.2.0 - resolution: "locate-path@npm:7.2.0" - dependencies: - p-locate: "npm:^6.0.0" - checksum: 10c0/139e8a7fe11cfbd7f20db03923cacfa5db9e14fa14887ea121345597472b4a63c1a42a8a5187defeeff6acf98fd568da7382aa39682d38f0af27433953a97751 - languageName: node - linkType: hard - "lodash.camelcase@npm:^4.3.0": version: 4.3.0 resolution: "lodash.camelcase@npm:4.3.0" @@ -11528,7 +11340,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:0.30.17": +"magic-string@npm:0.30.17, magic-string@npm:^0.30.17": version: 0.30.17 resolution: "magic-string@npm:0.30.17" dependencies: @@ -12180,36 +11992,37 @@ __metadata: languageName: node linkType: hard -"ng-packagr@npm:^19.0.0": - version: 19.2.2 - resolution: "ng-packagr@npm:19.2.2" +"ng-packagr@npm:^20.0.1": + version: 20.0.1 + resolution: "ng-packagr@npm:20.0.1" dependencies: + "@ampproject/remapping": "npm:^2.3.0" "@rollup/plugin-json": "npm:^6.1.0" "@rollup/wasm-node": "npm:^4.24.0" ajv: "npm:^8.17.1" ansi-colors: "npm:^4.1.3" browserslist: "npm:^4.22.1" chokidar: "npm:^4.0.1" - commander: "npm:^13.0.0" - convert-source-map: "npm:^2.0.0" + commander: "npm:^14.0.0" dependency-graph: "npm:^1.0.0" esbuild: "npm:^0.25.0" - fast-glob: "npm:^3.3.2" - find-cache-dir: "npm:^3.3.2" + find-cache-directory: "npm:^6.0.0" injection-js: "npm:^2.4.0" jsonc-parser: "npm:^3.3.1" less: "npm:^4.2.0" - ora: "npm:^5.1.0" - piscina: "npm:^4.7.0" + ora: "npm:^8.2.0" + piscina: "npm:^5.0.0" postcss: "npm:^8.4.47" rollup: "npm:^4.24.0" + rollup-plugin-dts: "npm:^6.2.0" rxjs: "npm:^7.8.1" sass: "npm:^1.81.0" + tinyglobby: "npm:^0.2.12" peerDependencies: - "@angular/compiler-cli": ^19.0.0 || ^19.1.0-next.0 || ^19.2.0-next.0 + "@angular/compiler-cli": ^20.0.0 || ^20.1.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 - typescript: ">=5.5 <5.9" + typescript: ">=5.8 <5.9" dependenciesMeta: rollup: optional: true @@ -12217,8 +12030,8 @@ __metadata: tailwindcss: optional: true bin: - ng-packagr: cli/main.js - checksum: 10c0/1f2802f2ea418b2a88503a3142c1b04bff4a7cd1673bced2fcb5189260fe78fd9b575f6746255268757d17ce456d019e9a96a1d6dd33995bc1212be776e24321 + ng-packagr: src/cli/main.js + checksum: 10c0/4520298e192a62edfaf13f21e9706e083f0bd8f0584b808c5d1906d97cc5faeae5b86ddd72943d52d6ea128035f803c384a7205a64d27d60fe836eb0fa29dd7c languageName: node linkType: hard @@ -12226,16 +12039,16 @@ __metadata: version: 0.0.0-use.local resolution: "ngx-datatable@workspace:." dependencies: - "@angular-devkit/build-angular": "npm:^19.1.4" - "@angular-devkit/core": "npm:^19.1.4" - "@angular-devkit/schematics": "npm:^19.1.4" - "@angular-eslint/builder": "npm:^18.0.0" - "@angular-eslint/eslint-plugin": "npm:^18.0.0" - "@angular-eslint/eslint-plugin-template": "npm:^18.0.0" - "@angular-eslint/schematics": "npm:^18.0.0" - "@angular-eslint/template-parser": "npm:^18.0.0" + "@angular-devkit/build-angular": "npm:^20.0.4" + "@angular-devkit/core": "npm:^20.0.4" + "@angular-devkit/schematics": "npm:^20.0.4" + "@angular-eslint/builder": "npm:^20.1.1" + "@angular-eslint/eslint-plugin": "npm:^20.1.1" + "@angular-eslint/eslint-plugin-template": "npm:^20.1.1" + "@angular-eslint/schematics": "npm:^20.1.1" + "@angular-eslint/template-parser": "npm:^20.1.1" "@angular/animations": "npm:^20.0.5" - "@angular/cdk": "npm:^18.2.14" + "@angular/cdk": "npm:^20.0.4" "@angular/cli": "npm:^20.0.4" "@angular/common": "npm:^20.0.5" "@angular/compiler": "npm:^20.0.5" @@ -12277,7 +12090,7 @@ __metadata: karma-coverage-istanbul-reporter: "npm:^3.0.3" karma-jasmine: "npm:5.1.0" karma-jasmine-html-reporter: "npm:2.0.0" - ng-packagr: "npm:^19.0.0" + ng-packagr: "npm:^20.0.1" npm-run-all: "npm:^4.1.5" prettier: "npm:2.7.1" pretty-quick: "npm:3.1.3" @@ -12705,19 +12518,7 @@ __metadata: languageName: node linkType: hard -"open@npm:10.1.0": - version: 10.1.0 - resolution: "open@npm:10.1.0" - dependencies: - default-browser: "npm:^5.2.1" - define-lazy-prop: "npm:^3.0.0" - is-inside-container: "npm:^1.0.0" - is-wsl: "npm:^3.1.0" - checksum: 10c0/c86d0b94503d5f735f674158d5c5d339c25ec2927562f00ee74590727292ed23e1b8d9336cb41ffa7e1fa4d3641d29b199b4ea37c78cb557d72b511743e90ebb - languageName: node - linkType: hard - -"open@npm:^10.0.3": +"open@npm:10.1.2, open@npm:^10.0.3": version: 10.1.2 resolution: "open@npm:10.1.2" dependencies: @@ -12763,7 +12564,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:5.4.1, ora@npm:^5.1.0": +"ora@npm:5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" dependencies: @@ -12780,7 +12581,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:8.2.0": +"ora@npm:8.2.0, ora@npm:^8.2.0": version: 8.2.0 resolution: "ora@npm:8.2.0" dependencies: @@ -12856,15 +12657,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: "npm:^1.0.0" - checksum: 10c0/a56af34a77f8df2ff61ddfb29431044557fcbcb7642d5a3233143ebba805fc7306ac1d448de724352861cb99de934bc9ab74f0d16fe6a5460bdbdf938de875ad - languageName: node - linkType: hard - "p-locate@npm:^4.1.0": version: 4.1.0 resolution: "p-locate@npm:4.1.0" @@ -12883,15 +12675,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^6.0.0": - version: 6.0.0 - resolution: "p-locate@npm:6.0.0" - dependencies: - p-limit: "npm:^4.0.0" - checksum: 10c0/d72fa2f41adce59c198270aa4d3c832536c87a1806e0f69dffb7c1a7ca998fb053915ca833d90f166a8c082d3859eabfed95f01698a3214c20df6bb8de046312 - languageName: node - linkType: hard - "p-map@npm:^7.0.2": version: 7.0.3 resolution: "p-map@npm:7.0.3" @@ -13043,14 +12826,14 @@ __metadata: languageName: node linkType: hard -"parse5-html-rewriting-stream@npm:7.0.0": - version: 7.0.0 - resolution: "parse5-html-rewriting-stream@npm:7.0.0" +"parse5-html-rewriting-stream@npm:7.1.0": + version: 7.1.0 + resolution: "parse5-html-rewriting-stream@npm:7.1.0" dependencies: - entities: "npm:^4.3.0" + entities: "npm:^6.0.0" parse5: "npm:^7.0.0" parse5-sax-parser: "npm:^7.0.0" - checksum: 10c0/658d3e2bae038e515bcce6ab6fba9484332d641f3ba82a6450649e1105492fe0a353101dbf751bddfc063509d06b55260bd4567970df3eaaa8391ae79d25ffbf + checksum: 10c0/e44a2f52a0012ace6c04e4eb7b9733dabdc86d9a6d7ffc30e980b89bfaa6cab7f1e74c2a4d09017037247119589eb0532c1ab0790b6ce64674cbbcc2bbaf0de7 languageName: node linkType: hard @@ -13100,13 +12883,6 @@ __metadata: languageName: node linkType: hard -"path-exists@npm:^5.0.0": - version: 5.0.0 - resolution: "path-exists@npm:5.0.0" - checksum: 10c0/b170f3060b31604cde93eefdb7392b89d832dfbc1bed717c9718cbe0f230c1669b7e75f87e19901da2250b84d092989a0f9e44d2ef41deb09aa3ad28e691a40a - languageName: node - linkType: hard - "path-is-absolute@npm:1.0.1, path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -13175,13 +12951,6 @@ __metadata: languageName: node linkType: hard -"path-type@npm:^6.0.0": - version: 6.0.0 - resolution: "path-type@npm:6.0.0" - checksum: 10c0/55baa8b1187d6dc683d5a9cfcc866168d6adff58e5db91126795376d818eee46391e00b2a4d53e44d844c7524a7d96aa68cc68f4f3e500d3d069a39e6535481c - languageName: node - linkType: hard - "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -13196,7 +12965,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.1": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -13263,27 +13032,27 @@ __metadata: languageName: node linkType: hard -"piscina@npm:4.8.0": - version: 4.8.0 - resolution: "piscina@npm:4.8.0" +"piscina@npm:5.1.1": + version: 5.1.1 + resolution: "piscina@npm:5.1.1" dependencies: "@napi-rs/nice": "npm:^1.0.1" dependenciesMeta: "@napi-rs/nice": optional: true - checksum: 10c0/963ee0dc0862e936c88357b21b0b4fa32407ab21e9600756504411f368dcfae7478c8a19e13d0dd8afed56a8252a8e5967ee4413aa33dd436751b7ee2804531e + checksum: 10c0/ca6cca2bff00c9808e199483c65f563d85e2cc5b0d2ce7238892d191e0f04e55dacaf857da2ee9e71c2cab50b55201bf29a6d8c17bbaed061e12bb3a08a71fbf languageName: node linkType: hard -"piscina@npm:^4.7.0": - version: 4.9.2 - resolution: "piscina@npm:4.9.2" +"piscina@npm:^5.0.0": + version: 5.1.2 + resolution: "piscina@npm:5.1.2" dependencies: "@napi-rs/nice": "npm:^1.0.1" dependenciesMeta: "@napi-rs/nice": optional: true - checksum: 10c0/ab67830065ff41523cd901db41b11045cb00a0be43bf79323ff7b4ef2fbce5e3a56ad440d99d6c3944ce94451a0a69fd175500e3220b21efe54142e601322189 + checksum: 10c0/12c8ee0a678d605ada768ced79428f2c4689b699e7c7bdd2f6c2abc794f0f6062fd43b8983ee45980956e25afc8dcb08a4dd2b7bc5647fe023fe45490e22d093 languageName: node linkType: hard @@ -13305,12 +13074,12 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^7.0.0": - version: 7.0.0 - resolution: "pkg-dir@npm:7.0.0" +"pkg-dir@npm:^8.0.0": + version: 8.0.0 + resolution: "pkg-dir@npm:8.0.0" dependencies: - find-up: "npm:^6.3.0" - checksum: 10c0/1afb23d2efb1ec9d8b2c4a0c37bf146822ad2774f074cb05b853be5dca1b40815c5960dd126df30ab8908349262a266f31b771e877235870a3b8fd313beebec5 + find-up-simple: "npm:^1.0.0" + checksum: 10c0/244c6af67540b7eeab823c56f61a6ca414fe48108a484bcb3b0743acc0dfaf106705555c353d65608ccd8ac3d9f696110e9b6bf55ef08f5f6a8d535a72a418e8 languageName: node linkType: hard @@ -13435,18 +13204,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.5.2": - version: 8.5.2 - resolution: "postcss@npm:8.5.2" - dependencies: - nanoid: "npm:^3.3.8" - picocolors: "npm:^1.1.1" - source-map-js: "npm:^1.2.1" - checksum: 10c0/3044d49bc725029ab62292e8bf9849741251b95f3b754e191bf8b4025414d40ec3b4ac05c5a563d4b50060b5c8e96683eb4d783d8d8fa3867eb7b763cbe66127 - languageName: node - linkType: hard - -"postcss@npm:^8.2.14, postcss@npm:^8.4.33, postcss@npm:^8.4.47, postcss@npm:^8.4.49, postcss@npm:^8.5.3": +"postcss@npm:8.5.3, postcss@npm:^8.2.14, postcss@npm:^8.4.33, postcss@npm:^8.4.47, postcss@npm:^8.4.49, postcss@npm:^8.5.3": version: 8.5.3 resolution: "postcss@npm:8.5.3" dependencies: @@ -13851,13 +13609,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.14.0": - version: 0.14.1 - resolution: "regenerator-runtime@npm:0.14.1" - checksum: 10c0/1b16eb2c4bceb1665c89de70dcb64126a22bc8eb958feef3cd68fe11ac6d2a4899b5cd1b80b0774c7c03591dc57d16631a7f69d2daa2ec98100e2f29f7ec4cc4 - languageName: node - linkType: hard - "regex-cache@npm:^0.4.2": version: 0.4.4 resolution: "regex-cache@npm:0.4.4" @@ -14156,30 +13907,47 @@ __metadata: languageName: node linkType: hard -"rollup@npm:4.34.8": - version: 4.34.8 - resolution: "rollup@npm:4.34.8" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.34.8" - "@rollup/rollup-android-arm64": "npm:4.34.8" - "@rollup/rollup-darwin-arm64": "npm:4.34.8" - "@rollup/rollup-darwin-x64": "npm:4.34.8" - "@rollup/rollup-freebsd-arm64": "npm:4.34.8" - "@rollup/rollup-freebsd-x64": "npm:4.34.8" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.34.8" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.34.8" - "@rollup/rollup-linux-arm64-gnu": "npm:4.34.8" - "@rollup/rollup-linux-arm64-musl": "npm:4.34.8" - "@rollup/rollup-linux-loongarch64-gnu": "npm:4.34.8" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.34.8" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.34.8" - "@rollup/rollup-linux-s390x-gnu": "npm:4.34.8" - "@rollup/rollup-linux-x64-gnu": "npm:4.34.8" - "@rollup/rollup-linux-x64-musl": "npm:4.34.8" - "@rollup/rollup-win32-arm64-msvc": "npm:4.34.8" - "@rollup/rollup-win32-ia32-msvc": "npm:4.34.8" - "@rollup/rollup-win32-x64-msvc": "npm:4.34.8" - "@types/estree": "npm:1.0.6" +"rollup-plugin-dts@npm:^6.2.0": + version: 6.2.1 + resolution: "rollup-plugin-dts@npm:6.2.1" + dependencies: + "@babel/code-frame": "npm:^7.26.2" + magic-string: "npm:^0.30.17" + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 + dependenciesMeta: + "@babel/code-frame": + optional: true + checksum: 10c0/f21c8726470851a40e6ca68ae580261cee8bc6275775291b9c0fdf93b868ed54f12b11c8c0dddce2c14f5691d6032b6647d094835ab9b6789226efa60e1aa71e + languageName: node + linkType: hard + +"rollup@npm:4.40.2, rollup@npm:^4.24.0, rollup@npm:^4.4.0": + version: 4.40.2 + resolution: "rollup@npm:4.40.2" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.40.2" + "@rollup/rollup-android-arm64": "npm:4.40.2" + "@rollup/rollup-darwin-arm64": "npm:4.40.2" + "@rollup/rollup-darwin-x64": "npm:4.40.2" + "@rollup/rollup-freebsd-arm64": "npm:4.40.2" + "@rollup/rollup-freebsd-x64": "npm:4.40.2" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.40.2" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.40.2" + "@rollup/rollup-linux-arm64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-arm64-musl": "npm:4.40.2" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.40.2" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-riscv64-musl": "npm:4.40.2" + "@rollup/rollup-linux-s390x-gnu": "npm:4.40.2" + "@rollup/rollup-linux-x64-gnu": "npm:4.40.2" + "@rollup/rollup-linux-x64-musl": "npm:4.40.2" + "@rollup/rollup-win32-arm64-msvc": "npm:4.40.2" + "@rollup/rollup-win32-ia32-msvc": "npm:4.40.2" + "@rollup/rollup-win32-x64-msvc": "npm:4.40.2" + "@types/estree": "npm:1.0.7" fsevents: "npm:~2.3.2" dependenciesMeta: "@rollup/rollup-android-arm-eabi": @@ -14208,6 +13976,8 @@ __metadata: optional: true "@rollup/rollup-linux-riscv64-gnu": optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true "@rollup/rollup-linux-s390x-gnu": optional: true "@rollup/rollup-linux-x64-gnu": @@ -14224,35 +13994,35 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/b9e711e33413112fbb761107c3fddc4561dfc74335c393542a829a85ccfb2763bfd17bf2422d84a2e9bee7646e5367018973e97005fdf64e49c2e209612f0eb6 + checksum: 10c0/cbe9b766891da74fbf7c3b50420bb75102e5c59afc0ea45751f7e43a581d2cd93367763f521f820b72e341cf1f6b9951fbdcd3be67a1b0aa774b754525a8b9c7 languageName: node linkType: hard -"rollup@npm:^4.24.0, rollup@npm:^4.30.1, rollup@npm:^4.4.0": - version: 4.40.2 - resolution: "rollup@npm:4.40.2" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.40.2" - "@rollup/rollup-android-arm64": "npm:4.40.2" - "@rollup/rollup-darwin-arm64": "npm:4.40.2" - "@rollup/rollup-darwin-x64": "npm:4.40.2" - "@rollup/rollup-freebsd-arm64": "npm:4.40.2" - "@rollup/rollup-freebsd-x64": "npm:4.40.2" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.40.2" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.40.2" - "@rollup/rollup-linux-arm64-gnu": "npm:4.40.2" - "@rollup/rollup-linux-arm64-musl": "npm:4.40.2" - "@rollup/rollup-linux-loongarch64-gnu": "npm:4.40.2" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.40.2" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.40.2" - "@rollup/rollup-linux-riscv64-musl": "npm:4.40.2" - "@rollup/rollup-linux-s390x-gnu": "npm:4.40.2" - "@rollup/rollup-linux-x64-gnu": "npm:4.40.2" - "@rollup/rollup-linux-x64-musl": "npm:4.40.2" - "@rollup/rollup-win32-arm64-msvc": "npm:4.40.2" - "@rollup/rollup-win32-ia32-msvc": "npm:4.40.2" - "@rollup/rollup-win32-x64-msvc": "npm:4.40.2" - "@types/estree": "npm:1.0.7" +"rollup@npm:^4.34.9": + version: 4.44.1 + resolution: "rollup@npm:4.44.1" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.44.1" + "@rollup/rollup-android-arm64": "npm:4.44.1" + "@rollup/rollup-darwin-arm64": "npm:4.44.1" + "@rollup/rollup-darwin-x64": "npm:4.44.1" + "@rollup/rollup-freebsd-arm64": "npm:4.44.1" + "@rollup/rollup-freebsd-x64": "npm:4.44.1" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.44.1" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.44.1" + "@rollup/rollup-linux-arm64-gnu": "npm:4.44.1" + "@rollup/rollup-linux-arm64-musl": "npm:4.44.1" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.44.1" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.44.1" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.44.1" + "@rollup/rollup-linux-riscv64-musl": "npm:4.44.1" + "@rollup/rollup-linux-s390x-gnu": "npm:4.44.1" + "@rollup/rollup-linux-x64-gnu": "npm:4.44.1" + "@rollup/rollup-linux-x64-musl": "npm:4.44.1" + "@rollup/rollup-win32-arm64-msvc": "npm:4.44.1" + "@rollup/rollup-win32-ia32-msvc": "npm:4.44.1" + "@rollup/rollup-win32-x64-msvc": "npm:4.44.1" + "@types/estree": "npm:1.0.8" fsevents: "npm:~2.3.2" dependenciesMeta: "@rollup/rollup-android-arm-eabi": @@ -14299,7 +14069,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/cbe9b766891da74fbf7c3b50420bb75102e5c59afc0ea45751f7e43a581d2cd93367763f521f820b72e341cf1f6b9951fbdcd3be67a1b0aa774b754525a8b9c7 + checksum: 10c0/6cc0175c626fd9f0fc325c1f1b86d5b5401d687973691dd5205b6b88a666ee0b96f401725da9090e090b31cb5a82ff9a0ef1c3db6dc14906f6c7a48cabad49b4 languageName: node linkType: hard @@ -14436,9 +14206,9 @@ __metadata: languageName: node linkType: hard -"sass@npm:1.85.0": - version: 1.85.0 - resolution: "sass@npm:1.85.0" +"sass@npm:1.88.0": + version: 1.88.0 + resolution: "sass@npm:1.88.0" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -14449,7 +14219,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10c0/a1af0c0596ae1904f66337d0c70a684db6e12210f97be4326cc3dcf18b0f956d7bc45ab2bcc7a8422d433d3eb3c9cb2cc8e60b2dafbdd01fb1ae5a23f5424690 + checksum: 10c0/dcb16dc29116bfa5a90485d24fd8020d2b0d95155bd2e31285901588729343b59fefe44365c5f146b2ba5a9ebadef90b23a7220b902507bdbd91ca2ba0a0b688 languageName: node linkType: hard @@ -14486,7 +14256,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0": +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.2": version: 4.3.2 resolution: "schema-utils@npm:4.3.2" dependencies: @@ -14578,24 +14348,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.3": - version: 7.6.3 - resolution: "semver@npm:7.6.3" - bin: - semver: bin/semver.js - checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf - languageName: node - linkType: hard - -"semver@npm:7.7.1, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3": - version: 7.7.1 - resolution: "semver@npm:7.7.1" - bin: - semver: bin/semver.js - checksum: 10c0/fd603a6fb9c399c6054015433051bdbe7b99a940a8fb44b85c2b524c4004b023d7928d47cb22154f8d054ea7ee8597f586605e05b52047f048278e4ac56ae958 - languageName: node - linkType: hard - "semver@npm:7.7.2": version: 7.7.2 resolution: "semver@npm:7.7.2" @@ -14614,6 +14366,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3": + version: 7.7.1 + resolution: "semver@npm:7.7.1" + bin: + semver: bin/semver.js + checksum: 10c0/fd603a6fb9c399c6054015433051bdbe7b99a940a8fb44b85c2b524c4004b023d7928d47cb22154f8d054ea7ee8597f586605e05b52047f048278e4ac56ae958 + languageName: node + linkType: hard + "send@npm:0.19.0": version: 0.19.0 resolution: "send@npm:0.19.0" @@ -14879,13 +14640,6 @@ __metadata: languageName: node linkType: hard -"slash@npm:^5.1.0": - version: 5.1.0 - resolution: "slash@npm:5.1.0" - checksum: 10c0/eb48b815caf0bdc390d0519d41b9e0556a14380f6799c72ba35caf03544d501d18befdeeef074bc9c052acf69654bc9e0d79d7f1de0866284137a40805299eb3 - languageName: node - linkType: hard - "slice-ansi@npm:^4.0.0": version: 4.0.0 resolution: "slice-ansi@npm:4.0.0" @@ -15572,7 +15326,21 @@ __metadata: languageName: node linkType: hard -"terser@npm:5.39.0, terser@npm:^5.31.1": +"terser@npm:5.39.1": + version: 5.39.1 + resolution: "terser@npm:5.39.1" + dependencies: + "@jridgewell/source-map": "npm:^0.3.3" + acorn: "npm:^8.8.2" + commander: "npm:^2.20.0" + source-map-support: "npm:~0.5.20" + bin: + terser: bin/terser + checksum: 10c0/d49e06dd4dd03661dac41f45c9cf187b2aa3fe80775235e838398c29311705169387c007f398ab44cd1bd8f89b14a1eea383feaa95c1cae29e3f5b6b606b6b37 + languageName: node + linkType: hard + +"terser@npm:^5.31.1": version: 5.39.0 resolution: "terser@npm:5.39.0" dependencies: @@ -15625,7 +15393,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.12": +"tinyglobby@npm:0.2.13, tinyglobby@npm:^0.2.12": version: 0.2.13 resolution: "tinyglobby@npm:0.2.13" dependencies: @@ -15635,6 +15403,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.13": + version: 0.2.14 + resolution: "tinyglobby@npm:0.2.14" + dependencies: + fdir: "npm:^6.4.4" + picomatch: "npm:^4.0.2" + checksum: 10c0/f789ed6c924287a9b7d3612056ed0cda67306cd2c80c249fd280cf1504742b12583a2089b61f4abbd24605f390809017240e250241f09938054c9b363e51c0a6 + languageName: node + linkType: hard + "tmp@npm:0.0.30": version: 0.0.30 resolution: "tmp@npm:0.0.30" @@ -15753,7 +15531,7 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^2.0.1": +"ts-api-utils@npm:^2.0.1, ts-api-utils@npm:^2.1.0": version: 2.1.0 resolution: "ts-api-utils@npm:2.1.0" peerDependencies: @@ -16070,13 +15848,6 @@ __metadata: languageName: node linkType: hard -"unicorn-magic@npm:^0.3.0": - version: 0.3.0 - resolution: "unicorn-magic@npm:0.3.0" - checksum: 10c0/0a32a997d6c15f1c2a077a15b1c4ca6f268d574cf5b8975e778bb98e6f8db4ef4e86dfcae4e158cd4c7e38fb4dd383b93b13eefddc7f178dea13d3ac8a603271 - languageName: node - linkType: hard - "union-value@npm:^1.0.0": version: 1.0.1 resolution: "union-value@npm:1.0.1" @@ -16260,14 +16031,17 @@ __metadata: languageName: node linkType: hard -"vite@npm:6.2.7": - version: 6.2.7 - resolution: "vite@npm:6.2.7" +"vite@npm:6.3.5": + version: 6.3.5 + resolution: "vite@npm:6.3.5" dependencies: esbuild: "npm:^0.25.0" + fdir: "npm:^6.4.4" fsevents: "npm:~2.3.3" + picomatch: "npm:^4.0.2" postcss: "npm:^8.5.3" - rollup: "npm:^4.30.1" + rollup: "npm:^4.34.9" + tinyglobby: "npm:^0.2.13" peerDependencies: "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 jiti: ">=1.21.0" @@ -16308,7 +16082,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/2da5df6bfdc386a3b24d7350c508e075a49a5b5c33eb4a327203eb175398a1da99d185c68bd2287be897032810700d95ea7ce72d1113d86f43de61f0ce4435da + checksum: 10c0/df70201659085133abffc6b88dcdb8a57ef35f742a01311fc56a4cfcda6a404202860729cc65a2c401a724f6e25f9ab40ce4339ed4946f550541531ced6fe41c languageName: node linkType: hard @@ -16411,13 +16185,14 @@ __metadata: languageName: node linkType: hard -"webpack-dev-server@npm:5.2.0": - version: 5.2.0 - resolution: "webpack-dev-server@npm:5.2.0" +"webpack-dev-server@npm:5.2.1": + version: 5.2.1 + resolution: "webpack-dev-server@npm:5.2.1" dependencies: "@types/bonjour": "npm:^3.5.13" "@types/connect-history-api-fallback": "npm:^1.5.4" "@types/express": "npm:^4.17.21" + "@types/express-serve-static-core": "npm:^4.17.21" "@types/serve-index": "npm:^1.9.4" "@types/serve-static": "npm:^1.15.5" "@types/sockjs": "npm:^0.3.36" @@ -16451,7 +16226,7 @@ __metadata: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: 10c0/afb2e51945ac54ef3039e11e377241e1cb97a8d3f526f39f13c3fa924c530fb6063200c2c3ae4e33e6bcc110d4abed777c09ce18e2d261012853d81f3c5820ab + checksum: 10c0/22bcf2bcc7c72cd2065883ed4368fbcdf20078bc746b07689d10a0546ee99ea00bc50f0474112278ffd8598a5bc237df2bf7bb7f6dcda940a16b1eb91137efea languageName: node linkType: hard @@ -16488,12 +16263,13 @@ __metadata: languageName: node linkType: hard -"webpack@npm:5.98.0": - version: 5.98.0 - resolution: "webpack@npm:5.98.0" +"webpack@npm:5.99.8": + version: 5.99.8 + resolution: "webpack@npm:5.99.8" dependencies: "@types/eslint-scope": "npm:^3.7.7" "@types/estree": "npm:^1.0.6" + "@types/json-schema": "npm:^7.0.15" "@webassemblyjs/ast": "npm:^1.14.1" "@webassemblyjs/wasm-edit": "npm:^1.14.1" "@webassemblyjs/wasm-parser": "npm:^1.14.1" @@ -16510,7 +16286,7 @@ __metadata: loader-runner: "npm:^4.2.0" mime-types: "npm:^2.1.27" neo-async: "npm:^2.6.2" - schema-utils: "npm:^4.3.0" + schema-utils: "npm:^4.3.2" tapable: "npm:^2.1.1" terser-webpack-plugin: "npm:^5.3.11" watchpack: "npm:^2.4.1" @@ -16520,7 +16296,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 10c0/bee4fa77f444802f0beafb2ff30eb5454a606163ad7d3cc9a5dcc9d24033c62407bed04601b25dea49ea3969b352c1b530a86c753246f42560a4a084eefb094e + checksum: 10c0/c4852c3b795ed3fba799d2925802a4e259b2de7c2c597f0aaf0e228acfdc6755389ed8c29f1dad86610a9c6ad968c0b57c702b93891d60f09d302af63b2debe0 languageName: node linkType: hard @@ -16961,13 +16737,6 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^1.0.0": - version: 1.2.1 - resolution: "yocto-queue@npm:1.2.1" - checksum: 10c0/5762caa3d0b421f4bdb7a1926b2ae2189fc6e4a14469258f183600028eb16db3e9e0306f46e8ebf5a52ff4b81a881f22637afefbef5399d6ad440824e9b27f9f - languageName: node - linkType: hard - "yoctocolors-cjs@npm:^2.1.2": version: 2.1.2 resolution: "yoctocolors-cjs@npm:2.1.2" From 59534d95180d89ecd6d9148dee94d532c76b7d89 Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Thu, 26 Jun 2025 15:12:32 -0500 Subject: [PATCH 104/105] fix linting errors --- .../ngx-datatable/src/lib/directives/orderable.directive.ts | 4 ++-- .../src/lib/services/scrollbar-helper.service.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts index 61dda470f..789545313 100644 --- a/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts +++ b/projects/swimlane/ngx-datatable/src/lib/directives/orderable.directive.ts @@ -2,6 +2,7 @@ import { AfterContentInit, ContentChildren, Directive, + DOCUMENT, EventEmitter, inject, KeyValueChangeRecord, @@ -9,8 +10,7 @@ import { KeyValueDiffers, OnDestroy, Output, - QueryList, - DOCUMENT + QueryList } from '@angular/core'; import { DraggableDirective } from './draggable.directive'; diff --git a/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts b/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts index 65cfe804e..87e805573 100644 --- a/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts +++ b/projects/swimlane/ngx-datatable/src/lib/services/scrollbar-helper.service.ts @@ -1,4 +1,4 @@ -import { inject, Injectable, DOCUMENT } from '@angular/core'; +import { DOCUMENT, inject, Injectable } from '@angular/core'; /** * Gets the width of the scrollbar. Nesc for windows From 68eb9b85fde75cdc07e97e9b03e60cd735264172 Mon Sep 17 00:00:00 2001 From: Mark Coleman Date: Fri, 27 Jun 2025 15:12:15 -0500 Subject: [PATCH 105/105] remove all occurrences of standalone from component decorators --- .../src/lib/components/body/body-row-wrapper.component.ts | 1 - .../src/lib/components/body/body-row.component.spec.ts | 3 +-- .../src/lib/components/body/body-row.component.ts | 1 - .../ngx-datatable/src/lib/components/body/body.component.ts | 1 - .../src/lib/components/columns/column.directive.spec.ts | 3 +-- .../src/lib/components/datatable.component.spec.ts | 6 ++---- src/app/app.component.ts | 1 - src/app/basic/basic-auto.component.ts | 1 - src/app/basic/basic-fixed.component.ts | 1 - src/app/basic/bootstrap.component.ts | 1 - src/app/basic/contextmenu.component.ts | 1 - src/app/basic/css.component.ts | 1 - src/app/basic/dark-theme.component.ts | 1 - src/app/basic/disabled-rows.component.ts | 1 - src/app/basic/dynamic-height.component.ts | 1 - src/app/basic/empty.component.ts | 1 - src/app/basic/filter.component.ts | 1 - src/app/basic/footer.component.ts | 1 - src/app/basic/fullscreen.component.ts | 1 - src/app/basic/inline.component.ts | 1 - src/app/basic/live.component.ts | 1 - src/app/basic/multiple.component.ts | 1 - src/app/basic/responsive.component.ts | 1 - src/app/basic/row-detail.component.ts | 1 - src/app/basic/row-grouping.component.ts | 1 - src/app/basic/rx.component.ts | 1 - src/app/basic/scrolling-dynamically.component.ts | 1 - src/app/basic/scrolling.component.ts | 1 - src/app/basic/tabs.component.ts | 1 - src/app/basic/virtual.component.ts | 1 - src/app/columns/column-flex.component.ts | 1 - src/app/columns/column-force.component.ts | 1 - src/app/columns/column-reorder.component.ts | 1 - src/app/columns/column-standard.component.ts | 1 - src/app/columns/column-toggle.component.ts | 1 - src/app/columns/pinning.component.ts | 1 - src/app/drag-drop/drag-drop.component.ts | 1 - src/app/paging/paging-client.component.ts | 1 - .../paging/paging-scrolling-novirtualization.component.ts | 1 - src/app/paging/paging-server.component.ts | 1 - src/app/paging/paging-virtual.component.ts | 1 - src/app/paging/scrolling-server.component.ts | 1 - src/app/selection/selection-cell.component.ts | 1 - src/app/selection/selection-chkbox-template.component.ts | 1 - src/app/selection/selection-chkbox.component.ts | 1 - src/app/selection/selection-disabled.component.ts | 1 - src/app/selection/selection-multi-click-chkbox.component.ts | 1 - src/app/selection/selection-multi-click.component.ts | 1 - src/app/selection/selection-multi.component.ts | 1 - src/app/selection/selection-single.component.ts | 1 - src/app/sorting/sorting-client.component.ts | 1 - src/app/sorting/sorting-comparator.component.ts | 1 - src/app/sorting/sorting-default.component.ts | 1 - src/app/sorting/sorting-server.component.ts | 1 - src/app/summary/summary-row-custom-template.component.ts | 1 - src/app/summary/summary-row-inline-html.component.ts | 1 - src/app/summary/summary-row-server-paging.component.ts | 1 - src/app/summary/summary-row-simple.component.ts | 1 - src/app/templates/template-dom.component.ts | 1 - src/app/templates/template-obj.component.ts | 1 - src/app/tree/client-tree.component.ts | 1 - src/app/tree/fullscreen.component.ts | 1 - 62 files changed, 4 insertions(+), 67 deletions(-) diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts index f632ef5bf..efcb37a3e 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row-wrapper.component.ts @@ -69,7 +69,6 @@ import { DatatableRowDetailDirective } from '../row-detail/row-detail.directive' class: 'datatable-row-wrapper' }, styleUrl: './body-row-wrapper.component.scss', - standalone: true, imports: [NgTemplateOutlet] }) export class DataTableRowWrapperComponent diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts index 5d44b414b..d6d4ecfa7 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.spec.ts @@ -10,8 +10,7 @@ import { toInternalColumn } from '../../utils/column-helper'; describe('DataTableBodyRowComponent', () => { @Component({ template: ` `, - imports: [DataTableBodyRowComponent], - standalone: true + imports: [DataTableBodyRowComponent] }) class TestHostComponent { rowIndex: RowIndex = { index: 0 }; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts index b06212612..4b43e8973 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -61,7 +61,6 @@ import { DataTableBodyCellComponent } from './body-cell.component'; } } `, styleUrl: './body-row.component.scss', - standalone: true, imports: [DataTableBodyCellComponent] }) export class DataTableBodyRowComponent implements DoCheck, OnChanges { diff --git a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts index 50bea30a0..d30405594 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/body/body.component.ts @@ -221,7 +221,6 @@ import { Keys } from '../../utils/keys'; class: 'datatable-body' }, styleUrl: './body.component.scss', - standalone: true, imports: [ DataTableGhostLoaderComponent, ScrollerComponent, diff --git a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts index 9b4523dff..78cb439ca 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/columns/column.directive.spec.ts @@ -17,8 +17,7 @@ import Spy = jasmine.Spy; `, imports: [DataTableColumnDirective], - providers: [ColumnChangesService], // usually provided by the table.component - standalone: true + providers: [ColumnChangesService] // usually provided by the table.component }) class TestFixtureComponent { columnName?: string; diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts index 045d2e1ae..15d54146b 100644 --- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts +++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.spec.ts @@ -16,8 +16,7 @@ describe('DatatableComponent', () => { @Component({ template: ` `, - imports: [DatatableComponent], - standalone: true + imports: [DatatableComponent] }) class TestFixtureComponent { columns: TableColumn[] = []; @@ -389,8 +388,7 @@ describe('DatatableComponent With Custom Templates', () => { DataTableColumnDirective, DataTableColumnCellDirective, DataTableColumnHeaderDirective - ], - standalone: true + ] }) // eslint-disable-next-line @angular-eslint/component-class-suffix class TestFixtureComponentWithCustomTemplates { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 055c93170..95e6f974f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -20,7 +20,6 @@ import { RouterLink, RouterOutlet } from '@angular/router'; useClass: HashLocationStrategy } ], - standalone: true, imports: [RouterLink, RouterOutlet] }) export class AppComponent { diff --git a/src/app/basic/basic-auto.component.ts b/src/app/basic/basic-auto.component.ts index 7d588fee2..8776590f4 100644 --- a/src/app/basic/basic-auto.component.ts +++ b/src/app/basic/basic-auto.component.ts @@ -36,7 +36,6 @@ import { DataService } from '../data.service';
    `, - standalone: true, imports: [DatatableComponent] }) export class BasicAutoComponent { diff --git a/src/app/basic/basic-fixed.component.ts b/src/app/basic/basic-fixed.component.ts index 43726515f..0cf60a7e2 100644 --- a/src/app/basic/basic-fixed.component.ts +++ b/src/app/basic/basic-fixed.component.ts @@ -34,7 +34,6 @@ import { DataService } from '../data.service';
    `, - standalone: true, imports: [DatatableComponent] }) export class BasicFixedComponent { diff --git a/src/app/basic/bootstrap.component.ts b/src/app/basic/bootstrap.component.ts index 7b7a02412..d57e5e91d 100644 --- a/src/app/basic/bootstrap.component.ts +++ b/src/app/basic/bootstrap.component.ts @@ -39,7 +39,6 @@ import { DataService } from '../data.service';
    `, - standalone: true, imports: [DatatableComponent] }) export class BootstrapThemeComponent { diff --git a/src/app/basic/contextmenu.component.ts b/src/app/basic/contextmenu.component.ts index eaaf7812b..a5fabbfcc 100644 --- a/src/app/basic/contextmenu.component.ts +++ b/src/app/basic/contextmenu.component.ts @@ -56,7 +56,6 @@ import { DataService } from '../data.service';
    `, - standalone: true, imports: [DatatableComponent] }) export class ContextMenuDemoComponent { diff --git a/src/app/basic/css.component.ts b/src/app/basic/css.component.ts index 8e4c620ad..5736352d7 100644 --- a/src/app/basic/css.component.ts +++ b/src/app/basic/css.component.ts @@ -42,7 +42,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class RowCssComponent { diff --git a/src/app/basic/dark-theme.component.ts b/src/app/basic/dark-theme.component.ts index 88b78a2e1..c1713a900 100644 --- a/src/app/basic/dark-theme.component.ts +++ b/src/app/basic/dark-theme.component.ts @@ -38,7 +38,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class DarkThemeComponent { diff --git a/src/app/basic/disabled-rows.component.ts b/src/app/basic/disabled-rows.component.ts index dd4cd6d59..915c01d63 100644 --- a/src/app/basic/disabled-rows.component.ts +++ b/src/app/basic/disabled-rows.component.ts @@ -86,7 +86,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [ DatatableComponent, DataTableColumnDirective, diff --git a/src/app/basic/dynamic-height.component.ts b/src/app/basic/dynamic-height.component.ts index 04cf61f69..b2d347a2e 100644 --- a/src/app/basic/dynamic-height.component.ts +++ b/src/app/basic/dynamic-height.component.ts @@ -37,7 +37,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class DynamicHeightComponent { diff --git a/src/app/basic/empty.component.ts b/src/app/basic/empty.component.ts index e786f37b6..c5bf29d8d 100644 --- a/src/app/basic/empty.component.ts +++ b/src/app/basic/empty.component.ts @@ -34,7 +34,6 @@ import { `, - standalone: true, imports: [DatatableComponent] }) export class BasicEmptyComponent { diff --git a/src/app/basic/filter.component.ts b/src/app/basic/filter.component.ts index 13e1b7d38..d27f9009c 100644 --- a/src/app/basic/filter.component.ts +++ b/src/app/basic/filter.component.ts @@ -42,7 +42,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class FilterComponent { diff --git a/src/app/basic/footer.component.ts b/src/app/basic/footer.component.ts index 41aabd664..5308e4c24 100644 --- a/src/app/basic/footer.component.ts +++ b/src/app/basic/footer.component.ts @@ -55,7 +55,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DatatableFooterDirective, DataTableFooterTemplateDirective] }) export class FooterDemoComponent { diff --git a/src/app/basic/fullscreen.component.ts b/src/app/basic/fullscreen.component.ts index b9dda172c..b24093ba6 100644 --- a/src/app/basic/fullscreen.component.ts +++ b/src/app/basic/fullscreen.component.ts @@ -46,7 +46,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class FullScreenComponent { diff --git a/src/app/basic/inline.component.ts b/src/app/basic/inline.component.ts index cd9f14b13..d4086bcdf 100644 --- a/src/app/basic/inline.component.ts +++ b/src/app/basic/inline.component.ts @@ -80,7 +80,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class InlineEditComponent { diff --git a/src/app/basic/live.component.ts b/src/app/basic/live.component.ts index 011114127..0bb8abe7e 100644 --- a/src/app/basic/live.component.ts +++ b/src/app/basic/live.component.ts @@ -45,7 +45,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class LiveDataComponent { diff --git a/src/app/basic/multiple.component.ts b/src/app/basic/multiple.component.ts index a3ed6c46e..a3cabcfca 100644 --- a/src/app/basic/multiple.component.ts +++ b/src/app/basic/multiple.component.ts @@ -42,7 +42,6 @@ import { `, - standalone: true, imports: [DatatableComponent] }) export class MultipleTablesComponent { diff --git a/src/app/basic/responsive.component.ts b/src/app/basic/responsive.component.ts index 92c8ad947..98b0c31b7 100644 --- a/src/app/basic/responsive.component.ts +++ b/src/app/basic/responsive.component.ts @@ -125,7 +125,6 @@ import { DataService } from '../data.service'; `, // eslint-disable-next-line @angular-eslint/use-component-view-encapsulation encapsulation: ViewEncapsulation.None, - standalone: true, imports: [ DatatableComponent, DatatableRowDetailDirective, diff --git a/src/app/basic/row-detail.component.ts b/src/app/basic/row-detail.component.ts index 19fceb77d..d231b5be3 100644 --- a/src/app/basic/row-detail.component.ts +++ b/src/app/basic/row-detail.component.ts @@ -98,7 +98,6 @@ import { DataService } from '../data.service'; `, // eslint-disable-next-line @angular-eslint/use-component-view-encapsulation encapsulation: ViewEncapsulation.None, - standalone: true, imports: [ DatatableComponent, DatatableRowDetailDirective, diff --git a/src/app/basic/row-grouping.component.ts b/src/app/basic/row-grouping.component.ts index e01ec2fe1..80c78c5ff 100644 --- a/src/app/basic/row-grouping.component.ts +++ b/src/app/basic/row-grouping.component.ts @@ -153,7 +153,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [ DatatableComponent, DatatableGroupHeaderDirective, diff --git a/src/app/basic/rx.component.ts b/src/app/basic/rx.component.ts index 7bd3d009e..47bcbe5b8 100644 --- a/src/app/basic/rx.component.ts +++ b/src/app/basic/rx.component.ts @@ -36,7 +36,6 @@ import { AsyncPipe } from '@angular/common'; `, - standalone: true, imports: [DatatableComponent, AsyncPipe] }) export class RxDemoComponent { diff --git a/src/app/basic/scrolling-dynamically.component.ts b/src/app/basic/scrolling-dynamically.component.ts index 3bcdc8cd2..1bcd35961 100644 --- a/src/app/basic/scrolling-dynamically.component.ts +++ b/src/app/basic/scrolling-dynamically.component.ts @@ -83,7 +83,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class ScrollingDynamicallyComponent { diff --git a/src/app/basic/scrolling.component.ts b/src/app/basic/scrolling.component.ts index cebc234c5..5e02268bf 100644 --- a/src/app/basic/scrolling.component.ts +++ b/src/app/basic/scrolling.component.ts @@ -43,7 +43,6 @@ import { `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class HorzVertScrollingComponent { diff --git a/src/app/basic/tabs.component.ts b/src/app/basic/tabs.component.ts index 1b23dfaaa..6808e8f5a 100644 --- a/src/app/basic/tabs.component.ts +++ b/src/app/basic/tabs.component.ts @@ -72,7 +72,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class TabsDemoComponent { diff --git a/src/app/basic/virtual.component.ts b/src/app/basic/virtual.component.ts index eb402d5a5..497b066f9 100644 --- a/src/app/basic/virtual.component.ts +++ b/src/app/basic/virtual.component.ts @@ -48,7 +48,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class VirtualScrollComponent { diff --git a/src/app/columns/column-flex.component.ts b/src/app/columns/column-flex.component.ts index d1ee3b421..f065fecee 100644 --- a/src/app/columns/column-flex.component.ts +++ b/src/app/columns/column-flex.component.ts @@ -49,7 +49,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class ColumnFlexComponent { diff --git a/src/app/columns/column-force.component.ts b/src/app/columns/column-force.component.ts index 9f2919dd9..003be6b04 100644 --- a/src/app/columns/column-force.component.ts +++ b/src/app/columns/column-force.component.ts @@ -49,7 +49,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class ColumnForceComponent { diff --git a/src/app/columns/column-reorder.component.ts b/src/app/columns/column-reorder.component.ts index 7e0243950..d601a12b5 100644 --- a/src/app/columns/column-reorder.component.ts +++ b/src/app/columns/column-reorder.component.ts @@ -61,7 +61,6 @@ import { NgClass } from '@angular/common';
    `, - standalone: true, imports: [DatatableComponent, NgClass] }) export class ColumnReorderComponent { diff --git a/src/app/columns/column-standard.component.ts b/src/app/columns/column-standard.component.ts index 8c78e7bfe..f030247f9 100644 --- a/src/app/columns/column-standard.component.ts +++ b/src/app/columns/column-standard.component.ts @@ -49,7 +49,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class ColumnStandardComponent { diff --git a/src/app/columns/column-toggle.component.ts b/src/app/columns/column-toggle.component.ts index 8cb4203b1..e93c762d2 100644 --- a/src/app/columns/column-toggle.component.ts +++ b/src/app/columns/column-toggle.component.ts @@ -54,7 +54,6 @@ import { Employee } from '../data.model'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class ColumnToggleComponent { diff --git a/src/app/columns/pinning.component.ts b/src/app/columns/pinning.component.ts index cc1be0b25..87593fd91 100644 --- a/src/app/columns/pinning.component.ts +++ b/src/app/columns/pinning.component.ts @@ -41,7 +41,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class ColumnPinningComponent { diff --git a/src/app/drag-drop/drag-drop.component.ts b/src/app/drag-drop/drag-drop.component.ts index b64223123..0ce0ef42c 100644 --- a/src/app/drag-drop/drag-drop.component.ts +++ b/src/app/drag-drop/drag-drop.component.ts @@ -43,7 +43,6 @@ import { Employee } from '../data.model'; `, - standalone: true, imports: [ DatatableComponent, CdkDropList, diff --git a/src/app/paging/paging-client.component.ts b/src/app/paging/paging-client.component.ts index 629028d11..4b3d893e6 100644 --- a/src/app/paging/paging-client.component.ts +++ b/src/app/paging/paging-client.component.ts @@ -31,7 +31,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class ClientPagingComponent { diff --git a/src/app/paging/paging-scrolling-novirtualization.component.ts b/src/app/paging/paging-scrolling-novirtualization.component.ts index e38932944..3ee95e6a3 100644 --- a/src/app/paging/paging-scrolling-novirtualization.component.ts +++ b/src/app/paging/paging-scrolling-novirtualization.component.ts @@ -40,7 +40,6 @@ import { Employee } from '../data.model'; `, - standalone: true, imports: [DatatableComponent] }) export class PagingScrollingNoVirtualizationComponent implements OnInit { diff --git a/src/app/paging/paging-server.component.ts b/src/app/paging/paging-server.component.ts index 1196525a0..2c2249bcf 100644 --- a/src/app/paging/paging-server.component.ts +++ b/src/app/paging/paging-server.component.ts @@ -37,7 +37,6 @@ import { Employee } from '../data.model'; `, - standalone: true, imports: [DatatableComponent] }) export class ServerPagingComponent implements OnInit { diff --git a/src/app/paging/paging-virtual.component.ts b/src/app/paging/paging-virtual.component.ts index 78e0f3468..b66a924e2 100644 --- a/src/app/paging/paging-virtual.component.ts +++ b/src/app/paging/paging-virtual.component.ts @@ -50,7 +50,6 @@ import { Employee } from '../data.model'; `, styleUrls: ['./paging-virtual.component.scss'], - standalone: true, imports: [DatatableComponent] }) export class VirtualPagingComponent { diff --git a/src/app/paging/scrolling-server.component.ts b/src/app/paging/scrolling-server.component.ts index 627479cb3..f49a29ab9 100644 --- a/src/app/paging/scrolling-server.component.ts +++ b/src/app/paging/scrolling-server.component.ts @@ -56,7 +56,6 @@ export class MockServerResultsService { `, styleUrls: ['./scrolling-server.component.css'], - standalone: true, imports: [DatatableComponent] }) export class ServerScrollingComponent { diff --git a/src/app/selection/selection-cell.component.ts b/src/app/selection/selection-cell.component.ts index 28626cb8e..37aa991a2 100644 --- a/src/app/selection/selection-cell.component.ts +++ b/src/app/selection/selection-cell.component.ts @@ -41,7 +41,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class CellSelectionComponent { diff --git a/src/app/selection/selection-chkbox-template.component.ts b/src/app/selection/selection-chkbox-template.component.ts index 376668ec4..4a156dd89 100644 --- a/src/app/selection/selection-chkbox-template.component.ts +++ b/src/app/selection/selection-chkbox-template.component.ts @@ -92,7 +92,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [ DatatableComponent, DataTableColumnDirective, diff --git a/src/app/selection/selection-chkbox.component.ts b/src/app/selection/selection-chkbox.component.ts index e2ea2dbff..3ca452508 100644 --- a/src/app/selection/selection-chkbox.component.ts +++ b/src/app/selection/selection-chkbox.component.ts @@ -79,7 +79,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class CheckboxSelectionComponent { diff --git a/src/app/selection/selection-disabled.component.ts b/src/app/selection/selection-disabled.component.ts index 2915c2cc7..c1a101887 100644 --- a/src/app/selection/selection-disabled.component.ts +++ b/src/app/selection/selection-disabled.component.ts @@ -58,7 +58,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class MultiDisableSelectionComponent { diff --git a/src/app/selection/selection-multi-click-chkbox.component.ts b/src/app/selection/selection-multi-click-chkbox.component.ts index 63557d750..6aa15ba31 100644 --- a/src/app/selection/selection-multi-click-chkbox.component.ts +++ b/src/app/selection/selection-multi-click-chkbox.component.ts @@ -80,7 +80,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class MultiClickCheckboxSelectionComponent { diff --git a/src/app/selection/selection-multi-click.component.ts b/src/app/selection/selection-multi-click.component.ts index 78de4a20a..de34b817f 100644 --- a/src/app/selection/selection-multi-click.component.ts +++ b/src/app/selection/selection-multi-click.component.ts @@ -61,7 +61,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class MultiClickSelectionComponent { diff --git a/src/app/selection/selection-multi.component.ts b/src/app/selection/selection-multi.component.ts index 84128e721..09fa9f768 100644 --- a/src/app/selection/selection-multi.component.ts +++ b/src/app/selection/selection-multi.component.ts @@ -64,7 +64,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class MultiSelectionComponent { diff --git a/src/app/selection/selection-single.component.ts b/src/app/selection/selection-single.component.ts index c81124ab0..9c5da1dc1 100644 --- a/src/app/selection/selection-single.component.ts +++ b/src/app/selection/selection-single.component.ts @@ -64,7 +64,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class SingleSelectionComponent { diff --git a/src/app/sorting/sorting-client.component.ts b/src/app/sorting/sorting-client.component.ts index 8d49a6c7f..74e2491b7 100644 --- a/src/app/sorting/sorting-client.component.ts +++ b/src/app/sorting/sorting-client.component.ts @@ -37,7 +37,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class ClientSortingComponent { diff --git a/src/app/sorting/sorting-comparator.component.ts b/src/app/sorting/sorting-comparator.component.ts index 86a02fe37..5180f807a 100644 --- a/src/app/sorting/sorting-comparator.component.ts +++ b/src/app/sorting/sorting-comparator.component.ts @@ -34,7 +34,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class SortingComparatorComponent { diff --git a/src/app/sorting/sorting-default.component.ts b/src/app/sorting/sorting-default.component.ts index ac662ac44..f44d38ab6 100644 --- a/src/app/sorting/sorting-default.component.ts +++ b/src/app/sorting/sorting-default.component.ts @@ -50,7 +50,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class DefaultSortingComponent implements OnInit { diff --git a/src/app/sorting/sorting-server.component.ts b/src/app/sorting/sorting-server.component.ts index 81e308a8f..ece7e005a 100644 --- a/src/app/sorting/sorting-server.component.ts +++ b/src/app/sorting/sorting-server.component.ts @@ -38,7 +38,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class ServerSortingComponent { diff --git a/src/app/summary/summary-row-custom-template.component.ts b/src/app/summary/summary-row-custom-template.component.ts index 4763c7063..1216447b4 100644 --- a/src/app/summary/summary-row-custom-template.component.ts +++ b/src/app/summary/summary-row-custom-template.component.ts @@ -44,7 +44,6 @@ import { DataService } from '../data.service'; `, styleUrls: ['./summary-row-custom-template.component.scss'], - standalone: true, imports: [DatatableComponent] }) export class SummaryRowCustomTemplateComponent implements OnInit { diff --git a/src/app/summary/summary-row-inline-html.component.ts b/src/app/summary/summary-row-inline-html.component.ts index 4f7d7764e..271ebd9d5 100644 --- a/src/app/summary/summary-row-inline-html.component.ts +++ b/src/app/summary/summary-row-inline-html.component.ts @@ -49,7 +49,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent, DataTableColumnDirective] }) export class SummaryRowInlineHtmlComponent { diff --git a/src/app/summary/summary-row-server-paging.component.ts b/src/app/summary/summary-row-server-paging.component.ts index b79cf7d37..a8e46be49 100644 --- a/src/app/summary/summary-row-server-paging.component.ts +++ b/src/app/summary/summary-row-server-paging.component.ts @@ -42,7 +42,6 @@ import { Employee } from '../data.model'; `, - standalone: true, imports: [DatatableComponent] }) export class SummaryRowServerPagingComponent implements OnInit { diff --git a/src/app/summary/summary-row-simple.component.ts b/src/app/summary/summary-row-simple.component.ts index 519f2ccdd..f9f5f1626 100644 --- a/src/app/summary/summary-row-simple.component.ts +++ b/src/app/summary/summary-row-simple.component.ts @@ -54,7 +54,6 @@ import { DataService } from '../data.service'; `, styleUrls: ['./summary-row-simple.component.scss'], - standalone: true, imports: [DatatableComponent] }) export class SummaryRowSimpleComponent { diff --git a/src/app/templates/template-dom.component.ts b/src/app/templates/template-dom.component.ts index 652006c22..2ed27fc88 100644 --- a/src/app/templates/template-dom.component.ts +++ b/src/app/templates/template-dom.component.ts @@ -59,7 +59,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [ DatatableComponent, DataTableColumnDirective, diff --git a/src/app/templates/template-obj.component.ts b/src/app/templates/template-obj.component.ts index fdcbc5f07..cdab20b02 100644 --- a/src/app/templates/template-obj.component.ts +++ b/src/app/templates/template-obj.component.ts @@ -46,7 +46,6 @@ import { DataService } from '../data.service'; `, - standalone: true, imports: [DatatableComponent] }) export class TemplateRefTemplatesComponent implements OnInit { diff --git a/src/app/tree/client-tree.component.ts b/src/app/tree/client-tree.component.ts index b7a39082d..afcb0753c 100644 --- a/src/app/tree/client-tree.component.ts +++ b/src/app/tree/client-tree.component.ts @@ -53,7 +53,6 @@ import { DataService } from '../data.service'; `, styles: ['.icon {height: 10px; width: 10px; }', '.disabled {opacity: 0.5; }'], - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellDirective] }) export class ClientTreeComponent { diff --git a/src/app/tree/fullscreen.component.ts b/src/app/tree/fullscreen.component.ts index 96bb75ebf..b26be3808 100644 --- a/src/app/tree/fullscreen.component.ts +++ b/src/app/tree/fullscreen.component.ts @@ -71,7 +71,6 @@ import { DataService } from '../data.service'; `, styles: ['.icon {height: 10px; width: 10px; }', '.disabled {opacity: 0.5; }'], - standalone: true, imports: [DatatableComponent, DataTableColumnDirective, DataTableColumnCellTreeToggle] }) export class FullScreenTreeComponent {