@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
package/ng-package.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3
- "dest": "../../dist/gas-admin-ui",
4
- "lib": {
5
- "entryFile": "src/public-api.ts"
6
- }
7
- }
@@ -1,52 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import {
4
- actionType,
5
- actionsFor,
6
- getAction,
7
- registerAction,
8
- type ActionDescriptor,
9
- } from './action-registry';
10
-
11
- function descriptor(
12
- type: string,
13
- surfaces: ActionDescriptor['surfaces'] = ['row'],
14
- ): ActionDescriptor {
15
- return { type, surfaces, run: async () => ({ ok: true }) };
16
- }
17
-
18
- describe('action-registry', () => {
19
- it('registra un descriptor y lo devuelve por su tipo', () => {
20
- registerAction(descriptor('compartir'));
21
- expect(getAction('compartir')?.type).toBe('compartir');
22
- });
23
-
24
- it('devuelve undefined para un tipo sin registrar', () => {
25
- expect(getAction('sin-registrar')).toBeUndefined();
26
- });
27
-
28
- it('al re-registrar un tipo reemplaza el descriptor anterior', () => {
29
- registerAction(descriptor('navegar', ['detail']));
30
- registerAction(descriptor('navegar', ['row', 'detail']));
31
- expect(getAction('navegar')?.surfaces).toEqual(['row', 'detail']);
32
- });
33
-
34
- it('lista sólo los descriptores cuya superficie coincide', () => {
35
- registerAction(descriptor('cabecera', ['header']));
36
- expect(actionsFor('header').map((d) => d.type)).toEqual(['cabecera']);
37
- expect(actionsFor('bulk')).toEqual([]);
38
- });
39
- });
40
-
41
- describe('actionType', () => {
42
- it('usa el tipo declarado', () => {
43
- expect(actionType({ id: 'x', label: 'X', type: 'trigger' })).toBe('trigger');
44
- expect(actionType({ id: 'x', label: 'X', type: 'copy-share', urlTemplate: '/p/{ref}' })).toBe(
45
- 'copy-share',
46
- );
47
- });
48
-
49
- it('una acción sin type es una navegación (NavigateAction.type es opcional)', () => {
50
- expect(actionType({ id: 'x', label: 'X', urlTemplate: '/p/{ref}' })).toBe('navigate');
51
- });
52
- });
@@ -1,126 +0,0 @@
1
- import type { Router } from '@angular/router';
2
-
3
- import type { LucideIcon } from '@lucide/angular';
4
-
5
- import {
6
- actionDescriptors,
7
- isShareAction,
8
- isTriggerAction,
9
- resolveShare,
10
- type ResolvedShare,
11
- } from './descriptors';
12
- import type { ResourceAction } from '../core/models/schema.model';
13
- import type { SessionUser } from '../core/services/auth.service';
14
- import type { ApiService } from '../core/services/api.service';
15
- import type { NotificationService } from '../core/services/notification.service';
16
-
17
- /**
18
- * Registro único de acciones (R3.9 · `refactormotor.md`).
19
- *
20
- * Es el gemelo del registro de render (`core/registry/render-registry.ts`):
21
- * en lugar de «qué componente pinta un tipo de campo», responde «qué
22
- * comportamiento ejecuta un tipo de acción» y permite **migrar el dispatch
23
- * if/copiado-pegado de las vistas (R3.11) a datos + un solo `run`**.
24
- *
25
- * Como los descriptores son objetos planos de módulo (no los inyecta Angular),
26
- * todo lo que necesiten llegar por el `ActionContext`: los puertos (`api`,
27
- * `router`, `toast`) y los datos (`record`, `resource`, `vars`).
28
- */
29
-
30
- /** Superficies donde una acción puede aparecer. */
31
- export type ActionSurface = 'row' | 'detail' | 'header' | 'bulk' | 'post-create';
32
-
33
- /**
34
- * Lo que aporta el llamador al ejecutar una acción: el registro sobre el que
35
- * corre y los puertos que el descriptor usará para actuar.
36
- *
37
- * `record` es `null` en las superficies sin fila (`header`, `bulk`), para que
38
- * un descriptor pueda distinguir «sin registro» de «registro vacío».
39
- */
40
- export interface ActionRequest {
41
- record: Record<string, unknown> | null;
42
- /** Id del recurso (schema) dueño de la acción. */
43
- resource: string;
44
- api: ApiService;
45
- router: Router;
46
- toast: NotificationService;
47
- user: SessionUser | null;
48
- /**
49
- * `keyField` del schema. **R3.12 (desviación nº 3 del contrato):** con
50
- * `record` forma la clave que necesita la ruta lógica de `trigger`
51
- * (`/admin/<recurso>/<key>/actions/<name>`). Lo aporta la vista, que es
52
- * quien tiene el schema.
53
- */
54
- keyField: string;
55
- }
56
-
57
- /**
58
- * Contexto que recibe el descriptor: la petición del llamador más el contexto
59
- * de interpolación ya resuelto. `ActionService.run` lo arma, así que ninguna
60
- * vista repite `buildInterpolationContext(record)`.
61
- */
62
- export interface ActionContext extends ActionRequest {
63
- /** `{...configGlobal, ...record, public_base_url}` — listo para las plantillas. */
64
- vars: Record<string, unknown>;
65
- }
66
-
67
- /** Resultado que la vista puede leer para saber si debe recargar. */
68
- export interface ActionResult {
69
- /** `false` cuando la acción no llegó a ejecutarse; el error ya se notificó. */
70
- ok: boolean;
71
- /** `true` cuando tocó datos y la vista debe recargar su listado/detalle. */
72
- reload?: boolean;
73
- }
74
-
75
- export interface ActionDescriptor {
76
- /** Clave del dispatch: el `type` del schema (`'navigate'` no lo declara). */
77
- type: string;
78
- /** Superficies donde esta acción puede aparecer. */
79
- surfaces: ActionSurface[];
80
- run: (ctx: ActionContext, action: ResourceAction) => Promise<ActionResult>;
81
- /** `true` si el descriptor exige confirmación antes de ejecutar. */
82
- confirm?: boolean;
83
- /**
84
- * Icono lucide que representa la acción donde el espacio es reducido
85
- * (la fila del listado). Sin él, la vista muestra `action.label`.
86
- */
87
- icon?: LucideIcon;
88
- }
89
-
90
- export { isShareAction, isTriggerAction, resolveShare, type ResolvedShare };
91
-
92
- const ACCIONES = new Map<string, ActionDescriptor>();
93
-
94
- /** Registra (o reemplaza) un descriptor de acción. */
95
- export function registerAction(descriptor: ActionDescriptor): void {
96
- ACCIONES.set(descriptor.type, descriptor);
97
- }
98
-
99
- export function getAction(type: string): ActionDescriptor | undefined {
100
- return ACCIONES.get(type);
101
- }
102
-
103
- /** Descriptores disponibles en una superficie. */
104
- export function actionsFor(surface: ActionSurface): ActionDescriptor[] {
105
- return [...ACCIONES.values()].filter((descriptor) => descriptor.surfaces.includes(surface));
106
- }
107
-
108
- /**
109
- * Clave de dispatch de una acción. `NavigateAction.type` es **opcional**
110
- * (schema.model.ts), así que una acción sin `type` es una navegación.
111
- */
112
- export function actionType(action: ResourceAction): string {
113
- return action.type ?? 'navigate';
114
- }
115
-
116
- /** Tipos registrados. Sólo para comprobaciones y tests. */
117
- export function actionTypes(): string[] {
118
- return [...ACCIONES.keys()];
119
- }
120
-
121
- // Catálogo a scope de módulo: se registra al importar, sin esperar a DI,
122
- // igual que el registro de render (mismo motivo: `buildFormSchema()` es una
123
- // función pura que consulta sin inyectar nada).
124
- for (const descriptor of actionDescriptors) {
125
- registerAction(descriptor);
126
- }
@@ -1,215 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
-
4
- import { ActionService } from './action-service';
5
- import { registerAction, type ActionContext, type ActionDescriptor } from './action-registry';
6
- import { actionDescriptors } from './descriptors';
7
- import type { ResourceAction } from '../core/models/schema.model';
8
- import type { ApiService } from '../core/services/api.service';
9
- import { ConfigService } from '../core/services/config.service';
10
- import type { NotificationService } from '../core/services/notification.service';
11
- import type { Router } from '@angular/router';
12
-
13
- /** Notificador falso: sólo el contrato que `ActionService` usa. */
14
- function fakeToast(): NotificationService & { confirm: ReturnType<typeof vi.fn> } {
15
- return {
16
- confirm: vi.fn().mockResolvedValue(true),
17
- error: vi.fn(),
18
- success: vi.fn(),
19
- info: vi.fn(),
20
- dismiss: vi.fn(),
21
- } as unknown as NotificationService & { confirm: ReturnType<typeof vi.fn> };
22
- }
23
-
24
- function fakeRequest(toast: NotificationService) {
25
- return {
26
- record: { slug: 'tecla', ref: 'p1' },
27
- resource: 'productos',
28
- api: {} as ApiService,
29
- router: { navigate: async () => true } as unknown as Router,
30
- toast,
31
- user: null,
32
- keyField: 'ref',
33
- };
34
- }
35
-
36
- const COMPARTIR: ResourceAction = {
37
- id: 'compartir',
38
- label: 'Compartir',
39
- type: 'copy-share',
40
- urlTemplate: 'https://demo/p/{ref}',
41
- };
42
-
43
- describe('ActionService', () => {
44
- let service: ActionService;
45
- let toast: ReturnType<typeof fakeToast>;
46
- const ensureLoaded = vi.fn<() => Promise<void>>().mockResolvedValue(undefined);
47
-
48
- beforeEach(() => {
49
- toast = fakeToast();
50
- ensureLoaded.mockClear();
51
- ensureLoaded.mockResolvedValue(undefined);
52
- TestBed.configureTestingModule({
53
- providers: [
54
- // ConfigService real pediría HttpClient/API_URL; sólo aporta `vars`
55
- // y el reintento de config que `copy-share` dispara.
56
- {
57
- provide: ConfigService,
58
- useValue: {
59
- ensureLoaded,
60
- buildInterpolationContext: (record: Record<string, unknown>) => ({
61
- ...record,
62
- public_base_url: 'https://demo',
63
- }),
64
- },
65
- },
66
- ],
67
- });
68
- service = TestBed.inject(ActionService);
69
- });
70
-
71
- // El `Map` del registro es estado de módulo **compartido entre ficheros**
72
- // cuando vitest los ejecuta en el mismo worker: varios tests de éste
73
- // sobrescriben `copy-share` / `navigate` / `trigger` con dobles.
74
- // Sin restaurar aquí, `contract.spec` y `descriptors.spec` leen esos dobles
75
- // y la suite se pone flaka **según el orden de ficheros** (falló 4 tests de
76
- // `descriptors.spec` en una corrida y 0 en la siguiente, sin tocar código).
77
- // Quien ensucia es quien limpia: el estado por defecto es el catálogo real.
78
- afterEach(() => {
79
- for (const descriptor of actionDescriptors) registerAction(descriptor);
80
- });
81
-
82
- it('ejecuta el descriptor y le entrega la petición + vars de interpolación', async () => {
83
- const vistos: ActionContext[] = [];
84
- registerAction({
85
- type: 'copy-share',
86
- surfaces: ['row', 'post-create'],
87
- run: async (ctx) => {
88
- vistos.push(ctx);
89
- return { ok: true, reload: true };
90
- },
91
- });
92
-
93
- const resultado = await service.run(COMPARTIR, fakeRequest(toast));
94
-
95
- expect(resultado).toEqual({ ok: true, reload: true });
96
- expect(vistos).toHaveLength(1);
97
- expect(vistos[0].record).toEqual({ slug: 'tecla', ref: 'p1' });
98
- expect(vistos[0].resource).toBe('productos');
99
- expect(vistos[0].vars).toEqual({ slug: 'tecla', ref: 'p1', public_base_url: 'https://demo' });
100
- });
101
-
102
- it('copy-share reintenta la config global ANTES de resolver vars', async () => {
103
- // Regresión del «mensaje = sólo la URL»: si el load del bootstrap falló,
104
- // el descriptor debe ver la config ya recargada, no el snapshot vacío.
105
- let ensureHecho = false;
106
- ensureLoaded.mockImplementation(async () => {
107
- ensureHecho = true;
108
- });
109
- const varsAlEjecutar: Record<string, unknown>[] = [];
110
- registerAction({
111
- type: 'copy-share',
112
- surfaces: ['row'],
113
- run: async (ctx) => {
114
- expect(ensureHecho).toBe(true);
115
- varsAlEjecutar.push(ctx.vars);
116
- return { ok: true };
117
- },
118
- });
119
-
120
- await service.run(COMPARTIR, fakeRequest(toast));
121
-
122
- expect(ensureLoaded).toHaveBeenCalledOnce();
123
- expect(varsAlEjecutar[0]).toEqual({
124
- slug: 'tecla',
125
- ref: 'p1',
126
- public_base_url: 'https://demo',
127
- });
128
- });
129
-
130
- it('acciones que no son copy-share no tocan la config', async () => {
131
- const run = vi.fn<NonNullable<ActionDescriptor['run']>>().mockResolvedValue({ ok: true });
132
- registerAction({ type: 'navigate', surfaces: ['row'], run });
133
-
134
- await service.run({ id: 'ver', label: 'Ver', urlTemplate: '/p/{ref}' }, fakeRequest(toast));
135
-
136
- expect(ensureLoaded).not.toHaveBeenCalled();
137
- });
138
-
139
- it('una acción sin type resuelve el descriptor navigate', async () => {
140
- const run = vi.fn<NonNullable<ActionDescriptor['run']>>();
141
- registerAction({ type: 'navigate', surfaces: ['row', 'detail'], run });
142
-
143
- await service.run({ id: 'ver', label: 'Ver', urlTemplate: '/p/{ref}' }, fakeRequest(toast));
144
-
145
- expect(run).toHaveBeenCalledOnce();
146
- });
147
-
148
- it('sin descriptor registrado rompe en lugar de ignorarse', async () => {
149
- // `ResourceAction` es una unión cerrada y el registro es estado de
150
- // módulo compartido entre tests: se fuerza un type que nadie registra
151
- // (el cast a `unknown` sólo salva al compilador, no cambia el código).
152
- const desconocida = { id: 'x', label: 'X', type: 'nadie' } as unknown as ResourceAction;
153
- await expect(service.run(desconocida, fakeRequest(toast))).rejects.toThrow(
154
- 'no tiene descriptor registrado',
155
- );
156
- });
157
-
158
- it('con confirmación rechazada no ejecuta y devuelve ok false', async () => {
159
- toast.confirm.mockResolvedValue(false);
160
- const run = vi.fn<NonNullable<ActionDescriptor['run']>>();
161
- registerAction({
162
- type: 'trigger',
163
- surfaces: ['row'],
164
- confirm: true,
165
- run,
166
- });
167
-
168
- const resultado = await service.run(
169
- {
170
- id: 'publicar',
171
- label: 'Publicar',
172
- type: 'trigger',
173
- confirmMessage: 'Se publicará para todos.',
174
- },
175
- fakeRequest(toast),
176
- );
177
-
178
- expect(toast.confirm).toHaveBeenCalledWith({
179
- title: 'Publicar',
180
- message: 'Se publicará para todos.',
181
- confirmLabel: 'Confirmar',
182
- cancelLabel: 'Cancelar',
183
- });
184
- expect(run).not.toHaveBeenCalled();
185
- expect(resultado).toEqual({ ok: false });
186
- });
187
-
188
- it('con confirmación aceptada ejecuta el descriptor', async () => {
189
- const run = vi.fn<NonNullable<ActionDescriptor['run']>>().mockResolvedValue({ ok: true });
190
- registerAction({ type: 'trigger', surfaces: ['row'], confirm: true, run });
191
-
192
- const resultado = await service.run(
193
- { id: 'duplicar', label: 'Duplicar', type: 'trigger' },
194
- fakeRequest(toast),
195
- );
196
-
197
- expect(run).toHaveBeenCalledOnce();
198
- expect(resultado).toEqual({ ok: true });
199
- });
200
-
201
- it('un error del descriptor se notifica y no se devuelve como éxito', async () => {
202
- registerAction({
203
- type: 'copy-share',
204
- surfaces: ['row'],
205
- run: async () => {
206
- throw new Error('El backend respondió 500');
207
- },
208
- });
209
-
210
- const resultado = await service.run(COMPARTIR, fakeRequest(toast));
211
-
212
- expect(toast.error).toHaveBeenCalledWith('El backend respondió 500');
213
- expect(resultado).toEqual({ ok: false });
214
- });
215
- });
@@ -1,87 +0,0 @@
1
- import { Service, inject } from '@angular/core';
2
-
3
- import {
4
- actionType,
5
- getAction,
6
- type ActionContext,
7
- type ActionRequest,
8
- type ActionResult,
9
- } from './action-registry';
10
- import type { ResourceAction } from '../core/models/schema.model';
11
- import { ConfigService } from '../core/services/config.service';
12
- import { ErrorMapperService } from '../core/services/error-mapper.service';
13
-
14
- /**
15
- * Ejecuta una acción declarada en el schema (R3.9 · `refactormotor.md`).
16
- *
17
- * Sustituye el dispatch por tipo que hoy vive en `list-view` y en las
18
- * copias de `detail-view` y `post-create-modal` (R3.11). El camino siempre
19
- * es el mismo:
20
- *
21
- * 1. resolver el descriptor (si no existe, **rompe** — nada de «disponible
22
- * próximamente», que hoy oculta esquemas mal declarados);
23
- * 2. pedir confirmación si el descriptor la exige;
24
- * 3. montar el `ActionContext` (petición + `vars` de interpolación);
25
- * 4. ejecutar y, si el descriptor lanza, notificar el error y devolver
26
- * `{ ok: false }` para que la vista no trate el fallo como éxito.
27
- */
28
- @Service()
29
- export class ActionService {
30
- private readonly config = inject(ConfigService);
31
- private readonly errores = inject(ErrorMapperService);
32
-
33
- async run(action: ResourceAction, request: ActionRequest): Promise<ActionResult> {
34
- const type = actionType(action);
35
- const descriptor = getAction(type);
36
- if (!descriptor) {
37
- throw new Error(
38
- `[actions] «${action.label}» no tiene descriptor registrado (type "${type}").`,
39
- );
40
- }
41
-
42
- if (descriptor.confirm) {
43
- const aceptado = await request.toast.confirm({
44
- title: action.label,
45
- message: confirmMessage(action),
46
- confirmLabel: 'Confirmar',
47
- cancelLabel: 'Cancelar',
48
- });
49
- if (!aceptado) {
50
- return { ok: false };
51
- }
52
- }
53
-
54
- // `copy-share` (R8.7) resuelve su mensaje contra la config global
55
- // (`share_message_template`). Si el load del bootstrap no llegó (arranque
56
- // sin sesión o red lenta), lo pedimos ahora —con la sesión ya iniciada—
57
- // ANTES de congelar `vars`: si no, el mensaje copiado degradaría a
58
- // «sólo la URL» hasta el próximo F5.
59
- if (descriptor.type === 'copy-share') {
60
- await this.config.ensureLoaded();
61
- }
62
-
63
- const ctx: ActionContext = { ...request, vars: this.vars(request.record) };
64
- try {
65
- return await descriptor.run(ctx, action);
66
- } catch (err) {
67
- request.toast.error(this.errores.messageOf(err));
68
- return { ok: false };
69
- }
70
- }
71
-
72
- /**
73
- * Config global + registro. Sin registro (`header`, `bulk`) el contexto de
74
- * interpolación queda vacío: el descriptor no tiene nada que interpolar.
75
- *
76
- * Público porque `detail-view` sólo **presenta** una acción (pinta
77
- * `<app-copy-share>`) en vez de ejecutarla, y aun así necesita el mismo
78
- * contexto: R3.11 acabó con la tercera copia de esta lógica.
79
- */
80
- vars(record: Record<string, unknown> | null): Record<string, unknown> {
81
- return record ? this.config.buildInterpolationContext(record) : {};
82
- }
83
- }
84
-
85
- function confirmMessage(action: ResourceAction): string {
86
- return 'confirmMessage' in action && action.confirmMessage ? action.confirmMessage : action.label;
87
- }
@@ -1,155 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi, type MockInstance } from 'vitest';
2
- import { of } from 'rxjs';
3
-
4
- import { getAction, type ActionContext } from './action-registry';
5
- import { resolveShare } from './descriptors';
6
- import type { CopyShareAction, NavigateAction, TriggerAction } from '../core/models/schema.model';
7
- import type { ApiService } from '../core/services/api.service';
8
- import type { NotificationService } from '../core/services/notification.service';
9
- import type { Router } from '@angular/router';
10
-
11
- const VARS = { public_base_url: 'https://demo', ref: 'p1', customer_name: 'Ana' };
12
-
13
- const COMPARTIR: CopyShareAction = {
14
- id: 'share',
15
- label: 'Compartir',
16
- type: 'copy-share',
17
- urlTemplate: '{public_base_url}/p/{ref}',
18
- shareTextTemplate: 'Hola {customer_name}, tu pedido {ref}',
19
- };
20
-
21
- function contexto(): ActionContext {
22
- return {
23
- record: { ref: 'p1' },
24
- resource: 'orders',
25
- api: { request: vi.fn().mockReturnValue(of({ ok: true })) } as unknown as ApiService,
26
- router: { navigateByUrl: vi.fn().mockResolvedValue(true) } as unknown as Router,
27
- toast: {
28
- success: vi.fn(),
29
- error: vi.fn(),
30
- info: vi.fn(),
31
- confirm: vi.fn(),
32
- dismiss: vi.fn(),
33
- } as unknown as NotificationService,
34
- user: null,
35
- keyField: 'ref',
36
- vars: VARS,
37
- };
38
- }
39
-
40
- /** El `run` de un tipo registrado; lanza si no existe (estado incoherente). */
41
- function ejecutar(type: string, action: CopyShareAction | NavigateAction | TriggerAction) {
42
- const descriptor = getAction(type);
43
- if (!descriptor) throw new Error(`sin descriptor «${type}»`);
44
- return descriptor.run;
45
- }
46
-
47
- describe('resolveShare', () => {
48
- it('interpola enlace y mensaje con el contexto del registro', () => {
49
- expect(resolveShare(COMPARTIR, VARS)).toEqual({
50
- url: 'https://demo/p/p1',
51
- shareText: 'Hola Ana, tu pedido p1',
52
- });
53
- });
54
-
55
- it('sin shareTextTemplate cae a share_message_template (config global)', () => {
56
- const action: CopyShareAction = { ...COMPARTIR, shareTextTemplate: undefined };
57
- expect(resolveShare(action, { ...VARS, share_message_template: 'Hola {ref}' })).toEqual({
58
- url: 'https://demo/p/p1',
59
- shareText: 'Hola p1',
60
- });
61
- });
62
-
63
- it('sin plantilla ninguna el mensaje queda vacío', () => {
64
- const action: CopyShareAction = { ...COMPARTIR, shareTextTemplate: undefined };
65
- expect(resolveShare(action, VARS).shareText).toBe('');
66
- });
67
- });
68
-
69
- describe('descriptores de acción', () => {
70
- const escritor = vi.fn().mockResolvedValue(undefined);
71
- let abrir: MockInstance;
72
-
73
- beforeEach(() => {
74
- escritor.mockClear();
75
- Object.defineProperty(window.navigator, 'clipboard', {
76
- value: { writeText: escritor },
77
- configurable: true,
78
- });
79
- abrir = vi.spyOn(window, 'open').mockReturnValue(null);
80
- });
81
-
82
- afterEach(() => {
83
- vi.restoreAllMocks();
84
- });
85
-
86
- it('copy-share copia el mensaje completo y lo anuncia', async () => {
87
- const ctx = contexto();
88
- const resultado = await ejecutar('copy-share', COMPARTIR)(ctx, COMPARTIR);
89
-
90
- expect(escritor).toHaveBeenCalledWith('Hola Ana, tu pedido p1 https://demo/p/p1');
91
- expect(ctx.toast.success).toHaveBeenCalledWith('Mensaje copiado al portapapeles.');
92
- expect(resultado).toEqual({ ok: true });
93
- });
94
-
95
- it('navigate abre una URL absoluta en otra pestaña', async () => {
96
- const action: NavigateAction = {
97
- id: 'ver',
98
- label: 'Ver público',
99
- urlTemplate: '{public_base_url}/p/{ref}',
100
- };
101
- const ctx = contexto();
102
-
103
- await ejecutar('navigate', action)(ctx, action);
104
-
105
- expect(abrir).toHaveBeenCalledWith('https://demo/p/p1', '_blank', 'noopener');
106
- expect(ctx.router.navigateByUrl).not.toHaveBeenCalled();
107
- });
108
-
109
- it('navigate entrega una ruta interna al router', async () => {
110
- const action: NavigateAction = { id: 'editar', label: 'Editar', urlTemplate: '/orders/p1' };
111
- const ctx = contexto();
112
-
113
- await ejecutar('navigate', action)(ctx, action);
114
-
115
- expect(ctx.router.navigateByUrl).toHaveBeenCalledWith('/orders/p1');
116
- expect(abrir).not.toHaveBeenCalled();
117
- });
118
-
119
- it('trigger arma la ruta lógica de la acción declarada y pide recarga', async () => {
120
- const action: TriggerAction = {
121
- id: 'markDelivered',
122
- label: 'Marcar entregado',
123
- type: 'trigger',
124
- };
125
- const ctx = contexto();
126
-
127
- const resultado = await ejecutar('trigger', action)(ctx, action);
128
-
129
- expect(ctx.api.request).toHaveBeenCalledWith('POST', '/admin/orders/p1/actions/markDelivered');
130
- expect(resultado).toEqual({ ok: true, reload: true });
131
- });
132
-
133
- it('trigger usa `name` cuando en el back se llama distinto que el `id`', async () => {
134
- const action: TriggerAction = {
135
- id: 'reenviar',
136
- label: 'Reenviar pin',
137
- type: 'trigger',
138
- name: 'resendPin',
139
- };
140
- const ctx = contexto();
141
-
142
- await ejecutar('trigger', action)(ctx, action);
143
-
144
- expect(ctx.api.request).toHaveBeenCalledWith('POST', '/admin/orders/p1/actions/resendPin');
145
- });
146
-
147
- it('sin clave de registro no dispara nada y lo dice (fail-loud)', async () => {
148
- const action: TriggerAction = { id: 'markDelivered', label: 'Marcar', type: 'trigger' };
149
- const ctx = contexto();
150
- ctx.record = null;
151
-
152
- await expect(ejecutar('trigger', action)(ctx, action)).rejects.toThrow('necesita la clave ref');
153
- expect(ctx.api.request).not.toHaveBeenCalled();
154
- });
155
- });