UI: Fixed incorrect entity details page link in autocomplete component

This commit is contained in:
Vladyslav_Prykhodko 2025-02-07 19:53:31 +02:00
parent 17bd5cc792
commit e63ae9c7fb
2 changed files with 28 additions and 36 deletions

View File

@ -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>

View File

@ -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 !== '';
}
} }