@ldquocc/dynamic-form 0.0.9 → 0.0.11

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 (298) hide show
  1. package/fesm2022/ldquocc-dynamic-form.mjs +4928 -0
  2. package/fesm2022/ldquocc-dynamic-form.mjs.map +1 -0
  3. package/index.d.ts +5 -0
  4. package/lib/dynamic-form.component.d.ts +67 -0
  5. package/lib/shared/base/base-select.component.d.ts +19 -0
  6. package/lib/shared/base/base-value-accessor.d.ts +69 -0
  7. package/{src/lib/shared/components/component.ts → lib/shared/components/component.d.ts} +14 -34
  8. package/lib/shared/components/dynamic-field/dynamic-field.component.d.ts +23 -0
  9. package/lib/shared/components/field-user-config/field-user-config.component.d.ts +10 -0
  10. package/lib/shared/components/fields/components/suffix/suffix.component.d.ts +12 -0
  11. package/lib/shared/components/fields/date/date-picker/date-picker.component.d.ts +17 -0
  12. package/lib/shared/components/fields/date/date-range/date-range.component.d.ts +17 -0
  13. package/lib/shared/components/fields/input/input-formatted/input-formatted.component.d.ts +20 -0
  14. package/lib/shared/components/fields/input/input-password/input-password.component.d.ts +12 -0
  15. package/lib/shared/components/fields/input/input-text/input-text.component.d.ts +14 -0
  16. package/lib/shared/components/fields/select/multi-select/multi-select.component.d.ts +21 -0
  17. package/lib/shared/components/fields/select/single-select/single-select.component.d.ts +22 -0
  18. package/lib/shared/components/fields/select/tree-select/tree-select.component.d.ts +28 -0
  19. package/lib/shared/components/fields/textarea/textarea.component.d.ts +14 -0
  20. package/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.d.ts +25 -0
  21. package/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.d.ts +76 -0
  22. package/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.d.ts +27 -0
  23. package/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.d.ts +29 -0
  24. package/lib/shared/config/dynamic-form.config.d.ts +9 -0
  25. package/lib/shared/consts/common/common.const.d.ts +5 -0
  26. package/lib/shared/consts/common/field-dependency.const.d.ts +1 -0
  27. package/lib/shared/consts/common/file.const.d.ts +148 -0
  28. package/{src/lib/shared/consts/common/index.ts → lib/shared/consts/common/index.d.ts} +4 -4
  29. package/lib/shared/consts/common/standalone-import.const.d.ts +7 -0
  30. package/lib/shared/consts/controls/control.const.d.ts +1 -0
  31. package/{src/lib/shared/consts/controls/index.ts → lib/shared/consts/controls/index.d.ts} +1 -1
  32. package/lib/shared/consts/fields/date-field.const.d.ts +7 -0
  33. package/lib/shared/consts/fields/field.const.d.ts +4 -0
  34. package/{src/lib/shared/consts/fields/index.ts → lib/shared/consts/fields/index.d.ts} +5 -5
  35. package/lib/shared/consts/fields/input-field.const.d.ts +4 -0
  36. package/lib/shared/consts/fields/input-formatted-field.const.d.ts +4 -0
  37. package/lib/shared/consts/fields/radio-field.const.d.ts +10 -0
  38. package/lib/shared/consts/fields/select-field.const.d.ts +6 -0
  39. package/lib/shared/consts/fields/upload-field.const.d.ts +1 -0
  40. package/lib/shared/consts/validators/pattern.const.d.ts +2 -0
  41. package/lib/shared/enums/common/field-dependency.enum.d.ts +9 -0
  42. package/lib/shared/enums/common/file-size-type.enum.d.ts +6 -0
  43. package/{src/lib/shared/enums/common/index.ts → lib/shared/enums/common/index.d.ts} +4 -4
  44. package/lib/shared/enums/common/output-value-type.enum.d.ts +19 -0
  45. package/lib/shared/enums/common/view-mode.enum.d.ts +4 -0
  46. package/lib/shared/enums/controls/control.enum.d.ts +11 -0
  47. package/{src/lib/shared/enums/controls/index.ts → lib/shared/enums/controls/index.d.ts} +1 -1
  48. package/lib/shared/enums/fields/date-field.enum.d.ts +4 -0
  49. package/lib/shared/enums/fields/field.enum.d.ts +20 -0
  50. package/{src/lib/shared/enums/fields/index.ts → lib/shared/enums/fields/index.d.ts} +6 -6
  51. package/lib/shared/enums/fields/input-field.enum.d.ts +6 -0
  52. package/lib/shared/enums/fields/input-formatted-field.enum.d.ts +6 -0
  53. package/lib/shared/enums/fields/select-field.enum.d.ts +4 -0
  54. package/lib/shared/enums/fields/upload-field.enum.d.ts +5 -0
  55. package/lib/shared/enums/form/dynamic-form.enum.d.ts +6 -0
  56. package/{src/lib/shared/enums/form/index.ts → lib/shared/enums/form/index.d.ts} +1 -1
  57. package/{src/lib/shared/enums/validators/index.ts → lib/shared/enums/validators/index.d.ts} +2 -2
  58. package/lib/shared/enums/validators/regex.enum.d.ts +38 -0
  59. package/lib/shared/enums/validators/validators.enum.d.ts +14 -0
  60. package/lib/shared/factories/auto-numeric-options.factory.d.ts +5 -0
  61. package/lib/shared/models/common/api-config.model.d.ts +4 -0
  62. package/lib/shared/models/common/api-response.model.d.ts +19 -0
  63. package/lib/shared/models/common/common.model.d.ts +29 -0
  64. package/lib/shared/models/common/field-dependency.model.d.ts +16 -0
  65. package/lib/shared/models/common/file-config.model.d.ts +11 -0
  66. package/{src/lib/shared/models/common/index.ts → lib/shared/models/common/index.d.ts} +7 -7
  67. package/lib/shared/models/common/obj-field.model.d.ts +59 -0
  68. package/lib/shared/models/common/object-storage.model.d.ts +15 -0
  69. package/{src/lib/shared/models/common/output-value-type.model.ts → lib/shared/models/common/output-value-type.model.d.ts} +4 -4
  70. package/lib/shared/models/common/table-models.d.ts +15 -0
  71. package/{src/lib/shared/models/common/view-mode.model.ts → lib/shared/models/common/view-mode.model.d.ts} +1 -1
  72. package/{src/lib/shared/models/controls/control.model.ts → lib/shared/models/controls/control.model.d.ts} +2 -3
  73. package/{src/lib/shared/models/controls/index.ts → lib/shared/models/controls/index.d.ts} +1 -1
  74. package/lib/shared/models/fields/date/base-date-field.model.d.ts +19 -0
  75. package/lib/shared/models/fields/date/date-picker-field.model.d.ts +12 -0
  76. package/lib/shared/models/fields/date/date-range-field.model.d.ts +12 -0
  77. package/{src/lib/shared/models/fields/date/index.ts → lib/shared/models/fields/date/index.d.ts} +3 -3
  78. package/lib/shared/models/fields/field-grid.model.d.ts +9 -0
  79. package/lib/shared/models/fields/field-group.model.d.ts +21 -0
  80. package/lib/shared/models/fields/field-user-config.model.d.ts +3 -0
  81. package/lib/shared/models/fields/field.model.d.ts +57 -0
  82. package/{src/lib/shared/models/fields/index.ts → lib/shared/models/fields/index.d.ts} +2 -2
  83. package/{src/lib/shared/models/fields/input/index.ts → lib/shared/models/fields/input/index.d.ts} +4 -4
  84. package/lib/shared/models/fields/input/input-field.model.d.ts +31 -0
  85. package/lib/shared/models/fields/input/input-formatted-field.model.d.ts +13 -0
  86. package/lib/shared/models/fields/input/input-password-field.model.d.ts +11 -0
  87. package/lib/shared/models/fields/input/input-text-field.model.d.ts +9 -0
  88. package/lib/shared/models/fields/radio/radio-base-field.model.d.ts +26 -0
  89. package/lib/shared/models/fields/select/multi-select-field.model.d.ts +11 -0
  90. package/lib/shared/models/fields/select/select-base-field.model.d.ts +40 -0
  91. package/lib/shared/models/fields/select/single-select-field.model.d.ts +9 -0
  92. package/lib/shared/models/fields/select/tree-select-field.model.d.ts +10 -0
  93. package/lib/shared/models/fields/textarea/textarea-field.model.d.ts +20 -0
  94. package/lib/shared/models/fields/upload/avatar-upload-field.model.d.ts +9 -0
  95. package/lib/shared/models/fields/upload/base-upload-field.model.d.ts +25 -0
  96. package/{src/lib/shared/models/fields/upload/index.ts → lib/shared/models/fields/upload/index.d.ts} +5 -5
  97. package/lib/shared/models/fields/upload/multi-file-upload-field.model.d.ts +10 -0
  98. package/lib/shared/models/fields/upload/multi-image-upload-field.model.d.ts +12 -0
  99. package/lib/shared/models/fields/upload/single-file-upload-field.model.d.ts +11 -0
  100. package/{src/lib/shared/models/form/dynamic-form.model.ts → lib/shared/models/form/dynamic-form.model.d.ts} +1 -1
  101. package/{src/lib/shared/models/form/index.ts → lib/shared/models/form/index.d.ts} +1 -1
  102. package/lib/shared/services/dynamic-form.service.d.ts +48 -0
  103. package/lib/shared/services/field.service.d.ts +41 -0
  104. package/lib/shared/services/file.service.d.ts +20 -0
  105. package/lib/shared/services/form-config.service.d.ts +10 -0
  106. package/lib/shared/services/form-data.service.d.ts +53 -0
  107. package/lib/shared/services/form-utils.d.ts +5 -0
  108. package/lib/shared/services/suffix.service.d.ts +12 -0
  109. package/lib/shared/services/validation.service.d.ts +10 -0
  110. package/lib/shared/utils/common/common.utils.d.ts +7 -0
  111. package/{src/lib/shared/utils/common/index.ts → lib/shared/utils/common/index.d.ts} +1 -1
  112. package/lib/shared/utils/date/date.utils.d.ts +6 -0
  113. package/{src/lib/shared/utils/date/index.ts → lib/shared/utils/date/index.d.ts} +1 -1
  114. package/lib/shared/utils/dynamic-form/dynamic-form.d.ts +11 -0
  115. package/lib/shared/utils/fields/fields.d.ts +20 -0
  116. package/{src/lib/shared/utils/fields/index.ts → lib/shared/utils/fields/index.d.ts} +1 -1
  117. package/lib/shared/utils/file/file.utils.d.ts +4 -0
  118. package/{src/lib/shared/utils/file/index.ts → lib/shared/utils/file/index.d.ts} +1 -1
  119. package/lib/shared/utils/validators/custom-validators.d.ts +11 -0
  120. package/lib/shared/utils/validators/default-error-message.d.ts +6 -0
  121. package/{src/lib/shared/utils/validators/index.ts → lib/shared/utils/validators/index.d.ts} +3 -3
  122. package/lib/shared/utils/validators/pattern.d.ts +4 -0
  123. package/package.json +31 -20
  124. package/{src/public-api.ts → public-api.d.ts} +29 -68
  125. package/ng-package.json +0 -15
  126. package/src/lib/dynamic-form.component.html +0 -121
  127. package/src/lib/dynamic-form.component.scss +0 -7
  128. package/src/lib/dynamic-form.component.spec.ts +0 -21
  129. package/src/lib/dynamic-form.component.ts +0 -237
  130. package/src/lib/dynamic-form.service.spec.ts +0 -16
  131. package/src/lib/dynamic-form.service.ts +0 -9
  132. package/src/lib/shared/base/base-select.component.ts +0 -183
  133. package/src/lib/shared/base/base-value-accessor.ts +0 -192
  134. package/src/lib/shared/components/d-form-testing/d-form-testing.component.html +0 -197
  135. package/src/lib/shared/components/d-form-testing/d-form-testing.component.less +0 -12
  136. package/src/lib/shared/components/d-form-testing/d-form-testing.component.spec.ts +0 -22
  137. package/src/lib/shared/components/d-form-testing/d-form-testing.component.ts +0 -197
  138. package/src/lib/shared/components/dynamic-field/dynamic-field.component.html +0 -218
  139. package/src/lib/shared/components/dynamic-field/dynamic-field.component.scss +0 -28
  140. package/src/lib/shared/components/dynamic-field/dynamic-field.component.spec.ts +0 -21
  141. package/src/lib/shared/components/dynamic-field/dynamic-field.component.ts +0 -67
  142. package/src/lib/shared/components/field-user-config/field-user-config.component.html +0 -38
  143. package/src/lib/shared/components/field-user-config/field-user-config.component.scss +0 -29
  144. package/src/lib/shared/components/field-user-config/field-user-config.component.ts +0 -33
  145. package/src/lib/shared/components/fields/components/suffix/suffix.component.html +0 -42
  146. package/src/lib/shared/components/fields/components/suffix/suffix.component.scss +0 -3
  147. package/src/lib/shared/components/fields/components/suffix/suffix.component.spec.ts +0 -22
  148. package/src/lib/shared/components/fields/components/suffix/suffix.component.ts +0 -32
  149. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.html +0 -20
  150. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.scss +0 -5
  151. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.spec.ts +0 -21
  152. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.ts +0 -148
  153. package/src/lib/shared/components/fields/date/date-range/date-range.component.html +0 -33
  154. package/src/lib/shared/components/fields/date/date-range/date-range.component.scss +0 -22
  155. package/src/lib/shared/components/fields/date/date-range/date-range.component.spec.ts +0 -21
  156. package/src/lib/shared/components/fields/date/date-range/date-range.component.ts +0 -133
  157. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.html +0 -31
  158. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.scss +0 -3
  159. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.spec.ts +0 -21
  160. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.ts +0 -148
  161. package/src/lib/shared/components/fields/input/input-password/input-password.component.html +0 -18
  162. package/src/lib/shared/components/fields/input/input-password/input-password.component.scss +0 -0
  163. package/src/lib/shared/components/fields/input/input-password/input-password.component.spec.ts +0 -21
  164. package/src/lib/shared/components/fields/input/input-password/input-password.component.ts +0 -56
  165. package/src/lib/shared/components/fields/input/input-text/input-text.component.html +0 -73
  166. package/src/lib/shared/components/fields/input/input-text/input-text.component.scss +0 -0
  167. package/src/lib/shared/components/fields/input/input-text/input-text.component.spec.ts +0 -21
  168. package/src/lib/shared/components/fields/input/input-text/input-text.component.ts +0 -98
  169. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.html +0 -73
  170. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.scss +0 -21
  171. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.spec.ts +0 -21
  172. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.ts +0 -212
  173. package/src/lib/shared/components/fields/select/single-select/single-select.component.html +0 -55
  174. package/src/lib/shared/components/fields/select/single-select/single-select.component.scss +0 -1
  175. package/src/lib/shared/components/fields/select/single-select/single-select.component.spec.ts +0 -21
  176. package/src/lib/shared/components/fields/select/single-select/single-select.component.ts +0 -217
  177. package/src/lib/shared/components/fields/select/single-select/sl.component.old.txt +0 -337
  178. package/src/lib/shared/components/fields/select/single-select/sl.component.old2.txt +0 -340
  179. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.html +0 -38
  180. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.scss +0 -1
  181. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.spec.ts +0 -21
  182. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.ts +0 -401
  183. package/src/lib/shared/components/fields/textarea/textarea.component.html +0 -29
  184. package/src/lib/shared/components/fields/textarea/textarea.component.scss +0 -17
  185. package/src/lib/shared/components/fields/textarea/textarea.component.spec.ts +0 -21
  186. package/src/lib/shared/components/fields/textarea/textarea.component.ts +0 -76
  187. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.html +0 -30
  188. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.scss +0 -22
  189. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.spec.ts +0 -22
  190. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.ts +0 -217
  191. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.html +0 -101
  192. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.scss +0 -117
  193. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.spec.ts +0 -22
  194. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.ts +0 -480
  195. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.html +0 -82
  196. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.less +0 -80
  197. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.spec.ts +0 -22
  198. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.ts +0 -288
  199. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.html +0 -104
  200. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.scss +0 -37
  201. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.spec.ts +0 -21
  202. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.ts +0 -317
  203. package/src/lib/shared/config/dynamic-form.config.ts +0 -11
  204. package/src/lib/shared/consts/common/common.const.ts +0 -5
  205. package/src/lib/shared/consts/common/field-dependency.const.ts +0 -1
  206. package/src/lib/shared/consts/common/file.const.ts +0 -130
  207. package/src/lib/shared/consts/common/sample-test.const.ts +0 -1648
  208. package/src/lib/shared/consts/common/standalone-import.const.ts +0 -51
  209. package/src/lib/shared/consts/controls/control.const.ts +0 -11
  210. package/src/lib/shared/consts/fields/date-field.const.ts +0 -12
  211. package/src/lib/shared/consts/fields/field.const.ts +0 -23
  212. package/src/lib/shared/consts/fields/input-field.const.ts +0 -4
  213. package/src/lib/shared/consts/fields/input-formatted-field.const.ts +0 -35
  214. package/src/lib/shared/consts/fields/radio-field.const.ts +0 -31
  215. package/src/lib/shared/consts/fields/select-field.const.ts +0 -7
  216. package/src/lib/shared/consts/fields/upload-field.const.ts +0 -1
  217. package/src/lib/shared/consts/validators/index.ts +0 -0
  218. package/src/lib/shared/consts/validators/pattern.const.ts +0 -117
  219. package/src/lib/shared/enums/common/component-ui.enum.ts +0 -8
  220. package/src/lib/shared/enums/common/field-dependency.enum.ts +0 -10
  221. package/src/lib/shared/enums/common/file-size-type.enum.ts +0 -6
  222. package/src/lib/shared/enums/common/output-value-type.enum.ts +0 -22
  223. package/src/lib/shared/enums/common/view-mode.enum.ts +0 -4
  224. package/src/lib/shared/enums/controls/control.enum.ts +0 -12
  225. package/src/lib/shared/enums/fields/date-field.enum.ts +0 -4
  226. package/src/lib/shared/enums/fields/field.enum.ts +0 -21
  227. package/src/lib/shared/enums/fields/input-field.enum.ts +0 -6
  228. package/src/lib/shared/enums/fields/input-formatted-field.enum.ts +0 -6
  229. package/src/lib/shared/enums/fields/select-field.enum.ts +0 -4
  230. package/src/lib/shared/enums/fields/upload-field.enum.ts +0 -5
  231. package/src/lib/shared/enums/form/dynamic-form.enum.ts +0 -6
  232. package/src/lib/shared/enums/validators/regex.enum.ts +0 -47
  233. package/src/lib/shared/enums/validators/validators.enum.ts +0 -17
  234. package/src/lib/shared/factories/auto-numeric-options.factory.ts +0 -14
  235. package/src/lib/shared/models/common/api-config.model.ts +0 -7
  236. package/src/lib/shared/models/common/api-response.model.ts +0 -20
  237. package/src/lib/shared/models/common/common.model.ts +0 -39
  238. package/src/lib/shared/models/common/field-dependency.model.ts +0 -27
  239. package/src/lib/shared/models/common/file-config.model.ts +0 -22
  240. package/src/lib/shared/models/common/obj-field.model.ts +0 -68
  241. package/src/lib/shared/models/common/object-storage.model.ts +0 -15
  242. package/src/lib/shared/models/common/table-models.ts +0 -16
  243. package/src/lib/shared/models/fields/date/base-date-field.model.ts +0 -52
  244. package/src/lib/shared/models/fields/date/date-picker-field.model.ts +0 -43
  245. package/src/lib/shared/models/fields/date/date-range-field.model.ts +0 -52
  246. package/src/lib/shared/models/fields/field-grid.model.ts +0 -10
  247. package/src/lib/shared/models/fields/field-group.model.ts +0 -50
  248. package/src/lib/shared/models/fields/field-user-config.model.ts +0 -8
  249. package/src/lib/shared/models/fields/field.model.ts +0 -184
  250. package/src/lib/shared/models/fields/input/input-field.model.ts +0 -111
  251. package/src/lib/shared/models/fields/input/input-formatted-field.model.ts +0 -38
  252. package/src/lib/shared/models/fields/input/input-password-field.model.ts +0 -38
  253. package/src/lib/shared/models/fields/input/input-text-field.model.ts +0 -26
  254. package/src/lib/shared/models/fields/radio/index.ts +0 -0
  255. package/src/lib/shared/models/fields/radio/radio-base-field.model.ts +0 -84
  256. package/src/lib/shared/models/fields/select/index.ts +0 -0
  257. package/src/lib/shared/models/fields/select/multi-select-field.model.ts +0 -46
  258. package/src/lib/shared/models/fields/select/select-base-field.model.ts +0 -125
  259. package/src/lib/shared/models/fields/select/single-select-field.model.ts +0 -43
  260. package/src/lib/shared/models/fields/select/tree-select-field.model.ts +0 -44
  261. package/src/lib/shared/models/fields/textarea/index.ts +0 -0
  262. package/src/lib/shared/models/fields/textarea/textarea-field.model.ts +0 -97
  263. package/src/lib/shared/models/fields/upload/avatar-upload-field.model.ts +0 -33
  264. package/src/lib/shared/models/fields/upload/base-upload-field.model.ts +0 -105
  265. package/src/lib/shared/models/fields/upload/multi-file-upload-field.model.ts +0 -34
  266. package/src/lib/shared/models/fields/upload/multi-image-upload-field.model.ts +0 -42
  267. package/src/lib/shared/models/fields/upload/single-file-upload-field.model.ts +0 -33
  268. package/src/lib/shared/models/validations/index.ts +0 -1
  269. package/src/lib/shared/models/validations/validations.model.ts +0 -14
  270. package/src/lib/shared/services/dynamic-form.service.spec.ts +0 -16
  271. package/src/lib/shared/services/dynamic-form.service.ts +0 -251
  272. package/src/lib/shared/services/field.service.spec.ts +0 -16
  273. package/src/lib/shared/services/field.service.ts +0 -152
  274. package/src/lib/shared/services/file.service.spec.ts +0 -16
  275. package/src/lib/shared/services/file.service.ts +0 -53
  276. package/src/lib/shared/services/form-config.service.ts +0 -53
  277. package/src/lib/shared/services/form-data.service.spec.ts +0 -16
  278. package/src/lib/shared/services/form-data.service.ts +0 -114
  279. package/src/lib/shared/services/form-utils.ts +0 -52
  280. package/src/lib/shared/services/suffix.service.spec.ts +0 -16
  281. package/src/lib/shared/services/suffix.service.ts +0 -16
  282. package/src/lib/shared/services/validation.service.spec.ts +0 -16
  283. package/src/lib/shared/services/validation.service.ts +0 -38
  284. package/src/lib/shared/utils/common/common.utils.ts +0 -52
  285. package/src/lib/shared/utils/date/date.utils.ts +0 -129
  286. package/src/lib/shared/utils/dynamic-field/dynamic-field.ts +0 -0
  287. package/src/lib/shared/utils/dynamic-field/index.ts +0 -0
  288. package/src/lib/shared/utils/dynamic-form/dynamic-form.ts +0 -114
  289. package/src/lib/shared/utils/dynamic-form/index.ts +0 -0
  290. package/src/lib/shared/utils/fields/fields.ts +0 -78
  291. package/src/lib/shared/utils/file/file.utils.ts +0 -37
  292. package/src/lib/shared/utils/validators/custom-validators.ts +0 -158
  293. package/src/lib/shared/utils/validators/default-error-message.ts +0 -42
  294. package/src/lib/shared/utils/validators/pattern.ts +0 -26
  295. package/tsconfig.lib.json +0 -15
  296. package/tsconfig.lib.prod.json +0 -11
  297. package/tsconfig.spec.json +0 -15
  298. /package/{src/lib/shared/styles → styles}/_common-form.scss +0 -0
