UI: Fixed incorrect entity details page link in autocomplete component
This commit is contained in:
parent
17bd5cc792
commit
e63ae9c7fb
@ -24,8 +24,8 @@
|
|||||||
(focusin)="onFocus()"
|
(focusin)="onFocus()"
|
||||||
[required]="required"
|
[required]="required"
|
||||||
[matAutocomplete]="entityAutocomplete"
|
[matAutocomplete]="entityAutocomplete"
|
||||||
[class.!hidden]="disabled && selectEntityFormGroup.get('entity').value">
|
[class.!hidden]="showEntityLink">
|
||||||
<a *ngIf="selectEntityFormGroup.get('entity').value && disabled" aria-label="Open device profile" [routerLink]=entityURL>
|
<a *ngIf="showEntityLink" aria-label="Open entity details page" [routerLink]=entityURL>
|
||||||
{{ displayEntityFn(selectEntityFormGroup.get('entity').value) }}
|
{{ displayEntityFn(selectEntityFormGroup.get('entity').value) }}
|
||||||
</a>
|
</a>
|
||||||
<button *ngIf="selectEntityFormGroup.get('entity').value && !disabled"
|
<button *ngIf="selectEntityFormGroup.get('entity').value && !disabled"
|
||||||
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ng-template #searchNotEmpty>
|
<ng-template #searchNotEmpty>
|
||||||
<span>
|
<span>
|
||||||
{{ translate.get(noEntitiesMatchingText, {entity: searchText}) | async }}
|
{{ noEntitiesMatchingText | translate: {entity: searchText} }}
|
||||||
</span>
|
</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -14,24 +14,13 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import {
|
import { Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||||
AfterViewInit,
|
|
||||||
Component,
|
|
||||||
ElementRef,
|
|
||||||
EventEmitter,
|
|
||||||
forwardRef,
|
|
||||||
Input,
|
|
||||||
OnInit,
|
|
||||||
Output,
|
|
||||||
ViewChild
|
|
||||||
} from '@angular/core';
|
|
||||||
import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field';
|
import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field';
|
||||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||||
import { merge, Observable, of, Subject } from 'rxjs';
|
import { firstValueFrom, merge, Observable, of, Subject } from 'rxjs';
|
||||||
import { catchError, debounceTime, map, share, switchMap, tap } from 'rxjs/operators';
|
import { catchError, debounceTime, 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 { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
|
import { AliasEntityType, EntityType } from '@shared/models/entity-type.models';
|
||||||
import { BaseData } from '@shared/models/base-data';
|
import { BaseData } from '@shared/models/base-data';
|
||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
@ -51,22 +40,22 @@ import { coerceArray, coerceBoolean } from '@shared/decorators/coercion';
|
|||||||
multi: true
|
multi: true
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit, AfterViewInit {
|
export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit {
|
||||||
|
|
||||||
selectEntityFormGroup: UntypedFormGroup;
|
selectEntityFormGroup: UntypedFormGroup;
|
||||||
|
|
||||||
modelValue: string | EntityId | null;
|
private modelValue: string | EntityId | null;
|
||||||
|
|
||||||
entityTypeValue: EntityType | AliasEntityType;
|
private entityTypeValue: EntityType | AliasEntityType;
|
||||||
|
|
||||||
entitySubtypeValue: string;
|
private entitySubtypeValue: string;
|
||||||
|
|
||||||
entityText: string;
|
private entityText: string;
|
||||||
|
|
||||||
noEntitiesMatchingText: string;
|
noEntitiesMatchingText: string;
|
||||||
notFoundEntities = 'entity.no-entities-text';
|
notFoundEntities = 'entity.no-entities-text';
|
||||||
|
|
||||||
entityRequiredText: string;
|
private entityRequiredText: string;
|
||||||
|
|
||||||
filteredEntities: Observable<Array<BaseData<EntityId>>>;
|
filteredEntities: Observable<Array<BaseData<EntityId>>>;
|
||||||
|
|
||||||
@ -78,7 +67,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
|
|
||||||
private refresh$ = new Subject<Array<BaseData<EntityId>>>();
|
private refresh$ = new Subject<Array<BaseData<EntityId>>>();
|
||||||
|
|
||||||
private propagateChange = (v: any) => { };
|
private propagateChange: (value: any) => void = () => { };
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set entityType(entityType: EntityType) {
|
set entityType(entityType: EntityType) {
|
||||||
@ -166,7 +155,6 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
|
|
||||||
|
|
||||||
constructor(private store: Store<AppState>,
|
constructor(private store: Store<AppState>,
|
||||||
public translate: TranslateService,
|
|
||||||
private entityService: EntityService,
|
private entityService: EntityService,
|
||||||
private fb: UntypedFormBuilder) {
|
private fb: UntypedFormBuilder) {
|
||||||
this.selectEntityFormGroup = this.fb.group({
|
this.selectEntityFormGroup = this.fb.group({
|
||||||
@ -178,7 +166,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
this.propagateChange = fn;
|
this.propagateChange = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnTouched(fn: any): void {
|
registerOnTouched(_fn: any): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -188,7 +176,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
.pipe(
|
.pipe(
|
||||||
debounceTime(150),
|
debounceTime(150),
|
||||||
tap(value => {
|
tap(value => {
|
||||||
let modelValue;
|
let modelValue: string | EntityId;
|
||||||
if (typeof value === 'string' || !value) {
|
if (typeof value === 'string' || !value) {
|
||||||
modelValue = null;
|
modelValue = null;
|
||||||
} else {
|
} else {
|
||||||
@ -207,9 +195,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {}
|
private load(): void {
|
||||||
|
|
||||||
load(): void {
|
|
||||||
if (this.entityTypeValue) {
|
if (this.entityTypeValue) {
|
||||||
switch (this.entityTypeValue) {
|
switch (this.entityTypeValue) {
|
||||||
case EntityType.ASSET:
|
case EntityType.ASSET:
|
||||||
@ -327,7 +313,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentEntity(): BaseData<EntityId> | null {
|
private getCurrentEntity(): BaseData<EntityId> | null {
|
||||||
const currentEntity = this.selectEntityFormGroup.get('entity').value;
|
const currentEntity = this.selectEntityFormGroup.get('entity').value;
|
||||||
if (currentEntity && typeof currentEntity !== 'string') {
|
if (currentEntity && typeof currentEntity !== 'string') {
|
||||||
return currentEntity as BaseData<EntityId>;
|
return currentEntity as BaseData<EntityId>;
|
||||||
@ -359,16 +345,17 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
}
|
}
|
||||||
let entity: BaseData<EntityId> = null;
|
let entity: BaseData<EntityId> = null;
|
||||||
try {
|
try {
|
||||||
entity = await this.entityService.getEntity(targetEntityType, id, {ignoreLoading: true, ignoreErrors: true}).toPromise();
|
entity = await firstValueFrom(this.entityService.getEntity(targetEntityType, id, {ignoreLoading: true, ignoreErrors: true}));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.propagateChange(null);
|
this.propagateChange(null);
|
||||||
}
|
}
|
||||||
this.modelValue = entity !== null ? (this.useFullEntityId ? entity.id : entity.id.id) : null;
|
this.modelValue = entity !== null ? (this.useFullEntityId ? entity.id : entity.id.id) : null;
|
||||||
this.entityURL = getEntityDetailsPageURL(this.modelValue as string, targetEntityType);
|
this.entityURL = !entity ? '' : getEntityDetailsPageURL(entity.id.id, targetEntityType);
|
||||||
this.selectEntityFormGroup.get('entity').patchValue(entity !== null ? entity : '', {emitEvent: false});
|
this.selectEntityFormGroup.get('entity').patchValue(entity !== null ? entity : '', {emitEvent: false});
|
||||||
this.entityChanged.emit(entity);
|
this.entityChanged.emit(entity);
|
||||||
} else {
|
} else {
|
||||||
this.modelValue = null;
|
this.modelValue = null;
|
||||||
|
this.entityURL = '';
|
||||||
this.selectEntityFormGroup.get('entity').patchValue('', {emitEvent: false});
|
this.selectEntityFormGroup.get('entity').patchValue('', {emitEvent: false});
|
||||||
}
|
}
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
@ -381,13 +368,14 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
private reset() {
|
||||||
this.selectEntityFormGroup.get('entity').patchValue('', {emitEvent: false});
|
this.selectEntityFormGroup.get('entity').patchValue('', {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateView(value: string | null, entity: BaseData<EntityId> | null) {
|
private updateView(value: string | EntityId | null, entity: BaseData<EntityId> | null) {
|
||||||
if (!isEqual(this.modelValue, value)) {
|
if (!isEqual(this.modelValue, value)) {
|
||||||
this.modelValue = value;
|
this.modelValue = value;
|
||||||
|
this.entityURL = !entity ? '' : getEntityDetailsPageURL(entity.id.id, entity.id.entityType as EntityType);
|
||||||
this.propagateChange(this.modelValue);
|
this.propagateChange(this.modelValue);
|
||||||
this.entityChanged.emit(entity);
|
this.entityChanged.emit(entity);
|
||||||
}
|
}
|
||||||
@ -397,7 +385,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
return entity ? entity.name : undefined;
|
return entity ? entity.name : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchEntities(searchText?: string): Observable<Array<BaseData<EntityId>>> {
|
private fetchEntities(searchText?: string): Observable<Array<BaseData<EntityId>>> {
|
||||||
this.searchText = searchText;
|
this.searchText = searchText;
|
||||||
const targetEntityType = this.checkEntityType(this.entityTypeValue);
|
const targetEntityType = this.checkEntityType(this.entityTypeValue);
|
||||||
return this.entityService.getEntitiesByNameFilter(targetEntityType, searchText,
|
return this.entityService.getEntitiesByNameFilter(targetEntityType, searchText,
|
||||||
@ -432,7 +420,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkEntityType(entityType: EntityType | AliasEntityType): EntityType {
|
private checkEntityType(entityType: EntityType | AliasEntityType): EntityType {
|
||||||
if (entityType === AliasEntityType.CURRENT_CUSTOMER) {
|
if (entityType === AliasEntityType.CURRENT_CUSTOMER) {
|
||||||
return EntityType.CUSTOMER;
|
return EntityType.CUSTOMER;
|
||||||
} else if (entityType === AliasEntityType.CURRENT_TENANT) {
|
} else if (entityType === AliasEntityType.CURRENT_TENANT) {
|
||||||
@ -454,4 +442,8 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
|
|||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this.createNew.emit();
|
this.createNew.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get showEntityLink(): boolean {
|
||||||
|
return this.selectEntityFormGroup.get('entity').value && this.disabled && this.entityURL !== '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user