@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,1097 +0,0 @@
1
- /**
2
- * Modelos del schema de recursos — única fuente de verdad de la UI.
3
- * Especificación: doc/base.md §3–§7 y §9.
4
- *
5
- * Contrato de imágenes (decisión api.md §1): `image_url` en todo el JSON.
6
- */
7
-
8
- /** Anchos de columna dentro de una fila del layout (base.md §4: 1–12). */
9
- export type GridWidth = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
10
-
11
- /** Operadores de `visibleWhen` / `readonlyWhen` (base.md §4). */
12
- export type ConditionOperator = 'eq' | 'ne' | 'empty' | 'contains';
13
-
14
- /**
15
- * Condición simple sobre otro campo del mismo nivel o del registro raíz.
16
- * Ej.: `{ field: 'availability', operator: 'eq', value: 'PreOrder' }`.
17
- */
18
- export interface FieldCondition {
19
- field: string;
20
- operator: ConditionOperator;
21
- /** Valor de comparación; no aplica para `empty`. */
22
- value?: string | number | boolean;
23
- }
24
-
25
- /**
26
- * Reglas de validación comunes (base.md §4).
27
- * Nota: algunas se solapan con opciones propias del tipo (§5); el motor de
28
- * validación (Fase 10) los fusiona y `validators` tiene prioridad.
29
- */
30
- export interface FieldValidators {
31
- minLength?: number;
32
- maxLength?: number;
33
- pattern?: string;
34
- min?: number;
35
- max?: number;
36
- minWords?: number;
37
- maxWords?: number;
38
- /** El valor debe ser único en el recurso (validación asíncrona). */
39
- unique?: boolean;
40
- }
41
-
42
- /** Propiedades comunes a todo campo (base.md §4). */
43
- export interface FieldBase<T> {
44
- /** Nombre de la propiedad en el JSON que envía/recibe el back. */
45
- key: string;
46
- /** Rótulo visible para el usuario en el formulario y la ficha. */
47
- label: string;
48
- /** Texto corto de ayuda que se muestra debajo del campo. */
49
- help?: string;
50
- /** Texto sugerente que se muestra dentro del input cuando está vacío. */
51
- placeholder?: string;
52
- /** Si es obligatorio. El back también lo valida (R7.4). */
53
- required?: boolean;
54
- /** Valor por defecto si el registro no trae este campo (ej. `default: 'none'` en un `select`/`dropdown`). */
55
- default?: T;
56
- /** Si el campo es solo lectura (no editable en el formulario). */
57
- readonly?: boolean;
58
- /** Bloquea el campo solo en creación, solo en edición o siempre. */
59
- readonlyOn?: 'create' | 'update' | 'always';
60
- /** Condición bajo la cual el campo es solo lectura (expresión sobre otros campos). */
61
- readonlyWhen?: FieldCondition;
62
- /** Condición bajo la cual el campo se muestra u oculta. */
63
- visibleWhen?: FieldCondition;
64
- /**
65
- * Ciclo de vida de la VISIBILIDAD: oculta el campo en creación, en edición
66
- * o siempre. Símétrico a `readonlyOn`, pero NO lo mismo que `visibleWhen`,
67
- * que expresa una condición sobre el valor de otro campo.
68
- *
69
- * Vale para los campos que LLENA EL BACK (`ref`, `pin`): en alta no existen
70
- * aún, así que mostrarlos vacíos y solo-lectura con un `help` que dice "se
71
- * genera solo al guardar" es ruido ocupando la sección. `hidden()` de Signal
72
- * Forms además los deja FUERA de la validación y del payload
73
- * (field-host:311 no los dibuja, form-model:52 los salta).
74
- */
75
- hiddenOn?: 'create' | 'update' | 'always';
76
- /**
77
- * Selección dependiente (guía §1: país → ciudad). Clave del campo padre
78
- * del MISMO nivel: mientras el padre esté vacío este campo queda
79
- * `disabled`, y si el padre cambia el hijo se reinicia a su valor por
80
- * defecto (plan 6.6).
81
- */
82
- dependsOn?: string;
83
- /** Reglas de validación (mínimo, máximo, patrón, unicidad, etc.). */
84
- validators?: FieldValidators;
85
- /** Ancho en la grilla del formulario (1–12), igual que un widget del dashboard. */
86
- width?: GridWidth;
87
- /** Id de la sección/pestaña del layout a la que pertenece (base.md §4). */
88
- section?: string;
89
- /**
90
- * R7.5: acceso por campo (B8 · R7.4b) — sólo UX; el back vuelve a
91
- * verificar en cada petición.
92
- */
93
- access?: {
94
- /** Código de nivel de acceso requerido para leer el campo. */
95
- read?: string;
96
- /** Código de nivel de acceso requerido para escribir el campo. */
97
- write?: string;
98
- };
99
- /**
100
- * Descripción corta de para qué sirve este campo. Se muestra como tooltip
101
- * al pasar el cursor sobre el rótulo en el formulario y la ficha.
102
- */
103
- description?: string;
104
- /** URL de documentación externa para este campo (se abre al hacer clic en el tooltip). */
105
- docLink?: string;
106
- }
107
-
108
- // ─────────────────────────────────────────────────────────────
109
- // §5.1 Campos simples (valor escalar)
110
- // ─────────────────────────────────────────────────────────────
111
-
112
- export interface SelectOption {
113
- value: string;
114
- label: string;
115
- disabled?: boolean;
116
- }
117
-
118
- export interface TextField extends FieldBase<string> {
119
- type: 'text';
120
- maxLength?: number;
121
- pattern?: string;
122
- }
123
-
124
- export interface ColorField extends FieldBase<string> {
125
- type: 'color';
126
- }
127
-
128
- export interface TextareaField extends FieldBase<string> {
129
- type: 'textarea';
130
- rows?: number;
131
- minWords?: number;
132
- maxWords?: number;
133
- /**
134
- * Marcadores insertables como chips bajo el área (plantillas de mensaje).
135
- * Cada chip escribe `{key}` en la posición del cursor, no al final: el
136
- * operador escribe, apreta, sigue escribiendo. El motor back no se entera —
137
- * recibe el string final y lo interpola (`interpolateTemplate`).
138
- *
139
- * `label` es el rótulo humano del botón ("PIN"); `key` es la clave que se
140
- * inserta y que el back resuelve contra `config + registro`.
141
- */
142
- tokens?: readonly TemplateToken[];
143
- }
144
-
145
- /** Chip insertable en un `textarea` de plantilla. */
146
- export interface TemplateToken {
147
- /** Clave insertada como `{key}` y resuelta por el motor. */
148
- key: string;
149
- /** Rótulo visible en el chip (el token va como tooltip). */
150
- label: string;
151
- }
152
-
153
- export interface SlugField extends FieldBase<string> {
154
- type: 'slug';
155
- /** Campo del que se autogenera el slug (ej. `name`). */
156
- from: string;
157
- /** Bloquea el campo una vez creado el registro (por defecto: sí). */
158
- lockAfterCreate?: boolean;
159
- }
160
-
161
- export interface NumberField extends FieldBase<number> {
162
- type: 'number';
163
- min?: number;
164
- max?: number;
165
- step?: number;
166
- decimals?: number;
167
- }
168
-
169
- export interface CurrencyField extends FieldBase<number> {
170
- type: 'currency';
171
- /** Campo del registro del que se toma la moneda (ej. `currency`). */
172
- currencyFrom?: string;
173
- }
174
-
175
- export interface BooleanField extends FieldBase<boolean> {
176
- type: 'boolean';
177
- trueLabel?: string;
178
- falseLabel?: string;
179
- }
180
-
181
- /**
182
- * De dónde salen las opciones de un desplegable: **exactamente una** de las
183
- * dos formas (XOR en el tipo, D62).
184
- *
185
- * - `options` — estáticas en el schema (el caso de las enums: `status`).
186
- * - `source` — pedidas al fetcher declarado (F8 · R6.5) para listados que
187
- * viven en otro recurso.
188
- *
189
- * Ninguna ⇒ un desplegable mudo; las dos ⇒ dos verdades para el mismo campo.
190
- * Ambas reglas viven en este tipo, no en un chequeo en runtime.
191
- */
192
- type SelectData =
193
- { options: SelectOption[]; source?: never } | { options?: never; source: DataSource };
194
-
195
- export type SelectField = FieldBase<string> & { type: 'select' } & SelectData;
196
-
197
- export type MultiselectField = FieldBase<string[]> & { type: 'multiselect' } & SelectData;
198
-
199
- /**
200
- * Desplegable nativo (`<select>`) que SIEMPRE se renderiza como lista
201
- * desplegable, independientemente de cuántas opciones tenga.
202
- *
203
- * A diferencia de `select` (que usa radio buttons para 2–4 opciones
204
- * estáticas por la guía de control §1), este tipo nunca muta a radios.
205
- * Úsalo cuando necesites un dropdown verdadero aunque tenga pocas opciones.
206
- */
207
- export interface DropdownField extends FieldBase<string> {
208
- type: 'dropdown';
209
- options: SelectOption[];
210
- }
211
-
212
- /**
213
- * Opción de un selector visual enriquecido (`rich-select`).
214
- *
215
- * Además de `value`/`label`, cada opción puede declarar una `preview` con
216
- * HTML seguro que el motor renderiza como tarjeta visual (badge, chip con
217
- * icono, color swatch, etc.). El HTML viaja en el schema y el motor lo
218
- * pinta tal cual tras pasar por el sanitizador de Angular.
219
- */
220
- export interface RichSelectOption {
221
- value: string;
222
- label: string;
223
- disabled?: boolean;
224
- /** HTML seguro para pintar como preview de la opción (ej. `<span class="chip">…</span>`). */
225
- preview?: string;
226
- }
227
-
228
- /**
229
- * Selector visual enriquecido: cada opción se renderiza como tarjeta con su
230
- * `preview` HTML en vez de un `<select>` nativo o radio buttons planos.
231
- * Sólo opciones estáticas (sin `source`).
232
- */
233
- export interface RichSelectField extends FieldBase<string> {
234
- type: 'rich-select';
235
- options: RichSelectOption[];
236
- /**
237
- * Ancho de cada tarjeta de opción en la grilla (1–12), igual que `width`
238
- * de un campo. Por defecto `4` (3 tarjetas por fila en escritorio).
239
- * Úsalo para opciones con preview larga (menos tarjetas por fila) o
240
- * preview corta (más tarjetas).
241
- */
242
- cardWidth?: GridWidth;
243
- /**
244
- * Cuántas tarjetas mostrar por fila en el punto de ruptura `lg`.
245
- * Sobrescribe el cálculo automático basado en `cardWidth`.
246
- * Ejemplo: `2` obliga a 2 columnas grandes sin importar el ancho.
247
- */
248
- cardCols?: 1 | 2 | 3 | 4 | 5 | 6;
249
- }
250
-
251
- export interface UrlField extends FieldBase<string> {
252
- type: 'url';
253
- }
254
-
255
- export interface EmailField extends FieldBase<string> {
256
- type: 'email';
257
- }
258
-
259
- export interface PhoneField extends FieldBase<string> {
260
- type: 'phone';
261
- /** Normalización del valor guardado. */
262
- format?: 'e164' | 'digits';
263
- }
264
-
265
- export interface DateField extends FieldBase<string> {
266
- type: 'date';
267
- /** Fecha ISO `YYYY-MM-DD` permitida. */
268
- min?: string;
269
- max?: string;
270
- }
271
-
272
- export interface TimeField extends FieldBase<string> {
273
- type: 'time';
274
- }
275
-
276
- export interface ReadonlyTextField extends FieldBase<string> {
277
- type: 'readonly-text';
278
- /** Formato de presentación (texto, fecha, moneda…). */
279
- format?: string;
280
- }
281
-
282
- // ─────────────────────────────────────────────────────────────
283
- // §5.2 Referencias
284
- // ─────────────────────────────────────────────────────────────
285
-
286
- /**
287
- * Fuente de datos declarada (F8 · R6.5): UN vocabulario para relations,
288
- * selects y widgets en lugar de tres. El fetcher es único
289
- * (`DataSourceService`) y la clave de su caché es `resource+view+params`.
290
- *
291
- * `params` son valores interpolados `{campo}` que el front resuelve contra su
292
- * contexto (el registro del formulario o la fila del widget) y manda como
293
- * `payload.params`; el back los inyecta en el ctx de las vistas, donde una
294
- * condición los lee con el operando `param: '<nombre>'`. Una vista que no
295
- * referencia ese parámetro no se ve afectada por él — sólo cambia la clave
296
- * de caché.
297
- *
298
- * Los parámetros llegan del navegador, así que son ENTRADA: sólo filtran
299
- * dentro del recurso que la ruta ya autoriza a leer (nunca ensanchan el
300
- * acceso) y una vista que pide un parámetro ausente queda fail-closed.
301
- */
302
- export interface DataSource {
303
- /** Recurso declarado (`resource.id`): su listado es el de las opciones. */
304
- resource: string;
305
- /** Vista declarada en `resource.views` (opcional): filtra en el back. */
306
- view?: string;
307
- /** Valores interpolados para la vista (`{campo}` ← contexto). */
308
- params?: Record<string, string>;
309
- /** Etiqueta por defecto de las filas (si no, `titleField` del recurso). */
310
- labelField?: string;
311
- /** Valor por defecto de las filas (si no, `keyField` del recurso). */
312
- valueField?: string;
313
- }
314
-
315
- export interface RelationField extends FieldBase<string> {
316
- type: 'relation';
317
- /**
318
- * De dónde salen las opciones (F8 · R6.5): `{ resource, view?, params?, … }`.
319
- * Antes eran tres claves planas (`resource`/`labelField`/`valueField`);
320
- * D62 las unifica con el resto de consumidores.
321
- */
322
- source: DataSource;
323
- /**
324
- * Segundo dato a mostrar junto a la etiqueta (guía §1: «Juan Pérez ·
325
- * DNI 123»). Se concatena con « · » y forma parte de la opción, así que
326
- * también se busca sobre él.
327
- */
328
- secondaryField?: string;
329
- /** Cargar solo registros activos (lo exige además la FK en el back). */
330
- onlyActive?: boolean;
331
- }
332
-
333
- // ─────────────────────────────────────────────────────────────
334
- // §5.3 Imagen — el valor es SOLO la URL pública (`image_url`)
335
- // ─────────────────────────────────────────────────────────────
336
-
337
- export interface ImageField extends FieldBase<string> {
338
- type: 'image';
339
- /** Tipos aceptados (ej. `image/*`, `image/png,image/jpeg`). */
340
- accept?: string;
341
- maxSizeMB?: number;
342
- /** Relación de aspecto de la vista previa (ej. `16/9`). */
343
- aspectRatio?: string;
344
- previewSize?: string;
345
- }
346
-
347
- // ─────────────────────────────────────────────────────────────
348
- // §5.3b Archivo — el valor es SOLO la URL pública (mismo contrato que `image`)
349
- // ─────────────────────────────────────────────────────────────
350
- // R9.5.3: como `image`, pero para CUALQUIER archivo (pdf, xlsx, zip…). La
351
- // única diferencia semántica es que NO fuerza el prefijo `image/` en el
352
- // cliente: el catálogo de formatos lo acota el backend por campo (`formats`
353
- // declarado) o la lista global, y el motor guarda igualmente la URL.
354
- export interface FileField extends FieldBase<string> {
355
- type: 'file';
356
- /** Formatos aceptados (ej. `image/*`, `pdf,docx`). Si falta, usa los del backend. */
357
- accept?: string;
358
- maxSizeMB?: number;
359
- }
360
-
361
- // ─────────────────────────────────────────────────────────────
362
- // §5.4 Campos compuestos (contienen otros campos)
363
- // ─────────────────────────────────────────────────────────────
364
-
365
- export interface GroupField extends FieldBase<Record<string, unknown>> {
366
- type: 'group';
367
- fields: FieldSchema[];
368
- /** Presentación del grupo (base.md §5.4). */
369
- display?: 'card' | 'collapsible' | 'inline';
370
- }
371
-
372
- /** Propiedades comunes a las listas (base.md §6). */
373
- export interface ListOptions {
374
- min?: number;
375
- max?: number;
376
- /** Si se puede reordenar (por defecto: sí). */
377
- sortable?: boolean;
378
- /** Campo donde se guarda el orden dentro de cada item (`position`). */
379
- positionField?: string;
380
- addLabel?: string;
381
- emptyText?: string;
382
- itemDisplay?: 'card' | 'row' | 'accordion';
383
- }
384
-
385
- export interface ListField extends FieldBase<Record<string, unknown>[]>, ListOptions {
386
- type: 'list';
387
- /** Campos de cada item (cualquier tipo, incluso `group` o `list`). */
388
- itemFields: FieldSchema[];
389
- /** Campo del item usado como título cuando está colapsado. */
390
- itemTitle?: string;
391
- /** El primer item tiene significado especial (ej. imagen principal). */
392
- primaryFirst?: boolean;
393
- }
394
-
395
- export interface StringListField extends FieldBase<string[]>, ListOptions {
396
- type: 'string-list';
397
- /** Tipo permitido de cada item (base.md §9: solo text, url o email). */
398
- itemType?: 'text' | 'url' | 'email';
399
- }
400
-
401
- export interface KeyValueItem {
402
- key: string;
403
- value: string;
404
- }
405
-
406
- export interface KeyValueField extends FieldBase<KeyValueItem[]>, ListOptions {
407
- type: 'key-value';
408
- }
409
-
410
- // ─────────────────────────────────────────────────────────────
411
- // §5.6 Widgets de panel (sólo `kind: 'dashboard'` — refactormotor.md F4)
412
- // ─────────────────────────────────────────────────────────────
413
-
414
- /**
415
- * Base de un widget de panel. Se declara en `ResourceSchema.widgets` — no
416
- * en `fields`, porque un KPI no es un campo: no se valida, no se envía y
417
- * `field-host` no lo renderiza. Sólo un recurso `kind: 'dashboard'` los
418
- * dibuja, y agregar un widget es tocar el schema, no el template.
419
- *
420
- * Su `key` es además la clave del dato en la respuesta del endpoint del
421
- * dashboard (`{ key: 'pendientes' }` ↔ `{ pendientes: 3 }`), salvo que el
422
- * widget declare otra fuente (F8 · R6.5).
423
- */
424
-
425
- /**
426
- * Fuente de datos de un widget: el mismo vocabulario declarado de F8 que usan
427
- * relations y selects (D62), más el caso «payload del panel».
428
- *
429
- * - `DataSource` (`{ resource, view?, params? }`): el widget pide sus filas o
430
- * su agregado al recurso declarado vía `DataSourceService`; deja de depender
431
- * de que un handler haya armado `data[widget.key]`.
432
- * - `{ kind: 'payload' }`: lee la respuesta COMPLETA del endpoint del
433
- * dashboard (varias claves a la vez).
434
- */
435
- export type WidgetSource = DataSource | { kind: 'payload' };
436
-
437
- export interface WidgetBase {
438
- key: string;
439
- label: string;
440
- help?: string;
441
- /** Ancho en la grilla del panel (1–12), igual que un campo. */
442
- width?: GridWidth;
443
- /**
444
- * Ancho en la grilla en mobile (1–12). Por defecto `12` (ancho completo,
445
- * apilado). Declararlo permite controlar el layout responsive en pantallas
446
- * chicas sin tocar el ancho de escritorio (`width`).
447
- */
448
- mobileWidth?: GridWidth;
449
- /**
450
- * De dónde saca sus datos (F8 · R6.5).
451
- *
452
- * - **ausente** (por defecto): `data[widget.key]`. Es el contrato normal y
453
- * el que usan los KPI (`{ key: 'pendientes' }` ↔ `{ pendientes: 3 }`).
454
- * - **`{ kind: 'payload' }`**: la respuesta COMPLETA, para widgets que se
455
- * componen de varias claves (`status-progress` leyendo `pendientes` +
456
- * `entregados` + `cancelados`) sin que el orquestador tenga que saber
457
- * qué tipo de widget es.
458
- * - **`DataSource`**: las filas salen del recurso declarado (vista
459
- * incluida), pedidas al fetcher común.
460
- */
461
- source?: WidgetSource;
462
- }
463
-
464
- /** KPI de una cifra suelta («3 pendientes»). */
465
- export interface MetricCardWidget extends WidgetBase {
466
- type: 'metric-card';
467
- /** Texto secundario bajo la cifra (estático, va en el schema). */
468
- hint?: string;
469
- }
470
-
471
- /** Barras por categoría con CSS/SVG — sin librería. */
472
- export interface BarChartWidget extends WidgetBase {
473
- type: 'bar-chart';
474
- /** Sufijo de las cifras del eje («unidades», «S/»). */
475
- unit?: string;
476
- }
477
-
478
- /**
479
- * Serie temporal con Chart.js.
480
- *
481
- * La librería (61,4 K gz medidos) vive en el chunk que abre el descriptor
482
- * (`import('./chart-line')`), así que **no entra en el bundle inicial**; el
483
- * `@defer (on viewport)` que el propio componente dibuja tarda además la
484
- * creación del lienzo hasta que el gráfico se ve. Ver
485
- * `widgets/chart-line/chart-line.ts`.
486
- */
487
- export interface ChartLineWidget extends WidgetBase {
488
- type: 'chart-line';
489
- /** Sufijo de las cifras del eje («unidades», «S/»). */
490
- unit?: string;
491
- }
492
-
493
- /** Tabla embebida de registros operativos (ej. pedidos que requieren atención). */
494
- export interface RecordListWidget extends WidgetBase {
495
- type: 'record-list';
496
- /**
497
- * Claves de columnas a mostrar en la tabla compacta.
498
- *
499
- * No lleva `resource`: si las filas vienen declaradas, ese recurso ya está
500
- * en `source.resource` (D63 retira la clave duplicada — estaba declarada y
501
- * nadie la leía).
502
- */
503
- columns: string[];
504
- /** Acción de navegación por fila. */
505
- action?: {
506
- label: string;
507
- routeTemplate: string;
508
- };
509
- }
510
-
511
- /** Grid de botones de accesos directos operativos. */
512
- export interface QuickActionsWidget extends WidgetBase {
513
- type: 'quick-actions';
514
- actions: {
515
- label: string;
516
- icon?: string;
517
- navigateTo: string;
518
- variant?: 'primary' | 'secondary' | 'outline';
519
- }[];
520
- }
521
-
522
- /** Barra de distribución porcentual de estados o categorías. */
523
- export interface StatusProgressWidget extends WidgetBase {
524
- type: 'status-progress';
525
- segments: {
526
- key: string;
527
- label: string;
528
- color: 'success' | 'warning' | 'danger' | 'neutral';
529
- }[];
530
- }
531
-
532
- export type WidgetSchema =
533
- | MetricCardWidget
534
- | BarChartWidget
535
- | ChartLineWidget
536
- | RecordListWidget
537
- | QuickActionsWidget
538
- | StatusProgressWidget;
539
-
540
- export type WidgetType = WidgetSchema['type'];
541
-
542
- // ─────────────────────────────────────────────────────────────
543
- // Unión discriminada por `type` (21 tipos, base.md §5)
544
- // ─────────────────────────────────────────────────────────────
545
-
546
- export type FieldSchema =
547
- | TextField
548
- | TextareaField
549
- | SlugField
550
- | NumberField
551
- | CurrencyField
552
- | BooleanField
553
- | SelectField
554
- | MultiselectField
555
- | RichSelectField
556
- | DropdownField
557
- | UrlField
558
- | EmailField
559
- | PhoneField
560
- | DateField
561
- | TimeField
562
- | ReadonlyTextField
563
- | RelationField
564
- | ImageField
565
- | FileField
566
- | GroupField
567
- | ListField
568
- | StringListField
569
- | KeyValueField
570
- | ColorField;
571
-
572
- export type FieldType = FieldSchema['type'];
573
-
574
- // ─────────────────────────────────────────────────────────────
575
- // Listado, layout y metadatos del recurso (base.md §3)
576
- // ─────────────────────────────────────────────────────────────
577
-
578
- export type ListColumnFormat =
579
- 'text' | 'badge' | 'thumbnail' | 'boolean' | 'number' | 'currency' | 'date';
580
-
581
- export interface ListColumn {
582
- key: string;
583
- label: string;
584
- /**
585
- * Sólo para sobreescribir: sin él manda la tabla de
586
- * `columns/column-defaults` (`FORMATO_POR_DEFECTO`) según el `type` del
587
- * campo con esta `key` (R4.4).
588
- */
589
- format?: ListColumnFormat;
590
- }
591
-
592
- export interface ListFilter {
593
- key: string;
594
- label: string;
595
- type?: 'text' | 'select' | 'boolean';
596
- options?: SelectOption[];
597
- }
598
-
599
- export interface LayoutSection {
600
- /** Coincide con `field.section`. */
601
- id: string;
602
- label: string;
603
- }
604
-
605
- export type LayoutMode = 'grid' | 'tabs' | 'sections' | 'steps' | 'columns';
606
-
607
- export interface ResourceLayout {
608
- /** Presentación del formulario. */
609
- mode?: LayoutMode;
610
- sections?: LayoutSection[];
611
- /** Número de columnas para `mode: 'columns'` (por defecto 2). */
612
- columns?: 2 | 3;
613
- }
614
-
615
- export interface ResourceActionBase {
616
- id: string;
617
- label: string;
618
- icon?: string;
619
- variant?: 'primary' | 'secondary' | 'outline' | 'danger';
620
- visibleWhen?: { field: string; op: 'eq' | 'neq' | 'in'; value: unknown }[];
621
- }
622
-
623
- export interface CopyShareAction extends ResourceActionBase {
624
- type: 'copy-share';
625
- urlTemplate: string;
626
- shareTextTemplate?: string;
627
- }
628
-
629
- export interface NavigateAction extends ResourceActionBase {
630
- type?: 'navigate';
631
- /** Plantilla con marcadores, ej. `/products/{slug}` o `/admin/orders?id={ref}`. */
632
- urlTemplate: string;
633
- }
634
-
635
- export interface TriggerAction extends ResourceActionBase {
636
- /**
637
- * Acción de dominio **declarada en el back** (B3 `actions.<name>`,
638
- * publicada como `POST /admin/<recurso>/:id/actions/<name>` — R5.4).
639
- * El destino no se declara acá: la ruta lógica se deriva en R3.12.
640
- */
641
- type: 'trigger';
642
- /** Nombre de la acción en el back si difiere del `id` de esta declaración. */
643
- name?: string;
644
- confirmMessage?: string;
645
- }
646
-
647
- /** Acciones extra de registro o listado (duplicar, compartir, navegar…). */
648
- export type ResourceAction = CopyShareAction | NavigateAction | TriggerAction;
649
-
650
- /** Configuración de diálogo/modal o acción tras crear un registro con éxito. */
651
- export interface PostCreateSchema {
652
- mode: 'modal' | 'toast' | 'redirect_detail' | 'stay';
653
- title?: string;
654
- description?: string;
655
- summaryFields?: string[];
656
- actions?: ResourceAction[];
657
- }
658
-
659
- /** Configuración de Ficha de Detalle (modo lectura estructurado). */
660
- export interface DetailViewSchema {
661
- enabled: boolean;
662
- headerFields?: string[];
663
- sections?: {
664
- id: string;
665
- label: string;
666
- fields: string[];
667
- }[];
668
- actions?: ResourceAction[];
669
- allowEdit?: boolean;
670
- allowDelete?: boolean;
671
- }
672
-
673
- /** Operaciones permitidas (base.md §3). `undefined` = permitido. */
674
- export interface ResourcePermissions {
675
- create?: boolean;
676
- update?: boolean;
677
- remove?: boolean;
678
- reorder?: boolean;
679
- }
680
-
681
- /**
682
- * Rutas de la API relativas a `API_URL` (base.md §3, api.md §6 Opción A).
683
- *
684
- * Marcadores que un path acepta — se resuelven ANTES de despachar la petición
685
- * (y para ambos drivers):
686
- *
687
- * - `{key}` — clave del registro actual; sólo aplica a las operaciones con
688
- * clave (`get`, `update`, `remove`). Si llega sin resolver, es error.
689
- * - `{<fuente>}` / `{<fuente>.<ruta.anidada>}` — valor de una fuente de
690
- * contexto: las construidas `auth` (sesión) y `config` (config global), o
691
- * cualquier fuente registrada en `provideGasAdmin({ valueSources })`.
692
- *
693
- * El valor se codifica como segmento de URL. Un marcador sin valor, o con una
694
- * fuente no registrada, lanza un error que nombra el path y el marcador: nunca
695
- * se envía un segmento vacío. Los singleton solo usan `get` / `update`.
696
- */
697
- export interface ResourceEndpoints {
698
- list?: string;
699
- get?: string;
700
- create?: string;
701
- update?: string;
702
- remove?: string;
703
- /**
704
- * Declaración opcional de cómo unwrappear la respuesta de esta operación.
705
- * Cuando se declara, el motor extrae el contenido de `dataKey` antes de
706
- * devolverlo al consumidor (ej.: `{ data: [...] }` → `[...]`).
707
- * Si no se declara, el motor mantiene el comportamiento actual:
708
- * respuesta pasada tal cual (array plano, `{ items }`, o objeto crudo).
709
- * Esta declaración es por operación; si se desea un valor global, usarlo
710
- * en cada operación o considerar un default a nivel de config en futuro.
711
- */
712
- responseUnwrap?: ResponseUnwrap;
713
- }
714
-
715
- /**
716
- * Cómo el motor debe desempaquetar la respuesta HTTP antes de entregarla.
717
- * Opcional y opt-in: schemas sin este campo siguen el contrato actual.
718
- *
719
- * - `dataKey`: clave en el body que contiene el payload real (ej. `data`,
720
- * `items`, `result`). Si el body no tiene esta clave, se devuelve `undefined`
721
- * para lista / objeto vacío según corresponda, y se lanza error en modo
722
- * estricto si se configura.
723
- * - `metaKey`: clave con metadatos (paginación, total, etc.). Se ignora en
724
- * el valor devuelto al consumidor pero puede leerse si el motor la expone
725
- * en futuro.
726
- * - `apply`: `'list' | 'get' | 'create' | 'update' | 'remove' | 'all'`.
727
- * Qué operaciones aplican el unwrap. Por defecto `'all'` cuando se declara.
728
- */
729
- export interface ResponseUnwrap {
730
- dataKey: string;
731
- metaKey?: string;
732
- apply?: 'list' | 'get' | 'create' | 'update' | 'remove' | 'all';
733
- /**
734
- * Claves de metadata de paginación dentro del sobre. Usadas por
735
- * `ApiService.listPage()` para armar `PageResult<T>`. Opcional: sin
736
- * declaración, el motor intenta auto-detectar claves comunes
737
- * (`nextCursor`, `total`, `hasMore`) y, si no hay, `hasMore = false`.
738
- */
739
- pagination?: {
740
- /** Clave del cursor siguiente dentro de `meta` (o del body si no hay `metaKey`). */
741
- cursorKey?: string;
742
- /** Clave del total de registros. */
743
- totalKey?: string;
744
- /** Clave del flag booleano "hay más páginas". */
745
- hasMoreKey?: string;
746
- };
747
- }
748
-
749
- /**
750
- * Método HTTP soportado por endpoints personalizados.
751
- * Declarado aquí (y no en api.service.ts) para evitar ciclos de importación
752
- * entre modelos y servicios.
753
- */
754
- export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
755
-
756
- /**
757
- * Definición de un endpoint personalizado más allá de los cinco estándar
758
- * (list/get/create/update/remove). Permite al consumidor declarar rutas con
759
- * verbos arbitrarios, segmentos extra, payloads JSON o multipart, y unwrap de
760
- * respuesta propio.
761
- *
762
- * Ejemplo:
763
- * name: 'recalculate-ranks'
764
- * method: 'POST'
765
- * path: '/admin/businesses/{businessId}/ranks/recalculate'
766
- * payloadMode: 'json'
767
- */
768
- export interface CustomEndpointDefinition {
769
- /** Nombre único del endpoint dentro del recurso. Se usa para invocarlo. */
770
- name: string;
771
- /** Método HTTP de la petición. */
772
- method: HttpMethod;
773
- /** Ruta relativa a `API_URL`. Puede incluir marcadores {key}, {auth.user.id}, etc. */
774
- path: string;
775
- /** Modo de payload: 'json' (default) o 'multipart' para FormData. */
776
- payloadMode?: 'json' | 'multipart';
777
- /** Unwrap de respuesta override para este endpoint. Si no se declara, se usa el del recurso. */
778
- responseUnwrap?: ResponseUnwrap;
779
- }
780
-
781
- export interface ResourceSchema {
782
- /** Identificador interno (`categories`). */
783
- id: string;
784
- label: string;
785
- labelPlural: string;
786
- /**
787
- * `collection` → listado, `singleton` → formulario directo,
788
- * `dashboard` → panel de sólo lectura (refactormotor.md F4; sus datos llegan
789
- * un endpoint declarativo, no de CRUD).
790
- */
791
- kind: 'collection' | 'singleton' | 'dashboard';
792
- endpoint: ResourceEndpoints;
793
- /** Campo que identifica el registro (`slug`). */
794
- keyField: string;
795
- /** Campo que se muestra como nombre del registro. */
796
- titleField: string;
797
- /** Endpoints personalizados más allá de list/get/create/update/remove. */
798
- customEndpoints?: Record<string, CustomEndpointDefinition>;
799
- /** Si el listado se reordena (requiere `positionField`). */
800
- sortable?: boolean;
801
- positionField?: string;
802
- listColumns: ListColumn[];
803
- filters?: ListFilter[];
804
- /** Campos buscables en el listado. */
805
- search?: string[];
806
- /** Árbol de campos del formulario (base.md §4–§6). */
807
- fields: FieldSchema[];
808
- /**
809
- * Widgets del panel — sólo `kind: 'dashboard'` (refactormotor.md F4).
810
- *
811
- * Van aparte de `fields`: un KPI no es un campo y no comparte `FieldBase`
812
- * (`required`/`visibleWhen`/`validators`…). Decisión tomada tras medir el
813
- * ripple de unirlos a `FieldSchema`: 18+ errores de tipos en 4 ficheros.
814
- * `contract-check` sólo recorre `fields`, así que esta propiedad no se
815
- * compara back↔front — el widget es config de UI, no dato almacenado.
816
- */
817
- widgets?: WidgetSchema[];
818
- layout?: ResourceLayout;
819
- actions?: ResourceAction[];
820
- /** Configuración de Ficha de Detalle estructurada para el recurso. */
821
- detail?: DetailViewSchema;
822
- /** Configuración de diálogo/modal post-creación. */
823
- postCreate?: PostCreateSchema;
824
- permissions?: ResourcePermissions;
825
- /**
826
- * Acceso declarado por recurso (auth.md §5.3) — **sólo UX**: oculta
827
- * ruta, entrada de menú y botones. Aunque el front se manipule, el back
828
- * vuelve a verificar en cada petición: esto nunca es una barrera.
829
- *
830
- * No lo declara ningún schema mientras sólo exista el rol `admin`
831
- * (§9.4): sin declaración el efecto es «sesión», que es lo correcto hoy.
832
- * Aparece el día que haya un segundo rol.
833
- */
834
- access?: ResourceAccess;
835
- /**
836
- * Claves de `fields` que el listado edita en un drawer sin navegar
837
- * (plan 6.5, guía §5: «edición rápida de pocos campos, panel lateral en
838
- * lugar de pantalla nueva»). 1–3 campos; si no se declara, no hay atajo.
839
- */
840
- quickEdit?: string[];
841
-
842
- // ── Metadatos públicos de `/admin/schema` (F7-1, PLAN-MEJORAS) ──
843
- // Ausentes ⇒ sólo manda el schema local (merge local-driven preservado).
844
- /** Rutas efectivas por operación, con la forma pública si la declara. */
845
- operations?: ResourceOperations;
846
- /** Vistas declaradas como metadatos (sin operandos internos). */
847
- views?: Record<string, ViewDescriptor>;
848
- /** Páginas y rutas del frontend; separado de `views` del backend. */
849
- uiViews?: Record<string, UiViewDescriptor>;
850
- /** Lo mínimo del backend para menú/acciones: `access` normalizado. */
851
- policies?: ResourcePolicies;
852
- }
853
-
854
- // ─────────────────────────────────────────────────────────────
855
- // Metadatos públicos de `/admin/schema` (F7-1)
856
- // ─────────────────────────────────────────────────────────────
857
-
858
- /** Forma pública de la respuesta de una operación (declaración `shape`). */
859
- export interface OperationShape {
860
- pick?: 'full' | 'list' | string[];
861
- include?: string[];
862
- rename?: Record<string, string>;
863
- nest?: Record<string, string[]>;
864
- envelope?: 'plain' | 'list';
865
- }
866
-
867
- /** Ruta efectiva de una operación: método + path (con `{key}` si aplica). */
868
- export interface OperationDescriptor {
869
- method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
870
- path: string;
871
- shape?: OperationShape;
872
- }
873
-
874
- /** Operaciones CRUD efectivas (derivadas de la misma ruta que el router). */
875
- export interface ResourceOperations {
876
- list?: OperationDescriptor;
877
- get?: OperationDescriptor;
878
- create?: OperationDescriptor;
879
- update?: OperationDescriptor;
880
- remove?: OperationDescriptor;
881
- }
882
-
883
- /**
884
- * Condición de vista como metadato público: el literal `value` y el `ref`
885
- * (metadato de relación) viajan; el operando interno `from: '$item.x'` no.
886
- */
887
- export interface ViewCondition {
888
- field: string;
889
- op: string;
890
- not?: boolean;
891
- value?: unknown;
892
- ref?: string;
893
- }
894
-
895
- /** Vista declarada publicada como metadato (F7-1). */
896
- export interface ViewDescriptor {
897
- where?: ViewCondition[];
898
- sort?: { field: string; dir?: 'asc' | 'desc' }[];
899
- limit?: number;
900
- extends?: string;
901
- /** Vista con handler propio (escape hatch): su existencia, nada más. */
902
- custom?: boolean;
903
- }
904
-
905
- /** Config para una `uiView` de tipo `calendar`. */
906
- export interface CalendarViewConfig {
907
- /** Campo `date` (o `datetime` futuro): inicio del evento. Obligatorio. */
908
- startField: string;
909
- /** Campo `date`/`time`: fin. Ausente ⇒ evento de 1 día sobre `startField`. */
910
- endField?: string;
911
- /** Campo `text`/`relation`: rótulo del evento. Obligatorio. */
912
- titleField: string;
913
- /** Campo `select`/`text`: color/estado (token de paleta o valor crudo). */
914
- colorField?: string;
915
- /** Vista por defecto al abrir. Por defecto `month`. */
916
- defaultView?: 'month' | 'week' | 'day' | 'agenda';
917
- /** Origen de filas; ausente ⇒ la propia instancia del recurso (su listado). */
918
- source?: DataSource;
919
- }
920
-
921
- /** Config para una `uiView` de tipo `kanban`. */
922
- export interface KanbanViewConfig {
923
- /** Campo `select`/`relation`: columna por valor. Obligatorio. */
924
- groupField: string;
925
- /** Orden estable de columnas. Valores no declarados ⇒ columna extra al final. */
926
- columns: KanbanColumn[];
927
- /** Rótulo de la tarjeta; ausente ⇒ `keyField` del recurso. */
928
- titleField?: string;
929
- /** Segundo renglón de la tarjeta (opcional). */
930
- subtitleField?: string;
931
- /** Origen de filas; ausente ⇒ la propia instancia del recurso. */
932
- source?: DataSource;
933
- }
934
-
935
- /** Una columna del tablero Kanban. */
936
- export interface KanbanColumn {
937
- /** Valor del `groupField` que agrupa esta columna. */
938
- value: string;
939
- /** Etiqueta visible de la columna. */
940
- label: string;
941
- }
942
-
943
- /**
944
- * Evento que dispara un `select` declarado (R9.9.4): `open`, `select` o una
945
- * acción con nombre (`open-detail`). El string libre cubre las acciones con
946
- * nombre sin perder autocompletado para los dos literales fijos.
947
- */
948
- export type SelectionTrigger = 'open' | 'select' | (string & {});
949
-
950
- /**
951
- * Destino de navegación declarado (R9.9.4 · spec view-navigation): recurso +
952
- * `uiView` declarada + params de ruta permitidos. Las URLs crudas o
953
- * externas NO son destinos válidos — el validador las rechaza pre-render.
954
- */
955
- export interface NavigationTarget {
956
- /** Recurso declarado (`schema.id` del front). */
957
- resource: string;
958
- /** Clave de `uiViews` en ese recurso. */
959
- view: string;
960
- /** Nombres de params de la ruta del destino (`:key` ⇒ `['key']`). */
961
- params?: string[];
962
- }
963
-
964
- /**
965
- * Vinculación selección ⇒ transición declarada en una `uiView` o en un hijo
966
- * de composición (R9.9.4). `route` exige un `NavigationTarget` declarado;
967
- * `inline` selecciona en local y `none` es un no-op explícito.
968
- */
969
- export type SelectionBinding =
970
- | { on: SelectionTrigger; mode: 'none' | 'inline' }
971
- | { on: SelectionTrigger; mode: 'route'; target: NavigationTarget };
972
-
973
- /** Base común de todo hijo de una composición embebida (R9.9.2). */
974
- export interface ViewChildBase {
975
- /** Identificador estable y único entre hermanos del mismo contenedor. */
976
- id: string;
977
- /** Etiqueta visible (rótulo de la pestaña). */
978
- label: string;
979
- /** Conserva el estado al cambiar de pestaña; ausente ⇒ destruir (R9.9.5). */
980
- retain?: boolean;
981
- /** Visibilidad declarativa (condiciones sobre campos del formulario). */
982
- visibleWhen?: FieldCondition[];
983
- }
984
-
985
- /**
986
- * Hijo declarado inline (`type` + `config`) o por referencia a una `uiView`
987
- * del mismo schema (`ref`). Los `ref` hacen posible que un contenedor
988
- * contenga —directa o transitivamente— a sí mismo: por eso el
989
- * `composition-validator` es obligatorio antes del render (D2).
990
- */
991
- export type ViewChildNode = (ViewChildBase & UiViewDescriptor) | (ViewChildBase & { ref: string });
992
-
993
- /** Config de una `uiView` contenedora `tabs` (R9.9.2). */
994
- export interface TabsConfig {
995
- /** Lista ordenada de hijos; el orden declarado es el orden de render. */
996
- children: ViewChildNode[];
997
- /** `id` del hijo seleccionado al montar; ausente ⇒ el primero. */
998
- initial?: string;
999
- }
1000
-
1001
- /** Vista `tabs` declarada en el schema local del frontend. */
1002
- export interface UiViewTabs extends UiViewBase {
1003
- type: 'tabs';
1004
- config: TabsConfig;
1005
- }
1006
-
1007
- /** Base común de toda `uiView`: tipo + ruta relativa al recurso. */
1008
- export interface UiViewBase {
1009
- /** Tipo resuelto por `kind: 'view'` en el registro de render. */
1010
- type: string;
1011
- /** Ruta relativa al recurso; ausente o vacía significa la ruta raíz. */
1012
- path?: string;
1013
- /**
1014
- * Binding de selección declarado (R9.9.4). Ausente ⇒ la hoja conserva su
1015
- * comportamiento local y NO navega; una URL cruda nunca es un destino
1016
- * válido (el `composition-validator` la rechaza antes del render, D2).
1017
- */
1018
- select?: SelectionBinding;
1019
- }
1020
-
1021
- /** Vista `calendar` declarada en el schema local del frontend. */
1022
- export interface UiViewCalendar extends UiViewBase {
1023
- type: 'calendar';
1024
- config: CalendarViewConfig;
1025
- }
1026
-
1027
- /** Vista `kanban` declarada en el schema local del frontend. */
1028
- export interface UiViewKanban extends UiViewBase {
1029
- type: 'kanban';
1030
- config: KanbanViewConfig;
1031
- }
1032
-
1033
- /**
1034
- * Una página/ruta declarada en el schema local del frontend, discriminada
1035
- * por `type`. Los tipos base (`list`/`detail`/`form`/`dashboard`) conservan
1036
- * la forma plana sin `config`; `calendar` y `kanban` llevan su config tipada.
1037
- */
1038
- export type UiViewDescriptor = UiViewBase | UiViewCalendar | UiViewKanban | UiViewTabs;
1039
-
1040
- /** Políticas públicas: sólo `access`, lo mínimo para menú/acciones. */
1041
- export interface ResourcePolicies {
1042
- access: {
1043
- read: string;
1044
- write: string;
1045
- /** R7.5: override por operación (B8 · R7.4a) */
1046
- operations?: Record<string, string>;
1047
- };
1048
- }
1049
-
1050
- /** §5.3 — `access` de un recurso. `requires` usa el vocabulario de §4.4. */
1051
- export interface ResourceAccess {
1052
- requires?: string;
1053
- roles?: string[];
1054
- }
1055
-
1056
- /** Un campo de la pantalla de login (auth.md §5.1). */
1057
- export interface AuthFieldDeclaration {
1058
- key: string;
1059
- /** `email` | `password` — tipos primitivos; el registro de render los
1060
- * absorberá en Fase 3 (R3.3), cuando exista el descriptor `password`. */
1061
- type: string;
1062
- required?: boolean;
1063
- }
1064
-
1065
- /** Supported auth providers. Extensible without breaking existing schemas. */
1066
- export type AuthProvider = 'password' | 'google' | (string & {});
1067
-
1068
- /** Firebase config block — present only when at least one Firebase provider is listed. */
1069
- export interface FirebaseAuthConfig {
1070
- /**
1071
- * The backend endpoint that exchanges a Firebase ID token for the app token.
1072
- * Defaults to '/auth/firebase' when omitted.
1073
- */
1074
- exchangeEndpoint?: string;
1075
- }
1076
-
1077
- /**
1078
- * Pantalla de login declarada (auth.md §5.1): **vive sólo en el schema del
1079
- * front** — el back no conoce estas etiquetas ni este layout, sólo declara
1080
- * el `input` de `/auth/login`. El `contract-check` (R2.11) verifica que las
1081
- * claves de `loginFields` existan en ese `input`.
1082
- */
1083
- export interface AuthSchema {
1084
- /** Proveedores disponibles: 'password' | 'google' u otros federados. */
1085
- providers: AuthProvider[];
1086
- loginFields: AuthFieldDeclaration[];
1087
- redirectAfterLogin: string;
1088
- /**
1089
- * D10-3 → **`false` siempre.** La opción «recordarme» con `localStorage`
1090
- * quedó denegada (§9.3): el token vive en `sessionStorage` y muere con la
1091
- * pestaña. Declarar `true` prometería un storage que nadie usa.
1092
- */
1093
- rememberMe: boolean;
1094
- /** Configuración de Firebase cuando se usan proveedores federados o Firebase Auth. */
1095
- firebase?: FirebaseAuthConfig;
1096
- }
1097
-