@@ -1,480 +0,0 @@
1
- import {
2
- Component,
3
- computed,
4
- effect,
5
- forwardRef,
6
- inject,
7
- signal,
8
- untracked,
9
- } from "@angular/core";
10
- import { CORE_MODULES } from "../../../../consts/common";
11
- import { BaseValueAccessor } from "../../../../base/base-value-accessor";
12
- import {
13
- NzUploadFile,
14
- NzUploadModule,
15
- NzUploadXHRArgs,
16
- } from "ng-zorro-antd/upload";
17
- import { MultiFileUploadField } from "../../../../models/fields/upload/multi-file-upload-field.model";
18
- import { FieldTypeEnum } from "../../../../enums/fields";
19
- import { isValidJSON } from "../../../../utils/common";
20
- import { MyUploadFile } from "../../../../models/common/common.model";
21
- import { ObjectStorage } from "../../../../models/common";
22
- import { FileService } from "../../../../services/file.service";
23
- import { Observable, of, Subscription } from "rxjs";
24
- import { NG_VALUE_ACCESSOR } from "@angular/forms";
25
- import { ControlTypeEnum } from "../../../../enums/controls";
26
- import { formatFileSize, getExtensions } from "../../../../utils/file";
27
- import { FileSizeTypeEnum } from "../../../../enums/common";
28
- import { FormConfigService } from "../../../../services/form-config.service";
29
- import { NzIconModule } from "ng-zorro-antd/icon";
30
- import { NzButtonModule } from "ng-zorro-antd/button";
31
- import { NzMessageService } from "ng-zorro-antd/message";
32
- import { NzNotificationService } from "ng-zorro-antd/notification";
33
-
34
- const ZORRO_MODULES = [NzUploadModule, NzIconModule, NzButtonModule];
35
-
36
- @Component({
37
- selector: "app-multi-file-upload",
38
- standalone: true,
39
- imports: [...CORE_MODULES, ...ZORRO_MODULES],
40
- templateUrl: "./multi-file-upload.component.html",
41
- styleUrl: "./multi-file-upload.component.scss",
42
- providers: [
43
- {
44
- provide: NG_VALUE_ACCESSOR,
45
- useExisting: forwardRef(() => MultiFileUploadComponent),
46
- multi: true,
47
- },
48
- ],
49
- })
50
- export class MultiFileUploadComponent extends BaseValueAccessor<
51
- string | File | NzUploadFile
52
- > {
53
- // Cast lại đúng instance là MultiFileUploadFile.
54
- readonly field = computed(() => {
55
- const base = this.fieldInput();
56
- if (
57
- !(base instanceof MultiFileUploadField) ||
58
- (base.type !== FieldTypeEnum.MultiFileUpload &&
59
- base.controlType !== ControlTypeEnum.Upload)
60
- ) {
61
- throw new Error("Expected MultiFileUploadField");
62
- }
63
- return base;
64
- });
65
-
66
- // Mảng lưu trữ objectStorage liên quan đến tập tin.
67
- objStorageList = signal<ObjectStorage[]>([]);
68
-
69
- // Mảng đại diện các images.
70
- allFiles = signal<MyUploadFile[]>([]);
71
-
72
- // Text hướng dẫn các loại extension được upload.
73
- readonly fileExtensionGuide = computed(() => {
74
- if (!this.isAddOrEdit()) return "";
75
- const { acceptedMimeTypes } = this.field();
76
- return `Hỗ trợ định dạng ${getExtensions(acceptedMimeTypes).join(", ")}`;
77
- });
78
-
79
- // Đếm số file đã pass beforeUpload nhưng chưa upload xong (đang trong hàng chờ customRequest/uploadFile).
80
- // Dùng để tính toán count chính xác khi user chọn nhiều file cùng lúc.
81
- pendingCount = signal<number>(0);
82
-
83
- // Buffer chứa các file đang chờ xử lý trong một batch (một lần chọn file từ dialog).
84
- private _batchBuffer: Array<{
85
- file: NzUploadFile;
86
- resolve: (pass: boolean) => void;
87
- }> = [];
88
-
89
- // Timer dùng để phát hiện kết thúc một batch (setTimeout(0)).
90
- private _batchTimer: ReturnType<typeof setTimeout> | null = null;
91
-
92
- private fileService = inject(FileService);
93
- private nzMessage = inject(NzMessageService);
94
- private nzNotification = inject(NzNotificationService);
95
- private formConfigService = inject(FormConfigService);
96
-
97
- constructor() {
98
- super();
99
- }
100
-
101
- // Chạy khi value form được gán bởi các hàm reset, patchValue, setValue.
102
- protected override writeValueToView(value: string): void {
103
- this.handleInitAllData(value);
104
-
105
- if (!this.isAddOrEdit()) return;
106
-
107
- // Gán data vào đầu ra của form.
108
- this.patchFormData(this.fieldKey(), value);
109
- }
110
-
111
- // Xử lý init các data cần thiết: objStorageList, allFiles, fileList, lưu giữ first value.
112
- // value sẽ là 1 string json mảng các objStorage.
113
- private handleInitAllData(value: string): void {
114
- // Reset khi đổi mode, hoặc model, hoặc fields.
115
- this.objStorageList.set([]);
116
- this.allFiles.set([]);
117
-
118
- if (isValidJSON(value)) {
119
- // Khởi tạo danh sách ObjectStorage từ data json.
120
- const objStorageList = JSON.parse(value) as ObjectStorage[];
121
- this.objStorageList.set(objStorageList);
122
-
123
- // Khởi tạo danh sách MyUploadFile từ data json.
124
- // File từ server luôn ở trạng thái success.
125
- const myUploadFiles = objStorageList.map(
126
- (objStorage) =>
127
- ({
128
- objStorage,
129
- isTemp: false,
130
- previewUrl: this.formConfigService.getViewFileUrl(
131
- objStorage.name ?? "",
132
- false,
133
- ),
134
- uploadStatus: "success",
135
- }) as MyUploadFile,
136
- );
137
- this.allFiles.set(myUploadFiles);
138
- }
139
- }
140
-
141
- /**
142
- * Xử lý trước khi upload — trả về Observable<boolean> để hỗ trợ batch detection.
143
- *
144
- * Cơ chế batch detection:
145
- * nz-upload gọi beforeUpload() từng file một (đồng bộ) trong cùng 1 JS tick khi user
146
- * chọn nhiều file. Mỗi lần gọi, file được đẩy vào _batchBuffer. Sau khi tất cả các
147
- * lần gọi đồng bộ kết thúc, setTimeout(0) kích hoạt _processBatch() để xử lý toàn bộ
148
- * batch một lần, cho phép kiểm tra tổng số lượng chính xác trước khi upload.
149
- */
150
- beforeUpload = (file: NzUploadFile): Observable<boolean> => {
151
- return new Observable<boolean>((subscriber) => {
152
- // Đẩy file vào buffer với hàm resolve tương ứng.
153
- this._batchBuffer.push({
154
- file,
155
- resolve: (pass: boolean) => {
156
- subscriber.next(pass);
157
- subscriber.complete();
158
- },
159
- });
160
-
161
- // Reset timer mỗi lần có file mới vào buffer.
162
- // Khi tất cả beforeUpload synchronous calls kết thúc, timer sẽ fire và gọi _processBatch().
163
- if (this._batchTimer !== null) clearTimeout(this._batchTimer);
164
- this._batchTimer = setTimeout(() => this._processBatch(), 0);
165
- });
166
- };
167
-
168
- /**
169
- * Xử lý toàn bộ batch file sau khi tất cả beforeUpload calls trong cùng 1 tick đã hoàn tất.
170
- *
171
- * Logic:
172
- * 1. Nếu tổng (file hiện tại + pending + batch) vượt maxFileCount → reject TOÀN BỘ batch.
173
- * 2. Validate từng file trong batch:
174
- * - File thỏa (MIME + size) → pendingCount++, resolve(true) → cho phép upload.
175
- * - File không thỏa → hiển thị NzMessage lỗi, resolve(false) → bỏ qua.
176
- */
177
- private _processBatch(): void {
178
- const batch = [...this._batchBuffer];
179
- this._batchBuffer = [];
180
- this._batchTimer = null;
181
-
182
- const { maxFileCount, maxSizeInMB, acceptedMimeTypes } = this.field();
183
-
184
- // Số file hiện tại: đã upload xong + đang trong hàng chờ upload.
185
- const currentCount = this.allFiles().length + this.pendingCount();
186
-
187
- // ── CHECK 1: Tổng batch vượt maxFileCount → reject TOÀN BỘ batch ──
188
- if (currentCount + batch.length > maxFileCount) {
189
- this.nzNotification.warning(
190
- "Cảnh báo",
191
- `Không thể tải lên: số lượng file tải lên vượt quá giới hạn cho phép. Tối đa ${maxFileCount} tập tin.`,
192
- { nzDuration: 4500 },
193
- );
194
- batch.forEach(({ resolve }) => resolve(false));
195
- return;
196
- }
197
-
198
- // ── CHECK 2: Validate từng file — upload file thỏa, báo lỗi file không thỏa ──
199
- for (const { file, resolve } of batch) {
200
- const originFile = file as unknown as File;
201
- const fileSizeInMB = formatFileSize(file.size!, FileSizeTypeEnum.MB);
202
- const fileType = file.type ?? "";
203
-
204
- const isSizeOk = fileSizeInMB <= maxSizeInMB;
205
- const isMimeOk = acceptedMimeTypes.includes(fileType);
206
-
207
- if (!isSizeOk || !isMimeOk) {
208
- // Xây dựng thông báo lỗi chi tiết cho từng file không thỏa.
209
- const reasons: string[] = [];
210
- if (!isMimeOk) reasons.push(`định dạng không hợp lệ`);
211
- if (!isSizeOk) reasons.push(`kích thước vượt ${maxSizeInMB}MB`);
212
-
213
- this.nzMessage.error(
214
- `"${file.name}" không được tải lên: ${reasons.join(", ")}.`,
215
- );
216
-
217
- // Propagate để CVA/validator hiển thị trạng thái lỗi trên control.
218
- this.propagateValue(originFile);
219
- resolve(false);
220
- continue;
221
- }
222
-
223
- // File hợp lệ: thêm optimistic entry vào allFiles với trạng thái loading ngay lập tức.
224
- // Dùng file.uid (do nz-upload tự tạo, duy nhất cho mỗi NzUploadFile) làm key để track và update sau này.
225
- const uid = file.uid;
226
- this.allFiles.update((curr) => [
227
- ...curr,
228
- {
229
- uid,
230
- objStorage: { id: uid, name: originFile.name }, // placeholder, sẽ được thay bằng data thật sau khi upload
231
- isTemp: true,
232
- previewUrl: "",
233
- uploadStatus: "loading",
234
- } as MyUploadFile,
235
- ]);
236
-
237
- // Propagate để trigger validator, tăng pendingCount, cho phép upload.
238
- this.propagateValue(originFile);
239
- this.pendingCount.update((c) => c + 1);
240
- resolve(true);
241
- }
242
- }
243
-
244
- customRequest = (item: NzUploadXHRArgs): Subscription => {
245
- // const originFile = nzUploadFile?.originFileObj;
246
- const uid = item.file.uid; // Stable key để map với optimistic entry trong allFiles.
247
- const originFile = item.file as unknown as File;
248
-
249
- // Nếu validation không thỏa, dừng tại đây và xóa optimistic entry khỏi list.
250
- if (this.control?.invalid) {
251
- this.pendingCount.update((c) => Math.max(0, c - 1));
252
- this.allFiles.update((curr) => curr.filter((f) => f.uid !== uid));
253
- return of(null).subscribe(); // fake subscription.
254
- }
255
-
256
- // Validation đã thỏa, tiến hành upload file.
257
- return this.uploadFile(originFile, uid);
258
- };
259
-
260
- private uploadFile(file: File, uid: string) {
261
- const { apiFileConfig, uploadTemp } = this.field();
262
- const newFileName = this.formConfigService.generateRandomFileName(
263
- file.name,
264
- "file",
265
- );
266
- const renamedFile = new File([file], newFileName, { type: file.type });
267
-
268
- const mimeCfg = apiFileConfig.perMimeTypeConfig?.[file.type]; // Lấy mimeTypes file upload.
269
- const uploadUrl = mimeCfg?.uploadUrl ?? apiFileConfig.uploadUrl; // Nếu có config upload riêng cho mimeTypes đang kiểm tra.
270
- const formData = mimeCfg?.buildFormData // Nếu có hàm custon buildFormData.
271
- ? mimeCfg.buildFormData(file, {})
272
- : (() => {
273
- // Mặc định
274
- const fd = new FormData();
275
- fd.append("File", renamedFile);
276
- // fd.append('isTemp', 'true');
277
- return fd;
278
- })();
279
-
280
- if (uploadTemp) formData.append("isTemp", "true");
281
-
282
- return this.fileService
283
- .uploadFile(renamedFile, formData, { uploadUrl })
284
- .pipe(this.takeUntilDestroy())
285
- .subscribe({
286
- next: (res) => {
287
- // Giảm pending dù thành công hay thất bại.
288
- this.pendingCount.update((c) => Math.max(0, c - 1));
289
-
290
- const { code, data, message } = res;
291
- if (code === 0) {
292
- // Cập nhật objStorageList với data thật từ server.
293
- this.objStorageList.update((curr) => [...curr, data]);
294
-
295
- // Thay thế optimistic entry (uid) bằng data thật, chuyển sang trạng thái success.
296
- this.allFiles.update((curr) =>
297
- curr.map((f) =>
298
- f.uid === uid
299
- ? ({
300
- ...f,
301
- objStorage: data,
302
- previewUrl: this.formConfigService.getViewFileUrl(
303
- data.name ?? "",
304
- true,
305
- ),
306
- uploadStatus: "success",
307
- } as MyUploadFile)
308
- : f,
309
- ),
310
- );
311
-
312
- this.patchFormData(
313
- this.fieldKey(),
314
- JSON.stringify(this.objStorageList()),
315
- );
316
- // Đồng bộ control value → validators (required) nhận biết có file thành công.
317
- this._syncControlValue();
318
- } else {
319
- // Cập nhật optimistic entry sang trạng thái error.
320
- this.allFiles.update((curr) =>
321
- curr.map((f) =>
322
- f.uid === uid
323
- ? ({ ...f, uploadStatus: "error" } as MyUploadFile)
324
- : f,
325
- ),
326
- );
327
- console.error(message);
328
- // Đồng bộ control value → nếu tất cả file đều fail, objStorageList rỗng → required kích hoạt.
329
- this._syncControlValue();
330
- }
331
- },
332
- error: () => {
333
- // Giảm pending khi upload thất bại.
334
- this.pendingCount.update((c) => Math.max(0, c - 1));
335
- // Cập nhật optimistic entry sang trạng thái error.
336
- this.allFiles.update((curr) =>
337
- curr.map((f) =>
338
- f.uid === uid
339
- ? ({ ...f, uploadStatus: "error" } as MyUploadFile)
340
- : f,
341
- ),
342
- );
343
- console.error("Lỗi trong quá trình tải tập đến máy chủ!!");
344
- // Đồng bộ control value → nếu tất cả file đều fail → required kích hoạt.
345
- this._syncControlValue();
346
- },
347
- });
348
- }
349
-
350
- handleDelete(file: MyUploadFile): void {
351
- const { objStorage, uploadStatus } = file;
352
- const { uploadTemp } = this.field();
353
-
354
- // Loại bỏ và cập nhật danh sách ObjectStorage.
355
- const newObjStorageList = this.objStorageList().filter(
356
- (item) => item.id !== objStorage?.id,
357
- );
358
- this.objStorageList.set(newObjStorageList);
359
-
360
- // Loại bỏ và cập nhật danh sách MyUploadFile.
361
- const newAllFiles = this.allFiles().filter(
362
- (item) => item.objStorage?.id !== objStorage?.id,
363
- );
364
- this.allFiles.set(newAllFiles);
365
-
366
- // File ở trạng thái error: upload chưa thành công, không cần gọi API xoá trên server.
367
- if (uploadStatus === "error") {
368
- this.patchFormData(
369
- this.fieldKey(),
370
- JSON.stringify(this.objStorageList()),
371
- );
372
- // Đồng bộ control value → nếu xóa hết file error còn lại → required kích hoạt.
373
- this._syncControlValue();
374
- return;
375
- }
376
-
377
- if (uploadTemp) {
378
- this.deleteObjStorage(objStorage.id || "");
379
- return;
380
- }
381
-
382
- // Cập nhật đầu ra cho form.
383
- this.patchFormData(this.fieldKey(), JSON.stringify(this.objStorageList()));
384
- // Đồng bộ control value → nếu xóa hết file → required kích hoạt.
385
- this._syncControlValue();
386
- }
387
-
388
- deleteObjStorage(id: string) {
389
- return this.fileService
390
- .deleteObjStorage(id, {
391
- deleteUrl: this.field().apiFileConfig.deleteUrl,
392
- })
393
- .pipe(this.takeUntilDestroy())
394
- .subscribe({
395
- next: (res) => {
396
- const { code, message } = res;
397
- if (code === 0) {
398
- const newObjStorageList = this.objStorageList().filter(
399
- (item) => item.id !== id,
400
- );
401
- this.objStorageList.set(newObjStorageList);
402
-
403
- this.patchFormData(
404
- this.fieldKey(),
405
- JSON.stringify(this.objStorageList()),
406
- );
407
- // Đồng bộ control value sau khi server xác nhận xóa.
408
- this._syncControlValue();
409
- } else {
410
- console.error(message);
411
- }
412
- },
413
- error: () => {
414
- console.error("Lỗi trong quá trình xóa tập tin khỏi máy chủ!!");
415
- // Fake vì hiện api xóa đang có vấn đề.
416
- const newObjStorageList = this.objStorageList().filter(
417
- (item) => item.id !== id,
418
- );
419
- this.objStorageList.set(newObjStorageList);
420
-
421
- this.patchFormData(
422
- this.fieldKey(),
423
- JSON.stringify(this.objStorageList()),
424
- );
425
- // Đồng bộ control value (fake delete thành công).
426
- this._syncControlValue();
427
- // Fake vì hiện api xóa đang có vấn đề.
428
- },
429
- });
430
- }
431
-
432
- /**
433
- * Xử lý click vào file item:
434
- * - Không làm gì nếu file đang loading hoặc ở trạng thái error.
435
- * - Gọi fileClick để xem file nếu đã upload thành công.
436
- */
437
- onFileItemClick(file: MyUploadFile): void {
438
- if (file.uploadStatus === "loading" || file.uploadStatus === "error")
439
- return;
440
- this.fileService.onFileClick(file.objStorage);
441
- }
442
-
443
- fileClick(objStorage: ObjectStorage): void {
444
- this.fileService.onFileClick(objStorage);
445
- }
446
-
447
- /**
448
- * Hủy toàn bộ batch đang chờ xử lý:
449
- * - Clear timer batch detection.
450
- * - Reject tất cả file trong buffer (resolve false).
451
- * - Reset pendingCount về 0.
452
- * Gọi khi form bị reset từ bên ngoài.
453
- */
454
- private _clearBatch(): void {
455
- if (this._batchTimer !== null) {
456
- clearTimeout(this._batchTimer);
457
- this._batchTimer = null;
458
- }
459
- this._batchBuffer.forEach(({ resolve }) => resolve(false));
460
- this._batchBuffer = [];
461
- this.pendingCount.set(0);
462
- }
463
-
464
- /**
465
- * Đồng bộ control value với trạng thái thực tế của danh sách file đã upload thành công.
466
- *
467
- * Gọi sau mỗi thay đổi về danh sách file (upload xong, xóa file) để đảm bảo:
468
- * - Không có file nào thành công → propagateValue('') → Validators.required kích hoạt.
469
- * - Có ít nhất 1 file thành công → propagateValue(JSON string) → validators pass.
470
- *
471
- * Validators hiện tại tương thích:
472
- * - acceptedMimeTypesValidator: bỏ qua nếu value falsy; parse JSON nếu là string.
473
- * - maxFileSizeInMBValidator: bỏ qua nếu value.size undefined (JSON string).
474
- */
475
- private _syncControlValue(): void {
476
- const list = this.objStorageList();
477
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
478
- this.propagateValue((list.length > 0 ? JSON.stringify(list) : "") as any);
479
- }
480
- }
@@ -1,82 +0,0 @@
1
- @if (isAddOrEdit()) {
2
- <div class="upload">
3
- <nz-upload
4
- [nzDisabled]="
5
- allFiles().length >= field().maxFileCount ||
6
- disabledSignal() ||
7
- uploading()
8
- "
9
- [nzShowUploadList]="false"
10
- [nzMultiple]="false"
11
- [nzBeforeUpload]="beforeUpload"
12
- [nzCustomRequest]="customRequest"
13
- >
14
- <button nz-button class="btn-upload" [nzLoading]="uploading()">
15
- Tải lên
16
- @if (!uploading()) {
17
- <nz-icon nzType="upload" nzTheme="outline" />
18
- }
19
- </button>
20
-
21
- <span class="ms-2 text-muted fs-12">
22
- (Đã tải lên {{ allFiles().length }}/{{ field().maxFileCount }}
23
- hình ảnh)
24
- </span>
25
- </nz-upload>
26
- </div>
27
- }
28
-
29
- <!-- Custom hiển thị danh sách hình ảnh -->
30
- @if (allFiles().length > 0) {
31
- <ng-container *ngTemplateOutlet="imageGroupTpl"></ng-container>
32
- }
33
-
34
- <!-- Template custom hiển thị danh sách hình ảnh -->
35
- <ng-template #imageGroupTpl>
36
- <nz-image-group>
37
- <div class="image-list">
38
- @for (file of allFiles(); track file.objStorage?.id; let i = $index) {
39
- <div
40
- class="image-card-container"
41
- [ngStyle]="{
42
- width: field().imageCardWidth,
43
- height: field().imageCardHeight,
44
- }"
45
- >
46
- <div class="image-item">
47
- <div class="image-item-info">
48
- <img
49
- [id]="file.objStorage.id"
50
- nz-image
51
- nzSrc="{{ file.previewUrl }}"
52
- alt="{{ file.objStorage.originalName }}"
53
- />
54
- </div>
55
-
56
- <div class="image-item-actions">
57
- <button
58
- nz-button
59
- nzType="text"
60
- nzSize="small"
61
- (click)="handlePreview(file)"
62
- >
63
- <nz-icon nzType="eye" nzTheme="outline" />
64
- </button>
65
-
66
- @if (isAddOrEdit()) {
67
- <button
68
- nz-button
69
- nzType="text"
70
- nzSize="small"
71
- (click)="handleDelete(file)"
72
- >
73
- <nz-icon nzType="delete" nzTheme="outline" />
74
- </button>
75
- }
76
- </div>
77
- </div>
78
- </div>
79
- }
80
- </div>
81
- </nz-image-group>
82
- </ng-template>
@@ -1,80 +0,0 @@
1
- .upload {
2
- margin-bottom: 0.625rem;
3
- nz-upload {
4
- .btn-upload {
5
- margin-right: 0.75rem;
6
- }
7
- }
8
- }
9
-
10
- .image-list {
11
- display: flex;
12
- gap: 8px;
13
- flex-wrap: nowrap;
14
- overflow-x: auto; /* bật scroll ngang */
15
- //max-width: 20%;
16
-
17
- .image-card-container {
18
- display: inline-block;
19
- margin: 0px 0.5rem 0.5rem 0;
20
- // width: 108px;
21
- // height: 108px;
22
- flex: 0 0 auto; /* item không co giãn, giữ kích thước */
23
-
24
- .image-item {
25
- padding: 0.5rem;
26
- border: 1px solid #cbd5e1;
27
- height: 100%;
28
- cursor: pointer;
29
- position: relative;
30
-
31
- .image-item-info {
32
- position: relative;
33
- height: 100%;
34
- overflow: hidden;
35
-
36
- img {
37
- display: block;
38
- width: 100%;
39
- height: 100%;
40
- object-fit: contain;
41
- }
42
- }
43
-
44
- .image-item-info::before {
45
- position: absolute;
46
- z-index: 1;
47
- width: 100%;
48
- height: 100%;
49
- background-color: rgba(0, 0, 0, 0.5);
50
- opacity: 0;
51
- transition: all 0.3s;
52
- content: ' ';
53
- }
54
-
55
- .image-item-actions {
56
- position: absolute;
57
- top: 50%;
58
- left: 50%;
59
- z-index: 10;
60
- white-space: nowrap;
61
- transform: translate(-50%, -50%);
62
- transition: all 0.5s;
63
- opacity: 0;
64
- > button {
65
- nz-icon {
66
- font-size: 1rem !important;
67
- color: #fdfdfdd9;
68
- }
69
- }
70
- }
71
- }
72
-
73
- .image-item:hover {
74
- .image-item-info::before,
75
- .image-item-actions {
76
- opacity: 1;
77
- }
78
- }
79
- }
80
- }
@@ -1,22 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-
3
- import { MultiImageUploadComponent } from './multi-image-upload.component';
4
-
5
- describe('MultiImageUploadComponent', () => {
6
- let component: MultiImageUploadComponent;
7
- let fixture: ComponentFixture<MultiImageUploadComponent>;
8
-
9
- beforeEach(async () => {
10
- await TestBed.configureTestingModule({
11
- imports: [MultiImageUploadComponent],
12
- }).compileComponents();
13
-
14
- fixture = TestBed.createComponent(MultiImageUploadComponent);
15
- component = fixture.componentInstance;
16
- fixture.detectChanges();
17
- });
18
-
19
- it('should create', () => {
20
- expect(component).toBeTruthy();
21
- });
22
- });