From 01392739142de097710df2c5c49ac13a7542e8a8 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 30 Sep 2024 10:44:15 -0400 Subject: [PATCH] remove filter string pipe, performance improvements (#10231) --- .../columns-selector.component.html | 26 +++---- .../columns-selector.component.spec.ts | 4 +- .../columns-selector.component.ts | 68 ++++++++++++++----- .../src/lib/pipes/filter-string.pipe.spec.ts | 44 ------------ lib/core/src/lib/pipes/filter-string.pipe.ts | 30 -------- lib/core/src/lib/pipes/pipe.module.ts | 2 - lib/core/src/lib/pipes/public-api.ts | 1 - 7 files changed, 64 insertions(+), 111 deletions(-) delete mode 100644 lib/core/src/lib/pipes/filter-string.pipe.spec.ts delete mode 100644 lib/core/src/lib/pipes/filter-string.pipe.ts diff --git a/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.html b/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.html index 56d4216abc..1743cb2b9c 100644 --- a/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.html +++ b/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.html @@ -37,21 +37,17 @@
- -
- -
{{translatedTitle}}
-
-
-
+
+ +
{{column.title | translate}}
+
+
diff --git a/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.spec.ts b/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.spec.ts index 63ddfd5a4c..344f67c03a 100644 --- a/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.spec.ts +++ b/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.spec.ts @@ -24,7 +24,7 @@ import { By } from '@angular/platform-browser'; import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; import { HarnessLoader } from '@angular/cdk/testing'; import { MatCheckboxHarness } from '@angular/material/checkbox/testing'; -import { NoopTranslateModule } from '@alfresco/adf-core'; +import { NoopTranslateModule } from '../../../testing/noop-translate.module'; describe('ColumnsSelectorComponent', () => { let fixture: ComponentFixture; @@ -91,6 +91,8 @@ describe('ColumnsSelectorComponent', () => { fixture.detectChanges(); }); + afterEach(() => fixture.destroy()); + it('should clear search after closing menu', fakeAsync(() => { menuOpenedTrigger.next(); fixture.detectChanges(); diff --git a/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.ts b/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.ts index f6d5655ab3..c2b4e91f93 100644 --- a/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.ts +++ b/lib/core/src/lib/datatable/components/columns-selector/columns-selector.component.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core'; import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms'; import { MatMenuTrigger } from '@angular/material/menu'; import { Subject } from 'rxjs'; @@ -27,25 +27,19 @@ import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatDividerModule } from '@angular/material/divider'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { FilterStringPipe } from '../../../pipes'; +import { TranslationService } from '../../../translation'; + @Component({ selector: 'adf-datatable-column-selector', standalone: true, - imports: [ - CommonModule, - TranslateModule, - MatButtonModule, - MatIconModule, - MatDividerModule, - ReactiveFormsModule, - MatCheckboxModule, - FilterStringPipe - ], + imports: [CommonModule, TranslateModule, MatButtonModule, MatIconModule, MatDividerModule, ReactiveFormsModule, MatCheckboxModule], templateUrl: './columns-selector.component.html', styleUrls: ['./columns-selector.component.scss'], encapsulation: ViewEncapsulation.None }) export class ColumnsSelectorComponent implements OnInit, OnDestroy { + private translationService = inject(TranslationService); + @Input() columns: DataColumn[] = []; @@ -68,8 +62,7 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy { ngOnInit(): void { this.mainMenuTrigger.menuOpened.pipe(takeUntil(this.onDestroy$)).subscribe(() => { - const columns = this.columns.map((column) => ({ ...column })); - this.columnItems = this.columnsSorting ? this.sortColumns(columns) : columns; + this.updateColumnItems(); }); this.mainMenuTrigger.menuClosed.pipe(takeUntil(this.onDestroy$)).subscribe(() => { @@ -78,9 +71,17 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy { this.searchInputControl.valueChanges.pipe(debounceTime(300), takeUntil(this.onDestroy$)).subscribe((searchQuery) => { this.searchQuery = searchQuery; + this.updateColumnItems(); }); } + private updateColumnItems(): void { + let columns = this.columns.map((column) => ({ ...column })); + columns = this.filterColumnItems(columns, this.searchQuery); + columns = this.sortColumns(columns); + this.columnItems = columns; + } + ngOnDestroy() { this.onDestroy$.next(true); this.onDestroy$.complete(); @@ -90,6 +91,34 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy { this.mainMenuTrigger.closeMenu(); } + private filterString(value: string = '', filterBy: string = ''): string { + const testResult = filterBy ? value.toLowerCase().indexOf(filterBy.toLowerCase()) > -1 : true; + return testResult ? value : ''; + } + + private filterColumnItems(columns: DataColumn[], query: string): DataColumn[] { + const result = []; + + for (const column of columns) { + if (!column.title) { + continue; + } + + if (!query) { + result.push(column); + continue; + } + + const title = this.translationService.instant(column.title); + + if (this.filterString(title, query)) { + result.push(column); + } + } + + return result; + } + changeColumnVisibility(column: DataColumn): void { column.isHidden = !column.isHidden; } @@ -103,14 +132,17 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy { return ( this.maxColumnsVisible && column.isHidden && - this.maxColumnsVisible === this.columnItems.filter((dataColumn) => !dataColumn.isHidden).length + this.maxColumnsVisible >= this.columnItems.filter((dataColumn) => !dataColumn.isHidden).length ); } private sortColumns(columns: DataColumn[]): DataColumn[] { - const shownColumns = columns.filter((column) => !column.isHidden); - const hiddenColumns = columns.filter((column) => column.isHidden); + if (this.columnsSorting) { + const shownColumns = columns.filter((column) => !column.isHidden); + const hiddenColumns = columns.filter((column) => column.isHidden); - return [...shownColumns, ...hiddenColumns]; + return [...shownColumns, ...hiddenColumns]; + } + return columns; } } diff --git a/lib/core/src/lib/pipes/filter-string.pipe.spec.ts b/lib/core/src/lib/pipes/filter-string.pipe.spec.ts deleted file mode 100644 index a2ce5714f2..0000000000 --- a/lib/core/src/lib/pipes/filter-string.pipe.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * @license - * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { FilterStringPipe } from './filter-string.pipe'; - -describe('FilterStringPipe', () => { - let pipe: FilterStringPipe; - - beforeEach(() => { - pipe = new FilterStringPipe(); - }); - - it('should left string', () => { - const result = pipe.transform('ABC', 'B'); - - expect(result).toBe('ABC'); - }); - - it('should filter out string', () => { - const result = pipe.transform('ABC', 'D'); - - expect(result).toBe(''); - }); - - it('should left string when no query string is passed', () => { - const result = pipe.transform('ABC'); - - expect(result).toBe('ABC'); - }); -}); diff --git a/lib/core/src/lib/pipes/filter-string.pipe.ts b/lib/core/src/lib/pipes/filter-string.pipe.ts deleted file mode 100644 index 27eb51cf63..0000000000 --- a/lib/core/src/lib/pipes/filter-string.pipe.ts +++ /dev/null @@ -1,30 +0,0 @@ -/*! - * @license - * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Pipe, PipeTransform } from '@angular/core'; - -@Pipe({ - name: 'filterString', - standalone: true -}) -export class FilterStringPipe implements PipeTransform { - transform(value: string = '', filterBy: string = ''): string { - const testResult = filterBy ? value.toLowerCase().indexOf(filterBy.toLowerCase()) > -1 : true; - - return testResult ? value : ''; - } -} diff --git a/lib/core/src/lib/pipes/pipe.module.ts b/lib/core/src/lib/pipes/pipe.module.ts index f75f6891b2..092d0d82a3 100644 --- a/lib/core/src/lib/pipes/pipe.module.ts +++ b/lib/core/src/lib/pipes/pipe.module.ts @@ -29,7 +29,6 @@ import { LocalizedDatePipe } from './localized-date.pipe'; import { DecimalNumberPipe } from './decimal-number.pipe'; import { MomentDatePipe } from './moment-date.pipe'; import { MomentDateTimePipe } from './moment-datetime.pipe'; -import { FilterStringPipe } from './filter-string.pipe'; import { DateTimePipe } from './date-time.pipe'; export const CORE_PIPES = [ @@ -45,7 +44,6 @@ export const CORE_PIPES = [ MomentDatePipe, MomentDateTimePipe, DateTimePipe, - FilterStringPipe, InitialUsernamePipe ] as const; diff --git a/lib/core/src/lib/pipes/public-api.ts b/lib/core/src/lib/pipes/public-api.ts index 0d56cb670a..5f53aa2273 100644 --- a/lib/core/src/lib/pipes/public-api.ts +++ b/lib/core/src/lib/pipes/public-api.ts @@ -29,4 +29,3 @@ export * from './pipe.module'; export * from './moment-date.pipe'; export * from './moment-datetime.pipe'; export * from './date-time.pipe'; -export * from './filter-string.pipe';