@ldquocc/dynamic-form 0.0.8 → 0.0.9

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/ng-package.json +15 -0
  2. package/package.json +20 -31
  3. package/src/lib/dynamic-form.component.html +121 -0
  4. package/src/lib/dynamic-form.component.scss +7 -0
  5. package/src/lib/dynamic-form.component.spec.ts +21 -0
  6. package/src/lib/dynamic-form.component.ts +237 -0
  7. package/src/lib/dynamic-form.service.spec.ts +16 -0
  8. package/src/lib/dynamic-form.service.ts +9 -0
  9. package/src/lib/shared/base/base-select.component.ts +183 -0
  10. package/src/lib/shared/base/base-value-accessor.ts +192 -0
  11. package/{lib/shared/components/component.d.ts → src/lib/shared/components/component.ts} +34 -14
  12. package/src/lib/shared/components/d-form-testing/d-form-testing.component.html +197 -0
  13. package/src/lib/shared/components/d-form-testing/d-form-testing.component.less +12 -0
  14. package/src/lib/shared/components/d-form-testing/d-form-testing.component.spec.ts +22 -0
  15. package/src/lib/shared/components/d-form-testing/d-form-testing.component.ts +197 -0
  16. package/src/lib/shared/components/dynamic-field/dynamic-field.component.html +218 -0
  17. package/src/lib/shared/components/dynamic-field/dynamic-field.component.scss +28 -0
  18. package/src/lib/shared/components/dynamic-field/dynamic-field.component.spec.ts +21 -0
  19. package/src/lib/shared/components/dynamic-field/dynamic-field.component.ts +67 -0
  20. package/src/lib/shared/components/field-user-config/field-user-config.component.html +38 -0
  21. package/src/lib/shared/components/field-user-config/field-user-config.component.scss +29 -0
  22. package/src/lib/shared/components/field-user-config/field-user-config.component.ts +33 -0
  23. package/src/lib/shared/components/fields/components/suffix/suffix.component.html +42 -0
  24. package/src/lib/shared/components/fields/components/suffix/suffix.component.scss +3 -0
  25. package/src/lib/shared/components/fields/components/suffix/suffix.component.spec.ts +22 -0
  26. package/src/lib/shared/components/fields/components/suffix/suffix.component.ts +32 -0
  27. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.html +20 -0
  28. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.scss +5 -0
  29. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.spec.ts +21 -0
  30. package/src/lib/shared/components/fields/date/date-picker/date-picker.component.ts +148 -0
  31. package/src/lib/shared/components/fields/date/date-range/date-range.component.html +33 -0
  32. package/src/lib/shared/components/fields/date/date-range/date-range.component.scss +22 -0
  33. package/src/lib/shared/components/fields/date/date-range/date-range.component.spec.ts +21 -0
  34. package/src/lib/shared/components/fields/date/date-range/date-range.component.ts +133 -0
  35. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.html +31 -0
  36. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.scss +3 -0
  37. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.spec.ts +21 -0
  38. package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.ts +148 -0
  39. package/src/lib/shared/components/fields/input/input-password/input-password.component.html +18 -0
  40. package/src/lib/shared/components/fields/input/input-password/input-password.component.scss +0 -0
  41. package/src/lib/shared/components/fields/input/input-password/input-password.component.spec.ts +21 -0
  42. package/src/lib/shared/components/fields/input/input-password/input-password.component.ts +56 -0
  43. package/src/lib/shared/components/fields/input/input-text/input-text.component.html +73 -0
  44. package/src/lib/shared/components/fields/input/input-text/input-text.component.scss +0 -0
  45. package/src/lib/shared/components/fields/input/input-text/input-text.component.spec.ts +21 -0
  46. package/src/lib/shared/components/fields/input/input-text/input-text.component.ts +98 -0
  47. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.html +73 -0
  48. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.scss +21 -0
  49. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.spec.ts +21 -0
  50. package/src/lib/shared/components/fields/select/multi-select/multi-select.component.ts +212 -0
  51. package/src/lib/shared/components/fields/select/single-select/single-select.component.html +55 -0
  52. package/src/lib/shared/components/fields/select/single-select/single-select.component.scss +1 -0
  53. package/src/lib/shared/components/fields/select/single-select/single-select.component.spec.ts +21 -0
  54. package/src/lib/shared/components/fields/select/single-select/single-select.component.ts +217 -0
  55. package/src/lib/shared/components/fields/select/single-select/sl.component.old.txt +337 -0
  56. package/src/lib/shared/components/fields/select/single-select/sl.component.old2.txt +340 -0
  57. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.html +38 -0
  58. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.scss +1 -0
  59. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.spec.ts +21 -0
  60. package/src/lib/shared/components/fields/select/tree-select/tree-select.component.ts +401 -0
  61. package/src/lib/shared/components/fields/textarea/textarea.component.html +29 -0
  62. package/src/lib/shared/components/fields/textarea/textarea.component.scss +17 -0
  63. package/src/lib/shared/components/fields/textarea/textarea.component.spec.ts +21 -0
  64. package/src/lib/shared/components/fields/textarea/textarea.component.ts +76 -0
  65. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.html +30 -0
  66. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.scss +22 -0
  67. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.spec.ts +22 -0
  68. package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.ts +217 -0
  69. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.html +101 -0
  70. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.scss +117 -0
  71. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.spec.ts +22 -0
  72. package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.ts +480 -0
  73. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.html +82 -0
  74. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.less +80 -0
  75. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.spec.ts +22 -0
  76. package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.ts +288 -0
  77. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.html +104 -0
  78. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.scss +37 -0
  79. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.spec.ts +21 -0
  80. package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.ts +317 -0
  81. package/src/lib/shared/config/dynamic-form.config.ts +11 -0
  82. package/src/lib/shared/consts/common/common.const.ts +5 -0
  83. package/src/lib/shared/consts/common/field-dependency.const.ts +1 -0
  84. package/src/lib/shared/consts/common/file.const.ts +130 -0
  85. package/{lib/shared/consts/common/index.d.ts → src/lib/shared/consts/common/index.ts} +4 -4
  86. package/src/lib/shared/consts/common/sample-test.const.ts +1648 -0
  87. package/src/lib/shared/consts/common/standalone-import.const.ts +51 -0
  88. package/src/lib/shared/consts/controls/control.const.ts +11 -0
  89. package/{lib/shared/consts/controls/index.d.ts → src/lib/shared/consts/controls/index.ts} +1 -1
  90. package/src/lib/shared/consts/fields/date-field.const.ts +12 -0
  91. package/src/lib/shared/consts/fields/field.const.ts +23 -0
  92. package/{lib/shared/consts/fields/index.d.ts → src/lib/shared/consts/fields/index.ts} +5 -5
  93. package/src/lib/shared/consts/fields/input-field.const.ts +4 -0
  94. package/src/lib/shared/consts/fields/input-formatted-field.const.ts +35 -0
  95. package/src/lib/shared/consts/fields/radio-field.const.ts +31 -0
  96. package/src/lib/shared/consts/fields/select-field.const.ts +7 -0
  97. package/src/lib/shared/consts/fields/upload-field.const.ts +1 -0
  98. package/src/lib/shared/consts/validators/index.ts +0 -0
  99. package/src/lib/shared/consts/validators/pattern.const.ts +117 -0
  100. package/src/lib/shared/enums/common/component-ui.enum.ts +8 -0
  101. package/src/lib/shared/enums/common/field-dependency.enum.ts +10 -0
  102. package/src/lib/shared/enums/common/file-size-type.enum.ts +6 -0
  103. package/{lib/shared/enums/common/index.d.ts → src/lib/shared/enums/common/index.ts} +4 -4
  104. package/src/lib/shared/enums/common/output-value-type.enum.ts +22 -0
  105. package/src/lib/shared/enums/common/view-mode.enum.ts +4 -0
  106. package/src/lib/shared/enums/controls/control.enum.ts +12 -0
  107. package/{lib/shared/enums/controls/index.d.ts → src/lib/shared/enums/controls/index.ts} +1 -1
  108. package/src/lib/shared/enums/fields/date-field.enum.ts +4 -0
  109. package/src/lib/shared/enums/fields/field.enum.ts +21 -0
  110. package/{lib/shared/enums/fields/index.d.ts → src/lib/shared/enums/fields/index.ts} +6 -6
  111. package/src/lib/shared/enums/fields/input-field.enum.ts +6 -0
  112. package/src/lib/shared/enums/fields/input-formatted-field.enum.ts +6 -0
  113. package/src/lib/shared/enums/fields/select-field.enum.ts +4 -0
  114. package/src/lib/shared/enums/fields/upload-field.enum.ts +5 -0
  115. package/src/lib/shared/enums/form/dynamic-form.enum.ts +6 -0
  116. package/{lib/shared/enums/form/index.d.ts → src/lib/shared/enums/form/index.ts} +1 -1
  117. package/{lib/shared/enums/validators/index.d.ts → src/lib/shared/enums/validators/index.ts} +2 -2
  118. package/src/lib/shared/enums/validators/regex.enum.ts +47 -0
  119. package/src/lib/shared/enums/validators/validators.enum.ts +17 -0
  120. package/src/lib/shared/factories/auto-numeric-options.factory.ts +14 -0
  121. package/src/lib/shared/models/common/api-config.model.ts +7 -0
  122. package/src/lib/shared/models/common/api-response.model.ts +20 -0
  123. package/src/lib/shared/models/common/common.model.ts +39 -0
  124. package/src/lib/shared/models/common/field-dependency.model.ts +27 -0
  125. package/src/lib/shared/models/common/file-config.model.ts +22 -0
  126. package/{lib/shared/models/common/index.d.ts → src/lib/shared/models/common/index.ts} +7 -7
  127. package/src/lib/shared/models/common/obj-field.model.ts +68 -0
  128. package/src/lib/shared/models/common/object-storage.model.ts +15 -0
  129. package/{lib/shared/models/common/output-value-type.model.d.ts → src/lib/shared/models/common/output-value-type.model.ts} +4 -4
  130. package/src/lib/shared/models/common/table-models.ts +16 -0
  131. package/{lib/shared/models/common/view-mode.model.d.ts → src/lib/shared/models/common/view-mode.model.ts} +1 -1
  132. package/{lib/shared/models/controls/control.model.d.ts → src/lib/shared/models/controls/control.model.ts} +3 -2
  133. package/{lib/shared/models/controls/index.d.ts → src/lib/shared/models/controls/index.ts} +1 -1
  134. package/src/lib/shared/models/fields/date/base-date-field.model.ts +52 -0
  135. package/src/lib/shared/models/fields/date/date-picker-field.model.ts +43 -0
  136. package/src/lib/shared/models/fields/date/date-range-field.model.ts +52 -0
  137. package/{lib/shared/models/fields/date/index.d.ts → src/lib/shared/models/fields/date/index.ts} +3 -3
  138. package/src/lib/shared/models/fields/field-grid.model.ts +10 -0
  139. package/src/lib/shared/models/fields/field-group.model.ts +50 -0
  140. package/src/lib/shared/models/fields/field-user-config.model.ts +8 -0
  141. package/src/lib/shared/models/fields/field.model.ts +184 -0
  142. package/{lib/shared/models/fields/index.d.ts → src/lib/shared/models/fields/index.ts} +2 -2
  143. package/{lib/shared/models/fields/input/index.d.ts → src/lib/shared/models/fields/input/index.ts} +4 -4
  144. package/src/lib/shared/models/fields/input/input-field.model.ts +111 -0
  145. package/src/lib/shared/models/fields/input/input-formatted-field.model.ts +38 -0
  146. package/src/lib/shared/models/fields/input/input-password-field.model.ts +38 -0
  147. package/src/lib/shared/models/fields/input/input-text-field.model.ts +26 -0
  148. package/src/lib/shared/models/fields/radio/index.ts +0 -0
  149. package/src/lib/shared/models/fields/radio/radio-base-field.model.ts +84 -0
  150. package/src/lib/shared/models/fields/select/index.ts +0 -0
  151. package/src/lib/shared/models/fields/select/multi-select-field.model.ts +46 -0
  152. package/src/lib/shared/models/fields/select/select-base-field.model.ts +125 -0
  153. package/src/lib/shared/models/fields/select/single-select-field.model.ts +43 -0
  154. package/src/lib/shared/models/fields/select/tree-select-field.model.ts +44 -0
  155. package/src/lib/shared/models/fields/textarea/index.ts +0 -0
  156. package/src/lib/shared/models/fields/textarea/textarea-field.model.ts +97 -0
  157. package/src/lib/shared/models/fields/upload/avatar-upload-field.model.ts +33 -0
  158. package/src/lib/shared/models/fields/upload/base-upload-field.model.ts +105 -0
  159. package/{lib/shared/models/fields/upload/index.d.ts → src/lib/shared/models/fields/upload/index.ts} +5 -5
  160. package/src/lib/shared/models/fields/upload/multi-file-upload-field.model.ts +34 -0
  161. package/src/lib/shared/models/fields/upload/multi-image-upload-field.model.ts +42 -0
  162. package/src/lib/shared/models/fields/upload/single-file-upload-field.model.ts +33 -0
  163. package/{lib/shared/models/form/dynamic-form.model.d.ts → src/lib/shared/models/form/dynamic-form.model.ts} +1 -1
  164. package/{lib/shared/models/form/index.d.ts → src/lib/shared/models/form/index.ts} +1 -1
  165. package/src/lib/shared/models/validations/index.ts +1 -0
  166. package/src/lib/shared/models/validations/validations.model.ts +14 -0
  167. package/src/lib/shared/services/dynamic-form.service.spec.ts +16 -0
  168. package/src/lib/shared/services/dynamic-form.service.ts +251 -0
  169. package/src/lib/shared/services/field.service.spec.ts +16 -0
  170. package/src/lib/shared/services/field.service.ts +152 -0
  171. package/src/lib/shared/services/file.service.spec.ts +16 -0
  172. package/src/lib/shared/services/file.service.ts +53 -0
  173. package/src/lib/shared/services/form-config.service.ts +53 -0
  174. package/src/lib/shared/services/form-data.service.spec.ts +16 -0
  175. package/src/lib/shared/services/form-data.service.ts +114 -0
  176. package/src/lib/shared/services/form-utils.ts +52 -0
  177. package/src/lib/shared/services/suffix.service.spec.ts +16 -0
  178. package/src/lib/shared/services/suffix.service.ts +16 -0
  179. package/src/lib/shared/services/validation.service.spec.ts +16 -0
  180. package/src/lib/shared/services/validation.service.ts +38 -0
  181. package/src/lib/shared/utils/common/common.utils.ts +52 -0
  182. package/{lib/shared/utils/common/index.d.ts → src/lib/shared/utils/common/index.ts} +1 -1
  183. package/src/lib/shared/utils/date/date.utils.ts +129 -0
  184. package/{lib/shared/utils/date/index.d.ts → src/lib/shared/utils/date/index.ts} +1 -1
  185. package/src/lib/shared/utils/dynamic-field/dynamic-field.ts +0 -0
  186. package/src/lib/shared/utils/dynamic-field/index.ts +0 -0
  187. package/src/lib/shared/utils/dynamic-form/dynamic-form.ts +114 -0
  188. package/src/lib/shared/utils/dynamic-form/index.ts +0 -0
  189. package/src/lib/shared/utils/fields/fields.ts +78 -0
  190. package/{lib/shared/utils/fields/index.d.ts → src/lib/shared/utils/fields/index.ts} +1 -1
  191. package/src/lib/shared/utils/file/file.utils.ts +37 -0
  192. package/{lib/shared/utils/file/index.d.ts → src/lib/shared/utils/file/index.ts} +1 -1
  193. package/src/lib/shared/utils/validators/custom-validators.ts +158 -0
  194. package/src/lib/shared/utils/validators/default-error-message.ts +42 -0
  195. package/{lib/shared/utils/validators/index.d.ts → src/lib/shared/utils/validators/index.ts} +3 -3
  196. package/src/lib/shared/utils/validators/pattern.ts +26 -0
  197. package/{public-api.d.ts → src/public-api.ts} +68 -28
  198. package/tsconfig.lib.json +15 -0
  199. package/tsconfig.lib.prod.json +11 -0
  200. package/tsconfig.spec.json +15 -0
  201. package/fesm2022/ldquocc-dynamic-form.mjs +0 -4938
  202. package/fesm2022/ldquocc-dynamic-form.mjs.map +0 -1
  203. package/index.d.ts +0 -5
  204. package/lib/dynamic-form.component.d.ts +0 -67
  205. package/lib/shared/base/base-select.component.d.ts +0 -19
  206. package/lib/shared/base/base-value-accessor.d.ts +0 -69
  207. package/lib/shared/components/dynamic-field/dynamic-field.component.d.ts +0 -23
  208. package/lib/shared/components/field-user-config/field-user-config.component.d.ts +0 -10
  209. package/lib/shared/components/fields/components/suffix/suffix.component.d.ts +0 -12
  210. package/lib/shared/components/fields/date/date-picker/date-picker.component.d.ts +0 -17
  211. package/lib/shared/components/fields/date/date-range/date-range.component.d.ts +0 -17
  212. package/lib/shared/components/fields/input/input-formatted/input-formatted.component.d.ts +0 -20
  213. package/lib/shared/components/fields/input/input-password/input-password.component.d.ts +0 -12
  214. package/lib/shared/components/fields/input/input-text/input-text.component.d.ts +0 -14
  215. package/lib/shared/components/fields/select/multi-select/multi-select.component.d.ts +0 -21
  216. package/lib/shared/components/fields/select/single-select/single-select.component.d.ts +0 -21
  217. package/lib/shared/components/fields/select/tree-select/tree-select.component.d.ts +0 -28
  218. package/lib/shared/components/fields/textarea/textarea.component.d.ts +0 -14
  219. package/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.d.ts +0 -25
  220. package/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.d.ts +0 -76
  221. package/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.d.ts +0 -27
  222. package/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.d.ts +0 -29
  223. package/lib/shared/config/dynamic-form.config.d.ts +0 -9
  224. package/lib/shared/consts/common/common.const.d.ts +0 -5
  225. package/lib/shared/consts/common/field-dependency.const.d.ts +0 -1
  226. package/lib/shared/consts/common/file.const.d.ts +0 -148
  227. package/lib/shared/consts/common/standalone-import.const.d.ts +0 -7
  228. package/lib/shared/consts/controls/control.const.d.ts +0 -1
  229. package/lib/shared/consts/fields/date-field.const.d.ts +0 -7
  230. package/lib/shared/consts/fields/field.const.d.ts +0 -4
  231. package/lib/shared/consts/fields/input-field.const.d.ts +0 -4
  232. package/lib/shared/consts/fields/input-formatted-field.const.d.ts +0 -4
  233. package/lib/shared/consts/fields/radio-field.const.d.ts +0 -10
  234. package/lib/shared/consts/fields/select-field.const.d.ts +0 -6
  235. package/lib/shared/consts/fields/upload-field.const.d.ts +0 -1
  236. package/lib/shared/consts/validators/pattern.const.d.ts +0 -2
  237. package/lib/shared/enums/common/field-dependency.enum.d.ts +0 -9
  238. package/lib/shared/enums/common/file-size-type.enum.d.ts +0 -6
  239. package/lib/shared/enums/common/output-value-type.enum.d.ts +0 -19
  240. package/lib/shared/enums/common/view-mode.enum.d.ts +0 -4
  241. package/lib/shared/enums/controls/control.enum.d.ts +0 -11
  242. package/lib/shared/enums/fields/date-field.enum.d.ts +0 -4
  243. package/lib/shared/enums/fields/field.enum.d.ts +0 -20
  244. package/lib/shared/enums/fields/input-field.enum.d.ts +0 -6
  245. package/lib/shared/enums/fields/input-formatted-field.enum.d.ts +0 -6
  246. package/lib/shared/enums/fields/select-field.enum.d.ts +0 -4
  247. package/lib/shared/enums/fields/upload-field.enum.d.ts +0 -5
  248. package/lib/shared/enums/form/dynamic-form.enum.d.ts +0 -6
  249. package/lib/shared/enums/validators/regex.enum.d.ts +0 -38
  250. package/lib/shared/enums/validators/validators.enum.d.ts +0 -14
  251. package/lib/shared/factories/auto-numeric-options.factory.d.ts +0 -5
  252. package/lib/shared/models/common/api-config.model.d.ts +0 -4
  253. package/lib/shared/models/common/api-response.model.d.ts +0 -19
  254. package/lib/shared/models/common/common.model.d.ts +0 -29
  255. package/lib/shared/models/common/field-dependency.model.d.ts +0 -16
  256. package/lib/shared/models/common/file-config.model.d.ts +0 -11
  257. package/lib/shared/models/common/obj-field.model.d.ts +0 -59
  258. package/lib/shared/models/common/object-storage.model.d.ts +0 -15
  259. package/lib/shared/models/common/table-models.d.ts +0 -15
  260. package/lib/shared/models/fields/date/base-date-field.model.d.ts +0 -19
  261. package/lib/shared/models/fields/date/date-picker-field.model.d.ts +0 -12
  262. package/lib/shared/models/fields/date/date-range-field.model.d.ts +0 -12
  263. package/lib/shared/models/fields/field-grid.model.d.ts +0 -9
  264. package/lib/shared/models/fields/field-group.model.d.ts +0 -21
  265. package/lib/shared/models/fields/field-user-config.model.d.ts +0 -3
  266. package/lib/shared/models/fields/field.model.d.ts +0 -57
  267. package/lib/shared/models/fields/input/input-field.model.d.ts +0 -31
  268. package/lib/shared/models/fields/input/input-formatted-field.model.d.ts +0 -13
  269. package/lib/shared/models/fields/input/input-password-field.model.d.ts +0 -11
  270. package/lib/shared/models/fields/input/input-text-field.model.d.ts +0 -9
  271. package/lib/shared/models/fields/radio/radio-base-field.model.d.ts +0 -26
  272. package/lib/shared/models/fields/select/multi-select-field.model.d.ts +0 -11
  273. package/lib/shared/models/fields/select/select-base-field.model.d.ts +0 -40
  274. package/lib/shared/models/fields/select/single-select-field.model.d.ts +0 -9
  275. package/lib/shared/models/fields/select/tree-select-field.model.d.ts +0 -10
  276. package/lib/shared/models/fields/textarea/textarea-field.model.d.ts +0 -20
  277. package/lib/shared/models/fields/upload/avatar-upload-field.model.d.ts +0 -9
  278. package/lib/shared/models/fields/upload/base-upload-field.model.d.ts +0 -25
  279. package/lib/shared/models/fields/upload/multi-file-upload-field.model.d.ts +0 -10
  280. package/lib/shared/models/fields/upload/multi-image-upload-field.model.d.ts +0 -12
  281. package/lib/shared/models/fields/upload/single-file-upload-field.model.d.ts +0 -11
  282. package/lib/shared/services/dynamic-form.service.d.ts +0 -48
  283. package/lib/shared/services/field.service.d.ts +0 -41
  284. package/lib/shared/services/file.service.d.ts +0 -20
  285. package/lib/shared/services/form-config.service.d.ts +0 -10
  286. package/lib/shared/services/form-data.service.d.ts +0 -53
  287. package/lib/shared/services/form-utils.d.ts +0 -5
  288. package/lib/shared/services/suffix.service.d.ts +0 -12
  289. package/lib/shared/services/validation.service.d.ts +0 -10
  290. package/lib/shared/utils/common/common.utils.d.ts +0 -7
  291. package/lib/shared/utils/date/date.utils.d.ts +0 -6
  292. package/lib/shared/utils/dynamic-form/dynamic-form.d.ts +0 -11
  293. package/lib/shared/utils/fields/fields.d.ts +0 -20
  294. package/lib/shared/utils/file/file.utils.d.ts +0 -4
  295. package/lib/shared/utils/validators/custom-validators.d.ts +0 -11
  296. package/lib/shared/utils/validators/default-error-message.d.ts +0 -6
  297. package/lib/shared/utils/validators/pattern.d.ts +0 -4
  298. /package/{styles → src/lib/shared/styles}/_common-form.scss +0 -0
