import { ChangeDetectionStrategy, Component, booleanAttribute, inject, input, output } from '@angular/core';
import { FieldNames } from '../../core/field-names';
let nextId = 0;
/**
* Fila de formulario SBO: etiqueta a la izquierda y, a la derecha, uno o varios
* controles en una misma línea (input + botón, select + botón, serie + número...).
* `action` pinta la flecha dorada de SAP (campo que enlaza a otro objeto o a una lista).
*
* El primer control de la fila toma el `id` al que apunta la etiqueta (ver `claimId`).
*/
@Component({
selector: 'sbo-field',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@if (error()) {
{{ error() }}
}
`,
styles: `
:host {
display: block;
}
.f {
display: grid;
grid-template-columns: var(--label-w, 165px) minmax(0, 1fr);
align-items: start;
gap: 8px;
min-height: 24px;
}
label {
padding-top: 3px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
label.req .t::after {
content: ' *';
color: var(--err);
}
label.ga {
position: relative;
padding-left: 14px;
}
label.ga::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
border-left: 8px solid var(--gold);
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
}
.db {
display: block;
margin-top: -2px;
font: 10.5px/1.2 var(--mono, monospace);
color: var(--quiet);
white-space: normal;
overflow-wrap: anywhere;
}
label.link {
cursor: pointer;
}
label.link:hover {
text-decoration: underline;
}
.ctl {
min-width: 0;
}
.err {
display: block;
margin-top: 1px;
font-size: 11.5px;
color: var(--err);
}
`,
})
export class SboField {
protected readonly names = inject(FieldNames);
readonly label = input.required();
/** Nombre del campo de SAP; sale como ayuda del cursor y, con «Ver campos», debajo de la etiqueta. */
readonly dbName = input();
readonly required = input(false, { transform: booleanAttribute });
readonly action = input(false, { transform: booleanAttribute });
/** La etiqueta es un enlace (ej. abrir el socio de negocio). */
readonly linkable = input(false, { transform: booleanAttribute });
readonly error = input();
readonly labelClick = output();
readonly controlId = `sbo-f-${++nextId}`;
readonly errorId = `${this.controlId}-err`;
private claimed = false;
/** El primer control de la fila recibe el id de la etiqueta; los demás deben llevar su `ariaLabel`. */
claimId(): string | null {
if (this.claimed) return null;
this.claimed = true;
return this.controlId;
}
}