Browse Source

Merge pull request #4781 from vvlladd28/improvement/autocomplete/debounceTime

UI: Improvement autocomplete component: debounceTime and catchError
pull/4851/head
Igor Kulikov 5 years ago
committed by GitHub
parent
commit
8c2c5b7175
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      ui-ngx/src/app/modules/home/components/alias/aliases-entity-autocomplete.component.ts
  2. 16
      ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.ts
  3. 10
      ui-ngx/src/app/modules/home/components/profile/tenant-profile-autocomplete.component.ts
  4. 15
      ui-ngx/src/app/modules/home/components/rule-chain/rule-chain-autocomplete.component.ts
  5. 7
      ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts
  6. 9
      ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts
  7. 18
      ui-ngx/src/app/shared/components/entity/entity-subtype-autocomplete.component.ts
  8. 11
      ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.ts
  9. 18
      ui-ngx/src/app/shared/components/queue/queue-type-list.component.ts

14
ui-ngx/src/app/modules/home/components/alias/aliases-entity-autocomplete.component.ts

@ -16,9 +16,9 @@
import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map, mergeMap, startWith, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, startWith, switchMap, tap } from 'rxjs/operators';
import { PageData } from '@shared/models/page/page-data'; import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -88,6 +88,7 @@ export class AliasesEntityAutocompleteComponent implements ControlValueAccessor,
ngOnInit() { ngOnInit() {
this.filteredEntityInfos = this.selectEntityInfoFormGroup.get('entityInfo').valueChanges this.filteredEntityInfos = this.selectEntityInfoFormGroup.get('entityInfo').valueChanges
.pipe( .pipe(
debounceTime(150),
tap(value => { tap(value => {
let modelValue; let modelValue;
if (typeof value === 'string' || !value) { if (typeof value === 'string' || !value) {
@ -99,7 +100,8 @@ export class AliasesEntityAutocompleteComponent implements ControlValueAccessor,
}), }),
startWith<string | EntityInfo>(''), startWith<string | EntityInfo>(''),
map(value => value ? (typeof value === 'string' ? value : value.name) : ''), map(value => value ? (typeof value === 'string' ? value : value.name) : ''),
mergeMap(name => this.fetchEntityInfos(name) ) distinctUntilChanged(),
switchMap(name => this.fetchEntityInfos(name))
); );
} }
@ -142,7 +144,9 @@ export class AliasesEntityAutocompleteComponent implements ControlValueAccessor,
} }
getEntityInfos(searchText: string): Observable<PageData<EntityInfo>> { getEntityInfos(searchText: string): Observable<PageData<EntityInfo>> {
return this.entityService.findEntityInfosByFilterAndName(this.entityFilter, searchText, {ignoreLoading: true}); return this.entityService.findEntityInfosByFilterAndName(this.entityFilter, searchText, {ignoreLoading: true}).pipe(
catchError(() => of(emptyPageData<EntityInfo>()))
);
} }
clear() { clear() {

16
ui-ngx/src/app/modules/home/components/profile/device-profile-autocomplete.component.ts

@ -20,16 +20,18 @@ import {
EventEmitter, EventEmitter,
forwardRef, forwardRef,
Input, Input,
NgZone, OnChanges, NgZone,
OnChanges,
OnInit, OnInit,
Output, SimpleChanges, Output,
SimpleChanges,
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { PageLink } from '@shared/models/page/page-link'; import { PageLink } from '@shared/models/page/page-link';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { map, mergeMap, share, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -44,6 +46,7 @@ import { DeviceProfileService } from '@core/http/device-profile.service';
import { DeviceProfileDialogComponent, DeviceProfileDialogData } from './device-profile-dialog.component'; import { DeviceProfileDialogComponent, DeviceProfileDialogData } from './device-profile-dialog.component';
import { MatAutocomplete } from '@angular/material/autocomplete'; import { MatAutocomplete } from '@angular/material/autocomplete';
import { AddDeviceProfileDialogComponent, AddDeviceProfileDialogData } from './add-device-profile-dialog.component'; import { AddDeviceProfileDialogComponent, AddDeviceProfileDialogData } from './add-device-profile-dialog.component';
import { emptyPageData } from "@shared/models/page/page-data";
@Component({ @Component({
selector: 'tb-device-profile-autocomplete', selector: 'tb-device-profile-autocomplete',
@ -143,6 +146,7 @@ export class DeviceProfileAutocompleteComponent implements ControlValueAccessor,
ngOnInit() { ngOnInit() {
this.filteredDeviceProfiles = this.selectDeviceProfileFormGroup.get('deviceProfile').valueChanges this.filteredDeviceProfiles = this.selectDeviceProfileFormGroup.get('deviceProfile').valueChanges
.pipe( .pipe(
debounceTime(150),
tap((value: DeviceProfileInfo | string) => { tap((value: DeviceProfileInfo | string) => {
let modelValue: DeviceProfileInfo | null; let modelValue: DeviceProfileInfo | null;
if (typeof value === 'string' || !value) { if (typeof value === 'string' || !value) {
@ -169,7 +173,8 @@ export class DeviceProfileAutocompleteComponent implements ControlValueAccessor,
return ''; return '';
} }
}), }),
mergeMap(name => this.fetchDeviceProfiles(name) ), distinctUntilChanged(),
switchMap(name => this.fetchDeviceProfiles(name)),
share() share()
); );
} }
@ -289,6 +294,7 @@ export class DeviceProfileAutocompleteComponent implements ControlValueAccessor,
direction: Direction.ASC direction: Direction.ASC
}); });
return this.deviceProfileService.getDeviceProfileInfos(pageLink, this.transportType, {ignoreLoading: true}).pipe( return this.deviceProfileService.getDeviceProfileInfos(pageLink, this.transportType, {ignoreLoading: true}).pipe(
catchError(() => of(emptyPageData<DeviceProfileInfo>())),
map(pageData => { map(pageData => {
let data = pageData.data; let data = pageData.data;
if (this.displayAllOnEmpty) { if (this.displayAllOnEmpty) {

10
ui-ngx/src/app/modules/home/components/profile/tenant-profile-autocomplete.component.ts

@ -16,10 +16,10 @@
import { Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core'; import { Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { PageLink } from '@shared/models/page/page-link'; import { PageLink } from '@shared/models/page/page-link';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { map, mergeMap, share, startWith, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -33,6 +33,7 @@ import { ENTER } from '@angular/cdk/keycodes';
import { TenantProfile } from '@shared/models/tenant.model'; import { TenantProfile } from '@shared/models/tenant.model';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { TenantProfileDialogComponent, TenantProfileDialogData } from './tenant-profile-dialog.component'; import { TenantProfileDialogComponent, TenantProfileDialogData } from './tenant-profile-dialog.component';
import { emptyPageData } from "@shared/models/page/page-data";
@Component({ @Component({
selector: 'tb-tenant-profile-autocomplete', selector: 'tb-tenant-profile-autocomplete',
@ -99,6 +100,7 @@ export class TenantProfileAutocompleteComponent implements ControlValueAccessor,
ngOnInit() { ngOnInit() {
this.filteredTenantProfiles = this.selectTenantProfileFormGroup.get('tenantProfile').valueChanges this.filteredTenantProfiles = this.selectTenantProfileFormGroup.get('tenantProfile').valueChanges
.pipe( .pipe(
debounceTime(150),
tap((value: EntityInfoData | string) => { tap((value: EntityInfoData | string) => {
let modelValue: TenantProfileId | null; let modelValue: TenantProfileId | null;
if (typeof value === 'string' || !value) { if (typeof value === 'string' || !value) {
@ -109,7 +111,8 @@ export class TenantProfileAutocompleteComponent implements ControlValueAccessor,
this.updateView(modelValue); this.updateView(modelValue);
}), }),
map(value => value ? (typeof value === 'string' ? value : value.name) : ''), map(value => value ? (typeof value === 'string' ? value : value.name) : ''),
mergeMap(name => this.fetchTenantProfiles(name) ), distinctUntilChanged(),
switchMap(name => this.fetchTenantProfiles(name)),
share() share()
); );
} }
@ -174,6 +177,7 @@ export class TenantProfileAutocompleteComponent implements ControlValueAccessor,
direction: Direction.ASC direction: Direction.ASC
}); });
return this.tenantProfileService.getTenantProfileInfos(pageLink, {ignoreLoading: true}).pipe( return this.tenantProfileService.getTenantProfileInfos(pageLink, {ignoreLoading: true}).pipe(
catchError(() => of(emptyPageData<EntityInfoData>())),
map(pageData => { map(pageData => {
return pageData.data; return pageData.data;
}) })

15
ui-ngx/src/app/modules/home/components/rule-chain/rule-chain-autocomplete.component.ts

@ -16,8 +16,8 @@
import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map, mergeMap, share, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -99,6 +99,7 @@ export class RuleChainAutocompleteComponent implements ControlValueAccessor, OnI
ngOnInit() { ngOnInit() {
this.filteredRuleChains = this.selectRuleChainFormGroup.get('ruleChainId').valueChanges this.filteredRuleChains = this.selectRuleChainFormGroup.get('ruleChainId').valueChanges
.pipe( .pipe(
debounceTime(150),
tap(value => { tap(value => {
let modelValue; let modelValue;
if (typeof value === 'string' || !value) { if (typeof value === 'string' || !value) {
@ -110,8 +111,10 @@ export class RuleChainAutocompleteComponent implements ControlValueAccessor, OnI
if (value === null) { if (value === null) {
this.clear(); this.clear();
} }
}), map(value => value ? (typeof value === 'string' ? value : value.name) : ''), }),
mergeMap(name => this.fetchRuleChain(name) ), map(value => value ? (typeof value === 'string' ? value : value.name) : ''),
distinctUntilChanged(),
switchMap(name => this.fetchRuleChain(name) ),
share() share()
); );
} }
@ -190,7 +193,9 @@ export class RuleChainAutocompleteComponent implements ControlValueAccessor, OnI
this.searchText = searchText; this.searchText = searchText;
// voba: at the moment device profiles are not supported by edge, so 'core' hardcoded // voba: at the moment device profiles are not supported by edge, so 'core' hardcoded
return this.entityService.getEntitiesByNameFilter(EntityType.RULE_CHAIN, searchText, return this.entityService.getEntitiesByNameFilter(EntityType.RULE_CHAIN, searchText,
50, RuleChainType.CORE, {ignoreLoading: true}); 50, RuleChainType.CORE, {ignoreLoading: true}).pipe(
catchError(() => of([]))
);
} }
clear() { clear() {

7
ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts

@ -19,7 +19,7 @@ import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { PageLink } from '@shared/models/page/page-link'; import { PageLink } from '@shared/models/page/page-link';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { map, mergeMap, startWith, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, startWith, switchMap, tap } from 'rxjs/operators';
import { emptyPageData, PageData } from '@shared/models/page/page-data'; import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { DashboardInfo } from '@app/shared/models/dashboard.models'; import { DashboardInfo } from '@app/shared/models/dashboard.models';
import { DashboardService } from '@core/http/dashboard.service'; import { DashboardService } from '@core/http/dashboard.service';
@ -107,6 +107,7 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI
ngOnInit() { ngOnInit() {
this.filteredDashboards = this.selectDashboardFormGroup.get('dashboard').valueChanges this.filteredDashboards = this.selectDashboardFormGroup.get('dashboard').valueChanges
.pipe( .pipe(
debounceTime(150),
tap(value => { tap(value => {
let modelValue; let modelValue;
if (typeof value === 'string' || !value) { if (typeof value === 'string' || !value) {
@ -118,7 +119,8 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI
}), }),
startWith<string | DashboardInfo>(''), startWith<string | DashboardInfo>(''),
map(value => value ? (typeof value === 'string' ? value : value.name) : ''), map(value => value ? (typeof value === 'string' ? value : value.name) : ''),
mergeMap(name => this.fetchDashboards(name) ) distinctUntilChanged(),
switchMap(name => this.fetchDashboards(name) )
); );
} }
@ -189,6 +191,7 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI
direction: Direction.ASC direction: Direction.ASC
}); });
return this.getDashboards(pageLink).pipe( return this.getDashboards(pageLink).pipe(
catchError(() => of(emptyPageData<DashboardInfo>())),
map(pageData => { map(pageData => {
return pageData.data; return pageData.data;
}) })

9
ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts

@ -26,8 +26,8 @@ import {
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map, mergeMap, share, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -142,6 +142,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
ngOnInit() { ngOnInit() {
this.filteredEntities = this.selectEntityFormGroup.get('entity').valueChanges this.filteredEntities = this.selectEntityFormGroup.get('entity').valueChanges
.pipe( .pipe(
debounceTime(150),
tap(value => { tap(value => {
let modelValue; let modelValue;
if (typeof value === 'string' || !value) { if (typeof value === 'string' || !value) {
@ -156,7 +157,8 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
}), }),
// startWith<string | BaseData<EntityId>>(''), // startWith<string | BaseData<EntityId>>(''),
map(value => value ? (typeof value === 'string' ? value : value.name) : ''), map(value => value ? (typeof value === 'string' ? value : value.name) : ''),
mergeMap(name => this.fetchEntities(name) ), distinctUntilChanged(),
switchMap(name => this.fetchEntities(name)),
share() share()
); );
} }
@ -326,6 +328,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
const targetEntityType = this.checkEntityType(this.entityTypeValue); const targetEntityType = this.checkEntityType(this.entityTypeValue);
return this.entityService.getEntitiesByNameFilter(targetEntityType, searchText, return this.entityService.getEntitiesByNameFilter(targetEntityType, searchText,
50, this.entitySubtypeValue, {ignoreLoading: true}).pipe( 50, this.entitySubtypeValue, {ignoreLoading: true}).pipe(
catchError(() => of(null)),
map((data) => { map((data) => {
if (data) { if (data) {
if (this.excludeEntityIds && this.excludeEntityIds.length) { if (this.excludeEntityIds && this.excludeEntityIds.length) {

18
ui-ngx/src/app/shared/components/entity/entity-subtype-autocomplete.component.ts

@ -16,8 +16,17 @@
import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable, Subscription, throwError } from 'rxjs'; import { Observable, of, Subscription, throwError } from 'rxjs';
import { map, mergeMap, publishReplay, refCount, tap } from 'rxjs/operators'; import {
catchError,
debounceTime,
distinctUntilChanged,
map,
publishReplay,
refCount,
switchMap,
tap
} from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -137,12 +146,14 @@ export class EntitySubTypeAutocompleteComponent implements ControlValueAccessor,
this.filteredSubTypes = this.subTypeFormGroup.get('subType').valueChanges this.filteredSubTypes = this.subTypeFormGroup.get('subType').valueChanges
.pipe( .pipe(
debounceTime(150),
distinctUntilChanged(),
tap(value => { tap(value => {
this.updateView(value); this.updateView(value);
}), }),
// startWith<string | EntitySubtype>(''), // startWith<string | EntitySubtype>(''),
map(value => value ? value : ''), map(value => value ? value : ''),
mergeMap(type => this.fetchSubTypes(type) ) switchMap(type => this.fetchSubTypes(type))
); );
} }
@ -221,6 +232,7 @@ export class EntitySubTypeAutocompleteComponent implements ControlValueAccessor,
} }
if (subTypesObservable) { if (subTypesObservable) {
this.subTypes = subTypesObservable.pipe( this.subTypes = subTypesObservable.pipe(
catchError(() => of([] as Array<EntitySubtype>)),
map(subTypes => subTypes.map(subType => subType.type)), map(subTypes => subTypes.map(subType => subType.type)),
publishReplay(1), publishReplay(1),
refCount() refCount()

11
ui-ngx/src/app/shared/components/ota-package/ota-package-autocomplete.component.ts

@ -16,8 +16,8 @@
import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map, mergeMap, share, tap } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -27,11 +27,11 @@ import { EntityType } from '@shared/models/entity-type.models';
import { BaseData } from '@shared/models/base-data'; import { BaseData } from '@shared/models/base-data';
import { EntityService } from '@core/http/entity.service'; import { EntityService } from '@core/http/entity.service';
import { TruncatePipe } from '@shared/pipe/truncate.pipe'; import { TruncatePipe } from '@shared/pipe/truncate.pipe';
import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { OtaPackageInfo, OtaUpdateTranslation, OtaUpdateType } from '@shared/models/ota-package.models'; import { OtaPackageInfo, OtaUpdateTranslation, OtaUpdateType } from '@shared/models/ota-package.models';
import { OtaPackageService } from '@core/http/ota-package.service'; import { OtaPackageService } from '@core/http/ota-package.service';
import { PageLink } from '@shared/models/page/page-link'; import { PageLink } from '@shared/models/page/page-link';
import { Direction } from '@shared/models/page/sort-order'; import { Direction } from '@shared/models/page/sort-order';
import { emptyPageData } from "@shared/models/page/page-data";
@Component({ @Component({
selector: 'tb-ota-package-autocomplete', selector: 'tb-ota-package-autocomplete',
@ -109,6 +109,7 @@ export class OtaPackageAutocompleteComponent implements ControlValueAccessor, On
ngOnInit() { ngOnInit() {
this.filteredPackages = this.otaPackageFormGroup.get('packageId').valueChanges this.filteredPackages = this.otaPackageFormGroup.get('packageId').valueChanges
.pipe( .pipe(
debounceTime(150),
tap(value => { tap(value => {
let modelValue; let modelValue;
if (typeof value === 'string' || !value) { if (typeof value === 'string' || !value) {
@ -122,7 +123,8 @@ export class OtaPackageAutocompleteComponent implements ControlValueAccessor, On
} }
}), }),
map(value => value ? (typeof value === 'string' ? value : value.title) : ''), map(value => value ? (typeof value === 'string' ? value : value.title) : ''),
mergeMap(name => this.fetchPackages(name)), distinctUntilChanged(),
switchMap(name => this.fetchPackages(name)),
share() share()
); );
} }
@ -217,6 +219,7 @@ export class OtaPackageAutocompleteComponent implements ControlValueAccessor, On
}); });
return this.otaPackageService.getOtaPackagesInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type, return this.otaPackageService.getOtaPackagesInfoByDeviceProfileId(pageLink, this.deviceProfileId, this.type,
{ignoreLoading: true}).pipe( {ignoreLoading: true}).pipe(
catchError(() => of(emptyPageData<OtaPackageInfo>())),
map((data) => data && data.data.length ? data.data : null) map((data) => data && data.data.length ? data.data : null)
); );
} }

18
ui-ngx/src/app/shared/components/queue/queue-type-list.component.ts

@ -16,8 +16,17 @@
import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map, mergeMap, publishReplay, refCount, tap } from 'rxjs/operators'; import {
catchError,
debounceTime,
distinctUntilChanged,
map,
publishReplay,
refCount,
switchMap,
tap
} from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state'; import { AppState } from '@app/core/core.state';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -87,11 +96,13 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
ngOnInit() { ngOnInit() {
this.filteredQueues = this.queueFormGroup.get('queue').valueChanges this.filteredQueues = this.queueFormGroup.get('queue').valueChanges
.pipe( .pipe(
debounceTime(150),
distinctUntilChanged(),
tap(value => { tap(value => {
this.updateView(value); this.updateView(value);
}), }),
map(value => value ? value : ''), map(value => value ? value : ''),
mergeMap(queue => this.fetchQueues(queue) ) switchMap(queue => this.fetchQueues(queue) )
); );
} }
@ -138,6 +149,7 @@ export class QueueTypeListComponent implements ControlValueAccessor, OnInit, Aft
fetchQueues(searchText?: string): Observable<Array<string>> { fetchQueues(searchText?: string): Observable<Array<string>> {
this.searchText = searchText; this.searchText = searchText;
return this.getQueues().pipe( return this.getQueues().pipe(
catchError(() => of([])),
map(queues => { map(queues => {
const result = queues.filter( queue => { const result = queues.filter( queue => {
return searchText ? queue.toUpperCase().startsWith(searchText.toUpperCase()) : true; return searchText ? queue.toUpperCase().startsWith(searchText.toUpperCase()) : true;

Loading…
Cancel
Save