mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
remove filter string pipe, performance improvements (#10231)
This commit is contained in:
parent
dd2bbd0a4b
commit
0139273914
@ -37,21 +37,17 @@
|
||||
</div>
|
||||
|
||||
<div class="adf-columns-selector-list-container">
|
||||
<ng-container *ngFor="let column of columnItems">
|
||||
<div
|
||||
*ngIf="(column.title | translate | filterString:searchQuery) as translatedTitle"
|
||||
class="adf-columns-selector-list-item">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
class="adf-columns-selector-column-checkbox"
|
||||
[attr.data-automation-id]="'adf-columns-selector-column-checkbox-' + column.title"
|
||||
[checked]="!column.isHidden"
|
||||
[disabled]="isCheckboxDisabled(column)"
|
||||
(change)="changeColumnVisibility(column)">
|
||||
<div class="adf-columns-selector-list-content">{{translatedTitle}}</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</ng-container>
|
||||
<div *ngFor="let column of columnItems" class="adf-columns-selector-list-item">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
class="adf-columns-selector-column-checkbox"
|
||||
[attr.data-automation-id]="'adf-columns-selector-column-checkbox-' + column.title"
|
||||
[checked]="!column.isHidden"
|
||||
[disabled]="isCheckboxDisabled(column)"
|
||||
(change)="changeColumnVisibility(column)">
|
||||
<div class="adf-columns-selector-list-content">{{column.title | translate}}</div>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="adf-columns-selector-divider"></mat-divider>
|
||||
|
@ -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<ColumnsSelectorComponent>;
|
||||
@ -91,6 +91,8 @@ describe('ColumnsSelectorComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => fixture.destroy());
|
||||
|
||||
it('should clear search after closing menu', fakeAsync(() => {
|
||||
menuOpenedTrigger.next();
|
||||
fixture.detectChanges();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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');
|
||||
});
|
||||
});
|
@ -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 : '';
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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';
|
||||
|
Loading…
x
Reference in New Issue
Block a user