Saltar al contenido principal

Display Templates

Paquetes: @tiendana/ngx-core/ui @tiendana/api-types

Componentes especializados para mostrar entidades de Tiendana con formato consistente y resaltado de búsqueda. Se usan como plantilla de ítem dentro de tdn-select o de forma independiente en listados.

Dependencia de @tiendana/api-types

Estos componentes usan tipos de @tiendana/api-types (Brand, Customer, Store, TerminalPOS, etc.), interfaces TypeScript basadas en los modelos reales de las bases de datos de Tiendana.

Características​

✅ Un componente standalone por entidad, todos con OnPush y signal inputs
✅ Resaltado de coincidencias con highlightedText, con normalización de acentos
✅ Imágenes resueltas con cfSrc y fallback cuando la entidad no tiene imagen
✅ Tres tamaños (small, normal, large) en los templates con foto circular

Componentes Disponibles​

Todos se importan desde @tiendana/ngx-core/ui.

SelectorClasedatasearchTermOtros inputs
brand-displayBrandDisplayComponentBrand | nullstring | null (requerido)-
category-displayCategoryDisplayComponentCategory | undefined | nullstring (requerido)-
country-displayCountryDisplayComponentCountrystring (opcional)-
country-phone-code-displayCountryPhoneCodeDisplayComponentCountrystring (opcional)-
customer-displayCustomerDisplayComponentCustomer | undefined | nullstring (opcional)size
device-displayDeviceDisplayComponentTerminalPOS | undefined | null-full
employee-displayEmployeeDisplayComponentApplicationUser | undefined | nullstring (opcional)size
payment-method-displayPaymentMethodDisplayComponentPaymentMethod | undefined | nullstring (opcional)-
store-displayStoreDisplayComponentStore | undefined | nullstring (opcional)-
supplier-displaySupplierDisplayComponentSupplier | undefined | nullstring (opcional)size

data es siempre requerido. country-display y country-phone-code-display construyen la URL de la bandera con getCloudfrontUrl a partir de code_1; el segundo muestra +{phone_code} y el nombre en español (name_es).

Antes terminal-pos-display

El template de dispositivos se llamaba terminal-pos-display (TerminalPosDisplayComponent). Desde ngx-core 0.8.0 es device-display (DeviceDisplayComponent): cambia el selector y el nombre de la clase. Ya no existe terminal-pos-display.

Tamaños​

customer-display, employee-display y supplier-display aceptan size con los valores 'small' | 'normal' | 'large' (default 'normal'). El valor se aplica como clase del host y define el tamaño de la foto y de la fuente:

sizeFotoFuente del nombre
small24px12px
normal40px14px
large100px12px
<customer-display [data]="customer" [searchTerm]="search()" size="small" />
<employee-display [data]="employee" size="large" />

La foto es circular, con un borde de 2px (--border-color) y, si la entidad no tiene imagen, usa assets/images/account_circle.svg.

Variables CSS de supplier-display

supplier-display comparte los nombres de variable de customer-display (--customer-photo-size y --customer-font-size), no define unas propias.

Variables CSS​

ComponenteVariableDefault
brand-display, category-display--brand-logo-size (en el img)30px
country-display, country-phone-code-display--img-size (en el img)20px
customer-display, supplier-display--customer-photo-size, --customer-font-sizesegún size
employee-display--employee-photo-size, --employee-font-sizesegún size
payment-method-display--pm-logo-size (en el img)20px

Patrón Común​

La mayoría comparte esta estructura: imagen a la izquierda y nombre con resaltado.

@Component({
selector: 'brand-display',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [HighlightedTextPipe, CfSrcDirective],
template: `
<img [cfSrc]="data()?.attachment" alt="Logo marca">
<div [innerHtml]="data()?.name | highlightedText : searchTerm() : true"></div>
`,
styleUrl: './brand-display.component.scss'
})
export class BrandDisplayComponent {
data = input.required<Brand | null>();
readonly searchTerm = input.required<string | null>();
}

store-display no lleva imagen: muestra el nombre (con resaltado) y debajo la dirección con la ciudad.

Uso​

En Listados​

@for (brand of brands(); track brand.id) {
<brand-display [data]="brand" [searchTerm]="searchTerm()" />
}

Dentro de tdn-select​

<tdn-select formControlName="customer" [data]="customers()" simple labelKey="full_name">
<ng-template #listItem let-item="item" let-searchTerm="searchTerm">
<customer-display [data]="item" [searchTerm]="searchTerm" />
</ng-template>
</tdn-select>

Mira tdn-select para las plantillas disponibles (listItem, etc.).

Tablas​

<table>
@for (customer of customers(); track customer.id) {
<tr>
<td>
<customer-display [data]="customer" [searchTerm]="tableSearch()" size="small" />
</td>
</tr>
}
</table>

Highlight de Búsqueda​

Los templates llaman a highlightedText con el tercer parámetro en true (normalización de acentos):

data()?.name | highlightedText : searchTerm() : true

El pipe no escapa el término como expresión regular: ver la nota en highlightedText.

Personalización​

Crea tus propios componentes display siguiendo el mismo patrón:

@Component({
selector: 'product-display',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [HighlightedTextPipe, CfSrcDirective],
template: `
<img [cfSrc]="data()?.image" alt="Producto">
<div [innerHtml]="data()?.name | highlightedText : searchTerm() : true"></div>
`
})
export class ProductDisplayComponent {
data = input.required<Product | null>();
searchTerm = input.required<string | null>();
}

Accesibilidad​

  • Los alt están fijados en cada template (por ejemplo Logo marca, Foto, Bandera del país).
  • Si necesitas un nombre accesible distinto, crea un template propio con el patrón anterior.