@tinya-code/gas-admin-ui 0.2.0-alpha.15 → 0.2.0-alpha.18

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.
Files changed (368) hide show
  1. package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs +84 -0
  2. package/fesm2022/tinya-code-gas-admin-ui-badge-EeCA_l-o.mjs.map +1 -0
  3. package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs +140 -0
  4. package/fesm2022/tinya-code-gas-admin-ui-bar-chart-G7sEMSBY.mjs.map +1 -0
  5. package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs +113 -0
  6. package/fesm2022/tinya-code-gas-admin-ui-boolean-B2ASKL0E.mjs.map +1 -0
  7. package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs +163 -0
  8. package/fesm2022/tinya-code-gas-admin-ui-button-BQjNW8KB.mjs.map +1 -0
  9. package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs +1027 -0
  10. package/fesm2022/tinya-code-gas-admin-ui-calendar-view-DCY8bj2V.mjs.map +1 -0
  11. package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs +278 -0
  12. package/fesm2022/tinya-code-gas-admin-ui-chart-line-BjdlKHoH.mjs.map +1 -0
  13. package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs +107 -0
  14. package/fesm2022/tinya-code-gas-admin-ui-color-Dljh_By3.mjs.map +1 -0
  15. package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs +101 -0
  16. package/fesm2022/tinya-code-gas-admin-ui-condition-evaluator-DY2k1M3C.mjs.map +1 -0
  17. package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs +141 -0
  18. package/fesm2022/tinya-code-gas-admin-ui-currency-BvuF3Z63.mjs.map +1 -0
  19. package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs +88 -0
  20. package/fesm2022/tinya-code-gas-admin-ui-data-source.service-96FSbN72.mjs.map +1 -0
  21. package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs +107 -0
  22. package/fesm2022/tinya-code-gas-admin-ui-date-1SJGXZrd.mjs.map +1 -0
  23. package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs +140 -0
  24. package/fesm2022/tinya-code-gas-admin-ui-display-badge-fwk6sDU7.mjs.map +1 -0
  25. package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs +119 -0
  26. package/fesm2022/tinya-code-gas-admin-ui-display-date-D7zLiDiG.mjs.map +1 -0
  27. package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs +125 -0
  28. package/fesm2022/tinya-code-gas-admin-ui-display-file-BiIhqvQC.mjs.map +1 -0
  29. package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs +152 -0
  30. package/fesm2022/tinya-code-gas-admin-ui-display-image-C1dhnZi1.mjs.map +1 -0
  31. package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs +211 -0
  32. package/fesm2022/tinya-code-gas-admin-ui-display-list-DOEuUbGe.mjs.map +1 -0
  33. package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs +116 -0
  34. package/fesm2022/tinya-code-gas-admin-ui-display-number-DDMzr4Hn.mjs.map +1 -0
  35. package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs +111 -0
  36. package/fesm2022/tinya-code-gas-admin-ui-display-text-B8CdVNpv.mjs.map +1 -0
  37. package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs +122 -0
  38. package/fesm2022/tinya-code-gas-admin-ui-dropdown-C3blvmE1.mjs.map +1 -0
  39. package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs +107 -0
  40. package/fesm2022/tinya-code-gas-admin-ui-email-CT_O5ihA.mjs.map +1 -0
  41. package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs +109 -0
  42. package/fesm2022/tinya-code-gas-admin-ui-empty-state-BMc0QtoT.mjs.map +1 -0
  43. package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs +45 -0
  44. package/fesm2022/tinya-code-gas-admin-ui-error-mapper.service-DY5y1FjE.mjs.map +1 -0
  45. package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs +50 -0
  46. package/fesm2022/tinya-code-gas-admin-ui-field-aria-BD1Wiggc.mjs.map +1 -0
  47. package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs +24 -0
  48. package/fesm2022/tinya-code-gas-admin-ui-field-node-CIK6KNN_.mjs.map +1 -0
  49. package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs +27 -0
  50. package/fesm2022/tinya-code-gas-admin-ui-field-path-B4-FTBGZ.mjs.map +1 -0
  51. package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs +408 -0
  52. package/fesm2022/tinya-code-gas-admin-ui-file-Dmxioog7.mjs.map +1 -0
  53. package/fesm2022/tinya-code-gas-admin-ui-form-view-CEe7aZ4m.mjs +4516 -0
  54. package/fesm2022/tinya-code-gas-admin-ui-form-view-CEe7aZ4m.mjs.map +1 -0
  55. package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs +82 -0
  56. package/fesm2022/tinya-code-gas-admin-ui-format-badge-CK8ct5Wk.mjs.map +1 -0
  57. package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs +105 -0
  58. package/fesm2022/tinya-code-gas-admin-ui-format-boolean-ClzezZz-.mjs.map +1 -0
  59. package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs +65 -0
  60. package/fesm2022/tinya-code-gas-admin-ui-format-currency-CVmniKml.mjs.map +1 -0
  61. package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs +65 -0
  62. package/fesm2022/tinya-code-gas-admin-ui-format-date-Dr1YsDd_.mjs.map +1 -0
  63. package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs +65 -0
  64. package/fesm2022/tinya-code-gas-admin-ui-format-number-CWCjpI4n.mjs.map +1 -0
  65. package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs +59 -0
  66. package/fesm2022/tinya-code-gas-admin-ui-format-text-DBOgJkH0.mjs.map +1 -0
  67. package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs +94 -0
  68. package/fesm2022/tinya-code-gas-admin-ui-format-thumbnail-PCRvxWKt.mjs.map +1 -0
  69. package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs +72 -0
  70. package/fesm2022/tinya-code-gas-admin-ui-gap-sorting-iTdy_DYG.mjs.map +1 -0
  71. package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs +238 -0
  72. package/fesm2022/tinya-code-gas-admin-ui-group-h7-O8tt4.mjs.map +1 -0
  73. package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs +416 -0
  74. package/fesm2022/tinya-code-gas-admin-ui-image-7UhJ7nqI.mjs.map +1 -0
  75. package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs +439 -0
  76. package/fesm2022/tinya-code-gas-admin-ui-kanban-view-Dl0Ol5Kb.mjs.map +1 -0
  77. package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs +513 -0
  78. package/fesm2022/tinya-code-gas-admin-ui-key-value-nVdgg5at.mjs.map +1 -0
  79. package/fesm2022/tinya-code-gas-admin-ui-list-DTtCYS4d.mjs +637 -0
  80. package/fesm2022/tinya-code-gas-admin-ui-list-DTtCYS4d.mjs.map +1 -0
  81. package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs +127 -0
  82. package/fesm2022/tinya-code-gas-admin-ui-metric-card-DnGMQL8l.mjs.map +1 -0
  83. package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs +251 -0
  84. package/fesm2022/tinya-code-gas-admin-ui-multiselect-PB28e-jl.mjs.map +1 -0
  85. package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs +66 -0
  86. package/fesm2022/tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs.map +1 -0
  87. package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs +114 -0
  88. package/fesm2022/tinya-code-gas-admin-ui-number-JNr7glc8.mjs.map +1 -0
  89. package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs +116 -0
  90. package/fesm2022/tinya-code-gas-admin-ui-phone-jR417hPf.mjs.map +1 -0
  91. package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs +235 -0
  92. package/fesm2022/tinya-code-gas-admin-ui-quick-actions-DCQ6emmF.mjs.map +1 -0
  93. package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs +8 -0
  94. package/fesm2022/tinya-code-gas-admin-ui-radio-mode-DxvN07DY.mjs.map +1 -0
  95. package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs +124 -0
  96. package/fesm2022/tinya-code-gas-admin-ui-readonly-text-BL7-4qie.mjs.map +1 -0
  97. package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs +249 -0
  98. package/fesm2022/tinya-code-gas-admin-ui-record-list-BiZfnd_7.mjs.map +1 -0
  99. package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs +39 -0
  100. package/fesm2022/tinya-code-gas-admin-ui-relation-drawer.service-B0kT8EiW.mjs.map +1 -0
  101. package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs +309 -0
  102. package/fesm2022/tinya-code-gas-admin-ui-relation-ykpJ3PYl.mjs.map +1 -0
  103. package/fesm2022/tinya-code-gas-admin-ui-render-registry-B88Pme-y.mjs +576 -0
  104. package/fesm2022/tinya-code-gas-admin-ui-render-registry-B88Pme-y.mjs.map +1 -0
  105. package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs +161 -0
  106. package/fesm2022/tinya-code-gas-admin-ui-rich-select-CIHaOrbU.mjs.map +1 -0
  107. package/fesm2022/tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs +11 -0
  108. package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs +685 -0
  109. package/fesm2022/tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs.map +1 -0
  110. package/fesm2022/tinya-code-gas-admin-ui-seed-DkVZbxPP.mjs +80 -0
  111. package/fesm2022/tinya-code-gas-admin-ui-seed-DkVZbxPP.mjs.map +1 -0
  112. package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs +296 -0
  113. package/fesm2022/tinya-code-gas-admin-ui-select-CDwX9yNO.mjs.map +1 -0
  114. package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs +119 -0
  115. package/fesm2022/tinya-code-gas-admin-ui-skeleton-DnWK0tcZ.mjs.map +1 -0
  116. package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs +158 -0
  117. package/fesm2022/tinya-code-gas-admin-ui-slug-DU58cbiY.mjs.map +1 -0
  118. package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs +26 -0
  119. package/fesm2022/tinya-code-gas-admin-ui-source-options-B9R4mw8-.mjs.map +1 -0
  120. package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs +205 -0
  121. package/fesm2022/tinya-code-gas-admin-ui-status-progress-DmeG8htE.mjs.map +1 -0
  122. package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs +432 -0
  123. package/fesm2022/tinya-code-gas-admin-ui-string-list-gleasqzD.mjs.map +1 -0
  124. package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs +36 -0
  125. package/fesm2022/tinya-code-gas-admin-ui-template-interpolator-ewv7CkNX.mjs.map +1 -0
  126. package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs +107 -0
  127. package/fesm2022/tinya-code-gas-admin-ui-text-CUPmL7W_.mjs.map +1 -0
  128. package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs +223 -0
  129. package/fesm2022/tinya-code-gas-admin-ui-textarea-CGLSIW13.mjs.map +1 -0
  130. package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs +107 -0
  131. package/fesm2022/tinya-code-gas-admin-ui-time-BcHzsTWf.mjs.map +1 -0
  132. package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs +60 -0
  133. package/fesm2022/tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs.map +1 -0
  134. package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs +141 -0
  135. package/fesm2022/tinya-code-gas-admin-ui-url-GO4LZi__.mjs.map +1 -0
  136. package/fesm2022/tinya-code-gas-admin-ui.mjs +4738 -0
  137. package/fesm2022/tinya-code-gas-admin-ui.mjs.map +1 -0
  138. package/package.json +15 -3
  139. package/types/tinya-code-gas-admin-ui.d.ts +3634 -0
  140. package/ng-package.json +0 -7
  141. package/src/lib/actions/action-registry.spec.ts +0 -52
  142. package/src/lib/actions/action-registry.ts +0 -126
  143. package/src/lib/actions/action-service.spec.ts +0 -215
  144. package/src/lib/actions/action-service.ts +0 -87
  145. package/src/lib/actions/descriptors.spec.ts +0 -155
  146. package/src/lib/actions/descriptors.ts +0 -154
  147. package/src/lib/columns/column-cell.ts +0 -33
  148. package/src/lib/columns/column-defaults.spec.ts +0 -99
  149. package/src/lib/columns/column-defaults.ts +0 -84
  150. package/src/lib/columns/column-format.spec.ts +0 -274
  151. package/src/lib/columns/descriptors.ts +0 -113
  152. package/src/lib/columns/format-badge.ts +0 -51
  153. package/src/lib/columns/format-boolean.ts +0 -58
  154. package/src/lib/columns/format-currency.ts +0 -30
  155. package/src/lib/columns/format-date.ts +0 -35
  156. package/src/lib/columns/format-number.ts +0 -32
  157. package/src/lib/columns/format-text.ts +0 -23
  158. package/src/lib/columns/format-thumbnail.ts +0 -63
  159. package/src/lib/core/adapters/firebase-auth.adapter.ts +0 -6
  160. package/src/lib/core/guards/auth.guard.spec.ts +0 -88
  161. package/src/lib/core/guards/auth.guard.ts +0 -48
  162. package/src/lib/core/guards/unsaved-changes.guard.ts +0 -16
  163. package/src/lib/core/interceptors/api-error.interceptor.spec.ts +0 -182
  164. package/src/lib/core/interceptors/api-error.interceptor.ts +0 -87
  165. package/src/lib/core/models/api.model.ts +0 -104
  166. package/src/lib/core/models/schema-descriptions.ts +0 -118
  167. package/src/lib/core/models/schema.model.ts +0 -1097
  168. package/src/lib/core/registry/composition-validator.spec.ts +0 -358
  169. package/src/lib/core/registry/composition-validator.ts +0 -270
  170. package/src/lib/core/registry/field-validators.spec.ts +0 -199
  171. package/src/lib/core/registry/field-validators.ts +0 -440
  172. package/src/lib/core/registry/render-host.spec.ts +0 -208
  173. package/src/lib/core/registry/render-host.ts +0 -646
  174. package/src/lib/core/registry/render-registry.spec.ts +0 -96
  175. package/src/lib/core/registry/render-registry.ts +0 -312
  176. package/src/lib/core/registry/schema-catalog.ts +0 -156
  177. package/src/lib/core/services/api.service.spec.ts +0 -1142
  178. package/src/lib/core/services/api.service.ts +0 -371
  179. package/src/lib/core/services/auth.service.spec.ts +0 -653
  180. package/src/lib/core/services/auth.service.ts +0 -503
  181. package/src/lib/core/services/config.service.spec.ts +0 -121
  182. package/src/lib/core/services/config.service.ts +0 -119
  183. package/src/lib/core/services/data-source.service.spec.ts +0 -179
  184. package/src/lib/core/services/data-source.service.ts +0 -142
  185. package/src/lib/core/services/error-mapper.service.spec.ts +0 -50
  186. package/src/lib/core/services/error-mapper.service.ts +0 -49
  187. package/src/lib/core/services/notification.service.ts +0 -73
  188. package/src/lib/core/services/relation-drawer.service.ts +0 -41
  189. package/src/lib/core/services/theme.service.spec.ts +0 -106
  190. package/src/lib/core/services/theme.service.ts +0 -86
  191. package/src/lib/core/services/transport.spec.ts +0 -198
  192. package/src/lib/core/services/transport.ts +0 -164
  193. package/src/lib/core/services/upload.service.ts +0 -81
  194. package/src/lib/core/testing/categories.schema.ts +0 -125
  195. package/src/lib/core/testing/orders.schema.ts +0 -372
  196. package/src/lib/core/testing/products.schema.ts +0 -258
  197. package/src/lib/core/testing/site.schema.ts +0 -195
  198. package/src/lib/core/testing/test-catalog.ts +0 -21
  199. package/src/lib/core/tokens.ts +0 -112
  200. package/src/lib/core/utils/clipboard.spec.ts +0 -55
  201. package/src/lib/core/utils/clipboard.ts +0 -90
  202. package/src/lib/core/utils/context-resolver.spec.ts +0 -95
  203. package/src/lib/core/utils/context-resolver.ts +0 -101
  204. package/src/lib/core/utils/response-unwrapper.spec.ts +0 -70
  205. package/src/lib/core/utils/response-unwrapper.ts +0 -103
  206. package/src/lib/core/utils/source-options.spec.ts +0 -96
  207. package/src/lib/core/utils/source-options.ts +0 -54
  208. package/src/lib/core/utils/template-interpolator.spec.ts +0 -59
  209. package/src/lib/core/utils/template-interpolator.ts +0 -56
  210. package/src/lib/core/view-navigation/view-navigation.service.spec.ts +0 -207
  211. package/src/lib/core/view-navigation/view-navigation.service.ts +0 -132
  212. package/src/lib/fields/boolean/boolean.descriptor.ts +0 -11
  213. package/src/lib/fields/boolean/boolean.ts +0 -40
  214. package/src/lib/fields/color/color.descriptor.ts +0 -12
  215. package/src/lib/fields/color/color.ts +0 -34
  216. package/src/lib/fields/currency/currency.descriptor.ts +0 -12
  217. package/src/lib/fields/currency/currency.ts +0 -67
  218. package/src/lib/fields/date/date.descriptor.ts +0 -12
  219. package/src/lib/fields/date/date.ts +0 -36
  220. package/src/lib/fields/descriptors.ts +0 -122
  221. package/src/lib/fields/display/display-badge.ts +0 -65
  222. package/src/lib/fields/display/display-date.ts +0 -39
  223. package/src/lib/fields/display/display-defaults.ts +0 -84
  224. package/src/lib/fields/display/display-file.ts +0 -41
  225. package/src/lib/fields/display/display-image.ts +0 -54
  226. package/src/lib/fields/display/display-list.ts +0 -107
  227. package/src/lib/fields/display/display-number.ts +0 -41
  228. package/src/lib/fields/display/display-text.ts +0 -42
  229. package/src/lib/fields/display/display.spec.ts +0 -242
  230. package/src/lib/fields/dropdown/dropdown.descriptor.ts +0 -12
  231. package/src/lib/fields/dropdown/dropdown.ts +0 -45
  232. package/src/lib/fields/email/email.descriptor.ts +0 -12
  233. package/src/lib/fields/email/email.ts +0 -28
  234. package/src/lib/fields/field-aria.ts +0 -60
  235. package/src/lib/fields/field-host/field-host.spec.ts +0 -118
  236. package/src/lib/fields/field-host/field-host.ts +0 -47
  237. package/src/lib/fields/field-node.ts +0 -88
  238. package/src/lib/fields/file/file.descriptor.ts +0 -14
  239. package/src/lib/fields/file/file.spec.ts +0 -134
  240. package/src/lib/fields/file/file.ts +0 -281
  241. package/src/lib/fields/group/group.descriptor.ts +0 -21
  242. package/src/lib/fields/group/group.ts +0 -110
  243. package/src/lib/fields/image/image.descriptor.ts +0 -12
  244. package/src/lib/fields/image/image.spec.ts +0 -117
  245. package/src/lib/fields/image/image.ts +0 -281
  246. package/src/lib/fields/key-value/key-value.descriptor.ts +0 -11
  247. package/src/lib/fields/key-value/key-value.ts +0 -283
  248. package/src/lib/fields/list/list.descriptor.ts +0 -21
  249. package/src/lib/fields/list/list.ts +0 -376
  250. package/src/lib/fields/multiselect/multiselect.descriptor.ts +0 -11
  251. package/src/lib/fields/multiselect/multiselect.spec.ts +0 -142
  252. package/src/lib/fields/multiselect/multiselect.ts +0 -152
  253. package/src/lib/fields/number/number.descriptor.ts +0 -12
  254. package/src/lib/fields/number/number.ts +0 -40
  255. package/src/lib/fields/phone/phone.descriptor.ts +0 -12
  256. package/src/lib/fields/phone/phone.ts +0 -46
  257. package/src/lib/fields/readonly-text/readonly-text.descriptor.ts +0 -12
  258. package/src/lib/fields/readonly-text/readonly-text.ts +0 -58
  259. package/src/lib/fields/relation/relation.descriptor.ts +0 -12
  260. package/src/lib/fields/relation/relation.spec.ts +0 -193
  261. package/src/lib/fields/relation/relation.ts +0 -224
  262. package/src/lib/fields/rich-select/rich-select.descriptor.ts +0 -12
  263. package/src/lib/fields/rich-select/rich-select.ts +0 -175
  264. package/src/lib/fields/select/radio-mode.ts +0 -25
  265. package/src/lib/fields/select/select.descriptor.ts +0 -12
  266. package/src/lib/fields/select/select.spec.ts +0 -162
  267. package/src/lib/fields/select/select.ts +0 -210
  268. package/src/lib/fields/slug/slug.descriptor.ts +0 -19
  269. package/src/lib/fields/slug/slug.ts +0 -67
  270. package/src/lib/fields/string-list/string-list.descriptor.ts +0 -11
  271. package/src/lib/fields/string-list/string-list.ts +0 -222
  272. package/src/lib/fields/text/text.descriptor.ts +0 -12
  273. package/src/lib/fields/text/text.ts +0 -35
  274. package/src/lib/fields/textarea/textarea.descriptor.ts +0 -12
  275. package/src/lib/fields/textarea/textarea.spec.ts +0 -117
  276. package/src/lib/fields/textarea/textarea.ts +0 -126
  277. package/src/lib/fields/time/time.descriptor.ts +0 -12
  278. package/src/lib/fields/time/time.ts +0 -28
  279. package/src/lib/fields/unknown-render/unknown-render.ts +0 -49
  280. package/src/lib/fields/url/url.descriptor.ts +0 -12
  281. package/src/lib/fields/url/url.ts +0 -53
  282. package/src/lib/gas-admin-ui.spec.ts +0 -21
  283. package/src/lib/gas-admin-ui.ts +0 -9
  284. package/src/lib/layouts/descriptors.ts +0 -9
  285. package/src/lib/pages/dashboard/dashboard.ts +0 -167
  286. package/src/lib/pages/detail-view/detail-view.spec.ts +0 -333
  287. package/src/lib/pages/detail-view/detail-view.ts +0 -570
  288. package/src/lib/pages/drawer-form/drawer-form.ts +0 -228
  289. package/src/lib/pages/form-view/form-model.ts +0 -88
  290. package/src/lib/pages/form-view/form-schema.ts +0 -255
  291. package/src/lib/pages/form-view/form-view.ts +0 -1622
  292. package/src/lib/pages/list-view/list-view.formats.spec.ts +0 -214
  293. package/src/lib/pages/list-view/list-view.ts +0 -882
  294. package/src/lib/pages/login/login.spec.ts +0 -109
  295. package/src/lib/pages/login/login.ts +0 -227
  296. package/src/lib/pages/resource-page/resource-page.ts +0 -234
  297. package/src/lib/shared/components/badge/badge.ts +0 -35
  298. package/src/lib/shared/components/button/button.ts +0 -65
  299. package/src/lib/shared/components/confirm-dialog/confirm-dialog.ts +0 -48
  300. package/src/lib/shared/components/copy-button/copy-button.ts +0 -56
  301. package/src/lib/shared/components/copy-share/copy-share.spec.ts +0 -122
  302. package/src/lib/shared/components/copy-share/copy-share.ts +0 -107
  303. package/src/lib/shared/components/drawer/drawer.spec.ts +0 -127
  304. package/src/lib/shared/components/drawer/drawer.ts +0 -172
  305. package/src/lib/shared/components/empty-state/empty-state.ts +0 -30
  306. package/src/lib/shared/components/modal/modal.spec.ts +0 -149
  307. package/src/lib/shared/components/modal/modal.ts +0 -145
  308. package/src/lib/shared/components/post-create-modal/post-create-modal.spec.ts +0 -165
  309. package/src/lib/shared/components/post-create-modal/post-create-modal.ts +0 -159
  310. package/src/lib/shared/components/skeleton/skeleton.ts +0 -31
  311. package/src/lib/shared/components/toast/toast.ts +0 -58
  312. package/src/lib/shared/utils/col-span.ts +0 -25
  313. package/src/lib/shared/utils/condition-evaluator.ts +0 -53
  314. package/src/lib/shared/utils/depends-on.ts +0 -48
  315. package/src/lib/shared/utils/dialog-focus.ts +0 -28
  316. package/src/lib/shared/utils/field-path.ts +0 -49
  317. package/src/lib/shared/utils/gap-sorting.ts +0 -144
  318. package/src/lib/shared/utils/seed.spec.ts +0 -64
  319. package/src/lib/shared/utils/seed.ts +0 -149
  320. package/src/lib/shared/utils/slugify.ts +0 -13
  321. package/src/lib/shared/utils/validators.ts +0 -41
  322. package/src/lib/shell/layout/layout.ts +0 -63
  323. package/src/lib/shell/shell.routes.spec.ts +0 -59
  324. package/src/lib/shell/shell.routes.ts +0 -122
  325. package/src/lib/shell/sidebar/sidebar.ts +0 -139
  326. package/src/lib/shell/theme-toggle/theme-toggle.ts +0 -74
  327. package/src/lib/views/calendar-view/calendar-model.ts +0 -426
  328. package/src/lib/views/calendar-view/calendar-view.spec.ts +0 -557
  329. package/src/lib/views/calendar-view/calendar-view.ts +0 -568
  330. package/src/lib/views/composer/composer-host.spec.ts +0 -301
  331. package/src/lib/views/composer/composer-host.ts +0 -248
  332. package/src/lib/views/composer/composer-imports.spec.ts +0 -54
  333. package/src/lib/views/composer/view-context.spec.ts +0 -117
  334. package/src/lib/views/composer/view-context.ts +0 -109
  335. package/src/lib/views/composer/view-slot.spec.ts +0 -130
  336. package/src/lib/views/composer/view-slot.ts +0 -178
  337. package/src/lib/views/descriptors.ts +0 -46
  338. package/src/lib/views/kanban-view/kanban-model.ts +0 -173
  339. package/src/lib/views/kanban-view/kanban-view.spec.ts +0 -540
  340. package/src/lib/views/kanban-view/kanban-view.ts +0 -327
  341. package/src/lib/widgets/bar-chart/bar-chart.descriptor.ts +0 -17
  342. package/src/lib/widgets/bar-chart/bar-chart.spec.ts +0 -66
  343. package/src/lib/widgets/bar-chart/bar-chart.ts +0 -76
  344. package/src/lib/widgets/chart-line/chart-line.descriptor.ts +0 -17
  345. package/src/lib/widgets/chart-line/chart-line.spec.ts +0 -113
  346. package/src/lib/widgets/chart-line/chart-line.ts +0 -219
  347. package/src/lib/widgets/descriptors.ts +0 -29
  348. package/src/lib/widgets/metric-card/metric-card.descriptor.ts +0 -41
  349. package/src/lib/widgets/metric-card/metric-card.spec.ts +0 -52
  350. package/src/lib/widgets/metric-card/metric-card.ts +0 -48
  351. package/src/lib/widgets/quick-actions/quick-actions.descriptor.ts +0 -13
  352. package/src/lib/widgets/quick-actions/quick-actions.spec.ts +0 -61
  353. package/src/lib/widgets/quick-actions/quick-actions.ts +0 -100
  354. package/src/lib/widgets/record-list/record-list.descriptor.ts +0 -16
  355. package/src/lib/widgets/record-list/record-list.spec.ts +0 -79
  356. package/src/lib/widgets/record-list/record-list.ts +0 -115
  357. package/src/lib/widgets/series.spec.ts +0 -42
  358. package/src/lib/widgets/series.ts +0 -56
  359. package/src/lib/widgets/status-progress/status-progress.descriptor.ts +0 -19
  360. package/src/lib/widgets/status-progress/status-progress.spec.ts +0 -63
  361. package/src/lib/widgets/status-progress/status-progress.ts +0 -104
  362. package/src/lib/widgets/widget-host/widget-host.spec.ts +0 -179
  363. package/src/lib/widgets/widget-host/widget-host.ts +0 -99
  364. package/src/public-api.ts +0 -104
  365. package/tinya-code-gas-admin-ui-0.2.0-alpha.15.tgz +0 -0
  366. package/tsconfig.lib.json +0 -13
  367. package/tsconfig.lib.prod.json +0 -11
  368. package/tsconfig.spec.json +0 -10
