@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.
- package/fesm2022/ldquocc-dynamic-form.mjs +4928 -0
- package/fesm2022/ldquocc-dynamic-form.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/dynamic-form.component.d.ts +67 -0
- package/lib/shared/base/base-select.component.d.ts +19 -0
- package/lib/shared/base/base-value-accessor.d.ts +69 -0
- package/{src/lib/shared/components/component.ts → lib/shared/components/component.d.ts} +14 -34
- package/lib/shared/components/dynamic-field/dynamic-field.component.d.ts +23 -0
- package/lib/shared/components/field-user-config/field-user-config.component.d.ts +10 -0
- package/lib/shared/components/fields/components/suffix/suffix.component.d.ts +12 -0
- package/lib/shared/components/fields/date/date-picker/date-picker.component.d.ts +17 -0
- package/lib/shared/components/fields/date/date-range/date-range.component.d.ts +17 -0
- package/lib/shared/components/fields/input/input-formatted/input-formatted.component.d.ts +20 -0
- package/lib/shared/components/fields/input/input-password/input-password.component.d.ts +12 -0
- package/lib/shared/components/fields/input/input-text/input-text.component.d.ts +14 -0
- package/lib/shared/components/fields/select/multi-select/multi-select.component.d.ts +21 -0
- package/lib/shared/components/fields/select/single-select/single-select.component.d.ts +22 -0
- package/lib/shared/components/fields/select/tree-select/tree-select.component.d.ts +28 -0
- package/lib/shared/components/fields/textarea/textarea.component.d.ts +14 -0
- package/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.d.ts +25 -0
- package/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.d.ts +76 -0
- package/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.d.ts +27 -0
- package/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.d.ts +29 -0
- package/lib/shared/config/dynamic-form.config.d.ts +9 -0
- package/lib/shared/consts/common/common.const.d.ts +5 -0
- package/lib/shared/consts/common/field-dependency.const.d.ts +1 -0
- package/lib/shared/consts/common/file.const.d.ts +148 -0
- package/{src/lib/shared/consts/common/index.ts → lib/shared/consts/common/index.d.ts} +4 -4
- package/lib/shared/consts/common/standalone-import.const.d.ts +7 -0
- package/lib/shared/consts/controls/control.const.d.ts +1 -0
- package/{src/lib/shared/consts/controls/index.ts → lib/shared/consts/controls/index.d.ts} +1 -1
- package/lib/shared/consts/fields/date-field.const.d.ts +7 -0
- package/lib/shared/consts/fields/field.const.d.ts +4 -0
- package/{src/lib/shared/consts/fields/index.ts → lib/shared/consts/fields/index.d.ts} +5 -5
- package/lib/shared/consts/fields/input-field.const.d.ts +4 -0
- package/lib/shared/consts/fields/input-formatted-field.const.d.ts +4 -0
- package/lib/shared/consts/fields/radio-field.const.d.ts +10 -0
- package/lib/shared/consts/fields/select-field.const.d.ts +6 -0
- package/lib/shared/consts/fields/upload-field.const.d.ts +1 -0
- package/lib/shared/consts/validators/pattern.const.d.ts +2 -0
- package/lib/shared/enums/common/field-dependency.enum.d.ts +9 -0
- package/lib/shared/enums/common/file-size-type.enum.d.ts +6 -0
- package/{src/lib/shared/enums/common/index.ts → lib/shared/enums/common/index.d.ts} +4 -4
- package/lib/shared/enums/common/output-value-type.enum.d.ts +19 -0
- package/lib/shared/enums/common/view-mode.enum.d.ts +4 -0
- package/lib/shared/enums/controls/control.enum.d.ts +11 -0
- package/{src/lib/shared/enums/controls/index.ts → lib/shared/enums/controls/index.d.ts} +1 -1
- package/lib/shared/enums/fields/date-field.enum.d.ts +4 -0
- package/lib/shared/enums/fields/field.enum.d.ts +20 -0
- package/{src/lib/shared/enums/fields/index.ts → lib/shared/enums/fields/index.d.ts} +6 -6
- package/lib/shared/enums/fields/input-field.enum.d.ts +6 -0
- package/lib/shared/enums/fields/input-formatted-field.enum.d.ts +6 -0
- package/lib/shared/enums/fields/select-field.enum.d.ts +4 -0
- package/lib/shared/enums/fields/upload-field.enum.d.ts +5 -0
- package/lib/shared/enums/form/dynamic-form.enum.d.ts +6 -0
- package/{src/lib/shared/enums/form/index.ts → lib/shared/enums/form/index.d.ts} +1 -1
- package/{src/lib/shared/enums/validators/index.ts → lib/shared/enums/validators/index.d.ts} +2 -2
- package/lib/shared/enums/validators/regex.enum.d.ts +38 -0
- package/lib/shared/enums/validators/validators.enum.d.ts +14 -0
- package/lib/shared/factories/auto-numeric-options.factory.d.ts +5 -0
- package/lib/shared/models/common/api-config.model.d.ts +4 -0
- package/lib/shared/models/common/api-response.model.d.ts +19 -0
- package/lib/shared/models/common/common.model.d.ts +29 -0
- package/lib/shared/models/common/field-dependency.model.d.ts +16 -0
- package/lib/shared/models/common/file-config.model.d.ts +11 -0
- package/{src/lib/shared/models/common/index.ts → lib/shared/models/common/index.d.ts} +7 -7
- package/lib/shared/models/common/obj-field.model.d.ts +59 -0
- package/lib/shared/models/common/object-storage.model.d.ts +15 -0
- package/{src/lib/shared/models/common/output-value-type.model.ts → lib/shared/models/common/output-value-type.model.d.ts} +4 -4
- package/lib/shared/models/common/table-models.d.ts +15 -0
- package/{src/lib/shared/models/common/view-mode.model.ts → lib/shared/models/common/view-mode.model.d.ts} +1 -1
- package/{src/lib/shared/models/controls/control.model.ts → lib/shared/models/controls/control.model.d.ts} +2 -3
- package/{src/lib/shared/models/controls/index.ts → lib/shared/models/controls/index.d.ts} +1 -1
- package/lib/shared/models/fields/date/base-date-field.model.d.ts +19 -0
- package/lib/shared/models/fields/date/date-picker-field.model.d.ts +12 -0
- package/lib/shared/models/fields/date/date-range-field.model.d.ts +12 -0
- package/{src/lib/shared/models/fields/date/index.ts → lib/shared/models/fields/date/index.d.ts} +3 -3
- package/lib/shared/models/fields/field-grid.model.d.ts +9 -0
- package/lib/shared/models/fields/field-group.model.d.ts +21 -0
- package/lib/shared/models/fields/field-user-config.model.d.ts +3 -0
- package/lib/shared/models/fields/field.model.d.ts +57 -0
- package/{src/lib/shared/models/fields/index.ts → lib/shared/models/fields/index.d.ts} +2 -2
- package/{src/lib/shared/models/fields/input/index.ts → lib/shared/models/fields/input/index.d.ts} +4 -4
- package/lib/shared/models/fields/input/input-field.model.d.ts +31 -0
- package/lib/shared/models/fields/input/input-formatted-field.model.d.ts +13 -0
- package/lib/shared/models/fields/input/input-password-field.model.d.ts +11 -0
- package/lib/shared/models/fields/input/input-text-field.model.d.ts +9 -0
- package/lib/shared/models/fields/radio/radio-base-field.model.d.ts +26 -0
- package/lib/shared/models/fields/select/multi-select-field.model.d.ts +11 -0
- package/lib/shared/models/fields/select/select-base-field.model.d.ts +40 -0
- package/lib/shared/models/fields/select/single-select-field.model.d.ts +9 -0
- package/lib/shared/models/fields/select/tree-select-field.model.d.ts +10 -0
- package/lib/shared/models/fields/textarea/textarea-field.model.d.ts +20 -0
- package/lib/shared/models/fields/upload/avatar-upload-field.model.d.ts +9 -0
- package/lib/shared/models/fields/upload/base-upload-field.model.d.ts +25 -0
- package/{src/lib/shared/models/fields/upload/index.ts → lib/shared/models/fields/upload/index.d.ts} +5 -5
- package/lib/shared/models/fields/upload/multi-file-upload-field.model.d.ts +10 -0
- package/lib/shared/models/fields/upload/multi-image-upload-field.model.d.ts +12 -0
- package/lib/shared/models/fields/upload/single-file-upload-field.model.d.ts +11 -0
- package/{src/lib/shared/models/form/dynamic-form.model.ts → lib/shared/models/form/dynamic-form.model.d.ts} +1 -1
- package/{src/lib/shared/models/form/index.ts → lib/shared/models/form/index.d.ts} +1 -1
- package/lib/shared/services/dynamic-form.service.d.ts +48 -0
- package/lib/shared/services/field.service.d.ts +41 -0
- package/lib/shared/services/file.service.d.ts +20 -0
- package/lib/shared/services/form-config.service.d.ts +10 -0
- package/lib/shared/services/form-data.service.d.ts +53 -0
- package/lib/shared/services/form-utils.d.ts +5 -0
- package/lib/shared/services/suffix.service.d.ts +12 -0
- package/lib/shared/services/validation.service.d.ts +10 -0
- package/lib/shared/utils/common/common.utils.d.ts +7 -0
- package/{src/lib/shared/utils/common/index.ts → lib/shared/utils/common/index.d.ts} +1 -1
- package/lib/shared/utils/date/date.utils.d.ts +6 -0
- package/{src/lib/shared/utils/date/index.ts → lib/shared/utils/date/index.d.ts} +1 -1
- package/lib/shared/utils/dynamic-form/dynamic-form.d.ts +11 -0
- package/lib/shared/utils/fields/fields.d.ts +20 -0
- package/{src/lib/shared/utils/fields/index.ts → lib/shared/utils/fields/index.d.ts} +1 -1
- package/lib/shared/utils/file/file.utils.d.ts +4 -0
- package/{src/lib/shared/utils/file/index.ts → lib/shared/utils/file/index.d.ts} +1 -1
- package/lib/shared/utils/validators/custom-validators.d.ts +11 -0
- package/lib/shared/utils/validators/default-error-message.d.ts +6 -0
- package/{src/lib/shared/utils/validators/index.ts → lib/shared/utils/validators/index.d.ts} +3 -3
- package/lib/shared/utils/validators/pattern.d.ts +4 -0
- package/package.json +31 -20
- package/{src/public-api.ts → public-api.d.ts} +29 -68
- package/ng-package.json +0 -15
- package/src/lib/dynamic-form.component.html +0 -121
- package/src/lib/dynamic-form.component.scss +0 -7
- package/src/lib/dynamic-form.component.spec.ts +0 -21
- package/src/lib/dynamic-form.component.ts +0 -237
- package/src/lib/dynamic-form.service.spec.ts +0 -16
- package/src/lib/dynamic-form.service.ts +0 -9
- package/src/lib/shared/base/base-select.component.ts +0 -183
- package/src/lib/shared/base/base-value-accessor.ts +0 -192
- package/src/lib/shared/components/d-form-testing/d-form-testing.component.html +0 -197
- package/src/lib/shared/components/d-form-testing/d-form-testing.component.less +0 -12
- package/src/lib/shared/components/d-form-testing/d-form-testing.component.spec.ts +0 -22
- package/src/lib/shared/components/d-form-testing/d-form-testing.component.ts +0 -197
- package/src/lib/shared/components/dynamic-field/dynamic-field.component.html +0 -218
- package/src/lib/shared/components/dynamic-field/dynamic-field.component.scss +0 -28
- package/src/lib/shared/components/dynamic-field/dynamic-field.component.spec.ts +0 -21
- package/src/lib/shared/components/dynamic-field/dynamic-field.component.ts +0 -67
- package/src/lib/shared/components/field-user-config/field-user-config.component.html +0 -38
- package/src/lib/shared/components/field-user-config/field-user-config.component.scss +0 -29
- package/src/lib/shared/components/field-user-config/field-user-config.component.ts +0 -33
- package/src/lib/shared/components/fields/components/suffix/suffix.component.html +0 -42
- package/src/lib/shared/components/fields/components/suffix/suffix.component.scss +0 -3
- package/src/lib/shared/components/fields/components/suffix/suffix.component.spec.ts +0 -22
- package/src/lib/shared/components/fields/components/suffix/suffix.component.ts +0 -32
- package/src/lib/shared/components/fields/date/date-picker/date-picker.component.html +0 -20
- package/src/lib/shared/components/fields/date/date-picker/date-picker.component.scss +0 -5
- package/src/lib/shared/components/fields/date/date-picker/date-picker.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/date/date-picker/date-picker.component.ts +0 -148
- package/src/lib/shared/components/fields/date/date-range/date-range.component.html +0 -33
- package/src/lib/shared/components/fields/date/date-range/date-range.component.scss +0 -22
- package/src/lib/shared/components/fields/date/date-range/date-range.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/date/date-range/date-range.component.ts +0 -133
- package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.html +0 -31
- package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.scss +0 -3
- package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/input/input-formatted/input-formatted.component.ts +0 -148
- package/src/lib/shared/components/fields/input/input-password/input-password.component.html +0 -18
- package/src/lib/shared/components/fields/input/input-password/input-password.component.scss +0 -0
- package/src/lib/shared/components/fields/input/input-password/input-password.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/input/input-password/input-password.component.ts +0 -56
- package/src/lib/shared/components/fields/input/input-text/input-text.component.html +0 -73
- package/src/lib/shared/components/fields/input/input-text/input-text.component.scss +0 -0
- package/src/lib/shared/components/fields/input/input-text/input-text.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/input/input-text/input-text.component.ts +0 -98
- package/src/lib/shared/components/fields/select/multi-select/multi-select.component.html +0 -73
- package/src/lib/shared/components/fields/select/multi-select/multi-select.component.scss +0 -21
- package/src/lib/shared/components/fields/select/multi-select/multi-select.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/select/multi-select/multi-select.component.ts +0 -212
- package/src/lib/shared/components/fields/select/single-select/single-select.component.html +0 -55
- package/src/lib/shared/components/fields/select/single-select/single-select.component.scss +0 -1
- package/src/lib/shared/components/fields/select/single-select/single-select.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/select/single-select/single-select.component.ts +0 -217
- package/src/lib/shared/components/fields/select/single-select/sl.component.old.txt +0 -337
- package/src/lib/shared/components/fields/select/single-select/sl.component.old2.txt +0 -340
- package/src/lib/shared/components/fields/select/tree-select/tree-select.component.html +0 -38
- package/src/lib/shared/components/fields/select/tree-select/tree-select.component.scss +0 -1
- package/src/lib/shared/components/fields/select/tree-select/tree-select.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/select/tree-select/tree-select.component.ts +0 -401
- package/src/lib/shared/components/fields/textarea/textarea.component.html +0 -29
- package/src/lib/shared/components/fields/textarea/textarea.component.scss +0 -17
- package/src/lib/shared/components/fields/textarea/textarea.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/textarea/textarea.component.ts +0 -76
- package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.html +0 -30
- package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.scss +0 -22
- package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.spec.ts +0 -22
- package/src/lib/shared/components/fields/upload/avatar-upload/avatar-upload.component.ts +0 -217
- package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.html +0 -101
- package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.scss +0 -117
- package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.spec.ts +0 -22
- package/src/lib/shared/components/fields/upload/multi-file-upload/multi-file-upload.component.ts +0 -480
- package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.html +0 -82
- package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.less +0 -80
- package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.spec.ts +0 -22
- package/src/lib/shared/components/fields/upload/multi-image-upload/multi-image-upload.component.ts +0 -288
- package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.html +0 -104
- package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.scss +0 -37
- package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.spec.ts +0 -21
- package/src/lib/shared/components/fields/upload/single-file-upload/single-file-upload.component.ts +0 -317
- package/src/lib/shared/config/dynamic-form.config.ts +0 -11
- package/src/lib/shared/consts/common/common.const.ts +0 -5
- package/src/lib/shared/consts/common/field-dependency.const.ts +0 -1
- package/src/lib/shared/consts/common/file.const.ts +0 -130
- package/src/lib/shared/consts/common/sample-test.const.ts +0 -1648
- package/src/lib/shared/consts/common/standalone-import.const.ts +0 -51
- package/src/lib/shared/consts/controls/control.const.ts +0 -11
- package/src/lib/shared/consts/fields/date-field.const.ts +0 -12
- package/src/lib/shared/consts/fields/field.const.ts +0 -23
- package/src/lib/shared/consts/fields/input-field.const.ts +0 -4
- package/src/lib/shared/consts/fields/input-formatted-field.const.ts +0 -35
- package/src/lib/shared/consts/fields/radio-field.const.ts +0 -31
- package/src/lib/shared/consts/fields/select-field.const.ts +0 -7
- package/src/lib/shared/consts/fields/upload-field.const.ts +0 -1
- package/src/lib/shared/consts/validators/index.ts +0 -0
- package/src/lib/shared/consts/validators/pattern.const.ts +0 -117
- package/src/lib/shared/enums/common/component-ui.enum.ts +0 -8
- package/src/lib/shared/enums/common/field-dependency.enum.ts +0 -10
- package/src/lib/shared/enums/common/file-size-type.enum.ts +0 -6
- package/src/lib/shared/enums/common/output-value-type.enum.ts +0 -22
- package/src/lib/shared/enums/common/view-mode.enum.ts +0 -4
- package/src/lib/shared/enums/controls/control.enum.ts +0 -12
- package/src/lib/shared/enums/fields/date-field.enum.ts +0 -4
- package/src/lib/shared/enums/fields/field.enum.ts +0 -21
- package/src/lib/shared/enums/fields/input-field.enum.ts +0 -6
- package/src/lib/shared/enums/fields/input-formatted-field.enum.ts +0 -6
- package/src/lib/shared/enums/fields/select-field.enum.ts +0 -4
- package/src/lib/shared/enums/fields/upload-field.enum.ts +0 -5
- package/src/lib/shared/enums/form/dynamic-form.enum.ts +0 -6
- package/src/lib/shared/enums/validators/regex.enum.ts +0 -47
- package/src/lib/shared/enums/validators/validators.enum.ts +0 -17
- package/src/lib/shared/factories/auto-numeric-options.factory.ts +0 -14
- package/src/lib/shared/models/common/api-config.model.ts +0 -7
- package/src/lib/shared/models/common/api-response.model.ts +0 -20
- package/src/lib/shared/models/common/common.model.ts +0 -39
- package/src/lib/shared/models/common/field-dependency.model.ts +0 -27
- package/src/lib/shared/models/common/file-config.model.ts +0 -22
- package/src/lib/shared/models/common/obj-field.model.ts +0 -68
- package/src/lib/shared/models/common/object-storage.model.ts +0 -15
- package/src/lib/shared/models/common/table-models.ts +0 -16
- package/src/lib/shared/models/fields/date/base-date-field.model.ts +0 -52
- package/src/lib/shared/models/fields/date/date-picker-field.model.ts +0 -43
- package/src/lib/shared/models/fields/date/date-range-field.model.ts +0 -52
- package/src/lib/shared/models/fields/field-grid.model.ts +0 -10
- package/src/lib/shared/models/fields/field-group.model.ts +0 -50
- package/src/lib/shared/models/fields/field-user-config.model.ts +0 -8
- package/src/lib/shared/models/fields/field.model.ts +0 -184
- package/src/lib/shared/models/fields/input/input-field.model.ts +0 -111
- package/src/lib/shared/models/fields/input/input-formatted-field.model.ts +0 -38
- package/src/lib/shared/models/fields/input/input-password-field.model.ts +0 -38
- package/src/lib/shared/models/fields/input/input-text-field.model.ts +0 -26
- package/src/lib/shared/models/fields/radio/index.ts +0 -0
- package/src/lib/shared/models/fields/radio/radio-base-field.model.ts +0 -84
- package/src/lib/shared/models/fields/select/index.ts +0 -0
- package/src/lib/shared/models/fields/select/multi-select-field.model.ts +0 -46
- package/src/lib/shared/models/fields/select/select-base-field.model.ts +0 -125
- package/src/lib/shared/models/fields/select/single-select-field.model.ts +0 -43
- package/src/lib/shared/models/fields/select/tree-select-field.model.ts +0 -44
- package/src/lib/shared/models/fields/textarea/index.ts +0 -0
- package/src/lib/shared/models/fields/textarea/textarea-field.model.ts +0 -97
- package/src/lib/shared/models/fields/upload/avatar-upload-field.model.ts +0 -33
- package/src/lib/shared/models/fields/upload/base-upload-field.model.ts +0 -105
- package/src/lib/shared/models/fields/upload/multi-file-upload-field.model.ts +0 -34
- package/src/lib/shared/models/fields/upload/multi-image-upload-field.model.ts +0 -42
- package/src/lib/shared/models/fields/upload/single-file-upload-field.model.ts +0 -33
- package/src/lib/shared/models/validations/index.ts +0 -1
- package/src/lib/shared/models/validations/validations.model.ts +0 -14
- package/src/lib/shared/services/dynamic-form.service.spec.ts +0 -16
- package/src/lib/shared/services/dynamic-form.service.ts +0 -251
- package/src/lib/shared/services/field.service.spec.ts +0 -16
- package/src/lib/shared/services/field.service.ts +0 -152
- package/src/lib/shared/services/file.service.spec.ts +0 -16
- package/src/lib/shared/services/file.service.ts +0 -53
- package/src/lib/shared/services/form-config.service.ts +0 -53
- package/src/lib/shared/services/form-data.service.spec.ts +0 -16
- package/src/lib/shared/services/form-data.service.ts +0 -114
- package/src/lib/shared/services/form-utils.ts +0 -52
- package/src/lib/shared/services/suffix.service.spec.ts +0 -16
- package/src/lib/shared/services/suffix.service.ts +0 -16
- package/src/lib/shared/services/validation.service.spec.ts +0 -16
- package/src/lib/shared/services/validation.service.ts +0 -38
- package/src/lib/shared/utils/common/common.utils.ts +0 -52
- package/src/lib/shared/utils/date/date.utils.ts +0 -129
- package/src/lib/shared/utils/dynamic-field/dynamic-field.ts +0 -0
- package/src/lib/shared/utils/dynamic-field/index.ts +0 -0
- package/src/lib/shared/utils/dynamic-form/dynamic-form.ts +0 -114
- package/src/lib/shared/utils/dynamic-form/index.ts +0 -0
- package/src/lib/shared/utils/fields/fields.ts +0 -78
- package/src/lib/shared/utils/file/file.utils.ts +0 -37
- package/src/lib/shared/utils/validators/custom-validators.ts +0 -158
- package/src/lib/shared/utils/validators/default-error-message.ts +0 -42
- package/src/lib/shared/utils/validators/pattern.ts +0 -26
- package/tsconfig.lib.json +0 -15
- package/tsconfig.lib.prod.json +0 -11
- package/tsconfig.spec.json +0 -15
- /package/{src/lib/shared/styles → styles}/_common-form.scss +0 -0
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import { BaseField } from "./shared/models/fields/field.model";
|
|
2
|
-
import {
|
|
3
|
-
Component,
|
|
4
|
-
computed,
|
|
5
|
-
effect,
|
|
6
|
-
EventEmitter,
|
|
7
|
-
inject,
|
|
8
|
-
input,
|
|
9
|
-
Input,
|
|
10
|
-
output,
|
|
11
|
-
Output,
|
|
12
|
-
signal,
|
|
13
|
-
untracked,
|
|
14
|
-
} from "@angular/core";
|
|
15
|
-
import { AbstractControl, FormGroup } from "@angular/forms";
|
|
16
|
-
import { buildForm } from "./shared/utils/dynamic-form/dynamic-form";
|
|
17
|
-
import { FieldTypeEnum } from "./shared/enums/fields";
|
|
18
|
-
import { NzFormModule } from "ng-zorro-antd/form";
|
|
19
|
-
import { FormModeEnum } from "./shared/enums/form";
|
|
20
|
-
import { FormMode } from "./shared/models/form";
|
|
21
|
-
import { DynamicFormService } from "./shared/services/dynamic-form.service";
|
|
22
|
-
|
|
23
|
-
import { FORM_MODULES } from "./shared/consts/common";
|
|
24
|
-
import { InputPasswordField } from "./shared/models/fields/input";
|
|
25
|
-
import { clone, isEqual } from "lodash-es";
|
|
26
|
-
import {
|
|
27
|
-
FieldGroup,
|
|
28
|
-
GroupedFields,
|
|
29
|
-
} from "./shared/models/fields/field-group.model";
|
|
30
|
-
import { buildGroupedFields } from "./shared/utils/fields";
|
|
31
|
-
import { DynamicFieldComponent } from "./shared/components/dynamic-field/dynamic-field.component";
|
|
32
|
-
import { debounceTime, distinctUntilChanged, Subject, takeUntil } from "rxjs";
|
|
33
|
-
|
|
34
|
-
import { NzGridModule } from "ng-zorro-antd/grid";
|
|
35
|
-
import { NzCollapseModule } from "ng-zorro-antd/collapse";
|
|
36
|
-
import { FormDataService } from "./shared/services/form-data.service";
|
|
37
|
-
|
|
38
|
-
const ZORRO_MODULES = [NzFormModule, NzGridModule, NzCollapseModule];
|
|
39
|
-
const COMPONENTS = [DynamicFieldComponent];
|
|
40
|
-
|
|
41
|
-
@Component({
|
|
42
|
-
selector: "app-dynamic-forms",
|
|
43
|
-
standalone: true,
|
|
44
|
-
imports: [...FORM_MODULES, ...ZORRO_MODULES, ...COMPONENTS],
|
|
45
|
-
templateUrl: "./dynamic-form.component.html",
|
|
46
|
-
styleUrls: ["./dynamic-form.component.scss"],
|
|
47
|
-
})
|
|
48
|
-
export class DynamicFormComponent {
|
|
49
|
-
// Id phân biệt form.
|
|
50
|
-
@Input() formId!: string;
|
|
51
|
-
|
|
52
|
-
// ===================== NGOÀI LUỒNG LOGIC ======================== //
|
|
53
|
-
// Debounce time for form value changes (ms)
|
|
54
|
-
// Default: 300ms
|
|
55
|
-
// Thời gian trễ cho sự thay đổi giá trị của form (ms)
|
|
56
|
-
@Input() valueChangesDebounceTime = 300;
|
|
57
|
-
|
|
58
|
-
// Emit form value changes
|
|
59
|
-
@Output() readonly formValueChanges = new EventEmitter<
|
|
60
|
-
Record<string, unknown>
|
|
61
|
-
>();
|
|
62
|
-
|
|
63
|
-
// Subject for cleanup subscriptions
|
|
64
|
-
private readonly destroy$ = new Subject<void>();
|
|
65
|
-
// ====================================================== //
|
|
66
|
-
|
|
67
|
-
// Input.
|
|
68
|
-
// Mảng fields mới.
|
|
69
|
-
readonly fields = input.required<BaseField<any>[]>();
|
|
70
|
-
// Signal model data.
|
|
71
|
-
readonly model = input<Record<string, any>>({});
|
|
72
|
-
// Signal form mode.
|
|
73
|
-
readonly mode = input<FormMode>(FormModeEnum.Add);
|
|
74
|
-
// Input signal groupFields.
|
|
75
|
-
readonly fieldGroups = input<FieldGroup[]>([]);
|
|
76
|
-
|
|
77
|
-
// Cho phép show nhưng field không thuộc group nào
|
|
78
|
-
readonly displayNonGroupedFields = input(true);
|
|
79
|
-
|
|
80
|
-
// Output.
|
|
81
|
-
readonly formSubmit = output<Record<string, unknown>>();
|
|
82
|
-
readonly formInvalid = output<BaseField<any>[]>();
|
|
83
|
-
|
|
84
|
-
// Mảng field cũ.
|
|
85
|
-
protected readonly oldFields = signal<BaseField<any>[]>([]);
|
|
86
|
-
|
|
87
|
-
// Check mode là add hay edit.
|
|
88
|
-
readonly isAddOrEdit = computed(() =>
|
|
89
|
-
[FormModeEnum.Add, FormModeEnum.Edit].includes(this.mode() as FormModeEnum),
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
// FormState check sự thay đổi giữa mode, newFields, model chỉ chạy 1 lần dù 3 cái đều đổi.
|
|
93
|
-
readonly formState = computed(() => ({
|
|
94
|
-
mode: this.mode(),
|
|
95
|
-
newFields: this.fields(),
|
|
96
|
-
model: this.model(),
|
|
97
|
-
}));
|
|
98
|
-
|
|
99
|
-
// Computed chạy lại khi fields hoặc groupFields thay đổi.
|
|
100
|
-
groupedFields = computed<GroupedFields>(() => {
|
|
101
|
-
const groups = this.fieldGroups();
|
|
102
|
-
const groupedFields = buildGroupedFields(this.oldFields(), groups);
|
|
103
|
-
return groupedFields;
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
protected readonly formModeEnum = FormModeEnum;
|
|
107
|
-
protected readonly fieldTypeEnum = FieldTypeEnum;
|
|
108
|
-
|
|
109
|
-
// Kiểm tra có cần ẩn field không?
|
|
110
|
-
isHiddenField = (field: BaseField<any>): boolean => {
|
|
111
|
-
const { isHidden } = field;
|
|
112
|
-
if (isHidden) return true;
|
|
113
|
-
if (field instanceof InputPasswordField) {
|
|
114
|
-
if (
|
|
115
|
-
this.mode() === FormModeEnum.Edit ||
|
|
116
|
-
this.mode() === FormModeEnum.View
|
|
117
|
-
) {
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return false;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
// Form group cho reactive form.
|
|
125
|
-
formGroup!: FormGroup;
|
|
126
|
-
|
|
127
|
-
readonly formDataService = inject(FormDataService);
|
|
128
|
-
constructor(private dFormService: DynamicFormService) {
|
|
129
|
-
// Trigger form từ submit bên ngoài.
|
|
130
|
-
effect(() => {
|
|
131
|
-
this.dFormService.submitTrigger();
|
|
132
|
-
if (untracked(() => this.isAddOrEdit())) {
|
|
133
|
-
const submit = this.dFormService.submitTrigger();
|
|
134
|
-
|
|
135
|
-
if (submit?.formId === this.formId) {
|
|
136
|
-
this.handleSubmit();
|
|
137
|
-
this.dFormService.triggerSubmit(null);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
ngOnDestroy(): void {
|
|
144
|
-
// Cleanup subscriptions
|
|
145
|
-
// Dọn dẹp các subscription
|
|
146
|
-
this.destroy$.next();
|
|
147
|
-
this.destroy$.complete();
|
|
148
|
-
|
|
149
|
-
// Loại bỏ output data khi dynamic form destroy component.
|
|
150
|
-
this.formDataService.clear(this.formId);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Đồng bộ fields sang dynamic-form service mỗi lần fields signal change.
|
|
154
|
-
syncFieldsEffect = effect(() => {
|
|
155
|
-
this.dFormService.setFields(this.fields());
|
|
156
|
-
this.formDataService.clear(this.formId);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Effect tạo FormGroup.
|
|
161
|
-
*/
|
|
162
|
-
createFormGroupEffect = effect(() => {
|
|
163
|
-
const { mode, newFields, model } = this.formState();
|
|
164
|
-
this.oldFields.set(newFields);
|
|
165
|
-
const computedFields = clone(newFields);
|
|
166
|
-
this.formGroup = buildForm(computedFields, mode, model);
|
|
167
|
-
this.dFormService.setFormGroup(this.formGroup);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Subscribe to form value changes
|
|
172
|
-
* Subscribe lắng nghe sự thay đổi giá trị của form
|
|
173
|
-
*/
|
|
174
|
-
private subscribeToFormValueChanges(): void {
|
|
175
|
-
if (!this.formGroup) return;
|
|
176
|
-
|
|
177
|
-
// Unsubscribe previous subscription if exists
|
|
178
|
-
this.destroy$.next();
|
|
179
|
-
|
|
180
|
-
this.formGroup.valueChanges
|
|
181
|
-
.pipe(
|
|
182
|
-
debounceTime(this.valueChangesDebounceTime),
|
|
183
|
-
distinctUntilChanged((prev, curr) => isEqual(prev, curr)),
|
|
184
|
-
takeUntil(this.destroy$),
|
|
185
|
-
)
|
|
186
|
-
.subscribe((formValue) => {
|
|
187
|
-
// console.log('Form value changed:', formValue);
|
|
188
|
-
this.formValueChanges.emit(formValue);
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Xử lý submit form và output ra ngoài.
|
|
194
|
-
*/
|
|
195
|
-
private handleSubmit() {
|
|
196
|
-
const form = this.formGroup;
|
|
197
|
-
const invalidFields: Array<BaseField<any>> = [];
|
|
198
|
-
|
|
199
|
-
// Xử lý trường hợp form chưa thỏa mãn validation.
|
|
200
|
-
if (form.invalid) {
|
|
201
|
-
const controls = form.controls;
|
|
202
|
-
for (const name in controls) {
|
|
203
|
-
if (controls[name].invalid) {
|
|
204
|
-
this.markControlForValidation(controls[name]);
|
|
205
|
-
const field = this.fields().find((field) => field.key === name);
|
|
206
|
-
if (field) invalidFields.push(field);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
this.formInvalid.emit(invalidFields);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const formData = untracked(() => this.formDataService.get(this.formId));
|
|
214
|
-
this.formSubmit.emit(formData ?? {});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Kích submit form ảo khi nhấn nút submit.
|
|
219
|
-
*/
|
|
220
|
-
private markControlForValidation(control: AbstractControl) {
|
|
221
|
-
control.markAllAsTouched();
|
|
222
|
-
control.markAsDirty();
|
|
223
|
-
control.updateValueAndValidity({ onlySelf: true, emitEvent: true });
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* TrackBy function for ngFor to optimize rendering.
|
|
228
|
-
*/
|
|
229
|
-
protected trackByField(index: number, field: BaseField<any>): string {
|
|
230
|
-
return field.key || `field-${index}`;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
readonly collapseCustomStyle = {
|
|
234
|
-
background: "#fff",
|
|
235
|
-
border: "0px",
|
|
236
|
-
};
|
|
237
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { DynamicFormService } from './dynamic-form.service';
|
|
4
|
-
|
|
5
|
-
describe('DynamicFormService', () => {
|
|
6
|
-
let service: DynamicFormService;
|
|
7
|
-
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
TestBed.configureTestingModule({});
|
|
10
|
-
service = TestBed.inject(DynamicFormService);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should be created', () => {
|
|
14
|
-
expect(service).toBeTruthy();
|
|
15
|
-
});
|
|
16
|
-
});
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { computed, Directive, effect, untracked } from "@angular/core";
|
|
2
|
-
import { rxResource, toObservable, toSignal } from "@angular/core/rxjs-interop";
|
|
3
|
-
import { combineLatest, Observable, of } from "rxjs";
|
|
4
|
-
import { catchError, map, switchMap } from "rxjs/operators";
|
|
5
|
-
import { DependTypeEnum } from "../enums/common";
|
|
6
|
-
import { ApiResponse } from "../models/common/api-response.model";
|
|
7
|
-
import {
|
|
8
|
-
FieldDependency,
|
|
9
|
-
FieldDependencyType,
|
|
10
|
-
} from "../models/common/field-dependency.model";
|
|
11
|
-
import { SelectBaseField } from "../models/fields/select/select-base-field.model";
|
|
12
|
-
import { BaseValueAccessor } from "./base-value-accessor";
|
|
13
|
-
|
|
14
|
-
@Directive()
|
|
15
|
-
export abstract class BaseSelectComponent<T> extends BaseValueAccessor<T> {
|
|
16
|
-
// Alias to strongly type the field input for Select base logic
|
|
17
|
-
protected readonly selectField = computed(
|
|
18
|
-
() => this.fieldInput() as SelectBaseField<any>,
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
protected isFirstLoad = true;
|
|
22
|
-
|
|
23
|
-
// 1. Tạo stream params từ các field phụ thuộc
|
|
24
|
-
private dependParams$ = toObservable(this.selectField).pipe(
|
|
25
|
-
switchMap((field) => {
|
|
26
|
-
const { dependsOn, dependType } = field;
|
|
27
|
-
|
|
28
|
-
if (!dependsOn || dependsOn.length === 0) {
|
|
29
|
-
return of({ valid: true, params: {} });
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const dependObs$ = this.createDependencyStreams(dependsOn);
|
|
33
|
-
|
|
34
|
-
return combineLatest(dependObs$).pipe(
|
|
35
|
-
map((results) => this.evaluateDependencies(results, dependType)),
|
|
36
|
-
);
|
|
37
|
-
}),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
private createDependencyStreams(
|
|
41
|
-
dependsOn: FieldDependency[],
|
|
42
|
-
): Observable<{ key: string; value: string | null }>[] {
|
|
43
|
-
return dependsOn.map((depend) =>
|
|
44
|
-
this.fieldService
|
|
45
|
-
.getDependValueChanges$(depend.fieldKey)
|
|
46
|
-
.pipe(map((val) => ({ key: depend.paramKey, value: val }))),
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private evaluateDependencies(
|
|
51
|
-
results: { key: string; value: string | null }[],
|
|
52
|
-
dependType: FieldDependencyType,
|
|
53
|
-
): { valid: boolean; params: Record<string, unknown> } {
|
|
54
|
-
const isValidValue = (val: string | null) =>
|
|
55
|
-
val !== null && val !== "" && val !== undefined;
|
|
56
|
-
|
|
57
|
-
let isConditionMet = false;
|
|
58
|
-
|
|
59
|
-
if (dependType === DependTypeEnum.Any) {
|
|
60
|
-
isConditionMet = results.some((r) => isValidValue(r.value));
|
|
61
|
-
} else {
|
|
62
|
-
isConditionMet = results.every((r) => isValidValue(r.value));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const params = results.reduce(
|
|
66
|
-
(acc, curr) => ({ ...acc, [curr.key]: curr.value }),
|
|
67
|
-
{},
|
|
68
|
-
);
|
|
69
|
-
return { valid: isConditionMet, params };
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private dependParamsSignal = toSignal(this.dependParams$, {
|
|
73
|
-
initialValue: { valid: false, params: {} },
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// 2. rxResource lấy danh sách
|
|
77
|
-
optionsResource = rxResource({
|
|
78
|
-
request: () => {
|
|
79
|
-
if (this.isView()) return undefined;
|
|
80
|
-
|
|
81
|
-
const state = this.dependParamsSignal();
|
|
82
|
-
if (!state || !state.valid) return undefined;
|
|
83
|
-
return state.params;
|
|
84
|
-
},
|
|
85
|
-
loader: ({ request: params }) => {
|
|
86
|
-
const field = untracked(() => this.selectField());
|
|
87
|
-
const fullApiUrl = field?.apiConfig?.baseUrl || "";
|
|
88
|
-
const apiParams = field?.apiConfig?.params || {};
|
|
89
|
-
|
|
90
|
-
const rawParams = { ...apiParams, ...params };
|
|
91
|
-
const finalParams = Object.fromEntries(
|
|
92
|
-
Object.entries(rawParams).filter(
|
|
93
|
-
([_, val]) => val !== null && val !== undefined && val !== "",
|
|
94
|
-
),
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
if (!fullApiUrl) {
|
|
98
|
-
return of({
|
|
99
|
-
code: 0,
|
|
100
|
-
message: "Success",
|
|
101
|
-
data: field?.options ?? [],
|
|
102
|
-
} as ApiResponse<Record<string, unknown>[]>);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return this.fieldService.getAllOptions(fullApiUrl, finalParams).pipe(
|
|
106
|
-
catchError((error) =>
|
|
107
|
-
of({ code: -1, message: "Error", data: [] } as ApiResponse<
|
|
108
|
-
Record<string, unknown>[]
|
|
109
|
-
>),
|
|
110
|
-
),
|
|
111
|
-
);
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// Gom chung loading từ rxResource và isDisabledSignal
|
|
116
|
-
disabled = computed(
|
|
117
|
-
() => this.optionsResource.isLoading() || this.disabledSignal(),
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
// 3. Xào nấu Options (Prepend, Append, Filter)
|
|
121
|
-
options = computed<Record<string, unknown>[]>(() => {
|
|
122
|
-
const state = this.dependParamsSignal();
|
|
123
|
-
const isLoading = this.optionsResource.isLoading();
|
|
124
|
-
const res = this.optionsResource.value();
|
|
125
|
-
|
|
126
|
-
if (!state || !state.valid || isLoading || !res || res.code !== 0) {
|
|
127
|
-
return [];
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const field = this.selectField();
|
|
131
|
-
const { optionsToPrepend, optionsToAppend, exceptOptions } = field;
|
|
132
|
-
const rawData = res.data || [];
|
|
133
|
-
|
|
134
|
-
return [...optionsToPrepend, ...rawData, ...optionsToAppend].filter(
|
|
135
|
-
(opt) =>
|
|
136
|
-
!exceptOptions.some(
|
|
137
|
-
(ex) => ex[field.bindValue] === opt[field.bindValue],
|
|
138
|
-
),
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
constructor() {
|
|
143
|
-
super();
|
|
144
|
-
|
|
145
|
-
// 4. Effect xử lý toàn bộ logic Form Control (Disable/Enable/Reset)
|
|
146
|
-
effect(() => {
|
|
147
|
-
const state = this.dependParamsSignal();
|
|
148
|
-
const isLoading = this.optionsResource.isLoading();
|
|
149
|
-
const res = this.optionsResource.value();
|
|
150
|
-
|
|
151
|
-
untracked(() => {
|
|
152
|
-
// CASE 1 & 2: CHƯA ĐỦ ĐIỀU KIỆN HOẶC ĐANG GỌI API -> Disable và Reset
|
|
153
|
-
if (!state || !state.valid || isLoading) {
|
|
154
|
-
this.disableControl();
|
|
155
|
-
if (!this.isFirstLoad) {
|
|
156
|
-
this.resetControl();
|
|
157
|
-
}
|
|
158
|
-
this.isFirstLoad = false;
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// CASE 3: API ĐÃ LOAD XONG
|
|
163
|
-
if (res) {
|
|
164
|
-
if (res.code !== 0) {
|
|
165
|
-
this.disableAndResetControl();
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const field = this.selectField();
|
|
170
|
-
if (!field.isDisabled) {
|
|
171
|
-
this.enableControl();
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Móc nối cho các class con có nhu cầu đồng bộ data sau khi load API
|
|
175
|
-
this.onApiOptionsLoaded();
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Cho phép component con overide nếu cần (ví dụ để hydrate sourceObject)
|
|
182
|
-
protected onApiOptionsLoaded(): void {}
|
|
183
|
-
}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
computed,
|
|
3
|
-
Directive,
|
|
4
|
-
inject,
|
|
5
|
-
input,
|
|
6
|
-
Input,
|
|
7
|
-
untracked,
|
|
8
|
-
signal,
|
|
9
|
-
effect,
|
|
10
|
-
} from "@angular/core";
|
|
11
|
-
import { AbstractControl, ControlValueAccessor } from "@angular/forms";
|
|
12
|
-
import { Subject, takeUntil } from "rxjs";
|
|
13
|
-
import { FormMode } from "../models/form";
|
|
14
|
-
import { FormModeEnum } from "../enums/form";
|
|
15
|
-
import { DynamicFormService } from "../services/dynamic-form.service";
|
|
16
|
-
import { FieldService } from "../services/field.service";
|
|
17
|
-
import { LastChangedParent } from "../models/common";
|
|
18
|
-
import { BaseField } from "../models/fields/field.model";
|
|
19
|
-
import { ViewModeEnum } from "../enums/common";
|
|
20
|
-
import { FormDataService } from "../services/form-data.service";
|
|
21
|
-
|
|
22
|
-
@Directive() // Dùng @Directive vì class này không có template riêng
|
|
23
|
-
export abstract class BaseValueAccessor<T> implements ControlValueAccessor {
|
|
24
|
-
// Control theo dạng field lấy từ reactive form.
|
|
25
|
-
@Input({ required: true }) formId!: string;
|
|
26
|
-
|
|
27
|
-
readonly fieldInput = input.required<BaseField<T>>();
|
|
28
|
-
protected readonly fieldKey = untracked(() =>
|
|
29
|
-
computed<string>(() => this.fieldInput().key),
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
@Input({ required: false }) control: AbstractControl<T> | null = null;
|
|
33
|
-
|
|
34
|
-
// Chế độ form: Add, Edit, View...
|
|
35
|
-
readonly modeSignal = input<FormMode>(FormModeEnum.Add);
|
|
36
|
-
|
|
37
|
-
readonly isAdd = computed(() => this.modeSignal() === "add");
|
|
38
|
-
readonly isEdit = computed(() => this.modeSignal() === "edit");
|
|
39
|
-
readonly isView = computed(() => this.modeSignal() === "view");
|
|
40
|
-
readonly isAddOrEdit = computed(() =>
|
|
41
|
-
["add", "edit"].includes(this.modeSignal()),
|
|
42
|
-
);
|
|
43
|
-
readonly isEditOrView = computed(() =>
|
|
44
|
-
["edit", "view"].includes(this.modeSignal()),
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
protected readonly formModeEnum = FormModeEnum;
|
|
48
|
-
protected readonly viewModeEnum = ViewModeEnum;
|
|
49
|
-
|
|
50
|
-
protected readonly destroy$ = new Subject<void>();
|
|
51
|
-
|
|
52
|
-
// Dành cho ControlValueAccessor.
|
|
53
|
-
protected value: T | null = null;
|
|
54
|
-
protected readonly valueSignal = signal<T | null>(null);
|
|
55
|
-
protected onChange: (value: T | null) => void = () => {};
|
|
56
|
-
protected onTouched: () => void = () => {};
|
|
57
|
-
protected isDisabled = false;
|
|
58
|
-
protected readonly disabledSignal = signal(false); // Đang có select dùng isDisableSignal nên sau này đồng bộ lại.
|
|
59
|
-
|
|
60
|
-
protected dFormService = inject(DynamicFormService);
|
|
61
|
-
protected formDataService = inject(FormDataService);
|
|
62
|
-
protected fieldService = inject(FieldService);
|
|
63
|
-
|
|
64
|
-
private readonly resetEffect = effect(() => {
|
|
65
|
-
const reset = this.dFormService.resetTrigger();
|
|
66
|
-
if (reset?.formId === this.formId) {
|
|
67
|
-
this.reset();
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// Dành cho UI
|
|
72
|
-
protected readonly viewMode = computed(() => this.fieldInput().viewMode);
|
|
73
|
-
|
|
74
|
-
protected readonly displayPlaceholder = computed(() => {
|
|
75
|
-
if (!this.isAddOrEdit()) return "";
|
|
76
|
-
|
|
77
|
-
const placeholder = this.fieldInput()?.placeholder;
|
|
78
|
-
if (placeholder) return placeholder;
|
|
79
|
-
|
|
80
|
-
return this.resolvePlaceholderText();
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// 2. Hàm sinh text mặc định (Component con có thể override hàm này)
|
|
84
|
-
protected resolvePlaceholderText(): string {
|
|
85
|
-
return "Nhập dữ liệu";
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
ngOnDestroy(): void {
|
|
89
|
-
this.destroy$.next();
|
|
90
|
-
this.destroy$.complete();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
protected takeUntilDestroy<T>() {
|
|
94
|
-
return takeUntil<T>(this.destroy$);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
writeValue(value: T | null): void {
|
|
98
|
-
this.value = value;
|
|
99
|
-
this.valueSignal.set(value);
|
|
100
|
-
this.writeValueToView(value); // 👈 component con override nếu cần.
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
registerOnChange(fn: (value: T | null) => void): void {
|
|
104
|
-
this.onChange = fn;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
registerOnTouched(fn: () => void): void {
|
|
108
|
-
this.onTouched = fn;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
setDisabledState(isDisabled: boolean): void {
|
|
112
|
-
this.isDisabled = isDisabled;
|
|
113
|
-
this.disabledSignal.set(isDisabled);
|
|
114
|
-
this.setDisabledOnView(isDisabled);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
protected propagateValue(value: T | null): void {
|
|
118
|
-
this.value = value;
|
|
119
|
-
this.valueSignal.set(value);
|
|
120
|
-
this.fieldService.onFieldChange(this.fieldKey(), value);
|
|
121
|
-
this.onChange(this.value);
|
|
122
|
-
// Khi thay đổi value.
|
|
123
|
-
this.handleValueChange(value);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Xử lý reset chung ban đầu.
|
|
127
|
-
protected reset(): void {
|
|
128
|
-
if (!this.control || !this.isAddOrEdit()) return;
|
|
129
|
-
const baseField = untracked(() => this.fieldInput());
|
|
130
|
-
this.control.reset(baseField.initialValue as T);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Thêm dữ liệu ở từng dạng field vào form data theo form id cụ thể.
|
|
135
|
-
* @param key Mã của field.
|
|
136
|
-
* @param value Giá trị của field.
|
|
137
|
-
*/
|
|
138
|
-
protected patchFormData(key: string, value: T | null): void {
|
|
139
|
-
this.formDataService.patch(this.formId, { [key]: value });
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Update data ở từng prop vào dependValuesSignal. Cơ chế nếu falsy thì không được phép cho vào dependValuesSignal.
|
|
143
|
-
protected updateDependValues(key: string, value: string): void {
|
|
144
|
-
this.fieldService.removeDependValues(key);
|
|
145
|
-
if (value) {
|
|
146
|
-
this.fieldService.updateDependValues(key, value);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Đánh dấu field có isParent là true vừa thay đổi.
|
|
151
|
-
protected updateLastChangedParent(key: string, value: unknown): void {
|
|
152
|
-
this.fieldService.updateLastChangedParent(key, value);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
protected disableAndResetControl(): void {
|
|
156
|
-
this.control?.reset();
|
|
157
|
-
this.control?.disable();
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
protected disableControl(): void {
|
|
161
|
-
this.control?.disable();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
protected enableControl(): void {
|
|
165
|
-
this.control?.enable();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
protected resetControl(): void {
|
|
169
|
-
this.control?.reset();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Optional: để component override riêng.
|
|
174
|
-
*/
|
|
175
|
-
// Xử lý giao diện khi ghi giá trị mới.
|
|
176
|
-
protected writeValueToView(value: T | null): void {}
|
|
177
|
-
|
|
178
|
-
// Khi value change.
|
|
179
|
-
protected handleValueChange(value: T | null): void {}
|
|
180
|
-
|
|
181
|
-
// Xử lý giao diện khi ghi thay đổi giá trị isDisabled.
|
|
182
|
-
protected setDisabledOnView(isDisabled: boolean): void {}
|
|
183
|
-
|
|
184
|
-
// Xử lý các logic riêng của reset ở add mode.
|
|
185
|
-
protected resetForAdd(): void {}
|
|
186
|
-
|
|
187
|
-
// Xử lý các logic riêng của reset ở edit mode.
|
|
188
|
-
protected resetForEdit(): void {}
|
|
189
|
-
|
|
190
|
-
// Xử lý các logic riêng chung cuối cùng.
|
|
191
|
-
protected finalizeReset(): void {}
|
|
192
|
-
}
|