@tinya-code/gas-admin-ui 0.2.0-alpha.7 → 0.2.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs +107 -0
- package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs.map +1 -0
- package/fesm2022/{tinya-code-gas-admin-ui-form-view-DN7g36Qu.mjs → tinya-code-gas-admin-ui-form-view-DRcpZH1V.mjs} +6 -4
- package/fesm2022/tinya-code-gas-admin-ui-form-view-DRcpZH1V.mjs.map +1 -0
- package/fesm2022/{tinya-code-gas-admin-ui-list-fSnmwLDC.mjs → tinya-code-gas-admin-ui-list-C1ZrXfW9.mjs} +2 -2
- package/fesm2022/{tinya-code-gas-admin-ui-list-fSnmwLDC.mjs.map → tinya-code-gas-admin-ui-list-C1ZrXfW9.mjs.map} +1 -1
- package/fesm2022/{tinya-code-gas-admin-ui-render-registry-XbMiaB7x.mjs → tinya-code-gas-admin-ui-render-registry-wGs_AG4N.mjs} +41 -21
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-wGs_AG4N.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui-rich-select-c0gTPZQ6.mjs +152 -0
- package/fesm2022/tinya-code-gas-admin-ui-rich-select-c0gTPZQ6.mjs.map +1 -0
- package/fesm2022/{tinya-code-gas-admin-ui-seed-CMnUYVxI.mjs → tinya-code-gas-admin-ui-seed-BK0epEqy.mjs} +2 -2
- package/fesm2022/{tinya-code-gas-admin-ui-seed-CMnUYVxI.mjs.map → tinya-code-gas-admin-ui-seed-BK0epEqy.mjs.map} +1 -1
- package/fesm2022/{tinya-code-gas-admin-ui-select--98lPbev.mjs → tinya-code-gas-admin-ui-select-CDwX9yNO.mjs} +55 -51
- package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs.map +1 -0
- package/fesm2022/tinya-code-gas-admin-ui.mjs +9 -5
- package/fesm2022/tinya-code-gas-admin-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/tinya-code-gas-admin-ui.d.ts +29 -2
- package/fesm2022/tinya-code-gas-admin-ui-form-view-DN7g36Qu.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-render-registry-XbMiaB7x.mjs.map +0 -1
- package/fesm2022/tinya-code-gas-admin-ui-select--98lPbev.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tinya-code-gas-admin-ui-render-registry-XbMiaB7x.mjs","names":[],"sources":["../../../projects/gas-admin-ui/src/lib/columns/descriptors.ts","../../../projects/gas-admin-ui/src/lib/fields/boolean/boolean.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/currency/currency.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/date/date.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/email/email.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/file/file.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/group/group.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/image/image.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/key-value/key-value.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/list/list.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/multiselect/multiselect.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/number/number.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/phone/phone.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/readonly-text/readonly-text.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/relation/relation.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/select/select.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/slug/slug.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/string-list/string-list.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/text/text.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/textarea/textarea.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/time/time.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/url/url.descriptor.ts","../../../projects/gas-admin-ui/src/lib/fields/descriptors.ts","../../../projects/gas-admin-ui/src/lib/layouts/descriptors.ts","../../../projects/gas-admin-ui/src/lib/widgets/series.ts","../../../projects/gas-admin-ui/src/lib/widgets/bar-chart/bar-chart.descriptor.ts","../../../projects/gas-admin-ui/src/lib/widgets/chart-line/chart-line.descriptor.ts","../../../projects/gas-admin-ui/src/lib/widgets/metric-card/metric-card.descriptor.ts","../../../projects/gas-admin-ui/src/lib/widgets/quick-actions/quick-actions.descriptor.ts","../../../projects/gas-admin-ui/src/lib/widgets/record-list/record-list.descriptor.ts","../../../projects/gas-admin-ui/src/lib/widgets/status-progress/status-progress.descriptor.ts","../../../projects/gas-admin-ui/src/lib/widgets/descriptors.ts","../../../projects/gas-admin-ui/src/lib/views/descriptors.ts","../../../projects/gas-admin-ui/src/lib/core/registry/render-registry.ts"],"sourcesContent":["import type { RenderDescriptor, RenderExtras } from '../core/registry/render-registry';\n\n/**\n * Manifiesto de descriptores de formato de columna (R4.3 · `kind:\n * 'column-format'`).\n *\n * Es el equivalente a `fields/descriptors.ts` y `widgets/descriptors.ts`:\n * una línea por formato y ningún import de componente — cada `load()` guarda\n * el cierre de un `import()` **con literal**, que es lo que permite al\n * bundler partir el chunk; el registro los recoge al importar este módulo\n * (`core/registry/render-registry.ts`).\n *\n * **Añadir un formato** ⇒ crear `format-<nombre>.ts` + una entrada acá.\n * `list-view` no se toca: ése es el criterio de éxito de R4.3.\n *\n * Todos comparten el cableado: el descriptor sólo expone la celda, que la\n * vista cuelga de `extras.data`.\n */\nconst inputs = (_config: unknown, extras: RenderExtras): Record<string, unknown> => ({\n cell: extras.data,\n});\n\nconst text: RenderDescriptor = {\n kind: 'column-format',\n type: 'text',\n since: '1.0',\n surfaces: ['list'],\n load: () => import('./format-text').then((module) => module.ColumnFormatText),\n inputs,\n};\n\nconst badge: RenderDescriptor = {\n kind: 'column-format',\n type: 'badge',\n since: '1.0',\n surfaces: ['list'],\n load: () => import('./format-badge').then((module) => module.ColumnFormatBadge),\n inputs,\n};\n\nconst thumbnail: RenderDescriptor = {\n kind: 'column-format',\n type: 'thumbnail',\n since: '1.0',\n surfaces: ['list'],\n load: () => import('./format-thumbnail').then((module) => module.ColumnFormatThumbnail),\n inputs,\n};\n\nconst boolean: RenderDescriptor = {\n kind: 'column-format',\n type: 'boolean',\n since: '1.0',\n surfaces: ['list'],\n load: () => import('./format-boolean').then((module) => module.ColumnFormatBoolean),\n inputs,\n};\n\nconst number: RenderDescriptor = {\n kind: 'column-format',\n type: 'number',\n since: '1.0',\n surfaces: ['list'],\n load: () => import('./format-number').then((module) => module.ColumnFormatNumber),\n inputs,\n};\n\nconst currency: RenderDescriptor = {\n kind: 'column-format',\n type: 'currency',\n since: '1.0',\n surfaces: ['list'],\n load: () => import('./format-currency').then((module) => module.ColumnFormatCurrency),\n inputs,\n};\n\nconst date: RenderDescriptor = {\n kind: 'column-format',\n type: 'date',\n since: '1.0',\n surfaces: ['list'],\n load: () => import('./format-date').then((module) => module.ColumnFormatDate),\n inputs,\n};\n\n/** Los 7 formatos del `@switch` que este registro reemplaza (R4.3). */\nexport const columnFormatDescriptors: readonly RenderDescriptor[] = [\n text,\n badge,\n thumbnail,\n boolean,\n number,\n currency,\n date,\n];\n\n/**\n * Los 7 nombres, como dato.\n *\n * Va en paralelo a `ListColumnFormat` (unión de `schema.model`) y lo vigila\n * `core/registry/contract.spec.ts`: la unión vive en tipos y el registro en\n * runtime, y sólo un test reconcilia los dos — el mismo tripwire que ya\n * existe para los 20 campos y los 6 widgets.\n */\nexport const COLUMN_FORMAT_TYPES = [\n 'text',\n 'badge',\n 'thumbnail',\n 'boolean',\n 'number',\n 'currency',\n 'date',\n] as const;\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `boolean` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'boolean',\n since: '1.0',\n load: () => import('./boolean').then((module) => module.FieldBoolean),\n seed: 'boolean',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `currency` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'currency',\n since: '1.0',\n load: () => import('./currency').then((module) => module.FieldCurrency),\n // Nace como `null`: no puede ser `0`, que sería un valor ya cargado.\n seed: 'number',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `date` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'date',\n since: '1.0',\n load: () => import('./date').then((module) => module.FieldDate),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `email` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'email',\n since: '1.0',\n load: () => import('./email').then((module) => module.FieldEmail),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `file` (R3.3 · R9.5.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'file',\n since: '9.5',\n load: () => import('./file').then((module) => module.FieldFile),\n // Nace como cadena: la URL pública es el valor, igual que en `image`.\n seed: 'string',\n surfaces: ['form', 'display'],\n // Como `image` (D27): control propio cuya sincronización con Signal Forms\n // vive en ɵɵcontrol, así que el host lo declara a mano con `[formField]`.\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `group` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'group',\n since: '1.0',\n load: () => import('./group').then((module) => module.FieldGroup),\n // Contenedor: siembra un nodo por cada hijo declarado.\n seed: 'recursive',\n surfaces: ['form', 'display'],\n // Compuesto: además de su árbol dibuja el template de sus hijos, que sólo\n // existe en la plantilla del host. Él es quien decide recibirlo (R3.6).\n inputs: (config, extras) => ({\n field: config,\n tree: extras.ctx.tree,\n serverErrors: extras.ctx.serverErrors,\n pathPrefix: extras.ctx.pathPrefix,\n content: extras.groupContent,\n }),\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `image` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'image',\n since: '1.0',\n load: () => import('./image').then((module) => module.FieldImage),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `key-value` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'key-value',\n since: '1.0',\n load: () => import('./key-value').then((module) => module.FieldKeyValue),\n seed: 'array',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `list` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'list',\n since: '1.0',\n load: () => import('./list').then((module) => module.FieldList),\n seed: 'array',\n surfaces: ['form', 'display'],\n // Compuesto: además de su árbol dibuja el template de cada hijo y hereda\n // el `exists` del nivel para no reactivar el borrado de filas (R3.6).\n inputs: (config, extras) => ({\n field: config,\n tree: extras.ctx.tree,\n childTemplate: extras.childTemplate,\n serverErrors: extras.ctx.serverErrors,\n pathPrefix: extras.ctx.pathPrefix,\n exists: extras.ctx.exists,\n }),\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `multiselect` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'multiselect',\n since: '1.0',\n load: () => import('./multiselect').then((module) => module.FieldMultiselect),\n seed: 'array',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `number` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'number',\n since: '1.0',\n load: () => import('./number').then((module) => module.FieldNumber),\n // Nace como `null`: no puede ser `0`, que sería un valor ya cargado.\n seed: 'number',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `phone` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'phone',\n since: '1.0',\n load: () => import('./phone').then((module) => module.FieldPhone),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `readonly-text` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'readonly-text',\n since: '1.0',\n load: () => import('./readonly-text').then((module) => module.FieldReadonlyText),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `relation` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'relation',\n since: '1.0',\n load: () => import('./relation').then((module) => module.FieldRelation),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `select` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'select',\n since: '1.0',\n load: () => import('./select').then((module) => module.FieldSelect),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `slug` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'slug',\n since: '1.0',\n load: () => import('./slug').then((module) => module.FieldSlug),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n // Se aparta de la forma estándar sólo por `exists`: con el registro ya\n // creado el campo queda bloqueado (`lockAfterCreate`, R3.6).\n inputs: (config, extras) => ({\n field: config,\n tree: extras.ctx.tree,\n exists: extras.ctx.exists,\n }),\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `string-list` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'string-list',\n since: '1.0',\n load: () => import('./string-list').then((module) => module.FieldStringList),\n seed: 'array',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `text` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'text',\n since: '1.0',\n load: () => import('./text').then((module) => module.FieldText),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `textarea` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'textarea',\n since: '1.0',\n load: () => import('./textarea').then((module) => module.FieldTextarea),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `time` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'time',\n since: '1.0',\n load: () => import('./time').then((module) => module.FieldTime),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del campo `url` (R3.3). */\nexport const descriptor: RenderDescriptor = {\n kind: 'field',\n type: 'url',\n since: '1.0',\n load: () => import('./url').then((module) => module.FieldUrl),\n // Nace como cadena: los textos, fechas, urls, selects y relacionales.\n seed: 'string',\n surfaces: ['form', 'display'],\n};\n","import type { RenderDescriptor } from '../core/registry/render-registry';\nimport type { FieldType } from '../core/models/schema.model';\n\nimport { descriptor as booleanDescriptor } from './boolean/boolean.descriptor';\nimport { descriptor as currencyDescriptor } from './currency/currency.descriptor';\nimport { descriptor as dateDescriptor } from './date/date.descriptor';\nimport { descriptor as emailDescriptor } from './email/email.descriptor';\nimport { descriptor as fileDescriptor } from './file/file.descriptor';\nimport { descriptor as groupDescriptor } from './group/group.descriptor';\nimport { descriptor as imageDescriptor } from './image/image.descriptor';\nimport { descriptor as keyValueDescriptor } from './key-value/key-value.descriptor';\nimport { descriptor as listDescriptor } from './list/list.descriptor';\nimport { descriptor as multiselectDescriptor } from './multiselect/multiselect.descriptor';\nimport { descriptor as numberDescriptor } from './number/number.descriptor';\nimport { descriptor as phoneDescriptor } from './phone/phone.descriptor';\nimport { descriptor as readonlyTextDescriptor } from './readonly-text/readonly-text.descriptor';\nimport { descriptor as relationDescriptor } from './relation/relation.descriptor';\nimport { descriptor as selectDescriptor } from './select/select.descriptor';\nimport { descriptor as slugDescriptor } from './slug/slug.descriptor';\nimport { descriptor as stringListDescriptor } from './string-list/string-list.descriptor';\nimport { descriptor as textDescriptor } from './text/text.descriptor';\nimport { descriptor as textareaDescriptor } from './textarea/textarea.descriptor';\nimport { descriptor as timeDescriptor } from './time/time.descriptor';\nimport { descriptor as urlDescriptor } from './url/url.descriptor';\n\n/**\n * Tripwire de compilación (R1.7 · D17): que la unión `FieldType` y los\n * tipos que la UI sabe dibujar sigan diciendo lo mismo.\n *\n * · un valor que no esté en la unión `FieldSchema` ⇒ `satisfies` falla;\n * · un tipo de la unión que falte acá ⇒ `FaltaEnLaUi` no es `never`.\n *\n * **No es una fuente de verdad en runtime.** El catálogo vive en\n * `core/registry/render-registry.ts`, alimentado por los descriptores de\n * abajo. Esta lista sólo existe para que `npm run build` y `npm test` vean\n * la aserción por igual, sin depender de que un test la ejecute.\n *\n * **Exportada en R3.7** para que `core/registry/contract.spec.ts` pueda\n * verificar además el sentido que este archivo no cubre — que cada nombre de\n * la lista tenga **descriptor**: aquí sólo se comprueba que está en la unión,\n * y un tipo declarado en la lista pero ausente del manifiesto se vería en el\n * primer schema que lo use.\n *\n * **Mudado acá en R3.8.** Vivía en `field-host/field-host.ts`, y §0 es\n * explícito: «si añadir un tipo obliga a editar `FieldHost`, el motor no\n * está terminado». Estaba sin uso en runtime — sólo servía a este tripwire —\n * así que trasladarlo acá no cambia comportamiento y deja el registro y su\n * aserción en el **mismo archivo**: añadir un tipo toca una carpeta y una\n * línea de este manifiesto, y el host no se entera.\n */\nexport const SUPPORTED_FIELD_TYPE_LIST = [\n 'text',\n 'textarea',\n 'slug',\n 'number',\n 'currency',\n 'boolean',\n 'select',\n 'multiselect',\n 'url',\n 'email',\n 'phone',\n 'date',\n 'time',\n 'readonly-text',\n 'group',\n 'list',\n 'string-list',\n 'key-value',\n 'relation',\n 'image',\n 'file',\n] as const satisfies readonly FieldType[];\n\ntype FaltaEnLaUi = Exclude<FieldType, (typeof SUPPORTED_FIELD_TYPE_LIST)[number]>;\nconst _exhaustivo: FaltaEnLaUi extends never\n ? true\n : ['Falta en SUPPORTED_FIELD_TYPE_LIST', FaltaEnLaUi] = true;\n\n/**\n * Manifiesto de descriptores de campo (R3.3 · registro único de render).\n *\n * Una línea por tipo: el registro los recoge al importar este módulo. Es la\n * **única** lista manual del catálogo de campos — `import.meta.glob` no\n * sobrevive a `ng build`, así que D9-1 se resuelve con «registro manual de\n * una línea». Ver `core/registry/render-registry.ts`.\n *\n * Añadir un tipo de campo ⇒ crear la carpeta + su `.descriptor.ts` + una\n * línea acá. **Ningún host se toca** (R3.8).\n */\nexport const fieldDescriptors: readonly RenderDescriptor[] = [\n booleanDescriptor,\n currencyDescriptor,\n dateDescriptor,\n emailDescriptor,\n fileDescriptor,\n groupDescriptor,\n imageDescriptor,\n keyValueDescriptor,\n listDescriptor,\n multiselectDescriptor,\n numberDescriptor,\n phoneDescriptor,\n readonlyTextDescriptor,\n relationDescriptor,\n selectDescriptor,\n slugDescriptor,\n stringListDescriptor,\n textDescriptor,\n textareaDescriptor,\n timeDescriptor,\n urlDescriptor,\n];\n","import type { LayoutDescriptor } from '../core/registry/render-registry';\n\nexport const layoutDescriptors: readonly LayoutDescriptor[] = [\n { kind: 'layout', type: 'grid', since: '9.2' },\n { kind: 'layout', type: 'tabs', since: '9.2' },\n { kind: 'layout', type: 'sections', since: '9.2' },\n { kind: 'layout', type: 'steps', since: '9.2' },\n { kind: 'layout', type: 'columns', since: '9.2' },\n];\n","import type { BarDatum } from './bar-chart/bar-chart';\n\n/**\n * Normaliza el payload de un gráfico a `{ label: string, value: number }`.\n *\n * El dashboard recibe filas de una tabla y no todas llegan limpias, así que\n * el filtro se hace en el **borde** — en el descriptor, antes de que el dato\n * llegue al componente — y no dentro de cada gráfico. `bar-chart` y\n * `chart-line` comparten la misma regla, de ahí la función suelta.\n *\n * Devuelve `[]` ante cualquier cosa que no sea un array: un `metric-card`\n * pasado por error a un gráfico no puede romper la tarjeta.\n */\nexport function toSeries(data: unknown): BarDatum[] {\n if (!Array.isArray(data)) {\n return [];\n }\n return data\n .map((row): BarDatum | null => {\n if (typeof row !== 'object' || row === null) return null;\n const r = row as { label?: unknown; group?: unknown; value?: unknown };\n // El agregado agrupado del backend (R6.2) llega como { group, value };\n // la forma histórica de tabla es { label, value }. El gráfico sólo\n // entiende label ⇒ traducimos acá, en el borde.\n const label = typeof r.label === 'string' ? r.label : r.group;\n if (typeof label !== 'string' || typeof r.value !== 'number') return null;\n return { label, value: r.value };\n })\n .filter((row): row is BarDatum => row !== null);\n}\n\n/**\n * Normaliza el payload de un contador repartido por segmentos a\n * `{ clave: número }`.\n *\n * Dos formas, igual que `toSeries`:\n * - **payload** del panel: ya es un objeto plano de contadores por clave;\n * - **fuente declarada** (F8 · R6.5): una vista con `groupBy` devuelve filas\n * `[{ group, value }]` y cada grupo es el nombre de un segmento.\n *\n * `null` ante cualquier otra cosa: `StatusProgress` lo pinta como vacío en\n * vez de sumar un `[object Object]`.\n */\nexport function toCounters(data: unknown): Record<string, unknown> | null {\n if (Array.isArray(data)) {\n const out: Record<string, unknown> = {};\n for (const row of data) {\n if (typeof row !== 'object' || row === null) continue;\n const r = row as { group?: unknown; value?: unknown };\n if (typeof r.group === 'string' && 'value' in r) out[r.group] = r.value;\n }\n return out;\n }\n if (typeof data === 'object' && data !== null) return data as Record<string, unknown>;\n return null;\n}\n","import type { BarChartWidget } from '../../core/models/schema.model';\nimport type { RenderDescriptor } from '../../core/registry/render-registry';\n\nimport { toSeries } from '../series';\n\n/** Descriptor del widget `bar-chart` (R3.6). */\nexport const descriptor: RenderDescriptor = {\n kind: 'widget',\n type: 'bar-chart',\n since: '1.0',\n load: () => import('./bar-chart').then((module) => module.BarChart),\n surfaces: ['display'],\n inputs: (config, extras) => {\n const cfg = config as BarChartWidget;\n return { label: cfg.label, data: toSeries(extras.data), unit: cfg.unit ?? '' };\n },\n};\n","import type { ChartLineWidget } from '../../core/models/schema.model';\nimport type { RenderDescriptor } from '../../core/registry/render-registry';\n\nimport { toSeries } from '../series';\n\n/** Descriptor del widget `chart-line` (R3.6). */\nexport const descriptor: RenderDescriptor = {\n kind: 'widget',\n type: 'chart-line',\n since: '1.0',\n load: () => import('./chart-line').then((module) => module.ChartLine),\n surfaces: ['display'],\n inputs: (config, extras) => {\n const cfg = config as ChartLineWidget;\n return { label: cfg.label, data: toSeries(extras.data), unit: cfg.unit ?? '' };\n },\n};\n","import type { MetricCardWidget } from '../../core/models/schema.model';\nimport type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/**\n * El dato de un KPI es un ESCALAR y puede llegar de dos formas:\n *\n * - **payload**: `data[widget.key]` ya es la cifra (la resuelve el handler\n * del panel);\n * - **fuente declarada** (F8 · R6.5): una vista con `aggregate` devuelve\n * `[{ value: … }]` y la cifra es ese `value`.\n *\n * Cualquier otra forma ⇒ `null`, que `MetricCard` pinta como vacío. Se\n * traduce acá, en el borde — el componente no debería saber de dónde salió\n * el número.\n */\nfunction valorDeKpi(data: unknown): number | string | null {\n if (Array.isArray(data)) {\n const first = data[0];\n if (typeof first !== 'object' || first === null) return null;\n const value = (first as { value?: unknown }).value;\n return value === undefined || value === null ? null : (value as number | string);\n }\n if (data === undefined) return null;\n return data as number | string | null;\n}\n\n/** Descriptor del widget `metric-card` (R3.6). */\nexport const descriptor: RenderDescriptor = {\n kind: 'widget',\n type: 'metric-card',\n since: '1.0',\n load: () => import('./metric-card').then((module) => module.MetricCard),\n surfaces: ['display'],\n // El KPI no recibe el widget entero: sólo vive de su rótulo, del dato y de\n // la nota al pie. Pasa el dato ya traducido — `MetricCard` distingue el\n // `0` de un vacío, y el `0` de un agregado llega como `[{ value: 0 }]`.\n inputs: (config, extras) => {\n const cfg = config as MetricCardWidget;\n return { label: cfg.label, value: valorDeKpi(extras.data), hint: cfg.hint ?? '' };\n },\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del widget `quick-actions` (R3.6). */\nexport const descriptor: RenderDescriptor = {\n kind: 'widget',\n type: 'quick-actions',\n since: '1.0',\n load: () => import('./quick-actions').then((module) => module.QuickActions),\n surfaces: ['display'],\n // El único widget sin dato: sus botones salen todos del schema. Por eso no\n // recibe `data` — `ngComponentOutletInputs` no admite inputs inexistentes.\n inputs: (config) => ({ widget: config }),\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\n/** Descriptor del widget `record-list` (R3.6). */\nexport const descriptor: RenderDescriptor = {\n kind: 'widget',\n type: 'record-list',\n since: '1.0',\n load: () => import('./record-list').then((module) => module.RecordList),\n surfaces: ['display'],\n // `RecordList` dibuja filas: fuera de un array no hay nada que listar, y un\n // objeto suelto no debe colarse como si fuera una única fila.\n inputs: (config, extras) => ({\n widget: config,\n data: Array.isArray(extras.data) ? (extras.data as Record<string, unknown>[]) : null,\n }),\n};\n","import type { RenderDescriptor } from '../../core/registry/render-registry';\n\nimport { toCounters } from '../series';\n\n/** Descriptor del widget `status-progress` (R3.6). */\nexport const descriptor: RenderDescriptor = {\n kind: 'widget',\n type: 'status-progress',\n since: '1.0',\n load: () => import('./status-progress').then((module) => module.StatusProgress),\n surfaces: ['display'],\n // Contadores por clave: un objeto plano del payload O las filas de una\n // fuente con `groupBy` (F8 · R6.5) — `toCounters` traduce en el borde y\n // devuelve `null` si no hay nada que contar.\n inputs: (config, extras) => ({\n widget: config,\n data: toCounters(extras.data),\n }),\n};\n","import type { RenderDescriptor } from '../core/registry/render-registry';\n\nimport { descriptor as barChartDescriptor } from './bar-chart/bar-chart.descriptor';\nimport { descriptor as chartLineDescriptor } from './chart-line/chart-line.descriptor';\nimport { descriptor as metricCardDescriptor } from './metric-card/metric-card.descriptor';\nimport { descriptor as quickActionsDescriptor } from './quick-actions/quick-actions.descriptor';\nimport { descriptor as recordListDescriptor } from './record-list/record-list.descriptor';\nimport { descriptor as statusProgressDescriptor } from './status-progress/status-progress.descriptor';\n\n/**\n * Manifiesto de descriptores de widget (R3.6 · registro único de render).\n *\n * Mismo criterio que `fields/descriptors.ts`: una línea por tipo y el\n * registro los recoge al importar este módulo. Es la **única** lista manual\n * del catálogo de widgets — `import.meta.glob` no sobrevive a `ng build`\n * (D9-1), así que se mantiene el «registro manual de una línea».\n *\n * Añadir un widget ⇒ crear la carpeta + su `.descriptor.ts` + una línea\n * acá. **Ningún host se toca** (R3.8): si el componente sigue la forma\n * estándar `{widget, data}` ni siquiera hay que escribir `inputs`.\n */\nexport const widgetDescriptors: readonly RenderDescriptor[] = [\n barChartDescriptor,\n chartLineDescriptor,\n metricCardDescriptor,\n quickActionsDescriptor,\n recordListDescriptor,\n statusProgressDescriptor,\n];\n","import type { RenderDescriptor } from '../core/registry/render-registry';\n\nexport const viewDescriptors: readonly RenderDescriptor[] = [\n {\n kind: 'view',\n type: 'list',\n since: '9.1',\n load: async () => (await import('../pages/resource-page/resource-page')).ResourcePage,\n },\n {\n kind: 'view',\n type: 'detail',\n since: '9.1',\n load: async () => (await import('../pages/resource-page/resource-page')).ResourcePage,\n },\n {\n kind: 'view',\n type: 'form',\n since: '9.1',\n load: async () => (await import('../pages/form-view/form-view')).FormView,\n },\n {\n kind: 'view',\n type: 'dashboard',\n since: '9.1',\n load: async () => (await import('../pages/resource-page/resource-page')).ResourcePage,\n },\n {\n kind: 'view',\n type: 'calendar',\n since: '9.8',\n load: async () => (await import('./calendar-view/calendar-view')).CalendarView,\n },\n {\n kind: 'view',\n type: 'kanban',\n since: '9.8',\n load: async () => (await import('./kanban-view/kanban-view')).KanbanView,\n },\n {\n kind: 'view',\n type: 'tabs',\n since: '9.9',\n load: async () => (await import('./composer/composer-host')).ComposerHost,\n },\n];\n","import {\n isDevMode,\n makeEnvironmentProviders,\n provideAppInitializer,\n type EnvironmentProviders,\n type TemplateRef,\n type Type,\n} from '@angular/core';\n\nimport type { RootTree } from '../../fields/field-node';\nimport type { SeedKind } from '../../shared/utils/seed';\nimport { columnFormatDescriptors } from '../../columns/descriptors';\nimport { fieldDescriptors } from '../../fields/descriptors';\nimport { layoutDescriptors } from '../../layouts/descriptors';\nimport { widgetDescriptors } from '../../widgets/descriptors';\nimport { viewDescriptors } from '../../views/descriptors';\nimport type { FieldSchema, LayoutMode, ListColumn, WidgetSchema } from '../models/schema.model';\n\n/**\n * Registro único de render (R3.1 · `doc/plan-refactor-motor.md` §3.1).\n *\n * Un solo sitio declara qué componentes sabe dibujar la UI: cada tipo de\n * campo, widget, acción o vista aporta un `RenderDescriptor` y el registro\n * lo resuelve por `(kind, type)`. Los hosts dejan de mantener `Set`s de tipos\n * e imports a mano — **en runtime el registro es la única fuente de verdad**.\n *\n * Se carga a scope de módulo y no desde DI: `buildFormSchema()` es una\n * función pura que consulta el registro sin inyectar nada, así que un\n * registro llenado únicamente por un provider dejaría esa consulta correr\n * contra un catálogo vacío. `provideRenderDescriptors()` existe igualmente\n * como punto de entrada explícito para `app.config.ts` (R3.2).\n *\n * Autodescubrimiento (D9-1): se opta por **registro manual** — un manifiesto\n * con una línea por descriptor — porque `import.meta.glob` no está\n * implementada por el bundler de producción (`@angular/build:application`\n * usa esbuild) y la llamada cruda sobreviviría en `dist/`, rompiendo el\n * arranque. Con Vite sólo en el dev-server y en el runner de tests, además,\n * el comportamiento habría diferido entre `npm test` y `npm run build`.\n */\n\n/** Qué clase de cosa se está resolviendo. Identificador único dentro de su `kind`. */\nexport type RenderKind = 'field' | 'column-format' | 'widget' | 'action' | 'view' | 'layout';\nexport type ComponentRenderKind = Exclude<RenderKind, 'layout'>;\n\n/** Superficies en las que un descriptor puede aparecer. */\nexport type RenderSurface = 'form' | 'display' | 'list' | 'filter';\n\n/**\n * Qué puede describir un `RenderDescriptor`: un campo del formulario, un\n * widget del dashboard o una columna de listado (R4.3).\n *\n * Es el tipo del input `config` del host. Los descriptores sólo comparten\n * `key` y `label`; lo demás lo decide cada `kind`, y quien necesita el resto\n * lo castea con su propia mirada (`cfgCampo()`, que es lo que el host ya\n * hacía antes de que existieran las columnas).\n */\nexport type RenderConfig = FieldSchema | WidgetSchema | ListColumn;\n\n/**\n * Contexto de render que el host expone por DI (R3.4 · `doc/plan-refactor-motor.md` §3.4).\n *\n * Los controles viven en un componente distinto por cada tipo, así que en vez\n * de repetir cinco inputs en los 20 el host lo provee una sola vez y cada\n * control lo inyecta si lo necesita — el mismo criterio que ya usaba\n * `FIELD_ARIA`.\n *\n * `tree` viaja en el contexto y no como input suelto porque es **por\n * instancia**: los hijos de un `group` o de un `list` navegan su subárbol, no\n * el del padre.\n *\n * Vive acá y no en `render-host.ts` porque el contrato de los descriptores\n * (`RenderExtras`) necesita nombrarlo: el descriptor de un campo compuesto\n * decide qué se le pasa al componente y eso sólo es escribible conociendo el\n * tipo. `render-host.ts` lo re-exporta para no mover a sus consumidores.\n */\nexport interface RenderContext {\n /** Árbol del formulario del nivel de este campo. */\n tree: RootTree;\n /** Errores del backend por ruta (`address.street`, `faq[2].answer`). */\n serverErrors: Record<string, string>;\n /** Prefijo de ruta de este campo en el registro raíz (`address.`). */\n pathPrefix: string;\n /** Si el registro ya existe (lo consume `slug` con `lockAfterCreate`). */\n exists: boolean;\n /** Recurso dueño del formulario (lo consume `image` para la firma, §11.2). */\n resource: string;\n}\n\n/**\n * Contexto vacío con el que arranca `RenderHost.ctx`.\n *\n * Sólo lo alcanza quien renderiza sin contexto — los widgets, que no forman\n * parte de un formulario. Un campo montado sin `ctx` es un error de\n * programación y `childTree` lo dice con su propio mensaje, igual que lo\n * decía el `input.required` anterior.\n */\nexport const RENDER_CONTEXT_VACIO: RenderContext = {\n tree: undefined as unknown as RootTree,\n serverErrors: {},\n pathPrefix: '',\n exists: false,\n resource: '',\n};\n\n/**\n * Segundo argumento de `RenderDescriptor.inputs`.\n *\n * Aporta lo que el host conoce y el descriptor no: el contexto de formulario\n * (sólo para campos), el payload del dato (sólo para widgets) y los dos\n * templates con los que se componen `group` y `list`.\n */\nexport interface RenderExtras {\n /** Contexto del nivel; `RENDER_CONTEXT_VACIO` cuando no hay formulario. */\n ctx: RenderContext;\n /** Payload del widget (`<app-widget-host [data]>`); `null` en campos. */\n data: unknown;\n /** Template del contenido de un `group`. */\n groupContent?: TemplateRef<unknown>;\n /** Template de los hijos de un `list`. */\n childTemplate?: TemplateRef<unknown>;\n}\n\n/**\n * Declaración de un componente renderizable.\n *\n * No lleva `configSchema`: esa cláusula de `refactormotor.md` no existe en\n * el código y el plan la descartó (D17).\n */\nexport interface RenderDescriptor<C = unknown> {\n /** Clase de cosa. */\n kind: ComponentRenderKind;\n /** Identificador `kebab-case`, único dentro de `kind`. */\n type: string;\n /** Versión del contrato en que apareció (`doc/refactormotor.md`). */\n since: string;\n /**\n * Carga perezosa del componente. El registro se resuelve sin arrastrar el\n * bundle: los descriptores sólo guardan el cierre, no la clase.\n */\n load: () => Promise<Type<any>>;\n /** Superficies en las que se usa. Sólo lo que se pueda evidenciar en el código. */\n surfaces?: RenderSurface[];\n /** Valores por defecto de la configuración del descriptor. */\n defaults?: Partial<C>;\n /**\n * Forma del valor inicial que siembra este campo en el modelo del\n * formulario (D32 · R3.8).\n *\n * **Dato, no función**: un nombre resuelto por `shared/utils/seed.ts`, no\n * una clausura. Así el descriptor sigue siendo puro —`kind`, `type`,\n * `load`, `surfaces`, `seed`— y `seed.ts` es el único dueño de recorrer\n * un árbol de campos. La alternativa (`seed: (cfg) => …`) obligaría a que\n * `group` importara `seedFields`, lo que cerraría un ciclo\n * registro → manifiesto → descriptor → `seed` → registro.\n *\n * Sólo los campos lo declaran. **Obligatorio para `kind: 'field'`** — lo\n * vigila `core/registry/contract.spec.ts`, porque la exhaustividad de una\n * unión de strings no puede imponerse en tiempo de compilación.\n */\n seed?: SeedKind;\n /**\n * Cableado del componente: qué inputs recibe y con qué valor.\n *\n * Es **la** pieza que mantiene el host genérico: sin esto el motor tendría\n * que saber que `metric-card` recibe `label/value/hint` y que `group`\n * necesita además el template de sus hijos, y «añadir un tipo» volvería a\n * tocar `render-host.ts` (R3.8). Cada descriptor declara el suyo y el host\n * sólo hace `ngComponentOutletInputs = descriptor.inputs(config, extras)`.\n *\n * No es obligatorio: el 80 % de los tipos comparten la forma estándar de su\n * `kind` — `{field, tree}` en campos, `{widget, data}` en widgets — y para\n * ellos el host aplica esa forma por defecto. Se declara sólo cuando el\n * componente se desvía de ella.\n */\n inputs?: (config: C, extras: RenderExtras) => Record<string, unknown>;\n}\n\n/** Declaración de un layout manejado por el host de formularios. */\nexport interface LayoutDescriptor {\n kind: 'layout';\n type: LayoutMode;\n since: string;\n}\n\n/** Catálogo en memoria: `kind:type` → descriptor. */\nconst RENDERERS = new Map<string, RenderDescriptor>();\nconst LAYOUTS = new Map<string, LayoutDescriptor>();\n\nfunction keyOf(kind: RenderKind, type: string): string {\n return `${kind}:${type}`;\n}\n\n/**\n * Registra un descriptor. Idempotente por clave: volver a registrar el mismo\n * `(kind, type)` lo sobrescribe, lo que permite que un módulo se recargue en\n * desarrollo sin duplicar entradas.\n */\nexport function register(kind: 'layout', descriptor: LayoutDescriptor): void;\nexport function register(kind: ComponentRenderKind, descriptor: RenderDescriptor): void;\nexport function register(kind: RenderKind, descriptor: RenderDescriptor | LayoutDescriptor): void {\n if (kind === 'layout') {\n if (!('kind' in descriptor) || descriptor.kind !== 'layout') {\n throw new Error(`El descriptor de layout \"${descriptor.type}\" no declara kind: \"layout\".`);\n }\n LAYOUTS.set(descriptor.type, descriptor);\n return;\n }\n if (descriptor.kind === 'layout') {\n throw new Error(\n `El descriptor de layout \"${descriptor.type}\" no puede registrarse como ${kind}.`,\n );\n }\n RENDERERS.set(keyOf(kind, descriptor.type), descriptor);\n}\n\n/**\n * Quita un descriptor (R7.6). Simétrico a `register`: los specs que\n * registran entradas de prueba deben retirarlas, o el catálogo global queda\n * contaminado para cualquier otro spec que lea `renderKinds()` (flaky por\n * orden de ejecución).\n */\nexport function unregister(kind: RenderKind, type: string): void {\n if (kind === 'layout') {\n LAYOUTS.delete(type);\n } else {\n RENDERERS.delete(keyOf(kind, type));\n }\n}\n\n/** Descriptor declarado para `(kind, type)`, o `undefined` si nadie lo registró. */\nexport function get(kind: ComponentRenderKind, type: string): RenderDescriptor | undefined {\n return RENDERERS.get(keyOf(kind, type));\n}\n\n/** ¿La UI sabe dibujar este `(kind, type)`? Reemplaza a los `Set`s de los hosts. */\nexport function isSupported(kind: RenderKind, type: string): boolean {\n return kind === 'layout' ? LAYOUTS.has(type) : RENDERERS.has(keyOf(kind, type));\n}\n\n/**\n * Componente para `(kind, type)`, o `fallback` si el tipo no está en el\n * catálogo.\n *\n * Es **asíncrona** porque `load()` importa el componente bajo demanda; el\n * `fallback` es síncrono y sólo se usa cuando no hay descriptor. Un fallo de\n * `load()` NO se traga: propagarlo es lo que hace visible un descriptor mal\n * escrito, y la política «nunca pantalla rota» la resuelve el llamante con el\n * `fallback` que ya recibe.\n */\nexport async function resolve<C = unknown>(\n kind: ComponentRenderKind,\n type: string,\n fallback: Type<C>,\n): Promise<Type<C>> {\n const descriptor = get(kind, type);\n if (!descriptor) return fallback;\n return (await descriptor.load()) as Type<C>;\n}\n\n// Catálogo a scope de módulo: se registra al importar, sin esperar a DI.\nfor (const descriptor of [\n ...fieldDescriptors,\n ...widgetDescriptors,\n ...columnFormatDescriptors,\n ...viewDescriptors,\n ...layoutDescriptors,\n]) {\n if (descriptor.kind === 'layout') {\n register('layout', descriptor);\n } else {\n register(descriptor.kind, descriptor);\n }\n}\n\n/**\n * Punto de entrada para `app.config.ts` (R3.2).\n *\n * El catálogo ya quedó cargado al importar este módulo; el provider sirve\n * para que el arranque sea explícito y para avisar en desarrollo si el\n * manifiesto vino vacío — que es exactamente lo que pasaría si alguien\n * borra una línea del manifiesto sin reemplazarla.\n */\nexport function provideRenderDescriptors(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideAppInitializer(() => {\n if (isDevMode() && RENDERERS.size === 0 && LAYOUTS.size === 0) {\n console.warn('[render-registry] el catálogo de descriptores vino vacío');\n }\n }),\n ]);\n}\n\n/** Cuántos descriptores hay registrados. Sólo para comprobaciones y tests. */\nexport function renderDescriptorCount(): number {\n return RENDERERS.size + LAYOUTS.size;\n}\n\n/**\n * `kind`s que hoy tienen al menos un descriptor.\n *\n * Existe para el test de exhaustividad (R3.7): él recorre los schemas de los\n * `kind`s que tienen registro y **falla** si aparece un `kind` con descriptor\n * que nadie recorre — de lo contrario «tener registro» y «estar cubierto»\n * serían dos afirmaciones distintas que nadie reconcilia.\n */\nexport function renderKinds(): RenderKind[] {\n const kinds = new Set<RenderKind>([...RENDERERS.values()].map((descriptor) => descriptor.kind));\n if (LAYOUTS.size > 0) {\n kinds.add('layout');\n }\n return [...kinds];\n}\n"],"mappings":";AAkBA,MAAM,UAAU,SAAkB,YAAmD,EACnF,MAAM,OAAO,KACd;AAkED,MAAa,0BAAuD;CAClE;EAhEA,MAAM;EACN,MAAM;EACN,OAAO;EACP,UAAU,CAAC,MAAM;EACjB,YAAY,OAAO,qDAAgB,CAAC,MAAM,WAAW,OAAO,gBAAgB;EAC5E;CA2DA;CACA;EAxDA,MAAM;EACN,MAAM;EACN,OAAO;EACP,UAAU,CAAC,MAAM;EACjB,YAAY,OAAO,sDAAiB,CAAC,MAAM,WAAW,OAAO,iBAAiB;EAC9E;CAmDA;CACA;EAhDA,MAAM;EACN,MAAM;EACN,OAAO;EACP,UAAU,CAAC,MAAM;EACjB,YAAY,OAAO,0DAAqB,CAAC,MAAM,WAAW,OAAO,qBAAqB;EACtF;CA2CA;CACA;EAxCA,MAAM;EACN,MAAM;EACN,OAAO;EACP,UAAU,CAAC,MAAM;EACjB,YAAY,OAAO,wDAAmB,CAAC,MAAM,WAAW,OAAO,mBAAmB;EAClF;CAmCA;CACA;EAhCA,MAAM;EACN,MAAM;EACN,OAAO;EACP,UAAU,CAAC,MAAM;EACjB,YAAY,OAAO,uDAAkB,CAAC,MAAM,WAAW,OAAO,kBAAkB;EAChF;CA2BA;CACA;EAxBA,MAAM;EACN,MAAM;EACN,OAAO;EACP,UAAU,CAAC,MAAM;EACjB,YAAY,OAAO,yDAAoB,CAAC,MAAM,WAAW,OAAO,oBAAoB;EACpF;CAmBA;CACA;EAhBA,MAAM;EACN,MAAM;EACN,OAAO;EACP,UAAU,CAAC,MAAM;EACjB,YAAY,OAAO,qDAAgB,CAAC,MAAM,WAAW,OAAO,gBAAgB;EAC5E;CAWA;AACD;AAUD,MAAa,sBAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;AACQ;AC7GV,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,iDAAY,CAAC,MAAM,WAAW,OAAO,YAAY;CACpE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACPD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,kDAAa,CAAC,MAAM,WAAW,OAAO,aAAa;CAEtE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,8CAAS,CAAC,MAAM,WAAW,OAAO,SAAS;CAE9D,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,+CAAU,CAAC,MAAM,WAAW,OAAO,UAAU;CAEhE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,8CAAS,CAAA,MAAA,MAAA,EAAA,CAAA,CAAA,CAAC,MAAM,WAAW,OAAO,SAAS;CAE9D,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAG7B;ACVD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,+CAAU,CAAC,MAAM,WAAW,OAAO,UAAU;CAEhE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;CAG5B,SAAS,QAAQ,YAAY;EAC3B,OAAO;EACP,MAAM,OAAO,IAAI;EACjB,cAAc,OAAO,IAAI;EACzB,YAAY,OAAO,IAAI;EACvB,SAAS,OAAO;CACjB;AACF;ACjBD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,+CAAU,CAAA,MAAA,MAAA,EAAA,CAAA,CAAA,CAAC,MAAM,WAAW,OAAO,UAAU;CAEhE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,mDAAc,CAAC,MAAM,WAAW,OAAO,aAAa;CACvE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACPD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,8CAAS,CAAC,MAAM,WAAW,OAAO,SAAS;CAC9D,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;CAG5B,SAAS,QAAQ,YAAY;EAC3B,OAAO;EACP,MAAM,OAAO,IAAI;EACjB,eAAe,OAAO;EACtB,cAAc,OAAO,IAAI;EACzB,YAAY,OAAO,IAAI;EACvB,QAAQ,OAAO,IAAI;CACpB;AACF;ACjBD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,qDAAgB,CAAA,MAAA,MAAA,EAAA,CAAA,CAAA,CAAC,MAAM,WAAW,OAAO,gBAAgB;CAC5E,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACPD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,gDAAW,CAAC,MAAM,WAAW,OAAO,WAAW;CAElE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,+CAAU,CAAC,MAAM,WAAW,OAAO,UAAU;CAEhE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,uDAAkB,CAAC,MAAM,WAAW,OAAO,iBAAiB;CAE/E,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,kDAAa,CAAC,MAAM,WAAW,OAAO,aAAa;CAEtE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,gDAAW,CAAC,MAAM,WAAW,OAAO,WAAW;CAElE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,8CAAS,CAAC,MAAM,WAAW,OAAO,SAAS;CAE9D,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;CAG5B,SAAS,QAAQ,YAAY;EAC3B,OAAO;EACP,MAAM,OAAO,IAAI;EACjB,QAAQ,OAAO,IAAI;CACpB;AACF;ACfD,MAAa,gBAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,qDAAgB,CAAC,MAAM,WAAW,OAAO,eAAe;CAC3E,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACPD,MAAa,eAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,8CAAS,CAAC,MAAM,WAAW,OAAO,SAAS;CAE9D,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,eAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,kDAAa,CAAC,MAAM,WAAW,OAAO,aAAa;CAEtE,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,eAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,8CAAS,CAAC,MAAM,WAAW,OAAO,SAAS;CAE9D,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACRD,MAAa,eAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,6CAAQ,CAAC,MAAM,WAAW,OAAO,QAAQ;CAE5D,MAAM;CACN,UAAU,CAAC,QAAQ,SAAS;AAC7B;ACuCD,MAAa,4BAA4B;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACuC;AAkBzC,MAAa,mBAAgD;CAC3D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AC9GD,MAAa,oBAAiD;CAC5D;EAAE,MAAM;EAAU,MAAM;EAAQ,OAAO;CAAK;CAC5C;EAAE,MAAM;EAAU,MAAM;EAAQ,OAAO;CAAK;CAC5C;EAAE,MAAM;EAAU,MAAM;EAAY,OAAO;CAAK;CAChD;EAAE,MAAM;EAAU,MAAM;EAAS,OAAO;CAAK;CAC7C;EAAE,MAAM;EAAU,MAAM;EAAW,OAAO;CAAK;AAChD;ACKD,SAAgB,SAAS,MAAa;CACpC,IAAI,CAAC,MAAM,QAAQ,IAAI,GACrB,OAAO,CAAA;CAET,OAAO,KACJ,KAAK,QAAwB;EAC5B,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM,OAAO;EACpD,MAAM,IAAI;EAIV,MAAM,QAAQ,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,EAAE;EACxD,IAAI,OAAO,UAAU,YAAY,OAAO,EAAE,UAAU,UAAU,OAAO;EACrE,OAAO;GAAE;GAAO,OAAO,EAAE;EAAK;CAChC,CAAC,CAAC,CACD,QAAQ,QAAyB,QAAQ,IAAI;AAClD;AAcA,SAAgB,WAAW,MAAa;CACtC,IAAI,MAAM,QAAQ,IAAI,GAAG;EACvB,MAAM,MAA+B,CAAA;EACrC,KAAK,MAAM,OAAO,MAAM;GACtB,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;GAC7C,MAAM,IAAI;GACV,IAAI,OAAO,EAAE,UAAU,YAAY,WAAW,GAAG,IAAI,EAAE,SAAS,EAAE;EACpE;EACA,OAAO;CACT;CACA,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,OAAO;CACtD,OAAO;AACT;ACjDA,MAAa,eAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,mDAAc,CAAC,MAAM,WAAW,OAAO,QAAQ;CAClE,UAAU,CAAC,SAAS;CACpB,SAAS,QAAQ,WAAU;EACzB,MAAM,MAAM;EACZ,OAAO;GAAE,OAAO,IAAI;GAAO,MAAM,SAAS,OAAO,IAAI;GAAG,MAAM,IAAI,QAAQ;EAAE;CAC9E;AACD;ACVD,MAAa,eAA+B;CAC1C,MAAM;CACN,MAAM;CACN,OAAO;CACP,YAAY,OAAO,oDAAe,CAAC,MAAM,WAAW,OAAO,SAAS;CACpE,UAAU,CAAC,SAAS;CACpB,SAAS,QAAQ,WAAU;EACzB,MAAM,MAAM;EACZ,OAAO;GAAE,OAAO,IAAI;GAAO,MAAM,SAAS,OAAO,IAAI;GAAG,MAAM,IAAI,QAAQ;EAAE;CAC9E;AACD;ACDD,SAAS,WAAW,MAAa;CAC/B,IAAI,MAAM,QAAQ,IAAI,GAAG;EACvB,MAAM,QAAQ,KAAK;EACnB,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;EACxD,MAAM,QAAS,MAA8B;EAC7C,OAAO,UAAU,UAAa,UAAU,OAAO,OAAQ;CACzD;CACA,IAAI,SAAS,QAAW,OAAO;CAC/B,OAAO;AACT;AIHA,MAAa,oBAAiD;CAC5D;CACA;CACA;EJIA,MAAM;EACN,MAAM;EACN,OAAO;EACP,YAAY,OAAO,qDAAgB,CAAC,MAAM,WAAW,OAAO,UAAU;EACtE,UAAU,CAAC,SAAS;EAIpB,SAAS,QAAQ,WAAU;GACzB,MAAM,MAAM;GACZ,OAAO;IAAE,OAAO,IAAI;IAAO,OAAO,WAAW,OAAO,IAAI;IAAG,MAAM,IAAI,QAAQ;GAAE;EACjF;CIfA;CACA;EHrBA,MAAM;EACN,MAAM;EACN,OAAO;EACP,YAAY,OAAO,uDAAkB,CAAC,MAAM,WAAW,OAAO,YAAY;EAC1E,UAAU,CAAC,SAAS;EAGpB,SAAS,YAAY,EAAE,QAAQ,OAAM;CGcrC;CACA;EFtBA,MAAM;EACN,MAAM;EACN,OAAO;EACP,YAAY,OAAO,qDAAgB,CAAC,MAAM,WAAW,OAAO,UAAU;EACtE,UAAU,CAAC,SAAS;EAGpB,SAAS,QAAQ,YAAY;GAC3B,QAAQ;GACR,MAAM,MAAM,QAAQ,OAAO,IAAI,IAAK,OAAO,OAAqC;EACjF;CEYD;CACA;EDrBA,MAAM;EACN,MAAM;EACN,OAAO;EACP,YAAY,OAAO,yDAAoB,CAAC,MAAM,WAAW,OAAO,cAAc;EAC9E,UAAU,CAAC,SAAS;EAIpB,SAAS,QAAQ,YAAY;GAC3B,QAAQ;GACR,MAAM,WAAW,OAAO,IAAI;EAC7B;CCUD;AACD;AC1BD,MAAa,kBAA+C;CAC1D;EACE,MAAM;EACN,MAAM;EACN,OAAO;EACP,MAAM,aAAa,MAAM,OAAO,gCAAuC,CAAA,MAAA,MAAA,EAAA,CAAA,EAAA,CAAE;CAC1E;CACD;EACE,MAAM;EACN,MAAM;EACN,OAAO;EACP,MAAM,aAAa,MAAM,OAAO,gCAAuC,CAAA,MAAA,MAAA,EAAA,CAAA,EAAA,CAAE;CAC1E;CACD;EACE,MAAM;EACN,MAAM;EACN,OAAO;EACP,MAAM,aAAa,MAAM,OAAO,mDAA+B,CAAA,MAAA,MAAA,EAAA,CAAA,EAAA,CAAE;CAClE;CACD;EACE,MAAM;EACN,MAAM;EACN,OAAO;EACP,MAAM,aAAa,MAAM,OAAO,gCAAuC,CAAA,MAAA,MAAA,EAAA,CAAA,EAAA,CAAE;CAC1E;CACD;EACE,MAAM;EACN,MAAM;EACN,OAAO;EACP,MAAM,aAAa,MAAM,OAAO,wDAAA,CAAkC;CACnE;CACD;EACE,MAAM;EACN,MAAM;EACN,OAAO;EACP,MAAM,aAAa,MAAM,OAAO,sDAAA,CAA8B;CAC/D;CACD;EACE,MAAM;EACN,MAAM;EACN,OAAO;EACP,MAAM,aAAa,MAAM,OAAO,gCAA2B,CAAA,MAAA,MAAA,EAAA,CAAA,EAAA,CAAE;CAC9D;AACF;ACmDD,MAAa,uBAAsC;CACjD,MAAM;CACN,cAAc,CAAA;CACd,YAAY;CACZ,QAAQ;CACR,UAAU;AACX;AAmFD,MAAM,4BAAY,IAAI,IAAG;AACzB,MAAM,0BAAU,IAAI,IAAG;AAEvB,SAAS,MAAM,MAAkB,MAAY;CAC3C,OAAO,GAAG,KAAI,GAAI;AACpB;AASA,SAAgB,SAAS,MAAkB,YAA+C;CACxF,IAAI,SAAS,UAAU;EACrB,IAAI,EAAE,UAAU,eAAe,WAAW,SAAS,UACjD,MAAM,IAAI,MAAM,4BAA4B,WAAW,KAAI,6BAA8B;EAE3F,QAAQ,IAAI,WAAW,MAAM,UAAU;EACvC;CACF;CACA,IAAI,WAAW,SAAS,UACtB,MAAM,IAAI,MACR,4BAA4B,WAAW,KAAI,8BAA+B,KAAI,EAAG;CAGrF,UAAU,IAAI,MAAM,MAAM,WAAW,IAAI,GAAG,UAAU;AACxD;AAQA,SAAgB,WAAW,MAAkB,MAAY;CACvD,IAAI,SAAS,UACX,QAAQ,OAAO,IAAI;MAEnB,UAAU,OAAO,MAAM,MAAM,IAAI,CAAC;AAEtC;AAGA,SAAgB,IAAI,MAA2B,MAAY;CACzD,OAAO,UAAU,IAAI,MAAM,MAAM,IAAI,CAAC;AACxC;AAGA,SAAgB,YAAY,MAAkB,MAAY;CACxD,OAAO,SAAS,WAAW,QAAQ,IAAI,IAAI,IAAI,UAAU,IAAI,MAAM,MAAM,IAAI,CAAC;AAChF;AAYA,eAAsB,QACpB,MACA,MACA,UAAiB;CAEjB,MAAM,aAAa,IAAI,MAAM,IAAI;CACjC,IAAI,CAAC,YAAY,OAAO;CACxB,OAAQ,MAAM,WAAW,KAAI;AAC/B;AAGA,KAAK,MAAM,cAAc;CACvB,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACJ,GACC,IAAI,WAAW,SAAS,UACtB,SAAS,UAAU,UAAU;KAE7B,SAAS,WAAW,MAAM,UAAU;AAYxC,SAAgB,2BAAwB;CACtC,OAAO,yBAAyB,CAC9B,4BAA2B;EACzB,IAAI,UAAS,KAAM,UAAU,SAAS,KAAK,QAAQ,SAAS,GAC1D,QAAQ,KAAK,0DAA0D;CAE3E,CAAC,CACF,CAAA;AACH;AAeA,SAAgB,cAAW;CACzB,MAAM,QAAQ,IAAI,IAAgB,CAAC,GAAG,UAAU,OAAM,CAAE,CAAC,CAAC,KAAK,eAAe,WAAW,IAAI,CAAC;CAC9F,IAAI,QAAQ,OAAO,GACjB,MAAM,IAAI,QAAQ;CAEpB,OAAO,CAAC,GAAG,KAAK;AAClB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tinya-code-gas-admin-ui-select--98lPbev.mjs","names":[],"sources":["../../../projects/gas-admin-ui/src/lib/fields/select/select.ts"],"sourcesContent":["import { Component, computed, inject, input, resource, signal } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\n\nimport type { SelectField, SelectOption } from '../../core/models/schema.model';\nimport { DataSourceService, dataSourceKey } from '../../core/services/data-source.service';\nimport { optionsFromRows } from '../../core/utils/source-options';\nimport { getSchema } from '../../core/registry/schema-catalog';\nimport { FieldAria } from '../field-aria';\nimport { childTree, type RootTree } from '../field-node';\nimport { esGrupoRadio } from './radio-mode';\n\n/**\n * Desplegable de un solo valor (base.md §5.1).\n *\n * Sus opciones se declaran de dos formas y **exactamente una** (XOR, D62):\n * `options` estáticas en el schema o `source` — una fuente declarada que\n * pide `DataSourceService` con la misma caché que usan las relaciones y los\n * widgets (F8 · R6.5). Mientras la vuelta no llega se anuncia; sin anuncio\n * un desplegable vacío se confundiría con «esto no tiene opciones».\n */\n@Component({\n selector: 'app-field-select',\n imports: [FieldAria, FormField],\n template: `\n @if (fallo()) {\n <p class=\"mb-1 text-xs text-danger\" role=\"alert\">No se pudieron cargar las opciones.</p>\n } @else if (cargando()) {\n <p class=\"mb-1 text-xs text-neutral\" role=\"status\">Cargando opciones…</p>\n }\n @if (useRadio()) {\n <!-- Guía de control: 2–4 opciones estáticas → radio buttons, no un\n desplegable. Cada opción es un label implícito (texto y control\n juntos) y el grupo se nombra con aria-label: el rótulo del host\n se dibuja como texto porque un grupo no es un único control con\n el que emparejar un for. formField va en CADA input: Signal\n Forms soporta radio (checked = value === element.value) y setea\n name/disabled del grupo por estado de campo. -->\n <div\n class=\"mt-1 flex flex-col gap-1\"\n role=\"radiogroup\"\n [attr.aria-label]=\"field().label\"\n data-testid=\"select-radios\"\n >\n @if (!field().required) {\n <label class=\"flex w-fit items-center gap-2 text-sm\">\n <input\n type=\"radio\"\n class=\"accent-primary\"\n [id]=\"state().name() + '-__vacio'\"\n value=\"\"\n [formField]=\"node()\"\n />\n <span class=\"text-neutral\">{{ field().placeholder ?? '— Seleccionar —' }}</span>\n </label>\n }\n @for (option of options(); track option.value) {\n <label class=\"flex w-fit items-center gap-2 text-sm\">\n <input\n type=\"radio\"\n class=\"accent-primary\"\n [id]=\"state().name() + '-' + option.value\"\n [value]=\"option.value\"\n [formField]=\"node()\"\n />\n <span>{{ option.label }}</span>\n </label>\n }\n </div>\n } @else if (useSearch()) {\n <!-- Guía §1: más de 7 opciones → dropdown con búsqueda. Se filtra el\n select nativo en vez de construir un combobox: el teclado, el\n anuncio de la opción activa y el valor elegido siguen siendo los\n del navegador. -->\n <input\n type=\"search\"\n class=\"mb-1 w-full rounded-lg border border-neutral/30 bg-surface px-2 py-1 text-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n placeholder=\"Buscar…\"\n aria-label=\"Buscar entre las opciones\"\n [attr.aria-controls]=\"state().name()\"\n [value]=\"query()\"\n (input)=\"onQuery($event)\"\n />\n }\n <select class=\"field-input\" [id]=\"state().name()\" [formField]=\"node()\">\n @if (!field().required) {\n <option value=\"\">{{ field().placeholder ?? '— Seleccionar —' }}</option>\n }\n @for (option of visibleOptions(); track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n {{ option.label }}\n </option>\n }\n </select>\n @if (noMatches()) {\n <p class=\"mt-1 text-xs text-neutral\" role=\"status\">Sin resultados para «{{ query() }}».</p>\n }\n `,\n})\nexport class FieldSelect {\n readonly field = input.required<SelectField>();\n readonly tree = input.required<RootTree>();\n\n private readonly ds = inject(DataSourceService);\n\n protected readonly node = computed(() => childTree<string>(this.tree(), this.field().key));\n protected readonly state = computed(() => this.node()());\n\n /** Texto escrito en el buscador (sólo se usa si supera el umbral). */\n protected readonly query = signal('');\n\n /**\n * Registro del formulario, sólo para resolver `{campo}` en `source.params`.\n * Sin parámetros declarados no se lee: el campo no depende del formulario.\n */\n private readonly registro = computed<Record<string, unknown> | undefined>(() => {\n const source = this.field().source;\n if (source === undefined || source.params === undefined) return undefined;\n return this.tree()().value();\n });\n\n /** `undefined` sin fuente ⇒ `resource` queda idle y jamás llama al loader. */\n private readonly claveFuente = computed(() => {\n const source = this.field().source;\n return source === undefined ? undefined : dataSourceKey(source, this.registro());\n });\n\n private readonly fuenteResource = resource({\n params: () => this.claveFuente(),\n loader: async () => {\n const source = this.field().source;\n if (source === undefined) return [];\n return this.ds.rows(source, this.registro());\n },\n });\n\n /**\n * Opciones efectivas: las estáticas del schema o las filas de la fuente\n * declarada, mapeadas con la misma regla que una relación (F8 · R6.5).\n */\n protected readonly options = computed<SelectOption[]>(() => {\n const field = this.field();\n if (field.source === undefined) return field.options ?? [];\n // `value()` del resource TIRA en estado error (contract de Angular):\n // se mira el estado antes de leerlo, o el propio render rompe en vez\n // de pintar el aviso de fallo.\n if (this.fuenteResource.status() === 'error') return [];\n return optionsFromRows(this.fuenteResource.value() ?? [], {\n source: field.source,\n target: getSchema(field.source.resource),\n });\n });\n\n /** Sólo aplica con `source`: una lista estática no tiene vuelta que esperar. */\n protected readonly cargando = computed(\n () => this.claveFuente() !== undefined && this.fuenteResource.status() === 'loading',\n );\n\n protected readonly fallo = computed(\n () => this.claveFuente() !== undefined && this.fuenteResource.status() === 'error',\n );\n\n /** Umbral de la guía §1: 5–7 opciones dropdown simple, más de 7 con búsqueda. */\n protected readonly useSearch = computed(() => this.options().length > 7);\n\n /** Guía §1: 2–4 opciones estáticas → radio buttons (ver `radio-mode.ts`). */\n protected readonly useRadio = computed(() => esGrupoRadio(this.field()));\n\n protected onQuery(event: Event): void {\n this.query.set((event.target as HTMLInputElement).value);\n }\n\n /**\n * Opciones que coinciden con el término, SIN conservar la elegida: es la\n * base del mensaje «Sin resultados».\n */\n protected readonly matches = computed<SelectOption[]>(() => {\n const all = this.options();\n const term = this.query().trim().toLowerCase();\n if (term === '') {\n return all;\n }\n return all.filter((option) => option.label.toLowerCase().includes(term));\n });\n\n /** El buscador está activo y no encontró nada nuevo (el elegido no cuenta). */\n protected readonly noMatches = computed(\n () => this.useSearch() && this.query().trim() !== '' && this.matches().length === 0,\n );\n\n /**\n * Opciones que se dibujan. Con búsqueda activa se acotan por etiqueta, pero\n * la opción elegida se conserva siempre aunque no coincida con el término:\n * si desapareciera del DOM, el select dejaría de mostrar el valor actual\n * (guía §1: «valor seleccionado siempre visible»).\n */\n protected readonly visibleOptions = computed<SelectOption[]>(() => {\n const filtered = this.matches();\n if (this.query().trim() === '') {\n return filtered;\n }\n const selected = String(this.state().value() ?? '');\n if (filtered.some((option) => option.value === selected)) {\n return filtered;\n }\n const kept = this.options().find((option) => option.value === selected);\n return kept === undefined ? filtered : [...filtered, kept];\n });\n}\n"],"mappings":"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"}
|