@@ -1,646 +0,0 @@
1
- import { NgComponentOutlet } from '@angular/common';
2
- import {
3
- Component,
4
- computed,
5
- effect,
6
- forwardRef,
7
- inject,
8
- InjectionToken,
9
- input,
10
- isDevMode,
11
- PendingTasks,
12
- signal,
13
- viewChild,
14
- type TemplateRef,
15
- type Type,
16
- } from '@angular/core';
17
- import { FormField } from '@angular/forms/signals';
18
- import { LucideCircleAlert } from '@lucide/angular';
19
-
20
- import { FIELD_ARIA, type FieldAriaContext } from '../../fields/field-aria';
21
- import {
22
- childTree,
23
- groupTree,
24
- type ListChildContext,
25
- type RootTree,
26
- } from '../../fields/field-node';
27
- import { FieldFile } from '../../fields/file/file';
28
- import { FieldImage } from '../../fields/image/image';
29
- import { FieldMultiselect } from '../../fields/multiselect/multiselect';
30
- import { esGrupoRadio } from '../../fields/select/radio-mode';
31
- import { displayLoader } from '../../fields/display/display-defaults';
32
- import { UnknownRender } from '../../fields/unknown-render/unknown-render';
33
- import type {
34
- FieldSchema,
35
- FileField,
36
- GroupField,
37
- ImageField,
38
- ListField,
39
- MultiselectField,
40
- SelectField,
41
- WidgetSchema,
42
- } from '../models/schema.model';
43
- import { Skeleton } from '../../shared/components/skeleton/skeleton';
44
- import { colSpanClass } from '../../shared/utils/col-span';
45
- import { getSchema } from './schema-catalog';
46
- import {
47
- get,
48
- isSupported,
49
- RENDER_CONTEXT_VACIO,
50
- resolve,
51
- type RenderConfig,
52
- type RenderContext,
53
- type RenderExtras,
54
- type ComponentRenderKind,
55
- } from './render-registry';
56
-
57
- /**
58
- * El contexto vive en el registro (R3.6): el contrato de `RenderDescriptor.
59
- * inputs` necesita nombrarlo. Se re-exporta acá para que `field-host` y sus
60
- * tests no cambien de domicilio.
61
- */
62
- export type { RenderContext } from './render-registry';
63
-
64
- /** Token con el que los controles inyectan el `RenderContext` del host. */
65
- export const RENDER_CONTEXT = new InjectionToken<RenderContext>('RENDER_CONTEXT');
66
-
67
- /**
68
- * Host genérico de render (R3.4).
69
- *
70
- * Sustituye el `@switch` de 21 ramas de `FieldHost` por una resolución contra
71
- * `core/registry/render-registry.ts`: el tipo llega por `[type]`, el registro
72
- * devuelve el componente y `NgComponentOutlet` lo monta. Añadir un tipo deja
73
- * de tocar este archivo.
74
- *
75
- * Conserva el envoltorio que `FieldHost` dibujaba — `<label>`, marca
76
- * required/opcional, `data-field`, `colSpanClass`, mensaje de error y ayuda —
77
- * porque eso es lo que el operador ve y no depende del tipo de control.
78
- *
79
- * **Sin imports de los 20 controles**: sólo llegan por `load()` perezoso del
80
- * descriptor. Mientras el `import()` resuelve se pinta `Skeleton`, y un tipo
81
- * fuera del catálogo degrada a `UnknownRender` en dev (nunca pantalla rota).
82
- *
83
- * **Modo `display` (R4.1 · R4.2).** El mismo host pinta la ficha de detalle:
84
- * con `mode="display"` no hay árbol, ni etiqueta, ni error — sólo el valor
85
- * crudo que llega por `[value]` y el componente que elige la tabla
86
- * `fields/display/display-defaults.ts`. El descriptor declara la superficie
87
- * (`surfaces: ['form', 'display']`) y, si no la declara o el tipo no está en
88
- * la tabla, corre la misma degradación controlada de R1.10.
89
- */
90
- @Component({
91
- selector: 'app-render-host',
92
- imports: [
93
- FieldFile,
94
- FieldImage,
95
- FieldMultiselect,
96
- FormField,
97
- LucideCircleAlert,
98
- NgComponentOutlet,
99
- RenderHost,
100
- Skeleton,
101
- UnknownRender,
102
- ],
103
- // El envoltorio de render es quien conoce la ayuda y el error —ambos viven
104
- // en SU plantilla—, así que de aquí sale el contexto de accesibilidad y el
105
- // de render, igual que salían de `FieldHost`.
106
- providers: [
107
- { provide: FIELD_ARIA, useExisting: forwardRef(() => RenderHost) },
108
- { provide: RENDER_CONTEXT, useExisting: forwardRef(() => RenderHost) },
109
- ],
110
- template: `
111
- <ng-template #groupContent>
112
- @for (child of group().fields; track child.key) {
113
- <div [class]="colSpan(child.width)">
114
- <app-render-host
115
- [kind]="kind()"
116
- [type]="child.type"
117
- [config]="child"
118
- [ctx]="groupChildCtx()"
119
- />
120
- </div>
121
- }
122
- </ng-template>
123
-
124
- <ng-template #childTpl let-child>
125
- @for (sub of child.fields; track sub.key) {
126
- <div [class]="child.row ? 'min-w-0 grow' : colSpan(sub.width)">
127
- <app-render-host
128
- [kind]="kind()"
129
- [type]="sub.type"
130
- [config]="sub"
131
- [ctx]="listChildCtx(child)"
132
- />
133
- </div>
134
- }
135
- </ng-template>
136
-
137
- @if (esDisplay()) {
138
- <!-- Rama de display (R4.1 · R4.2): sólo el valor crudo. El host no
139
- lee el árbol, no dibuja etiqueta ni error y no conoce la
140
- sección: detail-view agrupa y este bloque pinta. -->
141
- @if (vacio()) {
142
- <span aria-hidden="true">—</span>
143
- } @else if (soportaDisplay()) {
144
- @if (control()) {
145
- <ng-container
146
- [ngComponentOutlet]="control()"
147
- [ngComponentOutletInputs]="displayInputs()"
148
- />
149
- } @else {
150
- <app-skeleton [lines]="1" [height]="20" />
151
- }
152
- } @else if (showUnknown()) {
153
- <app-unknown-render [type]="type()" [label]="config().label" />
154
- }
155
- } @else if (supported()) {
156
- @if (esCampo()) {
157
- <div class="mb-4" [class.field-enter]="cfgCampo().visibleWhen" [attr.data-field]="name()">
158
- @if (type() !== 'group') {
159
- @if (composite()) {
160
- <!-- Sin control único no existe ancla para el atributo for del
161
- label: apuntaría a un id inexistente. Se dibuja como texto
162
- (en listas/key-value los hijos reciben su etiqueta por
163
- campo anidado; en un select en modo radio cada opción
164
- trae su label implícito y el grupo va con aria-label). -->
165
- <div class="mb-1 text-label font-medium">
166
- {{ config().label }}
167
- @if (showRequiredMark()) {
168
- <span aria-hidden="true" class="text-danger">*</span>
169
- }
170
- @if (showOptionalMark()) {
171
- <span class="font-normal text-neutral">(opcional)</span>
172
- }
173
- </div>
174
- } @else {
175
- <label [for]="name()" class="mb-1 block text-label font-medium">
176
- {{ config().label }}
177
- @if (showRequiredMark()) {
178
- <span aria-hidden="true" class="text-danger">*</span>
179
- }
180
- @if (showOptionalMark()) {
181
- <span class="font-normal text-neutral">(opcional)</span>
182
- }
183
- </label>
184
- }
185
- }
186
-
187
- @if (type() === 'multiselect') {
188
- <!-- Tres de los veintiuno no pueden pasar por "NgComponentOutlet": su
189
- sincronización con Signal Forms vive en ɵɵcontrol, una
190
- instrucción que el compilador emite únicamente junto al binding
191
- formField de la propia plantilla. Sin ese binding escrito en el
192
- HTML el model() de value nunca se inicializa y el control lanza
193
- NG0952. Se declaran a mano (D27) y el resto de tipos siguen
194
- saliendo del registro. -->
195
- <app-field-multiselect
196
- [id]="name()"
197
- [field]="multiselectCfg()"
198
- [formField]="multiselectNode()"
199
- [tree]="ctx().tree"
200
- />
201
- } @else if (type() === 'image') {
202
- <app-field-image
203
- [id]="name()"
204
- [field]="imageCfg()"
205
- [formField]="imageNode()"
206
- [resource]="ctx().resource"
207
- />
208
- } @else if (type() === 'file') {
209
- <app-field-file
210
- [id]="name()"
211
- [field]="fileCfg()"
212
- [formField]="fileNode()"
213
- [resource]="ctx().resource"
214
- />
215
- } @else {
216
- @if (control()) {
217
- <ng-container
218
- [ngComponentOutlet]="control()"
219
- [ngComponentOutletInputs]="controlInputs()"
220
- />
221
- } @else {
222
- <app-skeleton [lines]="2" [height]="32" />
223
- }
224
- }
225
-
226
- @if (errorMessage(); as message) {
227
- <p
228
- [id]="errorId()"
229
- class="mt-1 flex items-center gap-1 text-help text-danger"
230
- role="alert"
231
- >
232
- <svg lucideCircleAlert size="14" class="shrink-0" />
233
- {{ message }}
234
- </p>
235
- } @else if (cfgCampo().help; as help) {
236
- <p [id]="helpId()" class="mt-1 text-help text-neutral">{{ help }}</p>
237
- }
238
- </div>
239
- } @else {
240
- <!-- Rama de widget (R3.6): el mismo outlet y el mismo cableado que
241
- un campo, pero sin el envoltorio — un widget no tiene etiqueta
242
- asociada, ni marca required, ni error, ni ayuda. El ancho en la
243
- grilla lo pone su host (app-widget-host), no el motor. -->
244
- @if (control()) {
245
- <ng-container
246
- [ngComponentOutlet]="control()"
247
- [ngComponentOutletInputs]="controlInputs()"
248
- />
249
- } @else {
250
- <app-skeleton [lines]="2" [height]="32" />
251
- }
252
- }
253
- } @else if (showUnknown()) {
254
- <!-- R1.10: degradación controlada. Un tipo fuera del catálogo no
255
- revienta; en dev se avisa y en producción sólo se omite. -->
256
- <app-unknown-render [type]="type()" [label]="config().label" />
257
- }
258
- `,
259
- })
260
- export class RenderHost implements FieldAriaContext, RenderContext {
261
- /** Categoría de render. Resuelve campos y widgets (R3.6). */
262
- readonly kind = input<ComponentRenderKind>('field');
263
- /** Identificador del tipo dentro de su `kind`. */
264
- readonly type = input.required<string>();
265
- /**
266
- * Configuración del descriptor: el `FieldSchema` del campo, el
267
- * `WidgetSchema` del widget o la `ListColumn` de la columna (R4.3).
268
- */
269
- readonly config = input.required<RenderConfig>();
270
- /**
271
- * Contexto de render del nivel de este campo.
272
- *
273
- * Con valor por defecto y no requerido: los widgets no pertenecen a un
274
- * formulario y llegan sin árbol (R3.6). El default es un contexto vacío
275
- * que nunca se lee en esa rama — un campo montado sin contexto real ya
276
- * era un error antes y `childTree` lo sigue siendo.
277
- */
278
- readonly ctx = input<RenderContext>(RENDER_CONTEXT_VACIO);
279
- /** Payload del widget (`app-widget-host [data]`). `null` en campos. */
280
- readonly data = input<unknown>(null);
281
- /**
282
- * Superficie de render (R4.1).
283
- *
284
- * `'form'` (por defecto) es el formulario de siempre: árbol, etiqueta,
285
- * marca required, error y ayuda. `'display'` es la ficha de detalle:
286
- * valor crudo, sin envoltorio — es el `mode="display"` con el que
287
- * `detail-view` deja de dibujar sus propias celdas (R4.2).
288
- */
289
- readonly mode = input<'form' | 'display'>('form');
290
- /**
291
- * Valor crudo del registro, **sólo para el modo `display`**.
292
- *
293
- * En el formulario el valor vive en el árbol de Signal Forms y este
294
- * input se ignora: un campo de detalle no tiene árbol que consultar.
295
- */
296
- readonly value = input<unknown>(null);
297
- /**
298
- * Presentación en chip, **sólo para el modo `display`** (R4.2).
299
- *
300
- * La cabecera de la ficha siempre mostró `headerFields` como etiquetas
301
- * compactas, aunque el valor fuera texto plano. Sin este matiz el host
302
- * pintaría «ORD-42» como texto suelto y la cabecera cambiaría de cara en
303
- * los 7 detalles. El aviso va en el contrato de entrada de los display —
304
- * uniforme para los 6 — y sólo lo aprovechan los que dibujan texto: los
305
- * que ya son chip (`badge`) o no son un valor escalar (`image`, `list`)
306
- * lo ignoran a propósito.
307
- */
308
- readonly chip = input(false);
309
-
310
- private readonly dev = isDevMode();
311
-
312
- /** Mantiene `whenStable()` bloqueado mientras el descriptor carga su chunk. */
313
- private readonly pendientes = inject(PendingTasks);
314
-
315
- /** `true` cuando se dibuja un campo, `false` para cualquier otro `kind`. */
316
- protected readonly esCampo = computed(() => this.kind() === 'field');
317
-
318
- /** `true` en la rama de detalle (R4.1): sin árbol, etiqueta ni error. */
319
- protected readonly esDisplay = computed(() => this.mode() === 'display');
320
-
321
- /**
322
- * ¿El descriptor declara la superficie `display`? (R4.1)
323
- *
324
- * Es la respuesta a «cada descriptor de campo declara si sabe pintarse en
325
- * `display`»: sin esa declaración el host no pinta el valor en la ficha,
326
- * y `contract.spec.ts` vigila que los 20 la traigan.
327
- */
328
- private readonly declaraDisplay = computed(
329
- () => get(this.kind(), this.type())?.surfaces?.includes('display') ?? false,
330
- );
331
-
332
- /**
333
- * Componente que pinta este tipo en `display`.
334
- *
335
- * El descriptor sólo dice **si** sabe pintarse; **qué** componente usa lo
336
- * decide la tabla por tipo (`fields/display/display-defaults.ts`), que es
337
- * la que garantiza que el mismo `field.type` se pinte igual en todas las
338
- * fichas.
339
- */
340
- private readonly loaderDisplay = computed(() =>
341
- this.declaraDisplay() ? displayLoader(this.type()) : undefined,
342
- );
343
-
344
- /** El modo display tiene componente para este tipo. */
345
- protected readonly soportaDisplay = computed(() => this.loaderDisplay() !== undefined);
346
-
347
- /**
348
- * Valor vacío, con el mismo criterio que `formatValue` de `detail-view`
349
- * antes de R4.2 (`null`, `undefined` o `''`): se pinta un `—` y el
350
- * componente ni se monta. `false`, `0` y `[]` **no** están vacíos.
351
- */
352
- protected readonly vacio = computed(() => {
353
- const valor = this.value();
354
- return valor === null || valor === undefined || valor === '';
355
- });
356
-
357
- /** Configuración leída como campo. Sólo válida en la rama de campo. */
358
- private readonly cfgCampo = computed(() => this.config() as FieldSchema);
359
-
360
- private readonly node = computed(() => childTree<unknown>(this.ctx().tree, this.cfgCampo().key));
361
-
362
- protected readonly state = computed(() => this.node()());
363
-
364
- /** Nombre del control: ancla del `<label for>` y base de `*-help`/`*-error`. */
365
- protected readonly name = computed(() => this.state().name());
366
-
367
- /**
368
- * Fuera del catálogo o oculto por `visibleWhen`: no se dibuja.
369
- *
370
- * El `isSupported` va primero y corta antes de leer `state()`: un tipo
371
- * desconocido se siembra como `undefined`, Signal Forms no le crea nodo y
372
- * `childTree` lanzaría «El formulario no contiene el campo».
373
- *
374
- * El `esCampo()` corta lo mismo para los widgets: no hay árbol que ocultar
375
- * ni nodo que consultar, así que el widget se dibuja si está en el
376
- * catálogo y ya.
377
- */
378
- protected readonly supported = computed(() => {
379
- if (!isSupported(this.kind(), this.type())) {
380
- return false;
381
- }
382
- return this.esCampo() ? !this.state().hidden() : true;
383
- });
384
-
385
- /**
386
- * Sin renderizador para este tipo **en la superficie actual**.
387
- *
388
- * En `display`: el descriptor no declara la superficie o el tipo no está
389
- * en la tabla de display. En `form`: sigue siendo «fuera del catálogo».
390
- * Ninguna de las dos ramas toca `state()`, que en display no existe.
391
- */
392
- private readonly unsupported = computed(() =>
393
- this.esDisplay() ? !this.soportaDisplay() : !isSupported(this.kind(), this.type()),
394
- );
395
-
396
- protected readonly showUnknown = computed(() => this.unsupported() && this.dev);
397
-
398
- private readonly _trazaTipoDesconocido = effect(() => {
399
- if (!this.unsupported() || this.dev) return;
400
- const superficie = this.esDisplay() ? 'display' : 'form';
401
- console.warn(
402
- `[render-host] tipo sin renderizador (${superficie}): "${this.type()}" — se omite el control.`,
403
- );
404
- });
405
-
406
- // ── Resolución del componente ────────────────────────────────────────────
407
-
408
- /** Componente montado, o `null` mientras el `load()` perezoso resuelve. */
409
- private readonly control = signal<Type<unknown> | null>(null);
410
-
411
- /** Descarta cargas obsoletas cuando el tipo cambia antes de que resuelva. */
412
- private carga = 0;
413
-
414
- private readonly _cargar = effect(() => {
415
- const type = this.type();
416
- const carga = ++this.carga;
417
- this.control.set(null);
418
-
419
- // Modo display (R4.1): el componente sale de la tabla por tipo, no del
420
- // `load()` del descriptor — la tabla es la que garantiza que un mismo
421
- // `field.type` se pinte igual en todas las fichas.
422
- if (this.esDisplay()) {
423
- const loader = this.loaderDisplay();
424
- if (!loader) return;
425
- this.pendientes.run(async () => {
426
- const componente = await loader();
427
- if (this.carga === carga) this.control.set(componente);
428
- });
429
- return;
430
- }
431
-
432
- if (!isSupported(this.kind(), type)) return;
433
- // El `load()` del descriptor es un `import()` de chunk, que `whenStable()`
434
- // NO espera por sí solo (queda fuera del ciclo de estabilidad y el control
435
- // llegaría tarde a un `detectChanges()` posterior). Registrándolo como
436
- // tarea pendiente la estabilidad cubre la carga: el skeleton se pinta
437
- // mientras baja y el control aparece en el siguiente ciclo ya montado.
438
- this.pendientes.run(async () => {
439
- const componente = await resolve(this.kind(), type, UnknownRender);
440
- if (this.carga === carga) this.control.set(componente);
441
- });
442
- });
443
-
444
- /**
445
- * Inputs del componente de display.
446
- *
447
- * Forma fija y uniforme para los 6 componentes de
448
- * `fields/display/`: `field` (el `FieldSchema` completo, para los que
449
- * necesitan `options`), `value` (el valor crudo) y `chip` (la
450
- * presentación de la cabecera). El descriptor no interviene acá — en
451
- * display no hay ni control ni árbol que cablear.
452
- */
453
- private readonly displayInputs = computed<Record<string, unknown>>(() => ({
454
- field: this.config() as FieldSchema,
455
- value: this.value(),
456
- chip: this.chip(),
457
- }));
458
-
459
- /**
460
- * Inputs del componente montado.
461
- *
462
- * El motor no sabe qué recibe cada tipo: pregunta al descriptor (`inputs`)
463
- * y sólo aplica la forma estándar del `kind` cuando el descriptor no la
464
- * sobreescribe — `{field, tree}` en campos, `{widget, data}` en widgets.
465
- * Ésa es la pieza que hace que «añadir un tipo» no toque este archivo
466
- * (R3.8). `multiselect` e `image` no pasan por aquí: se declaran a mano
467
- * por D27.
468
- */
469
- private readonly controlInputs = computed<Record<string, unknown>>(() => {
470
- const cfg = this.config();
471
- const extras: RenderExtras = {
472
- ctx: this.ctx(),
473
- data: this.data(),
474
- groupContent: this.groupTpl(),
475
- childTemplate: this.childTpl(),
476
- };
477
-
478
- const descriptor = get(this.kind(), this.type());
479
- if (descriptor?.inputs) {
480
- return descriptor.inputs(cfg, extras);
481
- }
482
-
483
- return this.esCampo()
484
- ? { field: cfg as FieldSchema, tree: this.ctx().tree }
485
- : { widget: cfg, data: this.data() };
486
- });
487
-
488
- // ── Recursión de los tipos compuestos ────────────────────────────────────
489
-
490
- protected readonly group = computed(() => this.config() as GroupField);
491
- protected readonly list = computed(() => this.config() as ListField);
492
-
493
- private readonly groupTpl = viewChild<TemplateRef<unknown>>('groupContent');
494
- private readonly childTpl = viewChild<TemplateRef<unknown>>('childTpl');
495
-
496
- /** Subárbol y prefijo que heredan los hijos del grupo. */
497
- protected readonly groupChildCtx = computed<RenderContext>(() => ({
498
- ...this.ctx(),
499
- tree: groupTree(this.ctx().tree, this.config().key),
500
- pathPrefix: `${this.ctx().pathPrefix}${this.config().key}.`,
501
- }));
502
-
503
- protected listChildCtx(child: ListChildContext): RenderContext {
504
- return {
505
- tree: child.tree,
506
- serverErrors: child.errors,
507
- pathPrefix: child.prefix,
508
- exists: child.exists,
509
- resource: this.ctx().resource,
510
- };
511
- }
512
-
513
- /** `sm:col-span-*` compartido con el grupo (literales: Tailwind v4 es JIT). */
514
- colSpan(width?: number): string {
515
- return colSpanClass(width);
516
- }
517
-
518
- // ── Envoltorio: label, marcas y estado ───────────────────────────────────
519
-
520
- /**
521
- * Los tres `FormValueControl` se declaran en la plantilla (D27), así que
522
- * su campo necesita el tipo estrecho que exige cada input — el mismo
523
- * estrechado que hacía `FieldHost`.
524
- */
525
- protected readonly multiselectCfg = computed(() => this.config() as MultiselectField);
526
-
527
- protected readonly imageCfg = computed(() => this.config() as ImageField);
528
-
529
- protected readonly fileCfg = computed(() => this.config() as FileField);
530
-
531
- private readonly multiselectNode = computed(() =>
532
- childTree<string[]>(this.ctx().tree, this.config().key),
533
- );
534
-
535
- private readonly imageNode = computed(() =>
536
- childTree<string>(this.ctx().tree, this.config().key),
537
- );
538
-
539
- private readonly fileNode = computed(() => childTree<string>(this.ctx().tree, this.config().key));
540
-
541
- /**
542
- * Error visible: primero el del backend (si existe para esta ruta) y
543
- * después el propio, solo cuando el campo ya se tocó (validación al
544
- * perder el foco).
545
- */
546
- protected readonly errorMessage = computed<string | null>(() => {
547
- const serverError = this.ctx().serverErrors[`${this.ctx().pathPrefix}${this.config().key}`];
548
- if (serverError) {
549
- return serverError;
550
- }
551
- const state = this.state();
552
- if (!state.invalid() || !state.touched()) {
553
- return null;
554
- }
555
- return state.errors()[0]?.message ?? 'Revisa este campo.';
556
- });
557
-
558
- /**
559
- * Compuestos: varios controles internos, ninguno único. Para ellos
560
- * `<label for>` no tendría ancla, porque ningún elemento lleva el id del
561
- * campo padre (los hijos tienen los suyos propios).
562
- */
563
- protected readonly composite = computed(() => {
564
- const cfg = this.cfgCampo();
565
- if (new Set(['list', 'key-value', 'string-list', 'multiselect']).has(cfg.type)) {
566
- return true;
567
- }
568
- // Un select en modo radio (2–4 opciones estáticas) tampoco tiene ancla
569
- // única: el grupo se nombra con `aria-label`, así que su rótulo va como
570
- // texto. El cálculo vive en `radio-mode.ts` y lo comparte con el campo
571
- // para que las dos ramas nunca se desincronicen.
572
- return cfg.type === 'select' && esGrupoRadio(cfg as SelectField);
573
- });
574
-
575
- // Contexto de accesibilidad consumido por `FieldAria` en los controles.
576
-
577
- /**
578
- * Ancla de la ayuda, sólo mientras no hay error: §2 dice que el error
579
- * **reemplaza** la ayuda, de modo que el id no puede apuntar a un nodo
580
- * que ya no está en el DOM.
581
- */
582
- readonly helpId = computed(() =>
583
- this.cfgCampo().help && !this.errorMessage() ? `${this.name()}-help` : null,
584
- );
585
-
586
- readonly errorId = computed(() => (this.errorMessage() ? `${this.name()}-error` : null));
587
-
588
- readonly describedBy = computed(
589
- () => [this.helpId(), this.errorId()].filter(Boolean).join(' ') || null,
590
- );
591
-
592
- /** Mismo criterio que `errorMessage()` — el estado del control no es público. */
593
- readonly invalid = computed(() => this.errorMessage() !== null);
594
-
595
- readonly required = computed(() => this.cfgCampo().required ?? false);
596
-
597
- // §2: "si casi todos son obligatorios, marcar los opcionales con
598
- // «(opcional)»" en vez de sembrar `*` por todo el formulario.
599
-
600
- private readonly schema = computed(() => getSchema(this.ctx().resource));
601
-
602
- /**
603
- * Se decide una vez por recurso y se aplica a todos los niveles: es un
604
- * juicio de diseño sobre el formulario, no sobre un campo suelto. Contado
605
- * por nivel (sólo top-level) — un conteo plano mezcla los subcampos de
606
- * `group`/`list` y da ratios imposibles.
607
- */
608
- protected readonly markOptionals = computed(() => {
609
- const fields = this.schema()?.fields ?? [];
610
- if (fields.length === 0) {
611
- return false;
612
- }
613
- const required = fields.filter((field) => field.required).length;
614
- return required / fields.length >= 0.75;
615
- });
616
-
617
- protected readonly showRequiredMark = computed(
618
- () => !this.markOptionals() && this.cfgCampo().required,
619
- );
620
-
621
- protected readonly showOptionalMark = computed(
622
- () => this.markOptionals() && !this.cfgCampo().required,
623
- );
624
-
625
- // ── RenderContext (por DI) ───────────────────────────────────────────────
626
-
627
- get tree(): RootTree {
628
- return this.ctx().tree;
629
- }
630
-
631
- get serverErrors(): Record<string, string> {
632
- return this.ctx().serverErrors;
633
- }
634
-
635
- get pathPrefix(): string {
636
- return this.ctx().pathPrefix;
637
- }
638
-
639
- get exists(): boolean {
640
- return this.ctx().exists;
641
- }
642
-
643
- get resource(): string {
644
- return this.ctx().resource;
645
- }
646
- }