UI: Add useEntityDisplayName input property in entity-autocomplete.component and entity-list.component

This commit is contained in:
Vladyslav_Prykhodko 2025-10-08 16:30:40 +03:00
parent e3967e31fc
commit 7ee879a9c1
9 changed files with 36 additions and 8 deletions

View File

@ -60,7 +60,7 @@
#entityAutocomplete="matAutocomplete" #entityAutocomplete="matAutocomplete"
[displayWith]="displayEntityFn"> [displayWith]="displayEntityFn">
<mat-option *ngFor="let entity of filteredEntities | async" [value]="entity"> <mat-option *ngFor="let entity of filteredEntities | async" [value]="entity">
<span [innerHTML]="entity.name | highlight:searchText:true:'ig'"></span> <span [innerHTML]="displayEntityFn(entity) | highlight:searchText:true:'ig'"></span>
</mat-option> </mat-option>
<mat-option *ngIf="!(filteredEntities | async)?.length" [value]="null"> <mat-option *ngIf="!(filteredEntities | async)?.length" [value]="null">
<div (click)="$event.stopPropagation()"> <div (click)="$event.stopPropagation()">

View File

@ -22,7 +22,7 @@ import { catchError, debounceTime, map, share, switchMap, tap } from 'rxjs/opera
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 { 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, getEntityDisplayName } from '@shared/models/base-data';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { EntityService } from '@core/http/entity.service'; import { EntityService } from '@core/http/entity.service';
import { getCurrentAuthUser } from '@core/auth/auth.selectors'; import { getCurrentAuthUser } from '@core/auth/auth.selectors';
@ -138,6 +138,10 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
@coerceArray() @coerceArray()
additionalClasses: Array<string>; additionalClasses: Array<string>;
@Input()
@coerceBoolean()
useEntityDisplayName = false;
@Output() @Output()
entityChanged = new EventEmitter<BaseData<EntityId>>(); entityChanged = new EventEmitter<BaseData<EntityId>>();
@ -395,7 +399,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
} }
displayEntityFn(entity?: BaseData<EntityId>): string | undefined { displayEntityFn(entity?: BaseData<EntityId>): string | undefined {
return entity ? entity.name : undefined; return entity ? (this.useEntityDisplayName ? getEntityDisplayName(entity) : entity.name) : undefined;
} }
private fetchEntities(searchText?: string): Observable<Array<BaseData<EntityId>>> { private fetchEntities(searchText?: string): Observable<Array<BaseData<EntityId>>> {

View File

@ -36,6 +36,7 @@
*ngIf="modelValue.entityType" *ngIf="modelValue.entityType"
[required]="required" [required]="required"
[entityType]="modelValue.entityType" [entityType]="modelValue.entityType"
[useEntityDisplayName]="useEntityDisplayName"
formControlName="entityIds"> formControlName="entityIds">
</tb-entity-list> </tb-entity-list>
</div> </div>

View File

@ -68,6 +68,9 @@ export class EntityListSelectComponent implements ControlValueAccessor, OnInit {
@Input() @Input()
additionEntityTypes: {[key in string]: string} = {}; additionEntityTypes: {[key in string]: string} = {};
@Input({transform: booleanAttribute})
useEntityDisplayName = false;
displayEntityTypeSelect: boolean; displayEntityTypeSelect: boolean;
private defaultEntityType: EntityType | AliasEntityType = null; private defaultEntityType: EntityType | AliasEntityType = null;

View File

@ -28,7 +28,7 @@
class="tb-chip-row-ellipsis" class="tb-chip-row-ellipsis"
[removable]="!disabled" [removable]="!disabled"
(removed)="remove(entity)"> (removed)="remove(entity)">
{{entity.name}} {{ displayEntityFn(entity) }}
<mat-icon matChipRemove *ngIf="!disabled">close</mat-icon> <mat-icon matChipRemove *ngIf="!disabled">close</mat-icon>
</mat-chip-row> </mat-chip-row>
<input matInput type="text" placeholder="{{ !disabled ? placeholderText : '' }}" <input matInput type="text" placeholder="{{ !disabled ? placeholderText : '' }}"
@ -51,7 +51,7 @@
class="tb-autocomplete" class="tb-autocomplete"
[displayWith]="displayEntityFn"> [displayWith]="displayEntityFn">
<mat-option *ngFor="let entity of filteredEntities | async" [value]="entity"> <mat-option *ngFor="let entity of filteredEntities | async" [value]="entity">
<span [innerHTML]="entity.name | highlight:searchText"></span> <span [innerHTML]="displayEntityFn(entity) | highlight:searchText"></span>
</mat-option> </mat-option>
<mat-option *ngIf="!(filteredEntities | async)?.length" [value]="null"> <mat-option *ngIf="!(filteredEntities | async)?.length" [value]="null">
<div (click)="$event.stopPropagation()"> <div (click)="$event.stopPropagation()">

View File

@ -39,7 +39,7 @@ import { Observable } from 'rxjs';
import { filter, map, mergeMap, share, tap } from 'rxjs/operators'; import { filter, map, mergeMap, share, tap } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { EntityType } from '@shared/models/entity-type.models'; import { EntityType } from '@shared/models/entity-type.models';
import { BaseData } from '@shared/models/base-data'; import { BaseData, getEntityDisplayName } from '@shared/models/base-data';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { EntityService } from '@core/http/entity.service'; import { EntityService } from '@core/http/entity.service';
import { MatAutocomplete } from '@angular/material/autocomplete'; import { MatAutocomplete } from '@angular/material/autocomplete';
@ -125,6 +125,10 @@ export class EntityListComponent implements ControlValueAccessor, OnInit, OnChan
@coerceBoolean() @coerceBoolean()
allowCreateNew: boolean; allowCreateNew: boolean;
@Input()
@coerceBoolean()
useEntityDisplayName = false;
@Output() @Output()
createNew = new EventEmitter<string>(); createNew = new EventEmitter<string>();
@ -277,7 +281,7 @@ export class EntityListComponent implements ControlValueAccessor, OnInit, OnChan
} }
public displayEntityFn(entity?: BaseData<EntityId>): string | undefined { public displayEntityFn(entity?: BaseData<EntityId>): string | undefined {
return entity ? entity.name : undefined; return entity ? (this.useEntityDisplayName ? getEntityDisplayName(entity) : entity.name) : undefined;
} }
private fetchEntities(searchText?: string): Observable<Array<BaseData<EntityId>>> { private fetchEntities(searchText?: string): Observable<Array<BaseData<EntityId>>> {

View File

@ -33,6 +33,7 @@
[appearance]="appearance" [appearance]="appearance"
[required]="required" [required]="required"
[entityType]="modelValue.entityType" [entityType]="modelValue.entityType"
[useEntityDisplayName]="useEntityDisplayName"
formControlName="entityId"> formControlName="entityId">
</tb-entity-autocomplete> </tb-entity-autocomplete>
</div> </div>

View File

@ -62,6 +62,10 @@ export class EntitySelectComponent implements ControlValueAccessor, OnInit, Afte
@Input() @Input()
appearance: MatFormFieldAppearance = 'fill'; appearance: MatFormFieldAppearance = 'fill';
@Input()
@coerceBoolean()
useEntityDisplayName = false;
displayEntityTypeSelect: boolean; displayEntityTypeSelect: boolean;
AliasEntityType = AliasEntityType; AliasEntityType = AliasEntityType;

View File

@ -16,7 +16,9 @@
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { HasUUID } from '@shared/models/id/has-uuid'; import { HasUUID } from '@shared/models/id/has-uuid';
import { isDefinedAndNotNull } from '@core/utils'; import { isDefinedAndNotNull, isNotEmptyStr } from '@core/utils';
import { EntityType } from '@shared/models/entity-type.models';
import { User } from '@shared/models/user.model';
export declare type HasId = EntityId | HasUUID; export declare type HasId = EntityId | HasUUID;
@ -49,3 +51,12 @@ export function hasIdEquals(id1: HasId, id2: HasId): boolean {
return id1 === id2; return id1 === id2;
} }
} }
export function getEntityDisplayName(entity: BaseData<EntityId>): string {
if (entity?.id?.entityType === EntityType.USER) {
const user = entity as User;
const userName = (user?.firstName ?? '') + " " + (user?.lastName ?? '');
return isNotEmptyStr(userName) ? userName.trim() : entity?.name;
}
return isNotEmptyStr(entity?.label) ? entity.label : entity?.name;
}