@@ -0,0 +1,152 @@
1
+ import { HttpClient } from "@angular/common/http";
2
+ import {
3
+ inject,
4
+ Injectable,
5
+ Signal,
6
+ signal,
7
+ WritableSignal,
8
+ } from "@angular/core";
9
+ import { ApiResponse } from "../models/common/api-response.model";
10
+ import { LastChangedParent } from "../models/common";
11
+ import { BehaviorSubject, Observable, Subject } from "rxjs";
12
+
13
+ @Injectable({
14
+ providedIn: "root",
15
+ })
16
+ export class FieldService {
17
+ private httpClient = inject(HttpClient);
18
+
19
+ // Options for dropdown.
20
+ getAllOptions<T = Record<string, unknown>>(
21
+ apiUrl: string,
22
+ queryParams: Record<string, unknown>,
23
+ ) {
24
+ return this.httpClient.get<ApiResponse<T[]>>(apiUrl, {
25
+ params: { ...(queryParams as { [key: string]: any }) },
26
+ });
27
+ }
28
+
29
+ // =========================================================================
30
+ // --- CODE CŨ (Sử dụng Signal cho luồng phụ thuộc) ---
31
+ // =========================================================================
32
+ private dependValuesMap = new Map<string, WritableSignal<string>>();
33
+
34
+ updateDependValuesMap(key: string, value: string): void {
35
+ if (!this.dependValuesMap.has(key)) {
36
+ this.dependValuesMap.set(key, signal(value));
37
+ return;
38
+ }
39
+
40
+ const fieldSignal = this.dependValuesMap.get(key)!;
41
+ fieldSignal.set(value);
42
+ }
43
+
44
+ getDependValuesMap(): Map<string, Signal<string>> {
45
+ return this.dependValuesMap;
46
+ }
47
+
48
+ // =========================================================================
49
+ // --- CODE MỚI (Sử dụng RxJS BehaviorSubject cho luồng phụ thuộc) ---
50
+ // =========================================================================
51
+ // Giải thích kiến trúc mới:
52
+ // - Dùng BehaviorSubject vì nó lưu lại giá trị cuối cùng. Khi một field Con
53
+ // được khởi tạo sau field Cha và subscribe vào, nó sẽ lập tức nhận được
54
+ // giá trị hiện hành thay vì phải chờ Cha thay đổi lần nữa.
55
+ // - Cách này giúp thiết lập luồng dữ liệu dạng Push, rất dễ dàng kết hợp
56
+ // với rxResource hoặc switchMap ở phía Component Con để triệt tiêu lỗi Race-condition.
57
+
58
+ private dependValuesSubjectMap = new Map<
59
+ string,
60
+ BehaviorSubject<string | null>
61
+ >();
62
+
63
+ /**
64
+ * Bắn (Emit) giá trị thay đổi của một trường Parent vào stream.
65
+ * Sẽ được gọi bởi Component đóng vai trò là Cha (isParent = true).
66
+ */
67
+ emitDependValueChange(key: string, value: string): void {
68
+ if (!this.dependValuesSubjectMap.has(key)) {
69
+ this.dependValuesSubjectMap.set(
70
+ key,
71
+ new BehaviorSubject<string | null>(value),
72
+ );
73
+ return;
74
+ }
75
+
76
+ // Nếu đã có stream, đẩy giá trị mới vào ống nước.
77
+ this.dependValuesSubjectMap.get(key)!.next(value);
78
+ }
79
+
80
+ /**
81
+ * Trả về Observable của một trường để các Component Con có thể subscribe/nghe ngóng.
82
+ * Sẽ được gọi bởi các Component có chứa `dependsOn`.
83
+ */
84
+ getDependValueChanges$(key: string): Observable<string | null> {
85
+ if (!this.dependValuesSubjectMap.has(key)) {
86
+ // Đề phòng trường hợp Con subscribe trước khi Cha khởi tạo (hoặc Cha chưa patch value)
87
+ // Ta tạo sẵn một ống nước rỗng với giá trị ban đầu là null.
88
+ this.dependValuesSubjectMap.set(
89
+ key,
90
+ new BehaviorSubject<string | null>(null),
91
+ );
92
+ }
93
+ return this.dependValuesSubjectMap.get(key)!.asObservable();
94
+ }
95
+
96
+ // Signal lưu trữ đối tượng chứa các prop là fieldKey có isParent là true.
97
+ private dependValues = signal<Record<string, string>>({});
98
+
99
+ // Cập nhật giá trị theo key vào đối tượng của signal.
100
+ updateDependValues(key: string, value: string): void {
101
+ this.dependValues.update((curr) => ({ ...curr, [key]: value }));
102
+ }
103
+ // Xóa giá trị và loại bỏ key theo key khỏi đối tượng của signal.
104
+ removeDependValues(key: string): void {
105
+ this.dependValues.update(({ [key]: _, ...rest }) => rest);
106
+ }
107
+
108
+ getDependValues(): Record<string, string> {
109
+ return this.dependValues();
110
+ }
111
+
112
+ clearDependValues(): void {
113
+ this.dependValues.set({});
114
+ }
115
+
116
+ // Lấy trị trị theo key.
117
+ getValueProp(key: string) {
118
+ return this.dependValues()[key];
119
+ }
120
+
121
+ // Signal lưu giữ xem field có isParent gần nhất vừa change giá trị.
122
+ private lastChangedParent = signal<LastChangedParent | null>(null);
123
+
124
+ // Cập nhật key của parent gần nhất change.
125
+ updateLastChangedParent(key: string, value: unknown): void {
126
+ this.lastChangedParent.set({ key, value });
127
+ }
128
+
129
+ // Lấy ra key của parent gần nhất change.
130
+ getLastChangedParent(): LastChangedParent | null {
131
+ return this.lastChangedParent();
132
+ }
133
+
134
+ clearLastChangedParent(): void {
135
+ this.lastChangedParent.set(null);
136
+ }
137
+
138
+ // Field change cho bên ngoài form
139
+ private fieldChange = new Subject<{
140
+ key: string;
141
+ value: any;
142
+ }>();
143
+
144
+ fieldChange$ = this.fieldChange.asObservable(); // expose ra ngoài.
145
+
146
+ onFieldChange(key: string, value: any) {
147
+ this.fieldChange.next({
148
+ key,
149
+ value,
150
+ });
151
+ }
152
+ }
@@ -0,0 +1,16 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { FileService } from './file.service';
4
+
5
+ describe('FileService', () => {
6
+ let service: FileService;
7
+
8
+ beforeEach(() => {
9
+ TestBed.configureTestingModule({});
10
+ service = TestBed.inject(FileService);
11
+ });
12
+
13
+ it('should be created', () => {
14
+ expect(service).toBeTruthy();
15
+ });
16
+ });
@@ -0,0 +1,53 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { inject, Injectable } from '@angular/core';
3
+ import { ApiResponse } from '../models/common/api-response.model';
4
+ import { ObjectStorage } from '../models/common/object-storage.model';
5
+ import { Subject } from 'rxjs';
6
+ import { FormConfigService } from './form-config.service';
7
+
8
+ @Injectable({
9
+ providedIn: 'root',
10
+ })
11
+ export class FileService {
12
+ private httpClient = inject(HttpClient);
13
+ private formConfigService = inject(FormConfigService);
14
+
15
+ private fileClick$ = new Subject<ObjectStorage>();
16
+
17
+ fileClick = this.fileClick$.asObservable(); // expose ra ngoài.
18
+
19
+ onFileClick(objStorage: ObjectStorage) {
20
+ this.fileClick$.next(objStorage);
21
+ }
22
+
23
+ // Upload file đến server và trả về 1 ObjectStorage.
24
+ uploadFile(
25
+ file: File,
26
+ formData: FormData,
27
+ options?: {
28
+ uploadUrl?: string;
29
+ directoryId?: string;
30
+ },
31
+ ) {
32
+ if (!options) options = {};
33
+ if (!options.uploadUrl) {
34
+ options.uploadUrl = this.formConfigService['config'].systemApiUrl + 'ObjectStorage/public/upload'; // fallback
35
+ }
36
+ return this.httpClient.post<any>(options.uploadUrl, formData);
37
+ }
38
+
39
+ // Xóa ObjectStorage.
40
+ deleteObjStorage(
41
+ id: string,
42
+ options?: {
43
+ deleteUrl?: string;
44
+ directoryId?: string;
45
+ },
46
+ ) {
47
+ if (!options) options = {};
48
+ if (!options.deleteUrl) {
49
+ options.deleteUrl = this.formConfigService['config'].systemApiUrl + 'ObjectStorage/public/delete'; // fallback
50
+ }
51
+ return this.httpClient.delete<ApiResponse<unknown>>(`${options.deleteUrl}/${id}`);
52
+ }
53
+ }
@@ -0,0 +1,53 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { DYNAMIC_FORM_CONFIG } from '../config/dynamic-form.config';
3
+ import { FormUtils } from './form-utils';
4
+
5
+ @Injectable({ providedIn: 'root' })
6
+ export class FormConfigService {
7
+ private config = inject(DYNAMIC_FORM_CONFIG);
8
+
9
+ public handleApiUrlCreation(apiUrlFromApi: string, typeGrpCode?: string): string {
10
+ if (!apiUrlFromApi) return '';
11
+ let newApiUrl = '';
12
+ const domain = apiUrlFromApi.split('/')[0];
13
+
14
+ let newDomain = '';
15
+ switch (domain.toLowerCase()) {
16
+ case '{mainapiurl}':
17
+ newDomain = this.config.mainApiUrl;
18
+ break;
19
+ case '{systemapiurl}':
20
+ newDomain = this.config.systemApiUrl;
21
+ break;
22
+ case '{portalapiurl}':
23
+ newDomain = this.config.portalApiUrl;
24
+ break;
25
+ default:
26
+ newDomain = domain;
27
+ }
28
+
29
+ newApiUrl = apiUrlFromApi.replace(`${domain}/`, newDomain ? `${newDomain}/` : '');
30
+
31
+ if (typeGrpCode) {
32
+ newApiUrl = newApiUrl.replace('{ObjTypeGroupCode}', typeGrpCode);
33
+ }
34
+
35
+ return newApiUrl;
36
+ }
37
+
38
+ public generateRandomFileName(name: string, addition = ''): string {
39
+ const encodedName = FormUtils.makeFileNameEncode(name);
40
+ return `${this.config.prefix}_${addition || 'file'}_${
41
+ Math.floor(Math.random() * 9000000000) + 1000000000
42
+ }_${encodedName}`.toLocaleLowerCase();
43
+ }
44
+
45
+ public getViewFileUrl(fileName: string, isTemp: boolean = false): string {
46
+ const type = isTemp ? 'temporary' : 'public';
47
+ return `${this.config.storageUrl}${type}/${fileName}`;
48
+ }
49
+
50
+ public getStorageUrl(): string {
51
+ return this.config.storageUrl;
52
+ }
53
+ }
@@ -0,0 +1,16 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { FormDataService } from './form-data.service';
4
+
5
+ describe('FormDataService', () => {
6
+ let service: FormDataService;
7
+
8
+ beforeEach(() => {
9
+ TestBed.configureTestingModule({});
10
+ service = TestBed.inject(FormDataService);
11
+ });
12
+
13
+ it('should be created', () => {
14
+ expect(service).toBeTruthy();
15
+ });
16
+ });
@@ -0,0 +1,114 @@
1
+ import { Injectable, signal, untracked, WritableSignal } from '@angular/core';
2
+
3
+
4
+ @Injectable({
5
+ providedIn: 'root',
6
+ })
7
+ export class FormDataService {
8
+ // Lưu một hoặc nhiều form data.
9
+ private formDataMap = new Map<string, WritableSignal<Record<string, unknown>>>();
10
+
11
+ /**
12
+ * Kiểm tra xem đã tồn tại form data với form id truyền vào.
13
+ * @param formId Id của form.
14
+ * @returns true nếu có và ngược lại
15
+ */
16
+ has(formId: string): boolean {
17
+ if (!this.formDataMap.has(formId)) return false;
18
+ return true;
19
+ }
20
+
21
+ /**
22
+ * Cập nhật giá trị của một hoặc nhiều field vào form data theo form id.
23
+ * @param formId Id của form.
24
+ * @param data Đối tượng các field theo dạng key:value.
25
+ */
26
+ patch(formId: string, data: Record<string, unknown>) {
27
+ // Lấy form data từ formDataMap.
28
+ let formData = this.formDataMap.get(formId);
29
+
30
+ // Nếu chưa có form data trong formDataMap thì thêm mới. Ngược lại cập nhật field data vào formData.
31
+ if (!formData) {
32
+ formData = signal(data);
33
+ } else {
34
+ formData.update(curr => ({ ...curr, ...data }));
35
+ }
36
+
37
+ // Tiến hành cập nhật vào formDataMap.
38
+ this.formDataMap.set(formId, formData);
39
+ }
40
+
41
+ /**
42
+ * Gán form data theo form id.
43
+ * @param formId Id của form.
44
+ * @param data Đối tượng các field theo dạng key:value.
45
+ */
46
+ set(formId: string, data: Record<string, unknown>) {
47
+ this.formDataMap.set(formId, signal(data));
48
+ }
49
+
50
+ /**
51
+ * Lấy giá trị của form data theo form id có track signal.
52
+ * @param formId Id của form.
53
+ * @returns Record<string, unknown> nếu có giá trị. Ngược lại undefined.
54
+ */
55
+ get(formId: string): Record<string, unknown> | undefined {
56
+ const formData = this.formDataMap.get(formId);
57
+
58
+ if (!formData) return undefined;
59
+
60
+ return formData();
61
+ }
62
+
63
+ /**
64
+ * Lấy giá trị của form data theo form id không track signal.
65
+ * @param formId Id của form.
66
+ * @returns Record<string, unknown> nếu có giá trị. Ngược lại undefined.
67
+ */
68
+ getSnapshot(formId: string): Record<string, unknown> | undefined {
69
+ const formData = this.formDataMap.get(formId);
70
+
71
+ if (!formData) return undefined;
72
+
73
+ return untracked(() => formData());
74
+ }
75
+
76
+ /**
77
+ * Clear giá trị form data theo form id. Clear chứ không xóa khỏi formDataMap hoàn toàn.
78
+ * @param formId Id của form.
79
+ */
80
+ clear(formId: string) {
81
+ let formData = this.formDataMap.get(formId);
82
+
83
+ if (formData) {
84
+ formData.set({});
85
+ this.formDataMap.set(formId, formData);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Delete form data theo form id khỏi formDataMap.
91
+ * @param formId Id của form.
92
+ */
93
+ delete(formId: string) {
94
+ let formData = this.formDataMap.get(formId);
95
+ if (formData) this.formDataMap.delete(formId);
96
+ }
97
+
98
+ /**
99
+ *
100
+ * @param formId Id của form.
101
+ * @param key mã trường trong object form data.
102
+ * @returns unknown.
103
+ */
104
+ getFieldValue(formId: string, key: string): unknown {
105
+ let formData = this.formDataMap.get(formId);
106
+ let fieldValue: unknown = undefined;
107
+
108
+ if (formData) {
109
+ fieldValue = formData()?.[key];
110
+ }
111
+
112
+ return fieldValue;
113
+ }
114
+ }
@@ -0,0 +1,52 @@
1
+ import { format } from 'date-fns';
2
+
3
+ export class FormUtils {
4
+ public static makeFileNameEncode(str: string): string {
5
+ str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a');
6
+ str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, 'e');
7
+ str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i');
8
+ str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o');
9
+ str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u');
10
+ str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y');
11
+ str = str.replace(/đ/g, 'd');
12
+ str = str.replace(/À|Á|Ạ|Ả|Ã|Â|Ầ|Ấ|Ậ|Ẩ|Ẫ|Ă|Ằ|Ắ|Ặ|Ẳ|Ẵ/g, 'A');
13
+ str = str.replace(/È|É|Ẹ|Ẻ|Ẽ|Ê|Ề|Ế|Ệ|Ể|Ễ/g, 'E');
14
+ str = str.replace(/Ì|Í|Ị|Ỉ|Ĩ/g, 'I');
15
+ str = str.replace(/Ò|Ó|Ọ|Ỏ|Õ|Ô|Ồ|Ố|Ộ|Ổ|Ỗ|Ơ|Ờ|Ớ|Ợ|Ở|Ỡ/g, 'O');
16
+ str = str.replace(/Ù|Ú|Ụ|Ủ|Ũ|Ư|Ừ|Ứ|Ự|Ử|Ữ/g, 'U');
17
+ str = str.replace(/Ỳ|Ý|Ỵ|Ỷ|Ỹ/g, 'Y');
18
+ str = str.replace(/Đ/g, 'D');
19
+ str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, '');
20
+ str = str.replace(/\u02C6|\u0306|\u031B/g, '');
21
+ return str;
22
+ }
23
+
24
+ public static randomFileName(name: string): string {
25
+ const ns = name.split('.');
26
+ const extension = ns.pop();
27
+ const encodedName = FormUtils.makeFileNameEncode(ns.join('.'));
28
+ return `${encodedName}_${Math.floor(Math.random() * 90000) + 10000}.${extension}`.toLocaleLowerCase();
29
+ }
30
+
31
+ public static convertViewDate(date: unknown, ft: string = 'dd/MM/yyyy'): string {
32
+ let d: Date | null = null;
33
+ if (date instanceof Date) {
34
+ d = date;
35
+ } else if (typeof date === 'string') {
36
+ if (/^\d{4}-\d{2}-\d{2}/.test(date)) {
37
+ d = new Date(date);
38
+ } else if (/^\d{2}\/\d{2}\/\d{4}\s\d{2}:\d{2}:\d{2}$/.test(date)) {
39
+ const [datePart, timePart] = date.split(' ');
40
+ const [month, day, year] = datePart.split('/').map(Number);
41
+ const [hour, min, sec] = timePart.split(':').map(Number);
42
+ d = new Date(year, month - 1, day, hour, min, sec);
43
+ } else {
44
+ const parsed = new Date(date);
45
+ if (!isNaN(parsed.getTime())) {
46
+ d = parsed;
47
+ }
48
+ }
49
+ }
50
+ return d && !isNaN(d.getTime()) ? format(d, ft) : '';
51
+ }
52
+ }
@@ -0,0 +1,16 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { SuffixService } from './suffix.service';
4
+
5
+ describe('SuffixService', () => {
6
+ let service: SuffixService;
7
+
8
+ beforeEach(() => {
9
+ TestBed.configureTestingModule({});
10
+ service = TestBed.inject(SuffixService);
11
+ });
12
+
13
+ it('should be created', () => {
14
+ expect(service).toBeTruthy();
15
+ });
16
+ });
@@ -0,0 +1,16 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+
4
+ @Injectable({
5
+ providedIn: 'root',
6
+ })
7
+ export class SuffixService {
8
+ private suffixClick$ = new Subject<{ key: string; formId: string }>();
9
+
10
+ suffixClick = this.suffixClick$.asObservable(); // expose ra ngoài.
11
+
12
+ onSuffixClick(key: string, formId: string) {
13
+ this.suffixClick$.next({ key, formId });
14
+ }
15
+ constructor() {}
16
+ }
@@ -0,0 +1,16 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { ValidationService } from './validation.service';
4
+
5
+ describe('ValidationService', () => {
6
+ let service: ValidationService;
7
+
8
+ beforeEach(() => {
9
+ TestBed.configureTestingModule({});
10
+ service = TestBed.inject(ValidationService);
11
+ });
12
+
13
+ it('should be created', () => {
14
+ expect(service).toBeTruthy();
15
+ });
16
+ });
@@ -0,0 +1,38 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { BaseField } from '../models/fields/field.model';
4
+
5
+ @Injectable({
6
+ providedIn: 'root',
7
+ })
8
+ export class ValidationService {
9
+ constructor() {}
10
+
11
+ getFirstError(control: AbstractControl, field: BaseField<any>, fields: BaseField<any>[]): string {
12
+ // if (field.key === 'reminder') console.log("control?.errors", field.key, control?.errors);
13
+ if (!control?.errors || !field) return '';
14
+
15
+ const errorKey = Object.keys(control.errors)?.[0] || '';
16
+ const errorValue = control.errors?.[errorKey];
17
+
18
+ return this.getErrorMessage(errorKey, errorValue, field, fields);
19
+ }
20
+
21
+ private getErrorMessage(
22
+ errorKey: string,
23
+ errorValue: any,
24
+ field: BaseField<any>,
25
+ allFields: BaseField<any>[],
26
+ ): string {
27
+ let finalErrorMessage = '';
28
+
29
+ const customMessage = field.errorMessages?.[errorKey];
30
+ if (customMessage) return customMessage;
31
+
32
+ // 2. Nếu field có hàm getErrorMessage riêng.
33
+ const defaultErrorMessage = field.getErrorMessage(errorKey, errorValue, allFields);
34
+ if (defaultErrorMessage) return defaultErrorMessage;
35
+
36
+ return `Chưa cấu hình message lỗi cho trường ${field.key}`;
37
+ }
38
+ }
@@ -0,0 +1,52 @@
1
+ import { BaseField } from '../../models/fields/field.model';
2
+
3
+ // Kiểm tra tính hợp lệ của JSON string.
4
+ export const isValidJSON = (str: string): boolean => {
5
+ try {
6
+ JSON.parse(str);
7
+ } catch (e) {
8
+ return false;
9
+ }
10
+ return true;
11
+ };
12
+
13
+ // Tạo một chuỗi uuid.
14
+ export const uuidGenerator = (): string => {
15
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
16
+ var r = (Math.random() * 16) | 0,
17
+ v = c == 'x' ? r : (r & 0x3) | 0x8;
18
+ return v.toString(16);
19
+ });
20
+ };
21
+
22
+ export const lowerCaseFirstChar = (str: string): string => {
23
+ return str.charAt(0).toLowerCase() + str.slice(1);
24
+ };
25
+
26
+ export const upperCaseFirstChar = (str: string): string => {
27
+ return str.charAt(0).toUpperCase() + str.slice(1);
28
+ };
29
+
30
+ export const deepCopyArray = (array: BaseField<any>[]): BaseField<any>[] => {
31
+ return array.map(item => {
32
+ if (Array.isArray(item)) {
33
+ return deepCopyArray(item); // Deep copy nếu phần tử là mảng lồng nhau
34
+ } else if (item && typeof item === 'object') {
35
+ return deepCopyObject(item); // Deep copy nếu phần tử là đối tượng
36
+ }
37
+ return item; // Trả về giá trị gốc nếu không phải mảng hoặc đối tượng
38
+ }) as BaseField<any>[];
39
+ };
40
+
41
+ export const deepCopyObject = (obj: BaseField<any>): BaseField<any> => {
42
+ return Object.fromEntries(
43
+ Object.entries(obj).map(([key, value]) => {
44
+ if (Array.isArray(value)) {
45
+ return [key, deepCopyArray(value)]; // Deep copy nếu giá trị là mảng
46
+ } else if (value && typeof value === 'object') {
47
+ return [key, deepCopyObject(value)]; // Deep copy nếu giá trị là đối tượng
48
+ }
49
+ return [key, value]; // Trả về giá trị gốc
50
+ }),
51
+ ) as BaseField<any>;
52
+ };
@@ -1 +1 @@
1
- export * from './common.utils';
1
+ export * from './common.utils';