import { ChangeDetectionStrategy, Component, computed, input, model, resource } from '@angular/core'; import { UserFieldsApi, type UserFieldInfo } from '../../core/sl/user-fields'; import type { VhLookup } from '../value-help/value-help.types'; import { inject } from '@angular/core'; import { SelectField, TextField } from './fields'; import { FieldBase } from './field-base'; import { LookupField } from './lookup-field'; /** * Campo de usuario de SAP (`U_*`) que se pide según como lo definió SAP: lista desplegable si tiene valores válidos, * ventana de selección si está enlazado a una tabla de usuario, texto en otro caso (o mientras carga, o si la base de datos * no está configurada). El tipo numérico se guarda como número. */ @Component({ selector: 'sbo-udf-field', changeDetection: ChangeDetectionStrategy.OnPush, imports: [LookupField, SelectField, TextField], template: ` @if (kind() === 'select') { } @else if (kind() === 'lookup') { } @else { } `, styles: ':host { display: block; }', }) export class UdfField extends FieldBase { private readonly api = inject(UserFieldsApi); /** Tabla del campo (`OBTN`, `OWTQ`, `@MI_TABLA`) y alias sin el `U_` (`SIS_ESTLOT`). */ readonly table = input.required(); readonly alias = input.required(); readonly value = model(''); protected readonly info = resource({ params: () => ({ table: this.table(), alias: this.alias() }), loader: ({ params }) => this.api.get(params.table, params.alias), }); private readonly def = computed(() => (this.info.hasValue() ? this.info.value() : null)); protected readonly kind = computed<'select' | 'lookup' | 'text'>(() => { const d = this.def(); return d?.validValues.length ? 'select' : d?.linkedRows.length ? 'lookup' : 'text'; }); protected readonly str = computed(() => { const v = this.value(); return v === null || v === undefined ? '' : String(v); }); protected readonly options = computed(() => (this.def()?.validValues ?? []).map((v) => ({ value: v.value, label: v.description ? `${v.value} · ${v.description}` : v.value }))); protected readonly lookup = computed(() => { const d = this.def()!; return { title: d.description || d.linkedTable || 'Valores', resource: d.linkedTable ?? 'UserTable', columns: [ { key: 'code', title: 'Código', width: '140px', mono: true, searchable: true }, { key: 'name', title: 'Nombre', searchable: true }, ], rows: d.linkedRows.map((r) => ({ code: r.code, name: r.name })), valueKey: 'code', nameKey: 'name', codeWidth: '140px', }; }); protected emit(v: string | number | null): void { const s = v === null ? '' : String(v); this.value.set(this.def()?.type === 'N' && s.trim() !== '' && Number.isFinite(Number(s)) ? Number(s) : s); } }