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

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
@@ -0,0 +1,408 @@
1
+ import { t as __exportAll } from "./tinya-code-gas-admin-ui-rolldown-runtime-DpJrqANO.mjs";
2
+ import { b as ApiError } from "./tinya-code-gas-admin-ui-schema-catalog-D0Pk0wAN.mjs";
3
+ import { t as Button } from "./tinya-code-gas-admin-ui-button-BQjNW8KB.mjs";
4
+ import { t as NotificationService } from "./tinya-code-gas-admin-ui-notification.service-LjSULER6.mjs";
5
+ import { t as UploadService } from "./tinya-code-gas-admin-ui-upload.service-CZPEPCeN.mjs";
6
+ import * as i0 from "@angular/core";
7
+ import { Component, DestroyRef, computed, inject, input, model, output, signal, viewChild } from "@angular/core";
8
+ import { HttpEventType } from "@angular/common/http";
9
+ var file_exports = /* @__PURE__ */ __exportAll({ FieldFile: () => FieldFile });
10
+ var FieldFile = class FieldFile {
11
+ field = input.required(...ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []);
12
+ resource = input("", ...ngDevMode ? [{ debugName: "resource" }] : /* istanbul ignore next */ []);
13
+ value = model.required(...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
14
+ disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
15
+ touch = output();
16
+ upload = inject(UploadService);
17
+ notifications = inject(NotificationService);
18
+ destroyRef = inject(DestroyRef);
19
+ uploading = signal(false, ...ngDevMode ? [{ debugName: "uploading" }] : /* istanbul ignore next */ []);
20
+ progress = signal(0, ...ngDevMode ? [{ debugName: "progress" }] : /* istanbul ignore next */ []);
21
+ error = signal(null, ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
22
+ fileName = computed(() => {
23
+ const url = this.value();
24
+ const segment = url.split("/").pop() ?? url;
25
+ return decodeURIComponent(segment);
26
+ }, ...ngDevMode ? [{ debugName: "fileName" }] : /* istanbul ignore next */ []);
27
+ acceptAttr = computed(() => this.field().accept ?? "", ...ngDevMode ? [{ debugName: "acceptAttr" }] : /* istanbul ignore next */ []);
28
+ fileInput = viewChild.required("fileInput", ...ngDevMode ? [{ debugName: "fileInput" }] : /* istanbul ignore next */ []);
29
+ uploadSub;
30
+ pickFile() {
31
+ this.fileInput().nativeElement.click();
32
+ }
33
+ clear() {
34
+ this.value.set("");
35
+ this.error.set(null);
36
+ this.touch.emit();
37
+ }
38
+ onFileSelected(event) {
39
+ const input = event.target;
40
+ const file = input.files?.[0];
41
+ input.value = "";
42
+ if (file) this.startUpload(file);
43
+ }
44
+ onDrop(event) {
45
+ event.preventDefault();
46
+ const file = event.dataTransfer?.files?.[0];
47
+ if (file) this.startUpload(file);
48
+ }
49
+ startUpload(file) {
50
+ if (this.disabled()) return;
51
+ const problem = this.validate(file);
52
+ if (problem !== null) {
53
+ this.error.set(problem);
54
+ this.touch.emit();
55
+ return;
56
+ }
57
+ this.error.set(null);
58
+ this.uploading.set(true);
59
+ this.progress.set(0);
60
+ this.touch.emit();
61
+ this.uploadSub?.unsubscribe();
62
+ this.uploadSub = this.upload.uploadWithProgress(file, this.resource(), this.field().key).subscribe({
63
+ next: (event) => {
64
+ if (event.type === HttpEventType.UploadProgress) {
65
+ if (event.total) this.progress.set(Math.round(event.loaded / event.total * 100));
66
+ return;
67
+ }
68
+ if (event.type === HttpEventType.Response) {
69
+ const url = event.body ?? "";
70
+ this.uploading.set(false);
71
+ if (url === "") {
72
+ this.error.set("No se pudo subir el archivo.");
73
+ return;
74
+ }
75
+ this.value.set(url);
76
+ this.notifications.success("Archivo subido.");
77
+ }
78
+ },
79
+ error: (err) => {
80
+ this.uploading.set(false);
81
+ this.error.set(err instanceof ApiError ? err.message : "No se pudo subir el archivo. Revisa la conexión e inténtalo de nuevo.");
82
+ }
83
+ });
84
+ this.destroyRef.onDestroy(() => this.uploadSub?.unsubscribe());
85
+ }
86
+ validate(file) {
87
+ const accept = this.field().accept;
88
+ if (accept !== void 0 && accept !== "" && !acceptMatches(accept, file)) return "Formato no permitido para este campo.";
89
+ const maxSizeMB = this.field().maxSizeMB;
90
+ if (maxSizeMB !== void 0 && file.size > maxSizeMB * 1024 * 1024) return `El archivo supera ${maxSizeMB} MB.`;
91
+ return null;
92
+ }
93
+ static ɵfac = i0.ɵɵngDeclareFactory({
94
+ minVersion: "12.0.0",
95
+ version: "22.2.3",
96
+ ngImport: i0,
97
+ type: FieldFile,
98
+ deps: [],
99
+ target: i0.ɵɵFactoryTarget.Component
100
+ });
101
+ static ɵcmp = i0.ɵɵngDeclareComponent({
102
+ minVersion: "17.0.0",
103
+ version: "22.2.3",
104
+ type: FieldFile,
105
+ isStandalone: true,
106
+ selector: "app-field-file",
107
+ inputs: {
108
+ field: {
109
+ classPropertyName: "field",
110
+ publicName: "field",
111
+ isSignal: true,
112
+ isRequired: true,
113
+ transformFunction: null
114
+ },
115
+ resource: {
116
+ classPropertyName: "resource",
117
+ publicName: "resource",
118
+ isSignal: true,
119
+ isRequired: false,
120
+ transformFunction: null
121
+ },
122
+ value: {
123
+ classPropertyName: "value",
124
+ publicName: "value",
125
+ isSignal: true,
126
+ isRequired: true,
127
+ transformFunction: null
128
+ },
129
+ disabled: {
130
+ classPropertyName: "disabled",
131
+ publicName: "disabled",
132
+ isSignal: true,
133
+ isRequired: false,
134
+ transformFunction: null
135
+ }
136
+ },
137
+ outputs: {
138
+ value: "valueChange",
139
+ touch: "touch"
140
+ },
141
+ viewQueries: [{
142
+ propertyName: "fileInput",
143
+ first: true,
144
+ predicate: ["fileInput"],
145
+ descendants: true,
146
+ isSignal: true
147
+ }],
148
+ ngImport: i0,
149
+ template: ` @if (error(); as message) {
150
+ <p
151
+ class="mb-2 rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-xs text-danger"
152
+ role="alert"
153
+ >
154
+ {{ message }}
155
+ </p>
156
+ }
157
+ @if (uploading()) {
158
+ <div class="rounded-xl border border-neutral/20 bg-surface p-3" data-testid="file-uploading">
159
+ <div class="h-1.5 w-full overflow-hidden rounded-full bg-neutral/20">
160
+ <div
161
+ class="h-full rounded-full bg-primary transition-all"
162
+ [style.width.%]="progress()"
163
+ ></div>
164
+ </div>
165
+ <p class="mt-1 text-xs text-neutral">Subiendo… {{ progress() }}%</p>
166
+ </div>
167
+ } @else if (value()) {
168
+ <div
169
+ class="rounded-xl border border-neutral/20 bg-surface p-3"
170
+ data-testid="file-preview"
171
+ (dragover)="$event.preventDefault()"
172
+ (drop)="onDrop($event)"
173
+ >
174
+ <p class="truncate text-sm font-medium" [title]="value()">{{ fileName() }}</p>
175
+ <div class="mt-2 flex flex-wrap items-center gap-2">
176
+ <button
177
+ type="button"
178
+ app-button
179
+ variant="outline"
180
+ [disabled]="disabled()"
181
+ (click)="pickFile()"
182
+ >
183
+ Reemplazar
184
+ </button>
185
+ @if (!field().required) {
186
+ <button
187
+ type="button"
188
+ app-button
189
+ variant="outline"
190
+ [disabled]="disabled()"
191
+ (click)="clear()"
192
+ >
193
+ Quitar
194
+ </button>
195
+ }
196
+ <a
197
+ class="text-sm font-medium text-primary hover:underline"
198
+ [href]="value()"
199
+ target="_blank"
200
+ rel="noopener noreferrer"
201
+ >
202
+ Abrir
203
+ </a>
204
+ </div>
205
+ </div>
206
+ } @else {
207
+ <div
208
+ class="rounded-xl border-2 border-dashed border-neutral/30 p-6 text-center"
209
+ data-testid="file-dropzone"
210
+ (dragover)="$event.preventDefault()"
211
+ (drop)="onDrop($event)"
212
+ >
213
+ <p class="text-sm text-neutral">Arrastrá un archivo acá</p>
214
+ <button
215
+ type="button"
216
+ app-button
217
+ variant="outline"
218
+ class="mt-2"
219
+ [disabled]="disabled()"
220
+ (click)="pickFile()"
221
+ >
222
+ Subir archivo
223
+ </button>
224
+ </div>
225
+ }
226
+
227
+ <input
228
+ #fileInput
229
+ type="file"
230
+ class="sr-only"
231
+ [accept]="acceptAttr()"
232
+ [disabled]="disabled()"
233
+ (change)="onFileSelected($event)"
234
+ />`,
235
+ isInline: true,
236
+ dependencies: [{
237
+ kind: "component",
238
+ type: Button,
239
+ selector: "button[app-button]",
240
+ inputs: [
241
+ "variant",
242
+ "size",
243
+ "type",
244
+ "disabled",
245
+ "loading"
246
+ ]
247
+ }]
248
+ });
249
+ };
250
+ i0.ɵɵngDeclareClassMetadata({
251
+ minVersion: "12.0.0",
252
+ version: "22.2.3",
253
+ ngImport: i0,
254
+ type: FieldFile,
255
+ decorators: [{
256
+ type: Component,
257
+ args: [{
258
+ selector: "app-field-file",
259
+ imports: [Button],
260
+ template: ` @if (error(); as message) {
261
+ <p
262
+ class="mb-2 rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-xs text-danger"
263
+ role="alert"
264
+ >
265
+ {{ message }}
266
+ </p>
267
+ }
268
+ @if (uploading()) {
269
+ <div class="rounded-xl border border-neutral/20 bg-surface p-3" data-testid="file-uploading">
270
+ <div class="h-1.5 w-full overflow-hidden rounded-full bg-neutral/20">
271
+ <div
272
+ class="h-full rounded-full bg-primary transition-all"
273
+ [style.width.%]="progress()"
274
+ ></div>
275
+ </div>
276
+ <p class="mt-1 text-xs text-neutral">Subiendo… {{ progress() }}%</p>
277
+ </div>
278
+ } @else if (value()) {
279
+ <div
280
+ class="rounded-xl border border-neutral/20 bg-surface p-3"
281
+ data-testid="file-preview"
282
+ (dragover)="$event.preventDefault()"
283
+ (drop)="onDrop($event)"
284
+ >
285
+ <p class="truncate text-sm font-medium" [title]="value()">{{ fileName() }}</p>
286
+ <div class="mt-2 flex flex-wrap items-center gap-2">
287
+ <button
288
+ type="button"
289
+ app-button
290
+ variant="outline"
291
+ [disabled]="disabled()"
292
+ (click)="pickFile()"
293
+ >
294
+ Reemplazar
295
+ </button>
296
+ @if (!field().required) {
297
+ <button
298
+ type="button"
299
+ app-button
300
+ variant="outline"
301
+ [disabled]="disabled()"
302
+ (click)="clear()"
303
+ >
304
+ Quitar
305
+ </button>
306
+ }
307
+ <a
308
+ class="text-sm font-medium text-primary hover:underline"
309
+ [href]="value()"
310
+ target="_blank"
311
+ rel="noopener noreferrer"
312
+ >
313
+ Abrir
314
+ </a>
315
+ </div>
316
+ </div>
317
+ } @else {
318
+ <div
319
+ class="rounded-xl border-2 border-dashed border-neutral/30 p-6 text-center"
320
+ data-testid="file-dropzone"
321
+ (dragover)="$event.preventDefault()"
322
+ (drop)="onDrop($event)"
323
+ >
324
+ <p class="text-sm text-neutral">Arrastrá un archivo acá</p>
325
+ <button
326
+ type="button"
327
+ app-button
328
+ variant="outline"
329
+ class="mt-2"
330
+ [disabled]="disabled()"
331
+ (click)="pickFile()"
332
+ >
333
+ Subir archivo
334
+ </button>
335
+ </div>
336
+ }
337
+
338
+ <input
339
+ #fileInput
340
+ type="file"
341
+ class="sr-only"
342
+ [accept]="acceptAttr()"
343
+ [disabled]="disabled()"
344
+ (change)="onFileSelected($event)"
345
+ />`
346
+ }]
347
+ }],
348
+ propDecorators: {
349
+ field: [{
350
+ type: i0.Input,
351
+ args: [{
352
+ isSignal: true,
353
+ alias: "field",
354
+ required: true
355
+ }]
356
+ }],
357
+ resource: [{
358
+ type: i0.Input,
359
+ args: [{
360
+ isSignal: true,
361
+ alias: "resource",
362
+ required: false
363
+ }]
364
+ }],
365
+ value: [{
366
+ type: i0.Input,
367
+ args: [{
368
+ isSignal: true,
369
+ alias: "value",
370
+ required: true
371
+ }]
372
+ }, {
373
+ type: i0.Output,
374
+ args: ["valueChange"]
375
+ }],
376
+ disabled: [{
377
+ type: i0.Input,
378
+ args: [{
379
+ isSignal: true,
380
+ alias: "disabled",
381
+ required: false
382
+ }]
383
+ }],
384
+ touch: [{
385
+ type: i0.Output,
386
+ args: ["touch"]
387
+ }],
388
+ fileInput: [{
389
+ type: i0.ViewChild,
390
+ args: ["fileInput", { isSignal: true }]
391
+ }]
392
+ }
393
+ });
394
+ function acceptMatches(accept, file) {
395
+ for (const raw of accept.split(",")) {
396
+ const entry = raw.trim().toLowerCase();
397
+ if (entry === "") continue;
398
+ if (entry.startsWith(".")) {
399
+ if (file.name.toLowerCase().endsWith(entry)) return true;
400
+ } else if (entry.endsWith("/*")) {
401
+ if (file.type.startsWith(entry.slice(0, -1))) return true;
402
+ } else if (file.type === entry) return true;
403
+ }
404
+ return false;
405
+ }
406
+ export { file_exports as n, FieldFile as t };
407
+
408
+ //# sourceMappingURL=tinya-code-gas-admin-ui-file-Dmxioog7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tinya-code-gas-admin-ui-file-Dmxioog7.mjs","names":[],"sources":["../../../projects/gas-admin-ui/src/lib/fields/file/file.ts"],"sourcesContent":["import { HttpEventType } from '@angular/common/http';\nimport {\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport type { FileField } from '../../core/models/schema.model';\nimport { ApiError } from '../../core/models/api.model';\nimport { NotificationService } from '../../core/services/notification.service';\nimport { Button } from '../../shared/components/button/button';\nimport { UploadService } from '../../core/services/upload.service';\n\n/**\n * Carga de archivo (base.md §7 · R9.5.3): el valor es SOLO la URL pública,\n * igual que `image`, pero para cualquier tipo de archivo (pdf, xlsx, zip…).\n *\n * Espejo de `FieldImage` (D27: es un control propio que no pasa por\n * `NgComponentOutlet`, porque su `value` es un `model()` que el host\n * sincroniza por `[formField]`). La ÚNICA diferencia de comportamiento: no\n * fuerza el prefijo `image/` — el catálogo de formatos lo define el backend\n * por campo (`formats` declarado) o la lista global, y el cliente sólo\n * respeta `accept`/`maxSizeMB` como validación de comodidad.\n *\n * Estados: vacío (zona punteada + arrastrar-soltar), subiendo (progreso; el\n * valor no cambia hasta la respuesta), con archivo (nombre + Quitar / Ver) y\n * error (conserva el archivo anterior).\n */\n@Component({\n selector: 'app-field-file',\n imports: [Button],\n template: ` @if (error(); as message) {\n <p\n class=\"mb-2 rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-xs text-danger\"\n role=\"alert\"\n >\n {{ message }}\n </p>\n }\n @if (uploading()) {\n <div class=\"rounded-xl border border-neutral/20 bg-surface p-3\" data-testid=\"file-uploading\">\n <div class=\"h-1.5 w-full overflow-hidden rounded-full bg-neutral/20\">\n <div\n class=\"h-full rounded-full bg-primary transition-all\"\n [style.width.%]=\"progress()\"\n ></div>\n </div>\n <p class=\"mt-1 text-xs text-neutral\">Subiendo… {{ progress() }}%</p>\n </div>\n } @else if (value()) {\n <div\n class=\"rounded-xl border border-neutral/20 bg-surface p-3\"\n data-testid=\"file-preview\"\n (dragover)=\"$event.preventDefault()\"\n (drop)=\"onDrop($event)\"\n >\n <p class=\"truncate text-sm font-medium\" [title]=\"value()\">{{ fileName() }}</p>\n <div class=\"mt-2 flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n app-button\n variant=\"outline\"\n [disabled]=\"disabled()\"\n (click)=\"pickFile()\"\n >\n Reemplazar\n </button>\n @if (!field().required) {\n <button\n type=\"button\"\n app-button\n variant=\"outline\"\n [disabled]=\"disabled()\"\n (click)=\"clear()\"\n >\n Quitar\n </button>\n }\n <a\n class=\"text-sm font-medium text-primary hover:underline\"\n [href]=\"value()\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Abrir\n </a>\n </div>\n </div>\n } @else {\n <div\n class=\"rounded-xl border-2 border-dashed border-neutral/30 p-6 text-center\"\n data-testid=\"file-dropzone\"\n (dragover)=\"$event.preventDefault()\"\n (drop)=\"onDrop($event)\"\n >\n <p class=\"text-sm text-neutral\">Arrastrá un archivo acá</p>\n <button\n type=\"button\"\n app-button\n variant=\"outline\"\n class=\"mt-2\"\n [disabled]=\"disabled()\"\n (click)=\"pickFile()\"\n >\n Subir archivo\n </button>\n </div>\n }\n\n <input\n #fileInput\n type=\"file\"\n class=\"sr-only\"\n [accept]=\"acceptAttr()\"\n [disabled]=\"disabled()\"\n (change)=\"onFileSelected($event)\"\n />`,\n})\nexport class FieldFile implements FormValueControl<string> {\n readonly field = input.required<FileField>();\n /** Recurso dueño del archivo (firma de subida: carpeta de Cloudinary, §11.2). */\n readonly resource = input('');\n\n /** Sincronizado por el directive `FormField` del host. */\n readonly value = model.required<string>();\n readonly disabled = input(false);\n /** Marca el campo como tocado (upload/clear/error), como el `blur` nativo. */\n readonly touch = output<void>();\n\n private readonly upload = inject(UploadService);\n private readonly notifications = inject(NotificationService);\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly uploading = signal(false);\n protected readonly progress = signal(0);\n protected readonly error = signal<string | null>(null);\n\n /**\n * Nombre derivado de la URL para el preview. Cloudinary guarda el\n * `public_id` al final del path (…/v123/produccion/adjuntos/archivo_xyz):\n * lo presentable es el sufijo tras el último `/`, sin extensión ruidosa.\n */\n protected readonly fileName = computed(() => {\n const url = this.value();\n const segment = url.split('/').pop() ?? url;\n return decodeURIComponent(segment);\n });\n\n /** `accept` de `<input type=file>`: el declarado o `''` (sin forzar `image/*`). */\n protected readonly acceptAttr = computed(() => this.field().accept ?? '');\n\n /**\n * Template ref `#fileInput`: Angular NO auto-asigna las template refs a\n * propiedades de clase (mismo motivo que en `FieldImage`).\n */\n private readonly fileInput = viewChild.required<ElementRef<HTMLInputElement>>('fileInput');\n private uploadSub?: { unsubscribe(): void };\n\n protected pickFile(): void {\n this.fileInput().nativeElement.click();\n }\n\n protected clear(): void {\n this.value.set('');\n this.error.set(null);\n this.touch.emit();\n }\n\n protected onFileSelected(event: Event): void {\n const input = event.target as HTMLInputElement;\n const file = input.files?.[0];\n // Permite volver a elegir el mismo archivo tras un error.\n input.value = '';\n if (file) {\n this.startUpload(file);\n }\n }\n\n protected onDrop(event: Event): void {\n event.preventDefault();\n const file = (event as DragEvent).dataTransfer?.files?.[0];\n if (file) {\n this.startUpload(file);\n }\n }\n\n /** Valida en cliente (accept + maxSizeMB) y sube con progreso. */\n private startUpload(file: File): void {\n if (this.disabled()) {\n return;\n }\n const problem = this.validate(file);\n if (problem !== null) {\n this.error.set(problem);\n this.touch.emit();\n return;\n }\n this.error.set(null);\n this.uploading.set(true);\n this.progress.set(0);\n this.touch.emit();\n\n this.uploadSub?.unsubscribe();\n // El nombre del campo viaja siempre: si declara `formats`, el backend\n // firma ESA lista; sin formatos firma la lista global (R9.5.3).\n this.uploadSub = this.upload\n .uploadWithProgress(file, this.resource(), this.field().key)\n .subscribe({\n next: (event) => {\n if (event.type === HttpEventType.UploadProgress) {\n if (event.total) {\n this.progress.set(Math.round((event.loaded / event.total) * 100));\n }\n return;\n }\n if (event.type === HttpEventType.Response) {\n const url = event.body ?? '';\n this.uploading.set(false);\n if (url === '') {\n this.error.set('No se pudo subir el archivo.');\n return;\n }\n this.value.set(url);\n this.notifications.success('Archivo subido.');\n }\n },\n error: (err: unknown) => {\n this.uploading.set(false);\n // El backend explica el motivo (firma inválida, 429 rate-limit…).\n this.error.set(\n err instanceof ApiError\n ? err.message\n : 'No se pudo subir el archivo. Revisa la conexión e inténtalo de nuevo.',\n );\n },\n });\n this.destroyRef.onDestroy(() => this.uploadSub?.unsubscribe());\n }\n\n private validate(file: File): string | null {\n const accept = this.field().accept;\n if (accept !== undefined && accept !== '' && !acceptMatches(accept, file)) {\n return 'Formato no permitido para este campo.';\n }\n const maxSizeMB = this.field().maxSizeMB;\n if (maxSizeMB !== undefined && file.size > maxSizeMB * 1024 * 1024) {\n return `El archivo supera ${maxSizeMB} MB.`;\n }\n return null;\n }\n}\n\n/** `accept` de `<input type=file>`: lista, `tipo/*` o extensión `.png`. */\nfunction acceptMatches(accept: string, file: File): boolean {\n for (const raw of accept.split(',')) {\n const entry = raw.trim().toLowerCase();\n if (entry === '') {\n continue;\n }\n if (entry.startsWith('.')) {\n if (file.name.toLowerCase().endsWith(entry)) {\n return true;\n }\n } else if (entry.endsWith('/*')) {\n if (file.type.startsWith(entry.slice(0, -1))) {\n return true;\n }\n } else if (file.type === entry) {\n return true;\n }\n }\n return false;\n}\n"],"mappings":"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"}