UI: Fixed search in entities table, incorrect set query property when page go back. Improved detect change search text

This commit is contained in:
Vladyslav_Prykhodko 2023-08-15 11:42:18 +03:00
parent 12b232132f
commit 4a72c80005
8 changed files with 35 additions and 41 deletions

View File

@ -40,7 +40,7 @@ import { MatDialog } from '@angular/material/dialog';
import { DialogService } from '@core/services/dialog.service'; import { DialogService } from '@core/services/dialog.service';
import { Direction, SortOrder } from '@shared/models/page/sort-order'; import { Direction, SortOrder } from '@shared/models/page/sort-order';
import { merge, Subject } from 'rxjs'; import { merge, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, skip, startWith, takeUntil } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { import {
AttributeData, AttributeData,
@ -243,9 +243,7 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
ngAfterViewInit() { ngAfterViewInit() {
this.textSearch.valueChanges.pipe( this.textSearch.valueChanges.pipe(
debounceTime(150), debounceTime(150),
startWith(''), distinctUntilChanged((prev, current) => (this.pageLink.textSearch ?? '') === current.trim()),
distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()),
skip(1),
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((value) => { ).subscribe((value) => {
this.paginator.pageIndex = 0; this.paginator.pageIndex = 0;
@ -297,10 +295,10 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
} }
this.mode = 'default'; this.mode = 'default';
this.textSearchMode = false; this.textSearchMode = false;
this.textSearch.reset('', {emitEvent: false});
this.selectedWidgetsBundleAlias = null; this.selectedWidgetsBundleAlias = null;
this.attributeScope = this.defaultAttributeScope; this.attributeScope = this.defaultAttributeScope;
this.pageLink.textSearch = null; this.pageLink.textSearch = null;
this.textSearch.reset();
if (this.viewsInited) { if (this.viewsInited) {
this.paginator.pageIndex = 0; this.paginator.pageIndex = 0;
const sortable = this.sort.sortables.get('key'); const sortable = this.sort.sortables.get('key');

View File

@ -37,7 +37,7 @@ import { MatDialog } from '@angular/material/dialog';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort, SortDirection } from '@angular/material/sort'; import { MatSort, SortDirection } from '@angular/material/sort';
import { EntitiesDataSource } from '@home/models/datasource/entity-datasource'; import { EntitiesDataSource } from '@home/models/datasource/entity-datasource';
import { catchError, debounceTime, distinctUntilChanged, map, skip, startWith, takeUntil } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, skip, takeUntil } from 'rxjs/operators';
import { Direction, SortOrder } from '@shared/models/page/sort-order'; import { Direction, SortOrder } from '@shared/models/page/sort-order';
import { forkJoin, merge, Observable, of, Subject, Subscription } from 'rxjs'; import { forkJoin, merge, Observable, of, Subject, Subscription } from 'rxjs';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -60,7 +60,7 @@ import { AddEntityDialogData, EntityAction } from '@home/models/entity/entity-co
import { calculateIntervalStartEndTime, HistoryWindowType, Timewindow } from '@shared/models/time/time.models'; import { calculateIntervalStartEndTime, HistoryWindowType, Timewindow } from '@shared/models/time/time.models';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { TbAnchorComponent } from '@shared/components/tb-anchor.component'; import { TbAnchorComponent } from '@shared/components/tb-anchor.component';
import { isDefined, isEmptyStr, isEqual, isNotEmptyStr, isUndefined } from '@core/utils'; import { isDefined, isEqual, isNotEmptyStr, isUndefined } from '@core/utils';
import { HasUUID } from '@shared/models/id/has-uuid'; import { HasUUID } from '@shared/models/id/has-uuid';
import { ResizeObserver } from '@juggle/resize-observer'; import { ResizeObserver } from '@juggle/resize-observer';
import { hidePageSizePixelValue } from '@shared/models/constants'; import { hidePageSizePixelValue } from '@shared/models/constants';
@ -271,11 +271,11 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
this.pageLink.pageSize = Number(routerQueryParams.pageSize); this.pageLink.pageSize = Number(routerQueryParams.pageSize);
} }
const textSearchParam = routerQueryParams.textSearch; const textSearchParam = routerQueryParams.textSearch;
if (textSearchParam && !isEmptyStr(textSearchParam)) { if (isNotEmptyStr(textSearchParam)) {
const decodedTextSearch = decodeURI(routerQueryParams.textSearch); const decodedTextSearch = decodeURI(textSearchParam);
this.textSearchMode = true; this.textSearchMode = true;
this.textSearch.setValue(decodedTextSearch, { emitEvent: false });
this.pageLink.textSearch = decodedTextSearch.trim(); this.pageLink.textSearch = decodedTextSearch.trim();
this.textSearch.setValue(decodedTextSearch);
} }
} }
this.dataSource = this.entitiesTableConfig.dataSource(this.dataLoaded.bind(this)); this.dataSource = this.entitiesTableConfig.dataSource(this.dataLoaded.bind(this));
@ -312,9 +312,7 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
this.textSearch.valueChanges.pipe( this.textSearch.valueChanges.pipe(
debounceTime(150), debounceTime(150),
startWith(''), distinctUntilChanged((prev, current) => (this.pageLink.textSearch ?? '') === current.trim()),
distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()),
skip(1),
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe(value => { ).subscribe(value => {
const queryParams: PageQueryParam = {}; const queryParams: PageQueryParam = {};
@ -343,6 +341,15 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
} }
this.sort.active = params.property || this.entitiesTableConfig.defaultSortOrder.property; this.sort.active = params.property || this.entitiesTableConfig.defaultSortOrder.property;
this.sort.direction = (params.direction || this.entitiesTableConfig.defaultSortOrder.direction).toLowerCase() as SortDirection; this.sort.direction = (params.direction || this.entitiesTableConfig.defaultSortOrder.direction).toLowerCase() as SortDirection;
const textSearchParam = params.textSearch;
if (isNotEmptyStr(textSearchParam)) {
const decodedTextSearch = decodeURI(textSearchParam);
this.textSearchMode = true;
this.pageLink.textSearch = decodedTextSearch.trim();
this.textSearch.setValue(decodedTextSearch);
} else {
this.pageLink.textSearch = null;
}
this.updateData(); this.updateData();
}); });
} }
@ -373,12 +380,10 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
); );
if (this.displayPagination) { if (this.displayPagination) {
paginatorSubscription$ = this.paginator.page.asObservable().pipe( paginatorSubscription$ = this.paginator.page.asObservable().pipe(
map((data) => { map((data) => ({
return {
page: data.pageIndex === 0 ? null : data.pageIndex, page: data.pageIndex === 0 ? null : data.pageIndex,
pageSize: data.pageSize === this.defaultPageSize ? null : data.pageSize pageSize: data.pageSize === this.defaultPageSize ? null : data.pageSize
}; }))
})
); );
} }
this.updateDataSubscription = ((this.displayPagination ? merge(sortSubscription$, paginatorSubscription$) this.updateDataSubscription = ((this.displayPagination ? merge(sortSubscription$, paginatorSubscription$)
@ -590,8 +595,8 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
resetSortAndFilter(update: boolean = true, preserveTimewindow: boolean = false) { resetSortAndFilter(update: boolean = true, preserveTimewindow: boolean = false) {
this.textSearchMode = false; this.textSearchMode = false;
this.textSearch.reset('', {emitEvent: false});
this.pageLink.textSearch = null; this.pageLink.textSearch = null;
this.textSearch.reset();
if (this.entitiesTableConfig.useTimePageLink && !preserveTimewindow) { if (this.entitiesTableConfig.useTimePageLink && !preserveTimewindow) {
this.timewindow = this.entitiesTableConfig.defaultTimewindowInterval; this.timewindow = this.entitiesTableConfig.defaultTimewindowInterval;
} }

View File

@ -37,7 +37,7 @@ import { DialogService } from '@core/services/dialog.service';
import { EntityRelationService } from '@core/http/entity-relation.service'; import { EntityRelationService } from '@core/http/entity-relation.service';
import { Direction, SortOrder } from '@shared/models/page/sort-order'; import { Direction, SortOrder } from '@shared/models/page/sort-order';
import { forkJoin, merge, Observable, Subject } from 'rxjs'; import { forkJoin, merge, Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, skip, startWith, takeUntil } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
import { import {
EntityRelation, EntityRelation,
EntityRelationInfo, EntityRelationInfo,
@ -169,9 +169,7 @@ export class RelationTableComponent extends PageComponent implements AfterViewIn
ngAfterViewInit() { ngAfterViewInit() {
this.textSearch.valueChanges.pipe( this.textSearch.valueChanges.pipe(
debounceTime(150), debounceTime(150),
startWith(''), distinctUntilChanged((prev, current) => (this.pageLink.textSearch ?? '') === current.trim()),
distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()),
skip(1),
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((value) => { ).subscribe((value) => {
this.paginator.pageIndex = 0; this.paginator.pageIndex = 0;
@ -215,8 +213,8 @@ export class RelationTableComponent extends PageComponent implements AfterViewIn
resetSortAndFilter(update: boolean = true) { resetSortAndFilter(update: boolean = true) {
this.direction = EntitySearchDirection.FROM; this.direction = EntitySearchDirection.FROM;
this.updateColumns(); this.updateColumns();
this.textSearch.reset('', {emitEvent: false});
this.pageLink.textSearch = null; this.pageLink.textSearch = null;
this.textSearch.reset();
this.paginator.pageIndex = 0; this.paginator.pageIndex = 0;
const sortable = this.sort.sortables.get('type'); const sortable = this.sort.sortables.get('type');
this.sort.active = sortable.id; this.sort.active = sortable.id;

View File

@ -36,7 +36,7 @@ import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { BehaviorSubject, merge, Observable, of, ReplaySubject, Subject } from 'rxjs'; import { BehaviorSubject, merge, Observable, of, ReplaySubject, Subject } from 'rxjs';
import { emptyPageData, PageData } from '@shared/models/page/page-data'; import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { PageLink } from '@shared/models/page/page-link'; import { PageLink } from '@shared/models/page/page-link';
import { catchError, debounceTime, distinctUntilChanged, map, skip, startWith, takeUntil } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
import { EntityVersion, VersionCreationResult, VersionLoadResult } from '@shared/models/vc.models'; import { EntityVersion, VersionCreationResult, VersionLoadResult } from '@shared/models/vc.models';
import { EntitiesVersionControlService } from '@core/http/entities-version-control.service'; import { EntitiesVersionControlService } from '@core/http/entities-version-control.service';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
@ -183,9 +183,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni
ngAfterViewInit() { ngAfterViewInit() {
this.textSearch.valueChanges.pipe( this.textSearch.valueChanges.pipe(
debounceTime(400), debounceTime(400),
startWith(''), distinctUntilChanged((prev, current) => (this.pageLink.textSearch ?? '') === current.trim()),
distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()),
skip(1),
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((value) => { ).subscribe((value) => {
this.paginator.pageIndex = 0; this.paginator.pageIndex = 0;
@ -379,8 +377,8 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni
private resetSortAndFilter(update: boolean) { private resetSortAndFilter(update: boolean) {
this.textSearchMode = false; this.textSearchMode = false;
this.textSearch.reset('', {emitEvent: false});
this.pageLink.textSearch = null; this.pageLink.textSearch = null;
this.textSearch.reset();
if (this.viewsInited) { if (this.viewsInited) {
this.paginator.pageIndex = 0; this.paginator.pageIndex = 0;
const sortable = this.sort.sortables.get('timestamp'); const sortable = this.sort.sortables.get('timestamp');

View File

@ -44,7 +44,7 @@ import { Direction } from '@shared/models/page/sort-order';
import { CollectionViewer, DataSource, SelectionModel } from '@angular/cdk/collections'; import { CollectionViewer, DataSource, SelectionModel } from '@angular/cdk/collections';
import { BehaviorSubject, forkJoin, merge, Observable, Subject, Subscription } from 'rxjs'; import { BehaviorSubject, forkJoin, merge, Observable, Subject, Subscription } from 'rxjs';
import { emptyPageData, PageData } from '@shared/models/page/page-data'; import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { debounceTime, distinctUntilChanged, map, skip, startWith, take, takeUntil, tap } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, map, take, takeUntil, tap } from 'rxjs/operators';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort, SortDirection } from '@angular/material/sort'; import { MatSort, SortDirection } from '@angular/material/sort';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@ -297,9 +297,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.textSearch.valueChanges.pipe( this.textSearch.valueChanges.pipe(
debounceTime(150), debounceTime(150),
startWith(''), distinctUntilChanged((prev, current) => (this.pageLink.textSearch ?? '') === current.trim()),
distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()),
skip(1),
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((value) => { ).subscribe((value) => {
this.resetPageIndex(); this.resetPageIndex();

View File

@ -224,7 +224,6 @@ export class EntitiesHierarchyWidgetComponent extends PageComponent implements O
exitFilterMode() { exitFilterMode() {
this.textSearchMode = false; this.textSearchMode = false;
this.textSearch.reset(); this.textSearch.reset();
this.nodeEditCallbacks.clearSearch();
this.ctx.hideTitlePanel = false; this.ctx.hideTitlePanel = false;
this.ctx.detectChanges(true); this.ctx.detectChanges(true);
} }

View File

@ -50,7 +50,7 @@ import { BehaviorSubject, merge, Observable, Subject } from 'rxjs';
import { emptyPageData, PageData } from '@shared/models/page/page-data'; import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { entityTypeTranslations } from '@shared/models/entity-type.models'; import { entityTypeTranslations } from '@shared/models/entity-type.models';
import { debounceTime, distinctUntilChanged, map, skip, startWith, takeUntil } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort, SortDirection } from '@angular/material/sort'; import { MatSort, SortDirection } from '@angular/material/sort';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@ -240,9 +240,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.textSearch.valueChanges.pipe( this.textSearch.valueChanges.pipe(
debounceTime(150), debounceTime(150),
startWith(''), distinctUntilChanged((prev, current) => (this.pageLink.textSearch ?? '') === current.trim()),
distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()),
skip(1),
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((value) => { ).subscribe((value) => {
if (this.displayPagination) { if (this.displayPagination) {

View File

@ -108,7 +108,7 @@ export class HomeComponent extends PageComponent implements AfterViewInit, OnIni
distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()), distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()),
skip(1), skip(1),
takeUntil(this.destroy$) takeUntil(this.destroy$)
).subscribe((value) => this.searchTextUpdated(value)); ).subscribe(value => this.searchTextUpdated(value.trim()));
} }
sidenavClicked() { sidenavClicked() {
@ -181,7 +181,7 @@ export class HomeComponent extends PageComponent implements AfterViewInit, OnIni
private searchTextUpdated(searchText: string) { private searchTextUpdated(searchText: string) {
if (this.searchableComponent) { if (this.searchableComponent) {
this.searchableComponent.onSearchTextUpdated(searchText.trim()); this.searchableComponent.onSearchTextUpdated(searchText);
} }
} }
} }