@ldquocc/dynamic-form 0.0.9 → 0.0.10
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 +4909 -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 +21 -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,34 +0,0 @@
|
|
|
1
|
-
import { BaseUploadField } from './base-upload-field.model';
|
|
2
|
-
import { FieldTypeEnum } from '../../../enums/fields';
|
|
3
|
-
|
|
4
|
-
const DEFAULT_MULTI_FILE_UPLOAD_VALUE = '';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Interface của Multi file upload.
|
|
8
|
-
*/
|
|
9
|
-
export class MultiFileUploadField extends BaseUploadField<string | File> {
|
|
10
|
-
// Số lượng tập tin tối đa có thể tải lên.
|
|
11
|
-
maxFileCount: number;
|
|
12
|
-
|
|
13
|
-
constructor(init: Partial<MultiFileUploadField>) {
|
|
14
|
-
super(init);
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Gán giá trị cho các props cần giá trị mặc định ở Multi file upload.
|
|
18
|
-
*/
|
|
19
|
-
this.type = FieldTypeEnum.MultiFileUpload;
|
|
20
|
-
this.value = DEFAULT_MULTI_FILE_UPLOAD_VALUE;
|
|
21
|
-
this.initialValue = DEFAULT_MULTI_FILE_UPLOAD_VALUE;
|
|
22
|
-
this.maxFileCount = 6;
|
|
23
|
-
|
|
24
|
-
Object.assign(this, init);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
override getDefaultValue(): string | File {
|
|
28
|
-
return DEFAULT_MULTI_FILE_UPLOAD_VALUE;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
override toFormValue(modelValue: unknown): string | File {
|
|
32
|
-
return String(modelValue);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { BaseUploadField } from "./base-upload-field.model";
|
|
2
|
-
import { FieldTypeEnum } from "../../../enums/fields";
|
|
3
|
-
|
|
4
|
-
const DEFAULT_MULTI_IMAGE_UPLOAD_VALUE = "";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Interface của Multi image upload.
|
|
8
|
-
*/
|
|
9
|
-
export class MultiImageUploadField extends BaseUploadField<string | File> {
|
|
10
|
-
// Số lượng hình ảnh tối đa có thể tải lên.
|
|
11
|
-
maxFileCount: number;
|
|
12
|
-
|
|
13
|
-
// Độ dài card bao image.
|
|
14
|
-
imageCardWidth: string;
|
|
15
|
-
|
|
16
|
-
// Độ cao card bao image.
|
|
17
|
-
imageCardHeight: string;
|
|
18
|
-
|
|
19
|
-
constructor(init: Partial<MultiImageUploadField>) {
|
|
20
|
-
super(init);
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Gán giá trị cho các props cần giá trị mặc định ở Multi image upload.
|
|
24
|
-
*/
|
|
25
|
-
this.type = FieldTypeEnum.MultiImageUpload;
|
|
26
|
-
this.value = DEFAULT_MULTI_IMAGE_UPLOAD_VALUE;
|
|
27
|
-
this.initialValue = DEFAULT_MULTI_IMAGE_UPLOAD_VALUE;
|
|
28
|
-
this.maxFileCount = 6;
|
|
29
|
-
this.imageCardWidth = "108px";
|
|
30
|
-
this.imageCardHeight = "108px";
|
|
31
|
-
|
|
32
|
-
Object.assign(this, init);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
override getDefaultValue(): string | File {
|
|
36
|
-
return DEFAULT_MULTI_IMAGE_UPLOAD_VALUE;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
override toFormValue(modelValue: string | File): string {
|
|
40
|
-
return String(modelValue);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { FieldTypeEnum } from '../../../enums/fields';
|
|
2
|
-
import { Suffix } from '../../common/common.model';
|
|
3
|
-
import { BaseUploadField } from './base-upload-field.model';
|
|
4
|
-
|
|
5
|
-
const DEFAULT_SINGLE_FILE_UPLOAD_VALUE = '';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Interface của Single file upload. Đầu vào có thể là chuỗi JSON hoặc đối tượng File.
|
|
9
|
-
*/
|
|
10
|
-
export class SingleFileUploadField extends BaseUploadField<string | File> {
|
|
11
|
-
suffixes: Suffix[];
|
|
12
|
-
constructor(init: Partial<SingleFileUploadField>) {
|
|
13
|
-
super(init);
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Gán giá trị cho các props cần giá trị mặc định ở Single file upload.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
this.type = FieldTypeEnum.SingleFileUpload;
|
|
20
|
-
this.value = DEFAULT_SINGLE_FILE_UPLOAD_VALUE;
|
|
21
|
-
this.initialValue = DEFAULT_SINGLE_FILE_UPLOAD_VALUE;
|
|
22
|
-
this.suffixes = [];
|
|
23
|
-
Object.assign(this, init);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
override getDefaultValue(): string | File {
|
|
27
|
-
return DEFAULT_SINGLE_FILE_UPLOAD_VALUE;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
override toFormValue(modelValue: unknown): string {
|
|
31
|
-
return String(modelValue);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './validations.model';
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export interface RawValidation {
|
|
2
|
-
// Loại validation: required, minValue, maxLength,...
|
|
3
|
-
type: string;
|
|
4
|
-
|
|
5
|
-
// Dùng để truyền value cho loại validate. Cả có sẵn từ Reactive Form hoặc Custom Validate.
|
|
6
|
-
// Ví dụ: {type: minLength, params: {min:2}} hoặc Custom {type:between, params: {min:2, max:9}}
|
|
7
|
-
params?: any;
|
|
8
|
-
|
|
9
|
-
// Message chỉ địng cho validation.
|
|
10
|
-
message?: string;
|
|
11
|
-
|
|
12
|
-
// Phạm vi validation chỉ ở một field, hoặc group là validation chéo.
|
|
13
|
-
scope?: 'field' | 'group';
|
|
14
|
-
}
|
|
@@ -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,251 +0,0 @@
|
|
|
1
|
-
import { computed, inject, Injectable, signal } from "@angular/core";
|
|
2
|
-
import { BaseField } from "../models/fields/field.model";
|
|
3
|
-
import { Extra, ObjField } from "../models/common/obj-field.model";
|
|
4
|
-
import { isValidJSON, lowerCaseFirstChar } from "../utils/common";
|
|
5
|
-
import { FieldTypeEnum } from "../enums/fields";
|
|
6
|
-
import { InputPasswordField, InputTextField } from "../models/fields/input";
|
|
7
|
-
import { TextareaField } from "../models/fields/textarea/textarea-field.model";
|
|
8
|
-
import { SingleSelectField } from "../models/fields/select/single-select-field.model";
|
|
9
|
-
import { MultiSelectField } from "../models/fields/select/multi-select-field.model";
|
|
10
|
-
import { DatePickerField, DateRangeField } from "../models/fields/date";
|
|
11
|
-
import { SingleFileUploadField } from "../models/fields/upload/single-file-upload-field.model";
|
|
12
|
-
import { MultiFileUploadField } from "../models/fields/upload/multi-file-upload-field.model";
|
|
13
|
-
import { FormGroup } from "@angular/forms";
|
|
14
|
-
import { MultiImageUploadField } from "../models/fields/upload/multi-image-upload-field.model";
|
|
15
|
-
import { FormConfigService } from "./form-config.service";
|
|
16
|
-
import { AvatarUploadField } from "../models/fields/upload/avatar-upload-field.model";
|
|
17
|
-
import { TreeSelectField } from "../models/fields/select/tree-select-field.model";
|
|
18
|
-
|
|
19
|
-
@Injectable({
|
|
20
|
-
providedIn: "root",
|
|
21
|
-
})
|
|
22
|
-
export class DynamicFormService {
|
|
23
|
-
private formConfigService = inject(FormConfigService);
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Lưu giữ FormGroup hiện tại của dynamic form.
|
|
27
|
-
*/
|
|
28
|
-
private _formGroup!: FormGroup;
|
|
29
|
-
|
|
30
|
-
// Lấy FormGroup.
|
|
31
|
-
get formGroup() {
|
|
32
|
-
return this._formGroup;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Gán FormGroup.
|
|
36
|
-
setFormGroup(formGroup: FormGroup) {
|
|
37
|
-
this._formGroup = formGroup;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Lưu giữ fields hiện tại của dynamic form.
|
|
42
|
-
*/
|
|
43
|
-
private _fields!: BaseField<any>[];
|
|
44
|
-
|
|
45
|
-
// Lấy fields.
|
|
46
|
-
get fields() {
|
|
47
|
-
return this._fields;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Gán fields.
|
|
51
|
-
setFields(fields: BaseField<any>[]) {
|
|
52
|
-
this._fields = fields;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Thao tác với control và fields cũng như output đầu ra của data form.
|
|
57
|
-
*/
|
|
58
|
-
setFieldValue(fieldKey: string, rawValue: unknown) {
|
|
59
|
-
const field = this.fields.find((f) => f.key === fieldKey);
|
|
60
|
-
if (!field) return;
|
|
61
|
-
|
|
62
|
-
const formValue = field.toFormValue(rawValue);
|
|
63
|
-
this.formGroup.get(fieldKey)?.setValue(formValue);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Signal để kích hoạt submit từ bên ngoài.
|
|
68
|
-
*/
|
|
69
|
-
private readonly _submitTrigger = signal<{
|
|
70
|
-
formId: string | null;
|
|
71
|
-
time: number;
|
|
72
|
-
} | null>(null);
|
|
73
|
-
|
|
74
|
-
// Lấy signal để track vào effect.
|
|
75
|
-
get submitTrigger() {
|
|
76
|
-
return this._submitTrigger.asReadonly();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Tiến hành submit.
|
|
80
|
-
triggerSubmit(formId: string | null) {
|
|
81
|
-
this._submitTrigger.set({ formId, time: Date.now() }); // trigger tạo theo formId.
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Signal để kích hoạt reset từ bên ngoài.
|
|
86
|
-
*/
|
|
87
|
-
private readonly _resetTrigger = signal<{
|
|
88
|
-
formId: string;
|
|
89
|
-
time: number;
|
|
90
|
-
} | null>(null);
|
|
91
|
-
|
|
92
|
-
get resetTrigger() {
|
|
93
|
-
return this._resetTrigger.asReadonly();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
triggerReset(formId: string) {
|
|
97
|
-
if (formId) this._resetTrigger.set({ formId, time: Date.now() });
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Tạo mảng fields đầu vào theo mảng data từ objField.
|
|
102
|
-
*/
|
|
103
|
-
createFieldsByObjFields(
|
|
104
|
-
objFields: ObjField[],
|
|
105
|
-
formType: string,
|
|
106
|
-
options?: {},
|
|
107
|
-
): BaseField<any>[] {
|
|
108
|
-
let fields: BaseField<any>[] = [];
|
|
109
|
-
|
|
110
|
-
// Nếu không tồn tại objFields hoặc objFields là mảng rỗng.
|
|
111
|
-
if (!objFields || objFields.length === 0) return [];
|
|
112
|
-
|
|
113
|
-
for (const objField of objFields) {
|
|
114
|
-
// Bỏ qua những field không cấu hình.
|
|
115
|
-
if (!objField?.extra) {
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Nếu extra không phải chuỗi JSON hợp lệ.
|
|
120
|
-
if (objField?.extra && !isValidJSON(objField?.extra)) {
|
|
121
|
-
// console.warn(`Extra của field ${objField.code} không phải chuỗi dạng JSON`);
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const extra: Extra = JSON.parse(objField?.extra);
|
|
126
|
-
if (!extra.form) {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const form = extra.form;
|
|
131
|
-
const { formTypes, configs } = form;
|
|
132
|
-
|
|
133
|
-
if (!formTypes.includes(formType)) {
|
|
134
|
-
// console.error(`Field '${objField.code}' không tồn tại formType '${formType}'`);
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const fieldConfig = configs?.[formType];
|
|
139
|
-
if (!fieldConfig) {
|
|
140
|
-
// console.error(`Field '${objField.code}' không có config field với formType '${formType}'`);
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const field = this.createFieldFromJson(fieldConfig, objField);
|
|
145
|
-
if (field) {
|
|
146
|
-
fields.push(field);
|
|
147
|
-
} else {
|
|
148
|
-
// console.error(`Field '${objField.code}' không có fieldType phù hợp`);
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return fields.sort((a, b) => a.seqNum - b.seqNum);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private createFieldFromJson(
|
|
157
|
-
fieldConfig: BaseField<any>,
|
|
158
|
-
objField: ObjField,
|
|
159
|
-
): BaseField<any> | null {
|
|
160
|
-
fieldConfig.key =
|
|
161
|
-
fieldConfig?.key || lowerCaseFirstChar(objField.code) || "";
|
|
162
|
-
fieldConfig.label = fieldConfig?.label || objField?.name || "";
|
|
163
|
-
fieldConfig.groupCode = fieldConfig.groupCode ?? objField.viewType ?? "";
|
|
164
|
-
fieldConfig.seqNum = fieldConfig.seqNum ?? objField.seqNum;
|
|
165
|
-
fieldConfig.required = fieldConfig.required ?? objField.required === 3;
|
|
166
|
-
|
|
167
|
-
const fieldType = fieldConfig.type;
|
|
168
|
-
if (fieldType === FieldTypeEnum.InputText) {
|
|
169
|
-
return new InputTextField({ ...(fieldConfig as InputTextField) });
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (fieldType === FieldTypeEnum.InputPassword) {
|
|
173
|
-
return new InputPasswordField({ ...(fieldConfig as InputPasswordField) });
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (fieldType === FieldTypeEnum.Textarea) {
|
|
177
|
-
return new TextareaField({ ...(fieldConfig as TextareaField) });
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (fieldType === FieldTypeEnum.SingleSelect) {
|
|
181
|
-
const singleSelect = fieldConfig as SingleSelectField;
|
|
182
|
-
if (!singleSelect.apiConfig) {
|
|
183
|
-
singleSelect.apiConfig = {
|
|
184
|
-
baseUrl: this.formConfigService.handleApiUrlCreation(
|
|
185
|
-
objField.apiURL || "",
|
|
186
|
-
objField.objTypeGroupCode,
|
|
187
|
-
),
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
return new SingleSelectField({ ...singleSelect });
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (fieldType === FieldTypeEnum.MultiSelect) {
|
|
194
|
-
const multiSelect = fieldConfig as MultiSelectField;
|
|
195
|
-
if (!multiSelect.apiConfig) {
|
|
196
|
-
multiSelect.apiConfig = {
|
|
197
|
-
baseUrl: this.formConfigService.handleApiUrlCreation(
|
|
198
|
-
objField.apiURL || "",
|
|
199
|
-
objField.objTypeGroupCode,
|
|
200
|
-
),
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
return new MultiSelectField({ ...multiSelect });
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (fieldType === FieldTypeEnum.TreeSelect) {
|
|
207
|
-
const treeSelect = fieldConfig as TreeSelectField;
|
|
208
|
-
if (!treeSelect.apiConfig) {
|
|
209
|
-
treeSelect.apiConfig = {
|
|
210
|
-
baseUrl: this.formConfigService.handleApiUrlCreation(
|
|
211
|
-
objField.apiURL || "",
|
|
212
|
-
objField.objTypeGroupCode,
|
|
213
|
-
),
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
return new TreeSelectField({ ...treeSelect });
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (fieldType === FieldTypeEnum.DatePicker) {
|
|
220
|
-
return new DatePickerField({ ...(fieldConfig as DatePickerField) });
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (fieldType === FieldTypeEnum.DateRange) {
|
|
224
|
-
return new DateRangeField({ ...(fieldConfig as DateRangeField) });
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (fieldType === FieldTypeEnum.SingleFileUpload) {
|
|
228
|
-
return new SingleFileUploadField({
|
|
229
|
-
...(fieldConfig as SingleFileUploadField),
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (fieldType === FieldTypeEnum.MultiFileUpload) {
|
|
234
|
-
return new MultiFileUploadField({
|
|
235
|
-
...(fieldConfig as MultiFileUploadField),
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (fieldType === FieldTypeEnum.AvatarUpload) {
|
|
240
|
-
return new AvatarUploadField({ ...(fieldConfig as AvatarUploadField) });
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (fieldType === FieldTypeEnum.MultiImageUpload) {
|
|
244
|
-
return new MultiImageUploadField({
|
|
245
|
-
...(fieldConfig as MultiImageUploadField),
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return null;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
|
|
3
|
-
import { FieldService } from './field.service';
|
|
4
|
-
|
|
5
|
-
describe('FieldService', () => {
|
|
6
|
-
let service: FieldService;
|
|
7
|
-
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
TestBed.configureTestingModule({});
|
|
10
|
-
service = TestBed.inject(FieldService);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should be created', () => {
|
|
14
|
-
expect(service).toBeTruthy();
|
|
15
|
-
});
|
|
16
|
-
});
|
|
@@ -1,152 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
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
|
-
}
|