fx-form-builder-wrapper 2.0.98 → 2.0.100
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/esm2022/lib/components/customize-dropdown/customize-dropdown.component.mjs +398 -0
- package/esm2022/lib/components/dropdown-with-other/dropdown-with-other.component.mjs +6 -3
- package/esm2022/lib/components/fx-form-component/fx-form-component.component.mjs +3 -3
- package/esm2022/lib/components/radio-group/radio-group.component.mjs +6 -3
- package/esm2022/lib/components/summary/summary.component.mjs +14 -95
- package/esm2022/lib/components/uploader/uploader.component.mjs +2 -2
- package/esm2022/lib/fx-builder-wrapper.component.mjs +5 -5
- package/fesm2022/fx-form-builder-wrapper.mjs +414 -104
- package/fesm2022/fx-form-builder-wrapper.mjs.map +1 -1
- package/lib/components/customize-dropdown/customize-dropdown.component.d.ts +65 -0
- package/lib/components/dropdown-with-other/dropdown-with-other.component.d.ts +1 -0
- package/lib/components/radio-group/radio-group.component.d.ts +1 -0
- package/lib/components/summary/summary.component.d.ts +0 -1
- package/package.json +1 -1
|
@@ -1574,7 +1574,7 @@ class UploaderComponent extends FxBaseComponent {
|
|
|
1574
1574
|
title: '',
|
|
1575
1575
|
notes: '',
|
|
1576
1576
|
categoryId: '',
|
|
1577
|
-
type: fileType
|
|
1577
|
+
type: fileType
|
|
1578
1578
|
};
|
|
1579
1579
|
if (fileType === 'image') {
|
|
1580
1580
|
const reader = new FileReader();
|
|
@@ -2323,6 +2323,7 @@ class DropdownWithOtherComponent extends FxBaseComponent {
|
|
|
2323
2323
|
options = [];
|
|
2324
2324
|
isRequired = false;
|
|
2325
2325
|
isChildRequired = false;
|
|
2326
|
+
otherMaxLength = 768;
|
|
2326
2327
|
dropDownForm = this.fb.group({
|
|
2327
2328
|
selectedOption: [''],
|
|
2328
2329
|
otherInput: [{ value: '', disabled: true }],
|
|
@@ -2345,6 +2346,7 @@ class DropdownWithOtherComponent extends FxBaseComponent {
|
|
|
2345
2346
|
}
|
|
2346
2347
|
}, 200);
|
|
2347
2348
|
setTimeout(() => {
|
|
2349
|
+
this.otherMaxLength = Number(this.setting('other-maxLength')) || 768;
|
|
2348
2350
|
const mainControl = this.dropDownForm.get('selectedOption');
|
|
2349
2351
|
if (this.setting('isRequired') === 'true') {
|
|
2350
2352
|
this.isRequired = true;
|
|
@@ -2407,6 +2409,7 @@ class DropdownWithOtherComponent extends FxBaseComponent {
|
|
|
2407
2409
|
new FxStringSetting({ key: 'select-label', $title: 'Label', value: '' }),
|
|
2408
2410
|
new FxStringSetting({ key: 'other-label', $title: 'Other Label', value: '' }),
|
|
2409
2411
|
new FxStringSetting({ key: 'other-placeholder', $title: 'Other Placeholder', value: '' }),
|
|
2412
|
+
new FxStringSetting({ key: 'other-maxLength', $title: 'Other Max Length', value: 768 }),
|
|
2410
2413
|
new FxSelectSetting({ key: 'serviceName', $title: 'Service', value: '' }, [{ option: 'User Service', value: 'user_service' }, { option: 'Patient Service', value: 'patient_service' }, { option: 'Workflow Service', value: 'workflow_service' }]),
|
|
2411
2414
|
new FxSelectSetting({ key: 'isRequired', $title: 'Required', value: 'true' }, [{ option: 'Yes', value: 'true' }, { option: 'No', value: 'false' }]),
|
|
2412
2415
|
new FxStringSetting({ key: 'errorMessage', $title: 'Error Message', value: 'Please fill out the field' }),
|
|
@@ -2429,11 +2432,11 @@ class DropdownWithOtherComponent extends FxBaseComponent {
|
|
|
2429
2432
|
});
|
|
2430
2433
|
}
|
|
2431
2434
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropdownWithOtherComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.HttpClient }, { token: FxBuilderWrapperService }, { token: i3$2.ApiServiceRegistry }], target: i0.ɵɵFactoryTarget.Component });
|
|
2432
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DropdownWithOtherComponent, isStandalone: true, selector: "dropdown-with-other", viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"flex justify-center custom-dropdown\" [ngClass]=\"setting('customClass')\" *ngIf=\"false\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex flex-row gap-4 items-start\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n\r\n <!-- <label class=\"mb-1 font-semibold text-sm\"></label> -->\r\n <span class=\"input-label dark:text-gray-300\">{{ setting('select-label') }}</span>\r\n <select formControlName=\"selectedOption\" class=\"border p-2 rounded w-full\">\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n </div>\r\n\r\n <!-- Other input (only if 'Other' selected) -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n <label class=\"input-label dark:text-gray-300\">{{ setting('other-label') }}</label>\r\n <div class=\"relative\">\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{setting('other-placeholder')}}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n ></textarea>\r\n </div>\r\n <small *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Other is required.\r\n </small>\r\n </div>\r\n </div>\r\n\r\n \r\n </form>\r\n</div>\r\n\r\n<div class=\"custom-dropdown\" [ngClass]=\"setting('customClass')\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex gap-4 w-full\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n <select\r\n formControlName=\"selectedOption\"\r\n class=\"border p-2 rounded w-full\"\r\n >\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n\r\n <!-- Other input -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('other-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{ setting('other-placeholder') }}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n ></textarea>\r\n\r\n <small\r\n *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\"\r\n >\r\n {{ setting('errorMessageOther')}}\r\n </small>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n\r\n\r\n\r\n</fx-component>\r\n\r\n <!-- <small *ngIf=\"datePickerForm.get('date')?.touched && datePickerForm.get('date')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Date is required.\r\n </small> -->", styles: ["@import\"https://unpkg.com/primeng@17.18.10/resources/themes/lara-light-blue/theme.css\";@import\"https://unpkg.com/primeng@17.18.10/resources/primeng.min.css\";@import\"https://unpkg.com/primeicons@6.0.0/primeicons.css\";.formBuilder_dynamic_table{border:.6px solid #ccc}.formBuilder_dynamic_table>thead>tr{background-color:#4682b4;color:#fff}.formBuilder_dynamic_table>thead>tr>th{font-weight:400!important;padding:.25rem .55rem;font-size:.875rem;text-align:left}.formBuilder_dynamic_table>tbody>tr:nth-child(odd){background-color:#fff}.formBuilder_dynamic_table>tbody>tr:nth-child(2n){background-color:#f6f6f6}.formBuilder_dynamic_table>tbody>tr>td{text-align:left;padding:.25rem .55rem}[type=text],[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{border:1px solid #ccc;border-radius:4px;padding:4px}select:not([size]){background:url('data:image/svg+xml,<svg width=\"22\" height=\"20\" viewBox=\"0 0 26 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0D%0A <rect x=\"0.5\" width=\"24.766\" height=\"24\" rx=\"3\" fill=\"%23FF7900\" fill-opacity=\"0.1\"/>%0D%0A <path d=\"M12.8918 16.5019C12.7255 16.5019 12.5695 16.4736 12.4239 16.4169C12.2783 16.3602 12.1431 16.2628 12.0183 16.1248L6.27803 9.8162C6.04925 9.56477 5.92946 9.25025 5.91864 8.87265C5.90783 8.49505 6.02762 8.16956 6.27803 7.89619C6.50681 7.64476 6.79799 7.51905 7.15155 7.51905C7.50512 7.51905 7.7963 7.64476 8.02508 7.89619L12.8918 13.2105L17.7586 7.89619C17.9874 7.64476 18.2736 7.51356 18.6172 7.50259C18.9607 7.49162 19.2569 7.62282 19.5056 7.89619C19.7344 8.14762 19.8488 8.46762 19.8488 8.85619C19.8488 9.24477 19.7344 9.56477 19.5056 9.8162L13.7654 16.1248C13.6406 16.2619 13.5054 16.3593 13.3598 16.4169C13.2142 16.4745 13.0582 16.5028 12.8918 16.5019Z\" fill=\"%23FAA762\"/>%0D%0A</svg>%0D%0A') right .4rem center no-repeat #fff;border:1px solid #cdcdcd;padding:6px 30px 6px 10px;border-radius:4px;font-size:14px;font-weight:400;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%!important}.dd_down_icon{background:#f3a04126;border-radius:3px!important;padding:2px}[type=checkbox]{padding:12px}[type=checkbox]:checked{background-color:#f3a041!important;padding:12px;background-size:1em 1em!important}[type=radio]{width:20px;height:20px}[type=radio]:checked{background-color:#f3a041!important;background-size:1.5em 1.5em}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-color: #f3a041 !important}:is() .p-multiselect{height:37.6px!important;border:1px solid #cdcdcd}:is() .p-multiselect .p-multiselect-label{padding:.5rem .75rem}:is() .p-multiselect .p-multiselect-label .p-placeholder{color:#454545}:is() .p-multiselect .p-multiselect-trigger{width:2.5rem!important}.dd_down_icon span{color:#f3a041}.orientation{height:82%!important}.confirmation-dialog .p-dialog-content{text-align:center}.field-required{color:red;font-size:1.1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FxComponent, selector: "fx-component", inputs: ["fxData"] }, { kind: "ngmodule", type: CalendarModule }] });
|
|
2435
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DropdownWithOtherComponent, isStandalone: true, selector: "dropdown-with-other", viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"flex justify-center custom-dropdown\" [ngClass]=\"setting('customClass')\" *ngIf=\"false\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex flex-row gap-4 items-start\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n\r\n <!-- <label class=\"mb-1 font-semibold text-sm\"></label> -->\r\n <span class=\"input-label dark:text-gray-300\">{{ setting('select-label') }}</span>\r\n <select formControlName=\"selectedOption\" class=\"border p-2 rounded w-full\">\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n </div>\r\n\r\n <!-- Other input (only if 'Other' selected) -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n <label class=\"input-label dark:text-gray-300\">{{ setting('other-label') }}</label>\r\n <div class=\"relative\">\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{setting('other-placeholder')}}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n ></textarea>\r\n </div>\r\n <small *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Other is required.\r\n </small>\r\n </div>\r\n </div>\r\n\r\n \r\n </form>\r\n</div>\r\n\r\n<div class=\"custom-dropdown\" [ngClass]=\"setting('customClass')\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex gap-4 w-full\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n <select\r\n formControlName=\"selectedOption\"\r\n class=\"border p-2 rounded w-full\"\r\n >\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n\r\n <!-- Other input -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('other-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{ setting('other-placeholder') }}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n [maxlength]=\"otherMaxLength\"\r\n ></textarea>\r\n\r\n <small\r\n *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\"\r\n >\r\n {{ setting('errorMessageOther')}}\r\n </small>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n\r\n\r\n\r\n</fx-component>\r\n\r\n <!-- <small *ngIf=\"datePickerForm.get('date')?.touched && datePickerForm.get('date')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Date is required.\r\n </small> -->", styles: ["@import\"https://unpkg.com/primeng@17.18.10/resources/themes/lara-light-blue/theme.css\";@import\"https://unpkg.com/primeng@17.18.10/resources/primeng.min.css\";@import\"https://unpkg.com/primeicons@6.0.0/primeicons.css\";.formBuilder_dynamic_table{border:.6px solid #ccc}.formBuilder_dynamic_table>thead>tr{background-color:#4682b4;color:#fff}.formBuilder_dynamic_table>thead>tr>th{font-weight:400!important;padding:.25rem .55rem;font-size:.875rem;text-align:left}.formBuilder_dynamic_table>tbody>tr:nth-child(odd){background-color:#fff}.formBuilder_dynamic_table>tbody>tr:nth-child(2n){background-color:#f6f6f6}.formBuilder_dynamic_table>tbody>tr>td{text-align:left;padding:.25rem .55rem}[type=text],[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{border:1px solid #ccc;border-radius:4px;padding:4px}select:not([size]){background:url('data:image/svg+xml,<svg width=\"22\" height=\"20\" viewBox=\"0 0 26 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0D%0A <rect x=\"0.5\" width=\"24.766\" height=\"24\" rx=\"3\" fill=\"%23FF7900\" fill-opacity=\"0.1\"/>%0D%0A <path d=\"M12.8918 16.5019C12.7255 16.5019 12.5695 16.4736 12.4239 16.4169C12.2783 16.3602 12.1431 16.2628 12.0183 16.1248L6.27803 9.8162C6.04925 9.56477 5.92946 9.25025 5.91864 8.87265C5.90783 8.49505 6.02762 8.16956 6.27803 7.89619C6.50681 7.64476 6.79799 7.51905 7.15155 7.51905C7.50512 7.51905 7.7963 7.64476 8.02508 7.89619L12.8918 13.2105L17.7586 7.89619C17.9874 7.64476 18.2736 7.51356 18.6172 7.50259C18.9607 7.49162 19.2569 7.62282 19.5056 7.89619C19.7344 8.14762 19.8488 8.46762 19.8488 8.85619C19.8488 9.24477 19.7344 9.56477 19.5056 9.8162L13.7654 16.1248C13.6406 16.2619 13.5054 16.3593 13.3598 16.4169C13.2142 16.4745 13.0582 16.5028 12.8918 16.5019Z\" fill=\"%23FAA762\"/>%0D%0A</svg>%0D%0A') right .4rem center no-repeat #fff;border:1px solid #cdcdcd;padding:6px 30px 6px 10px;border-radius:4px;font-size:14px;font-weight:400;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%!important}.dd_down_icon{background:#f3a04126;border-radius:3px!important;padding:2px}[type=checkbox]{padding:12px}[type=checkbox]:checked{background-color:#f3a041!important;padding:12px;background-size:1em 1em!important}[type=radio]{width:20px;height:20px}[type=radio]:checked{background-color:#f3a041!important;background-size:1.5em 1.5em}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-color: #f3a041 !important}:is() .p-multiselect{height:37.6px!important;border:1px solid #cdcdcd}:is() .p-multiselect .p-multiselect-label{padding:.5rem .75rem}:is() .p-multiselect .p-multiselect-label .p-placeholder{color:#454545}:is() .p-multiselect .p-multiselect-trigger{width:2.5rem!important}.dd_down_icon span{color:#f3a041}.orientation{height:82%!important}.confirmation-dialog .p-dialog-content{text-align:center}.field-required{color:red;font-size:1.1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FxComponent, selector: "fx-component", inputs: ["fxData"] }, { kind: "ngmodule", type: CalendarModule }] });
|
|
2433
2436
|
}
|
|
2434
2437
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropdownWithOtherComponent, decorators: [{
|
|
2435
2438
|
type: Component,
|
|
2436
|
-
args: [{ selector: 'dropdown-with-other', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent, CalendarModule], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"flex justify-center custom-dropdown\" [ngClass]=\"setting('customClass')\" *ngIf=\"false\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex flex-row gap-4 items-start\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n\r\n <!-- <label class=\"mb-1 font-semibold text-sm\"></label> -->\r\n <span class=\"input-label dark:text-gray-300\">{{ setting('select-label') }}</span>\r\n <select formControlName=\"selectedOption\" class=\"border p-2 rounded w-full\">\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n </div>\r\n\r\n <!-- Other input (only if 'Other' selected) -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n <label class=\"input-label dark:text-gray-300\">{{ setting('other-label') }}</label>\r\n <div class=\"relative\">\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{setting('other-placeholder')}}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n ></textarea>\r\n </div>\r\n <small *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Other is required.\r\n </small>\r\n </div>\r\n </div>\r\n\r\n \r\n </form>\r\n</div>\r\n\r\n<div class=\"custom-dropdown\" [ngClass]=\"setting('customClass')\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex gap-4 w-full\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n <select\r\n formControlName=\"selectedOption\"\r\n class=\"border p-2 rounded w-full\"\r\n >\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n\r\n <!-- Other input -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('other-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{ setting('other-placeholder') }}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n ></textarea>\r\n\r\n <small\r\n *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\"\r\n >\r\n {{ setting('errorMessageOther')}}\r\n </small>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n\r\n\r\n\r\n</fx-component>\r\n\r\n <!-- <small *ngIf=\"datePickerForm.get('date')?.touched && datePickerForm.get('date')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Date is required.\r\n </small> -->", styles: ["@import\"https://unpkg.com/primeng@17.18.10/resources/themes/lara-light-blue/theme.css\";@import\"https://unpkg.com/primeng@17.18.10/resources/primeng.min.css\";@import\"https://unpkg.com/primeicons@6.0.0/primeicons.css\";.formBuilder_dynamic_table{border:.6px solid #ccc}.formBuilder_dynamic_table>thead>tr{background-color:#4682b4;color:#fff}.formBuilder_dynamic_table>thead>tr>th{font-weight:400!important;padding:.25rem .55rem;font-size:.875rem;text-align:left}.formBuilder_dynamic_table>tbody>tr:nth-child(odd){background-color:#fff}.formBuilder_dynamic_table>tbody>tr:nth-child(2n){background-color:#f6f6f6}.formBuilder_dynamic_table>tbody>tr>td{text-align:left;padding:.25rem .55rem}[type=text],[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{border:1px solid #ccc;border-radius:4px;padding:4px}select:not([size]){background:url('data:image/svg+xml,<svg width=\"22\" height=\"20\" viewBox=\"0 0 26 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0D%0A <rect x=\"0.5\" width=\"24.766\" height=\"24\" rx=\"3\" fill=\"%23FF7900\" fill-opacity=\"0.1\"/>%0D%0A <path d=\"M12.8918 16.5019C12.7255 16.5019 12.5695 16.4736 12.4239 16.4169C12.2783 16.3602 12.1431 16.2628 12.0183 16.1248L6.27803 9.8162C6.04925 9.56477 5.92946 9.25025 5.91864 8.87265C5.90783 8.49505 6.02762 8.16956 6.27803 7.89619C6.50681 7.64476 6.79799 7.51905 7.15155 7.51905C7.50512 7.51905 7.7963 7.64476 8.02508 7.89619L12.8918 13.2105L17.7586 7.89619C17.9874 7.64476 18.2736 7.51356 18.6172 7.50259C18.9607 7.49162 19.2569 7.62282 19.5056 7.89619C19.7344 8.14762 19.8488 8.46762 19.8488 8.85619C19.8488 9.24477 19.7344 9.56477 19.5056 9.8162L13.7654 16.1248C13.6406 16.2619 13.5054 16.3593 13.3598 16.4169C13.2142 16.4745 13.0582 16.5028 12.8918 16.5019Z\" fill=\"%23FAA762\"/>%0D%0A</svg>%0D%0A') right .4rem center no-repeat #fff;border:1px solid #cdcdcd;padding:6px 30px 6px 10px;border-radius:4px;font-size:14px;font-weight:400;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%!important}.dd_down_icon{background:#f3a04126;border-radius:3px!important;padding:2px}[type=checkbox]{padding:12px}[type=checkbox]:checked{background-color:#f3a041!important;padding:12px;background-size:1em 1em!important}[type=radio]{width:20px;height:20px}[type=radio]:checked{background-color:#f3a041!important;background-size:1.5em 1.5em}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-color: #f3a041 !important}:is() .p-multiselect{height:37.6px!important;border:1px solid #cdcdcd}:is() .p-multiselect .p-multiselect-label{padding:.5rem .75rem}:is() .p-multiselect .p-multiselect-label .p-placeholder{color:#454545}:is() .p-multiselect .p-multiselect-trigger{width:2.5rem!important}.dd_down_icon span{color:#f3a041}.orientation{height:82%!important}.confirmation-dialog .p-dialog-content{text-align:center}.field-required{color:red;font-size:1.1em}\n"] }]
|
|
2439
|
+
args: [{ selector: 'dropdown-with-other', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent, CalendarModule], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"flex justify-center custom-dropdown\" [ngClass]=\"setting('customClass')\" *ngIf=\"false\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex flex-row gap-4 items-start\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n\r\n <!-- <label class=\"mb-1 font-semibold text-sm\"></label> -->\r\n <span class=\"input-label dark:text-gray-300\">{{ setting('select-label') }}</span>\r\n <select formControlName=\"selectedOption\" class=\"border p-2 rounded w-full\">\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n </div>\r\n\r\n <!-- Other input (only if 'Other' selected) -->\r\n <div class=\"flex flex-col w-1/2\">\r\n <div class=\"relative\">\r\n <label class=\"input-label dark:text-gray-300\">{{ setting('other-label') }}</label>\r\n <div class=\"relative\">\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{setting('other-placeholder')}}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n ></textarea>\r\n </div>\r\n <small *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Other is required.\r\n </small>\r\n </div>\r\n </div>\r\n\r\n \r\n </form>\r\n</div>\r\n\r\n<div class=\"custom-dropdown\" [ngClass]=\"setting('customClass')\">\r\n <form [formGroup]=\"dropDownForm\" class=\"flex gap-4 w-full\">\r\n \r\n <!-- Dropdown -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n <select\r\n formControlName=\"selectedOption\"\r\n class=\"border p-2 rounded w-full\"\r\n >\r\n <option value=\"\">Select</option>\r\n <option *ngFor=\"let option of options\" [value]=\"option.value\">\r\n {{ option?.label }}\r\n </option>\r\n </select>\r\n <small *ngIf=\"dropDownForm.get('selectedOption')?.touched && dropDownForm.get('selectedOption')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorMessage')}}\r\n </small>\r\n </div>\r\n\r\n <!-- Other input -->\r\n <div class=\"flex-1 relative\">\r\n <label class=\"input-label dark:text-gray-300\">\r\n {{ setting('other-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n <textarea\r\n formControlName=\"otherInput\"\r\n placeholder=\"{{ setting('other-placeholder') }}\"\r\n class=\"border p-2 rounded w-full\"\r\n rows=\"2\"\r\n [maxlength]=\"otherMaxLength\"\r\n ></textarea>\r\n\r\n <small\r\n *ngIf=\"dropDownForm.get('otherInput')?.touched && dropDownForm.get('otherInput')?.errors?.['required']\"\r\n class=\"text-red-500\"\r\n >\r\n {{ setting('errorMessageOther')}}\r\n </small>\r\n </div>\r\n\r\n </form>\r\n</div>\r\n\r\n\r\n\r\n</fx-component>\r\n\r\n <!-- <small *ngIf=\"datePickerForm.get('date')?.touched && datePickerForm.get('date')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n Date is required.\r\n </small> -->", styles: ["@import\"https://unpkg.com/primeng@17.18.10/resources/themes/lara-light-blue/theme.css\";@import\"https://unpkg.com/primeng@17.18.10/resources/primeng.min.css\";@import\"https://unpkg.com/primeicons@6.0.0/primeicons.css\";.formBuilder_dynamic_table{border:.6px solid #ccc}.formBuilder_dynamic_table>thead>tr{background-color:#4682b4;color:#fff}.formBuilder_dynamic_table>thead>tr>th{font-weight:400!important;padding:.25rem .55rem;font-size:.875rem;text-align:left}.formBuilder_dynamic_table>tbody>tr:nth-child(odd){background-color:#fff}.formBuilder_dynamic_table>tbody>tr:nth-child(2n){background-color:#f6f6f6}.formBuilder_dynamic_table>tbody>tr>td{text-align:left;padding:.25rem .55rem}[type=text],[type=email],[type=url],[type=password],[type=number],[type=date],[type=datetime-local],[type=month],[type=search],[type=tel],[type=time],[type=week],[multiple],textarea,select{border:1px solid #ccc;border-radius:4px;padding:4px}select:not([size]){background:url('data:image/svg+xml,<svg width=\"22\" height=\"20\" viewBox=\"0 0 26 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0D%0A <rect x=\"0.5\" width=\"24.766\" height=\"24\" rx=\"3\" fill=\"%23FF7900\" fill-opacity=\"0.1\"/>%0D%0A <path d=\"M12.8918 16.5019C12.7255 16.5019 12.5695 16.4736 12.4239 16.4169C12.2783 16.3602 12.1431 16.2628 12.0183 16.1248L6.27803 9.8162C6.04925 9.56477 5.92946 9.25025 5.91864 8.87265C5.90783 8.49505 6.02762 8.16956 6.27803 7.89619C6.50681 7.64476 6.79799 7.51905 7.15155 7.51905C7.50512 7.51905 7.7963 7.64476 8.02508 7.89619L12.8918 13.2105L17.7586 7.89619C17.9874 7.64476 18.2736 7.51356 18.6172 7.50259C18.9607 7.49162 19.2569 7.62282 19.5056 7.89619C19.7344 8.14762 19.8488 8.46762 19.8488 8.85619C19.8488 9.24477 19.7344 9.56477 19.5056 9.8162L13.7654 16.1248C13.6406 16.2619 13.5054 16.3593 13.3598 16.4169C13.2142 16.4745 13.0582 16.5028 12.8918 16.5019Z\" fill=\"%23FAA762\"/>%0D%0A</svg>%0D%0A') right .4rem center no-repeat #fff;border:1px solid #cdcdcd;padding:6px 30px 6px 10px;border-radius:4px;font-size:14px;font-weight:400;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%!important}.dd_down_icon{background:#f3a04126;border-radius:3px!important;padding:2px}[type=checkbox]{padding:12px}[type=checkbox]:checked{background-color:#f3a041!important;padding:12px;background-size:1em 1em!important}[type=radio]{width:20px;height:20px}[type=radio]:checked{background-color:#f3a041!important;background-size:1.5em 1.5em}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-color: #f3a041 !important}:is() .p-multiselect{height:37.6px!important;border:1px solid #cdcdcd}:is() .p-multiselect .p-multiselect-label{padding:.5rem .75rem}:is() .p-multiselect .p-multiselect-label .p-placeholder{color:#454545}:is() .p-multiselect .p-multiselect-trigger{width:2.5rem!important}.dd_down_icon span{color:#f3a041}.orientation{height:82%!important}.confirmation-dialog .p-dialog-content{text-align:center}.field-required{color:red;font-size:1.1em}\n"] }]
|
|
2437
2440
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.HttpClient }, { type: FxBuilderWrapperService }, { type: i3$2.ApiServiceRegistry }], propDecorators: { fxComponent: [{
|
|
2438
2441
|
type: ViewChild,
|
|
2439
2442
|
args: ['fxComponent']
|
|
@@ -2465,6 +2468,7 @@ class RadioGroupComponent extends FxBaseComponent {
|
|
|
2465
2468
|
compareValue;
|
|
2466
2469
|
isRequired = false;
|
|
2467
2470
|
isChildRequired = false;
|
|
2471
|
+
remarkMaxLength = 84;
|
|
2468
2472
|
constructor(cdr, http, fxBuilderWrapperService, fxApiService) {
|
|
2469
2473
|
super(cdr);
|
|
2470
2474
|
this.cdr = cdr;
|
|
@@ -2492,6 +2496,7 @@ class RadioGroupComponent extends FxBaseComponent {
|
|
|
2492
2496
|
}, 200);
|
|
2493
2497
|
setTimeout(() => {
|
|
2494
2498
|
const mainControl = this.confirmationForm.get('confirmation');
|
|
2499
|
+
this.remarkMaxLength = Number(this.setting('remark-maxlength')) || 84;
|
|
2495
2500
|
if (this.setting('isRadioRequired') === 'true') {
|
|
2496
2501
|
this.isRequired = true;
|
|
2497
2502
|
mainControl?.setValidators([Validators.required]);
|
|
@@ -2549,6 +2554,7 @@ class RadioGroupComponent extends FxBaseComponent {
|
|
|
2549
2554
|
new FxStringSetting({ key: 'error-msg', $title: 'Error message', value: 'Please select' }),
|
|
2550
2555
|
new FxStringSetting({ key: 'remark-placeholder', $title: 'Additional field placeholder', value: 'enter here' }),
|
|
2551
2556
|
new FxSelectSetting({ key: 'isRadioRequired', $title: 'Required', value: 'true' }, [{ option: 'Yes', value: 'true' }, { option: 'No', value: 'false' }]),
|
|
2557
|
+
new FxStringSetting({ key: 'remark-maxlength', $title: 'Additional field max length', value: 84 }),
|
|
2552
2558
|
// new FxStringSetting({ key: 'other-placeholder', $title: 'Other Placeholder', value: '' }),
|
|
2553
2559
|
// new FxSelectSetting({key: 'serviceName', $title: 'Service', value: ''}, [{option: 'User Service', value: 'user_service'}, {option: 'Patient Service', value: 'patient_service'},{option: 'Workflow Service', value: 'workflow_service'}]),
|
|
2554
2560
|
// // new FxSelectSetting({key: 'service', $title: 'Service', value: 'local'}, [{option: 'Local', value: 'local'}, {option: 'QA', value: 'qa'},{option: 'UAT', value: 'uat'},{option: 'Production', value: 'prod'}]),
|
|
@@ -2578,11 +2584,11 @@ class RadioGroupComponent extends FxBaseComponent {
|
|
|
2578
2584
|
}
|
|
2579
2585
|
}
|
|
2580
2586
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RadioGroupComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.HttpClient }, { token: FxBuilderWrapperService }, { token: i3$2.ApiServiceRegistry }], target: i0.ɵɵFactoryTarget.Component });
|
|
2581
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RadioGroupComponent, isStandalone: true, selector: "radio-group-custom", inputs: { showOnSelection: "showOnSelection" }, viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div [ngClass]=\"setting('customClasss')\">\r\n<form [formGroup]=\"confirmationForm\" class=\"flex gap-4 w-full\">\r\n <div class=\"flex-1 w-full\">\r\n <!-- Title -->\r\n <label class=\"font-semibold text-gray-800\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n\r\n <!-- TWO COLUMN LAYOUT -->\r\n \r\n\r\n <!-- LEFT COLUMN (RADIO GROUP) -->\r\n <div class=\"flex-1\">\r\n\r\n <div class=\"flex gap-3 my-2\"> \r\n <!-- stack vertically so height is correct -->\r\n <label\r\n *ngFor=\"let opt of options\"\r\n class=\"flex items-center gap-2 cursor-pointer text-gray-700\"\r\n >\r\n <input\r\n type=\"radio\"\r\n formControlName=\"confirmation\"\r\n [value]=\"opt.value\"\r\n (change)=\"onSelectionChange(opt.value)\"\r\n class=\"w-4 h-4 accent-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ opt.option }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Radio error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('confirmation')?.touched &&\r\n confirmationForm.get('confirmation')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n </div>\r\n \r\n <!-- RIGHT COLUMN (TEXTAREA) -->\r\n <div *ngIf=\"showTextArea\" class=\"flex-1 relative mt-2 md:mt-1\">\r\n\r\n <label class=\"input-label font-medium text-gray-700\">\r\n {{ setting('additional-field-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n\r\n <textarea\r\n formControlName=\"remarks\"\r\n rows=\"3\"\r\n placeholder=\"{{ setting('remark-placeholder') }}\"\r\n class=\"border border-gray-300 rounded-lg p-3 w-full resize-none shadow-sm\r\n focus:outline-none focus:ring-2 focus:ring-blue-500\"\r\n ></textarea>\r\n\r\n <!-- Textarea error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('remarks')?.touched &&\r\n confirmationForm.get('remarks')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('additional-field-error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n\r\n\r\n</form>\r\n</div>\r\n\r\n\r\n</fx-component>\r\n", styles: [".custom-gap{gap:1rem}.field-required{color:red;font-size:1.1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FxComponent, selector: "fx-component", inputs: ["fxData"] }, { kind: "ngmodule", type: CalendarModule }, { kind: "ngmodule", type: RadioButtonModule }] });
|
|
2587
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RadioGroupComponent, isStandalone: true, selector: "radio-group-custom", inputs: { showOnSelection: "showOnSelection" }, viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div [ngClass]=\"setting('customClasss')\">\r\n<form [formGroup]=\"confirmationForm\" class=\"flex gap-4 w-full\">\r\n <div class=\"flex-1 w-full\">\r\n <!-- Title -->\r\n <label class=\"font-semibold text-gray-800\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n\r\n <!-- TWO COLUMN LAYOUT -->\r\n \r\n\r\n <!-- LEFT COLUMN (RADIO GROUP) -->\r\n <div class=\"flex-1\">\r\n\r\n <div class=\"flex gap-3 my-2\"> \r\n <!-- stack vertically so height is correct -->\r\n <label\r\n *ngFor=\"let opt of options\"\r\n class=\"flex items-center gap-2 cursor-pointer text-gray-700\"\r\n >\r\n <input\r\n type=\"radio\"\r\n formControlName=\"confirmation\"\r\n [value]=\"opt.value\"\r\n (change)=\"onSelectionChange(opt.value)\"\r\n class=\"w-4 h-4 accent-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ opt.option }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Radio error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('confirmation')?.touched &&\r\n confirmationForm.get('confirmation')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n </div>\r\n \r\n <!-- RIGHT COLUMN (TEXTAREA) -->\r\n <div *ngIf=\"showTextArea\" class=\"flex-1 relative mt-2 md:mt-1\">\r\n\r\n <label class=\"input-label font-medium text-gray-700\">\r\n {{ setting('additional-field-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n\r\n <textarea\r\n formControlName=\"remarks\"\r\n rows=\"3\"\r\n placeholder=\"{{ setting('remark-placeholder') }}\"\r\n class=\"border border-gray-300 rounded-lg p-3 w-full resize-none shadow-sm\r\n focus:outline-none focus:ring-2 focus:ring-blue-500\"\r\n [maxlength]=\"remarkMaxLength\" \r\n ></textarea>\r\n\r\n <!-- Textarea error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('remarks')?.touched &&\r\n confirmationForm.get('remarks')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('additional-field-error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n\r\n\r\n</form>\r\n</div>\r\n\r\n\r\n</fx-component>\r\n", styles: [".custom-gap{gap:1rem}.field-required{color:red;font-size:1.1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FxComponent, selector: "fx-component", inputs: ["fxData"] }, { kind: "ngmodule", type: CalendarModule }, { kind: "ngmodule", type: RadioButtonModule }] });
|
|
2582
2588
|
}
|
|
2583
2589
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RadioGroupComponent, decorators: [{
|
|
2584
2590
|
type: Component,
|
|
2585
|
-
args: [{ selector: 'radio-group-custom', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent, CalendarModule, RadioButtonModule], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div [ngClass]=\"setting('customClasss')\">\r\n<form [formGroup]=\"confirmationForm\" class=\"flex gap-4 w-full\">\r\n <div class=\"flex-1 w-full\">\r\n <!-- Title -->\r\n <label class=\"font-semibold text-gray-800\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n\r\n <!-- TWO COLUMN LAYOUT -->\r\n \r\n\r\n <!-- LEFT COLUMN (RADIO GROUP) -->\r\n <div class=\"flex-1\">\r\n\r\n <div class=\"flex gap-3 my-2\"> \r\n <!-- stack vertically so height is correct -->\r\n <label\r\n *ngFor=\"let opt of options\"\r\n class=\"flex items-center gap-2 cursor-pointer text-gray-700\"\r\n >\r\n <input\r\n type=\"radio\"\r\n formControlName=\"confirmation\"\r\n [value]=\"opt.value\"\r\n (change)=\"onSelectionChange(opt.value)\"\r\n class=\"w-4 h-4 accent-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ opt.option }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Radio error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('confirmation')?.touched &&\r\n confirmationForm.get('confirmation')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n </div>\r\n \r\n <!-- RIGHT COLUMN (TEXTAREA) -->\r\n <div *ngIf=\"showTextArea\" class=\"flex-1 relative mt-2 md:mt-1\">\r\n\r\n <label class=\"input-label font-medium text-gray-700\">\r\n {{ setting('additional-field-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n\r\n <textarea\r\n formControlName=\"remarks\"\r\n rows=\"3\"\r\n placeholder=\"{{ setting('remark-placeholder') }}\"\r\n class=\"border border-gray-300 rounded-lg p-3 w-full resize-none shadow-sm\r\n focus:outline-none focus:ring-2 focus:ring-blue-500\"\r\n ></textarea>\r\n\r\n <!-- Textarea error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('remarks')?.touched &&\r\n confirmationForm.get('remarks')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('additional-field-error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n\r\n\r\n</form>\r\n</div>\r\n\r\n\r\n</fx-component>\r\n", styles: [".custom-gap{gap:1rem}.field-required{color:red;font-size:1.1em}\n"] }]
|
|
2591
|
+
args: [{ selector: 'radio-group-custom', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent, CalendarModule, RadioButtonModule], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div [ngClass]=\"setting('customClasss')\">\r\n<form [formGroup]=\"confirmationForm\" class=\"flex gap-4 w-full\">\r\n <div class=\"flex-1 w-full\">\r\n <!-- Title -->\r\n <label class=\"font-semibold text-gray-800\">\r\n {{ setting('select-label') }} <span class=\"field-required\" *ngIf=\"isRequired\">*</span>\r\n </label>\r\n\r\n <!-- TWO COLUMN LAYOUT -->\r\n \r\n\r\n <!-- LEFT COLUMN (RADIO GROUP) -->\r\n <div class=\"flex-1\">\r\n\r\n <div class=\"flex gap-3 my-2\"> \r\n <!-- stack vertically so height is correct -->\r\n <label\r\n *ngFor=\"let opt of options\"\r\n class=\"flex items-center gap-2 cursor-pointer text-gray-700\"\r\n >\r\n <input\r\n type=\"radio\"\r\n formControlName=\"confirmation\"\r\n [value]=\"opt.value\"\r\n (change)=\"onSelectionChange(opt.value)\"\r\n class=\"w-4 h-4 accent-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ opt.option }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Radio error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('confirmation')?.touched &&\r\n confirmationForm.get('confirmation')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n </div>\r\n \r\n <!-- RIGHT COLUMN (TEXTAREA) -->\r\n <div *ngIf=\"showTextArea\" class=\"flex-1 relative mt-2 md:mt-1\">\r\n\r\n <label class=\"input-label font-medium text-gray-700\">\r\n {{ setting('additional-field-label') }} <span class=\"field-required\" *ngIf=\"isChildRequired\">*</span>\r\n </label>\r\n\r\n <textarea\r\n formControlName=\"remarks\"\r\n rows=\"3\"\r\n placeholder=\"{{ setting('remark-placeholder') }}\"\r\n class=\"border border-gray-300 rounded-lg p-3 w-full resize-none shadow-sm\r\n focus:outline-none focus:ring-2 focus:ring-blue-500\"\r\n [maxlength]=\"remarkMaxLength\" \r\n ></textarea>\r\n\r\n <!-- Textarea error -->\r\n <small\r\n *ngIf=\"\r\n confirmationForm.get('remarks')?.touched &&\r\n confirmationForm.get('remarks')?.errors?.['required']\r\n \"\r\n class=\"text-red-500 mt-1\"\r\n >\r\n {{ setting('additional-field-error-msg') }}\r\n </small>\r\n\r\n </div>\r\n\r\n\r\n\r\n</form>\r\n</div>\r\n\r\n\r\n</fx-component>\r\n", styles: [".custom-gap{gap:1rem}.field-required{color:red;font-size:1.1em}\n"] }]
|
|
2586
2592
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.HttpClient }, { type: FxBuilderWrapperService }, { type: i3$2.ApiServiceRegistry }], propDecorators: { showOnSelection: [{
|
|
2587
2593
|
type: Input
|
|
2588
2594
|
}], fxComponent: [{
|
|
@@ -2967,7 +2973,7 @@ class SummaryComponent extends FxBaseComponent {
|
|
|
2967
2973
|
summaryForm = this.fb.group({
|
|
2968
2974
|
summary: [''],
|
|
2969
2975
|
});
|
|
2970
|
-
dynamicText = '
|
|
2976
|
+
dynamicText = '';
|
|
2971
2977
|
constructor(cdr, http, fxBuilderWrapperService) {
|
|
2972
2978
|
super(cdr);
|
|
2973
2979
|
this.cdr = cdr;
|
|
@@ -2978,145 +2984,450 @@ class SummaryComponent extends FxBaseComponent {
|
|
|
2978
2984
|
});
|
|
2979
2985
|
}
|
|
2980
2986
|
ngOnInit() {
|
|
2987
|
+
this.dynamicText = this.setting('summaryText') || '';
|
|
2981
2988
|
this.fxBuilderWrapperService.variables$
|
|
2982
2989
|
.pipe(takeUntil(this.destroy$))
|
|
2983
2990
|
.subscribe((variables) => {
|
|
2984
2991
|
if (!variables)
|
|
2985
2992
|
return;
|
|
2986
|
-
this.datePickerMap = new Map();
|
|
2987
|
-
// for (const [key, value] of Object.entries(variables) as [string, any][]) {
|
|
2988
|
-
// if (key.includes('lib-date-picker')) {
|
|
2989
|
-
// this.datePickerMap.set(key, value);
|
|
2990
|
-
// }
|
|
2991
|
-
// }
|
|
2992
|
-
for (const [key, value] of Object.entries(variables)) {
|
|
2993
|
-
if (value &&
|
|
2994
|
-
typeof value === 'object' &&
|
|
2995
|
-
'date' in value) {
|
|
2996
|
-
this.datePickerMap.set(key, value);
|
|
2997
|
-
}
|
|
2998
|
-
}
|
|
2999
2993
|
});
|
|
3000
|
-
// const today = new Date();
|
|
3001
|
-
// this.minDate = new Date(today);
|
|
3002
|
-
// this.minDate.setDate(today.getDate() - 30);
|
|
3003
|
-
// this.maxDate = new Date(today);
|
|
3004
|
-
// this.maxDate.setDate(today.getDate() + 30);
|
|
3005
|
-
// this.minDate = this.formatDate(new Date(this.today.setDate(new Date().getDate() - 30)));
|
|
3006
|
-
// this.maxDate = this.formatDate(new Date(this.today.setDate(new Date().getDate() + 31)));
|
|
3007
|
-
const today = new Date();
|
|
3008
|
-
const min = new Date();
|
|
3009
|
-
min.setDate(today.getDate() - 30);
|
|
3010
|
-
const max = new Date();
|
|
3011
|
-
max.setDate(today.getDate());
|
|
3012
|
-
this.minDate = this.formatDate(min);
|
|
3013
|
-
this.maxDate = this.formatDate(max);
|
|
3014
|
-
// this.getRangeValues();
|
|
3015
2994
|
}
|
|
3016
|
-
// get dateControl() {
|
|
3017
|
-
// return this.datePickerForm.get('date');
|
|
3018
|
-
// }
|
|
3019
2995
|
ngAfterViewInit() {
|
|
3020
2996
|
const key = this.fxComponent?.fxData?.name;
|
|
3021
2997
|
if (key) {
|
|
3022
|
-
const datePatch = this.datePickerMap.get(key);
|
|
3023
|
-
const finalDate = datePatch || this.formatDate(new Date());
|
|
3024
|
-
if (datePatch) {
|
|
3025
|
-
this.minDate = datePatch;
|
|
3026
|
-
}
|
|
3027
|
-
else {
|
|
3028
|
-
this.minDate = this.formatDate(new Date(this.today.setDate(new Date().getDate() - 30)));
|
|
3029
|
-
}
|
|
3030
|
-
// this.datePickerForm.patchValue({date:finalDate});
|
|
3031
2998
|
}
|
|
3032
2999
|
this.getContextBaseId();
|
|
3033
3000
|
}
|
|
3034
|
-
getRangeValues() {
|
|
3035
|
-
this.http.get(this.setting('apiURL')).subscribe(response => {
|
|
3036
|
-
const today = new Date();
|
|
3037
|
-
const minOffset = response[this.setting('minDateKey')] || this.setting('minValidation');
|
|
3038
|
-
const maxOffset = response[this.setting('maxDateKey')] || this.setting('maxValidation');
|
|
3039
|
-
// this.minDate = new Date(today);
|
|
3040
|
-
// this.minDate.setDate(today.getDate() + minOffset);
|
|
3041
|
-
// this.maxDate = new Date(today);
|
|
3042
|
-
// this.maxDate.setDate(today.getDate() + maxOffset);
|
|
3043
|
-
this.minDate = this.formatDate(new Date(this.today.setDate(new Date().getDate() + minOffset)));
|
|
3044
|
-
this.maxDate = this.formatDate(new Date(this.today.setDate(new Date().getDate() + maxOffset)));
|
|
3045
|
-
});
|
|
3046
|
-
}
|
|
3047
3001
|
formatDate(date) {
|
|
3048
3002
|
return date.toISOString().split('T')[0];
|
|
3049
3003
|
}
|
|
3050
3004
|
settings() {
|
|
3051
3005
|
return [
|
|
3052
|
-
new FxStringSetting({ key: '
|
|
3053
|
-
new FxStringSetting({ key: '
|
|
3054
|
-
new FxStringSetting({ key: 'apiURL', $title: 'API Url', value: '' }),
|
|
3055
|
-
new FxStringSetting({ key: 'minDateKey', $title: 'Min Range API Key', value: '' }),
|
|
3056
|
-
new FxStringSetting({ key: 'maxDateKey', $title: 'Max Range API Key', value: '' }),
|
|
3057
|
-
new FxStringSetting({ key: 'placeHolder', $title: 'Placeholder', value: 'Select Date' }),
|
|
3058
|
-
new FxStringSetting({ key: 'label', $title: 'Label', value: '' }),
|
|
3059
|
-
new FxStringSetting({ key: 'datePickerErrorMessage', $title: 'Error Message', value: 'Please fill out the field' }),
|
|
3006
|
+
new FxStringSetting({ key: 'summaryText', $title: 'Summary Text', value: '' }),
|
|
3007
|
+
new FxStringSetting({ key: 'summaryLabel', $title: 'Label', value: '' }),
|
|
3060
3008
|
];
|
|
3061
3009
|
}
|
|
3062
3010
|
validations() {
|
|
3063
|
-
return [
|
|
3011
|
+
return [];
|
|
3064
3012
|
}
|
|
3065
3013
|
updateTextArea() {
|
|
3066
|
-
// Get all the form control values
|
|
3067
|
-
console.log('Updating text area with dynamic values', this.fxComponent);
|
|
3068
3014
|
const formValues = this.fxComponent?.fxData?.$formGroup?.value;
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
console.log('Form Values:', formValues);
|
|
3072
|
-
this.dynamicText = this.replacePlaceholders(this.dynamicText, formValues);
|
|
3073
|
-
console.log('Replaced dynamic text:', this.dynamicText);
|
|
3074
|
-
this.summaryForm.patchValue({ summary: this.dynamicText });
|
|
3015
|
+
const dynamicText = this.replacePlaceholders(this.dynamicText, formValues);
|
|
3016
|
+
this.summaryForm.patchValue({ summary: dynamicText });
|
|
3075
3017
|
this.cdr.detectChanges();
|
|
3076
3018
|
}
|
|
3077
|
-
// // Method to replace placeholders in the string based on form control values
|
|
3078
|
-
// replacePlaceholders(template: string, values: any): string {
|
|
3079
|
-
// // Use a regular expression to find placeholders like {name}, {age}, etc.
|
|
3080
|
-
// return template.replace(/{(.*?)}/g, (match, placeholder) => {
|
|
3081
|
-
// // For each placeholder, look it up in the form control values
|
|
3082
|
-
// return values[placeholder] !== undefined ? values[placeholder] : match;
|
|
3083
|
-
// });
|
|
3084
|
-
// }
|
|
3085
3019
|
replacePlaceholders(template, values) {
|
|
3086
|
-
// Log the values to debug
|
|
3087
|
-
console.log('Values:', values);
|
|
3088
|
-
// Use a regular expression to find placeholders like {name}, {age}, etc.
|
|
3089
3020
|
return template.replace(/{(.*?)}/g, (match, placeholder) => {
|
|
3090
|
-
// Log each placeholder being processed
|
|
3091
|
-
console.log('Processing placeholder:', placeholder);
|
|
3092
|
-
// Check if the placeholder exists in values
|
|
3093
3021
|
if (values[placeholder] !== undefined) {
|
|
3094
|
-
|
|
3095
|
-
return values[placeholder]; // Replace placeholder with its value
|
|
3022
|
+
return values[placeholder];
|
|
3096
3023
|
}
|
|
3097
3024
|
else {
|
|
3098
|
-
|
|
3099
|
-
return match; // Keep placeholder if no value found
|
|
3025
|
+
return match;
|
|
3100
3026
|
}
|
|
3101
3027
|
});
|
|
3102
3028
|
}
|
|
3103
3029
|
ngAfterViewChecked() {
|
|
3104
|
-
// After the view has been checked, update text area if needed
|
|
3105
3030
|
this.updateTextArea();
|
|
3106
|
-
this.cdr.detectChanges();
|
|
3031
|
+
this.cdr.detectChanges();
|
|
3107
3032
|
}
|
|
3108
3033
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SummaryComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.HttpClient }, { token: FxBuilderWrapperService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3109
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SummaryComponent, isStandalone: true, selector: "lib-summary", viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"custom-date-picker relative\">\r\n <form [formGroup]=\"summaryForm\">\r\n\r\n <label
|
|
3034
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SummaryComponent, isStandalone: true, selector: "lib-summary", viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"custom-date-picker relative\">\r\n <form [formGroup]=\"summaryForm\">\r\n\r\n <label class=\"summary-label\">{{ setting('summaryLabel') }}</label>\r\n <div class=\"relative\">\r\n <textarea formControlName=\"summary\" readonly class=\"w-full\"></textarea>\r\n </div>\r\n <!-- <div>\r\n <small *ngIf=\"datePickerForm.get('date')?.touched && datePickerForm.get('date')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('datePickerErrorMessage') }}\r\n </small>\r\n </div> -->\r\n </form>\r\n </div>\r\n\r\n</fx-component>", styles: [".summary-label{color:#4682b4;font-weight:600;margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: FxComponent, selector: "fx-component", inputs: ["fxData"] }] });
|
|
3110
3035
|
}
|
|
3111
3036
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SummaryComponent, decorators: [{
|
|
3112
3037
|
type: Component,
|
|
3113
|
-
args: [{ selector: 'lib-summary', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"custom-date-picker relative\">\r\n <form [formGroup]=\"summaryForm\">\r\n\r\n <label
|
|
3038
|
+
args: [{ selector: 'lib-summary', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"custom-date-picker relative\">\r\n <form [formGroup]=\"summaryForm\">\r\n\r\n <label class=\"summary-label\">{{ setting('summaryLabel') }}</label>\r\n <div class=\"relative\">\r\n <textarea formControlName=\"summary\" readonly class=\"w-full\"></textarea>\r\n </div>\r\n <!-- <div>\r\n <small *ngIf=\"datePickerForm.get('date')?.touched && datePickerForm.get('date')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('datePickerErrorMessage') }}\r\n </small>\r\n </div> -->\r\n </form>\r\n </div>\r\n\r\n</fx-component>", styles: [".summary-label{color:#4682b4;font-weight:600;margin-bottom:10px}\n"] }]
|
|
3114
3039
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.HttpClient }, { type: FxBuilderWrapperService }], propDecorators: { fxComponent: [{
|
|
3115
3040
|
type: ViewChild,
|
|
3116
3041
|
args: ['fxComponent']
|
|
3117
3042
|
}] } });
|
|
3118
3043
|
|
|
3119
|
-
|
|
3044
|
+
class CustomizeDropdownComponent extends FxBaseComponent {
|
|
3045
|
+
cdr;
|
|
3046
|
+
http;
|
|
3047
|
+
fxBuilderWrapperService;
|
|
3048
|
+
fxApiService;
|
|
3049
|
+
fb;
|
|
3050
|
+
eRef;
|
|
3051
|
+
destroy$ = new Subject();
|
|
3052
|
+
form;
|
|
3053
|
+
formObject = {};
|
|
3054
|
+
dropdownOpen = false;
|
|
3055
|
+
formSubmitted = false;
|
|
3056
|
+
fxComponent;
|
|
3057
|
+
findingsOptions = [];
|
|
3058
|
+
type1Options = [{
|
|
3059
|
+
label: 'Proclination',
|
|
3060
|
+
value: 'Proclination',
|
|
3061
|
+
info: 'Forward inclination of teeth',
|
|
3062
|
+
selected: false,
|
|
3063
|
+
subOptions: [
|
|
3064
|
+
{ label: 'Mild', value: 'mild' },
|
|
3065
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3066
|
+
{ label: 'Severe', value: 'severe' }
|
|
3067
|
+
]
|
|
3068
|
+
},
|
|
3069
|
+
{
|
|
3070
|
+
label: 'Crowding',
|
|
3071
|
+
value: 'Crowding',
|
|
3072
|
+
selected: false,
|
|
3073
|
+
subOptions: [
|
|
3074
|
+
{ label: 'Mild', value: 'mild' },
|
|
3075
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3076
|
+
{ label: 'Severe', value: 'severe' }
|
|
3077
|
+
]
|
|
3078
|
+
},
|
|
3079
|
+
{
|
|
3080
|
+
label: 'Spacing',
|
|
3081
|
+
value: 'Spacing',
|
|
3082
|
+
selected: false,
|
|
3083
|
+
subOptions: [
|
|
3084
|
+
{ label: 'Mild', value: 'mild' },
|
|
3085
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3086
|
+
{ label: 'Severe', value: 'severe' }
|
|
3087
|
+
]
|
|
3088
|
+
},
|
|
3089
|
+
{
|
|
3090
|
+
label: 'Retroclination',
|
|
3091
|
+
value: 'Retroclination',
|
|
3092
|
+
info: 'Backward inclination of teeth',
|
|
3093
|
+
selected: false,
|
|
3094
|
+
subOptions: [
|
|
3095
|
+
{ label: 'Mild', value: 'mild' },
|
|
3096
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3097
|
+
{ label: 'Severe', value: 'severe' }
|
|
3098
|
+
]
|
|
3099
|
+
},
|
|
3100
|
+
{
|
|
3101
|
+
label: 'Rotation',
|
|
3102
|
+
value: 'Rotation',
|
|
3103
|
+
selected: false,
|
|
3104
|
+
subOptions: [
|
|
3105
|
+
{ label: 'Mild', value: 'mild' },
|
|
3106
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3107
|
+
{ label: 'Severe', value: 'severe' }
|
|
3108
|
+
]
|
|
3109
|
+
}];
|
|
3110
|
+
type2Options = [
|
|
3111
|
+
{
|
|
3112
|
+
label: 'Normal',
|
|
3113
|
+
value: 'Normal',
|
|
3114
|
+
info: '',
|
|
3115
|
+
selected: false,
|
|
3116
|
+
subOptions: [
|
|
3117
|
+
{ label: 'Mild', value: 'mild' },
|
|
3118
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3119
|
+
{ label: 'Severe', value: 'severe' }
|
|
3120
|
+
]
|
|
3121
|
+
},
|
|
3122
|
+
{
|
|
3123
|
+
label: 'Deep Bite',
|
|
3124
|
+
value: 'Deep Bite',
|
|
3125
|
+
selected: false,
|
|
3126
|
+
subOptions: [
|
|
3127
|
+
{ label: 'Mild', value: 'mild' },
|
|
3128
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3129
|
+
{ label: 'Severe', value: 'severe' }
|
|
3130
|
+
]
|
|
3131
|
+
},
|
|
3132
|
+
{
|
|
3133
|
+
label: 'Open Bite',
|
|
3134
|
+
value: 'Open Bite',
|
|
3135
|
+
selected: false,
|
|
3136
|
+
subOptions: [
|
|
3137
|
+
{ label: 'Mild', value: 'mild' },
|
|
3138
|
+
{ label: 'Moderate', value: 'moderate' },
|
|
3139
|
+
{ label: 'Severe', value: 'severe' }
|
|
3140
|
+
]
|
|
3141
|
+
},
|
|
3142
|
+
];
|
|
3143
|
+
isRequired = false;
|
|
3144
|
+
// @HostListener('document:click', ['$event'])
|
|
3145
|
+
// onClickOutside(event: MouseEvent) {
|
|
3146
|
+
// if (this.dropdownOpen && !this.eRef.nativeElement.contains(event.target)) {
|
|
3147
|
+
// this.dropdownOpen = false;
|
|
3148
|
+
// this.cdr.detectChanges();
|
|
3149
|
+
// }
|
|
3150
|
+
// }
|
|
3151
|
+
config = {
|
|
3152
|
+
displayMode: 'ellipsis',
|
|
3153
|
+
placeholderLabel: 'Select Finding'
|
|
3154
|
+
};
|
|
3155
|
+
customizedDropDownMap = new Map();
|
|
3156
|
+
constructor(cdr, http, fxBuilderWrapperService, fxApiService, fb, eRef) {
|
|
3157
|
+
super(cdr);
|
|
3158
|
+
this.cdr = cdr;
|
|
3159
|
+
this.http = http;
|
|
3160
|
+
this.fxBuilderWrapperService = fxBuilderWrapperService;
|
|
3161
|
+
this.fxApiService = fxApiService;
|
|
3162
|
+
this.fb = fb;
|
|
3163
|
+
this.eRef = eRef;
|
|
3164
|
+
this.form = this.fb.group({
|
|
3165
|
+
findings: [[]]
|
|
3166
|
+
});
|
|
3167
|
+
this.onInit.subscribe(() => this._register(this.form));
|
|
3168
|
+
}
|
|
3169
|
+
ngAfterViewInit() {
|
|
3170
|
+
// setTimeout(()=>{
|
|
3171
|
+
// const data = [
|
|
3172
|
+
// {
|
|
3173
|
+
// label: "Proclination",
|
|
3174
|
+
// value: "proclination",
|
|
3175
|
+
// subSelection: {
|
|
3176
|
+
// label: "Mild",
|
|
3177
|
+
// value: "mild"
|
|
3178
|
+
// }
|
|
3179
|
+
// },
|
|
3180
|
+
// {
|
|
3181
|
+
// label: "Overbite",
|
|
3182
|
+
// value: "overbite",
|
|
3183
|
+
// subSelection: {
|
|
3184
|
+
// label: "Moderate",
|
|
3185
|
+
// value: "moderate"
|
|
3186
|
+
// }
|
|
3187
|
+
// }
|
|
3188
|
+
// ];
|
|
3189
|
+
// this.patchExistingValues(data);
|
|
3190
|
+
// },2000);
|
|
3191
|
+
setTimeout(() => {
|
|
3192
|
+
const key = this.fxComponent?.fxData?.name;
|
|
3193
|
+
if (key && this.customizedDropDownMap.has(key)) {
|
|
3194
|
+
const data = this.customizedDropDownMap.get(key)?.findings;
|
|
3195
|
+
this.patchExistingValues(data);
|
|
3196
|
+
}
|
|
3197
|
+
}, 1000);
|
|
3198
|
+
setTimeout(() => {
|
|
3199
|
+
const mainControl = this.form.get('findings');
|
|
3200
|
+
if (this.setting('isFindingsRequired') === 'true') {
|
|
3201
|
+
this.isRequired = true;
|
|
3202
|
+
mainControl?.setValidators([Validators.required]);
|
|
3203
|
+
mainControl?.updateValueAndValidity();
|
|
3204
|
+
}
|
|
3205
|
+
}, 500);
|
|
3206
|
+
}
|
|
3207
|
+
ngOnInit() {
|
|
3208
|
+
if (this.setting('optionType') === 'type1') {
|
|
3209
|
+
this.findingsOptions = this.type1Options;
|
|
3210
|
+
}
|
|
3211
|
+
else if (this.setting('optionType') === 'type2') {
|
|
3212
|
+
this.findingsOptions = this.type2Options;
|
|
3213
|
+
}
|
|
3214
|
+
this.fxBuilderWrapperService.variables$
|
|
3215
|
+
.pipe(takeUntil(this.destroy$))
|
|
3216
|
+
.subscribe((variables) => {
|
|
3217
|
+
if (!variables)
|
|
3218
|
+
return;
|
|
3219
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
3220
|
+
if (value &&
|
|
3221
|
+
typeof value === 'object' &&
|
|
3222
|
+
'findings' in value) {
|
|
3223
|
+
this.customizedDropDownMap.set(key, value);
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
});
|
|
3227
|
+
// const serviceUrl = this.fxApiService.getServiceUrl(this.setting('serviceName'));
|
|
3228
|
+
// this.getOptions(serviceUrl, this.setting('clinicalNotesURL'));
|
|
3229
|
+
}
|
|
3230
|
+
getOptions(serviceUrl, url) {
|
|
3231
|
+
const finalUrl = serviceUrl + url;
|
|
3232
|
+
this.http.get(finalUrl).subscribe({
|
|
3233
|
+
next: (response) => {
|
|
3234
|
+
// Future API logic here
|
|
3235
|
+
},
|
|
3236
|
+
error: (err) => console.error('Error fetching options', err)
|
|
3237
|
+
});
|
|
3238
|
+
}
|
|
3239
|
+
settings() {
|
|
3240
|
+
return [
|
|
3241
|
+
new FxSelectSetting({ key: 'displayMode', $title: 'Display Mode', value: 'ellipsis' }, [{ option: 'Ellipsis', value: 'ellipsis' }, { option: 'Compact', value: 'compact' }]),
|
|
3242
|
+
new FxSelectSetting({ key: 'optionType', $title: 'Option Type', value: 'type1' }, [{ option: 'Finding Type Options', value: 'type1' }, { option: 'Vetical Type Options', value: 'type2' }]),
|
|
3243
|
+
new FxStringSetting({ key: 'placeholderLabel', $title: 'Placeholder', value: 'Select Options' }),
|
|
3244
|
+
new FxStringSetting({ key: 'findingLabel', $title: 'Label', value: 'Label' }),
|
|
3245
|
+
new FxSelectSetting({ key: 'isFindingsRequired', $title: 'Required', value: 'true' }, [{ option: 'Yes', value: 'true' }, { option: 'No', value: 'false' }]),
|
|
3246
|
+
new FxStringSetting({ key: 'errorFindingMessage', $title: 'Error Message', value: 'Please fill out the field' }),
|
|
3247
|
+
];
|
|
3248
|
+
}
|
|
3249
|
+
validations() {
|
|
3250
|
+
return [FxValidatorService.required];
|
|
3251
|
+
}
|
|
3252
|
+
/** Dropdown Behavior **/
|
|
3253
|
+
toggleDropdown() {
|
|
3254
|
+
this.dropdownOpen = !this.dropdownOpen;
|
|
3255
|
+
}
|
|
3256
|
+
toggleOption(option, event) {
|
|
3257
|
+
event.stopPropagation();
|
|
3258
|
+
// Toggle checkbox value
|
|
3259
|
+
option.selected = !option.selected;
|
|
3260
|
+
// Reset radios when unchecked
|
|
3261
|
+
if (!option.selected) {
|
|
3262
|
+
option.subSelection = null;
|
|
3263
|
+
option.touched = false;
|
|
3264
|
+
}
|
|
3265
|
+
else {
|
|
3266
|
+
option.touched = true;
|
|
3267
|
+
}
|
|
3268
|
+
// ✅ Force UI refresh so radios appear instantly
|
|
3269
|
+
this.cdr.detectChanges();
|
|
3270
|
+
// Update reactive form
|
|
3271
|
+
this.updateFindings();
|
|
3272
|
+
}
|
|
3273
|
+
/** Form & Label Helpers **/
|
|
3274
|
+
get hasSelectedFindings() {
|
|
3275
|
+
return this.findingsOptions.some(f => f.selected);
|
|
3276
|
+
}
|
|
3277
|
+
get selectedFindingsLabel() {
|
|
3278
|
+
const selected = this.findingsOptions
|
|
3279
|
+
.filter(f => {
|
|
3280
|
+
if (f.selected) {
|
|
3281
|
+
// If finding has sub-options → only show if a sub-option is selected
|
|
3282
|
+
if (f.subOptions?.length) {
|
|
3283
|
+
return !!f.subSelection;
|
|
3284
|
+
}
|
|
3285
|
+
// If no sub-options → always show
|
|
3286
|
+
return true;
|
|
3287
|
+
}
|
|
3288
|
+
return false;
|
|
3289
|
+
})
|
|
3290
|
+
.map(f => f.label);
|
|
3291
|
+
if (selected.length === 0)
|
|
3292
|
+
return this.setting('placeholderLabel');
|
|
3293
|
+
// Display mode logic (Compact or Ellipsis)
|
|
3294
|
+
const maxCount = this.setting('displayMode') === 'compact' ? 2 : 3;
|
|
3295
|
+
if (this.setting('displayMode') === 'compact') {
|
|
3296
|
+
return selected.length <= maxCount
|
|
3297
|
+
? selected.join(', ')
|
|
3298
|
+
: `${selected.slice(0, maxCount).join(', ')} +${selected.length - maxCount} more`;
|
|
3299
|
+
}
|
|
3300
|
+
if (this.setting('displayMode') === 'ellipsis') {
|
|
3301
|
+
return selected.length > maxCount
|
|
3302
|
+
? `${selected.slice(0, maxCount).join(', ')}, ...`
|
|
3303
|
+
: selected.join(', ');
|
|
3304
|
+
}
|
|
3305
|
+
return selected.join(', ');
|
|
3306
|
+
}
|
|
3307
|
+
/** Update Findings + Validation **/
|
|
3308
|
+
// updateFindings() {
|
|
3309
|
+
// const selected = this.findingsOptions
|
|
3310
|
+
// .filter(f => {
|
|
3311
|
+
// if (f.selected) {
|
|
3312
|
+
// // Only include in final form if:
|
|
3313
|
+
// // - no subOptions, or
|
|
3314
|
+
// // - subOptions with valid subSelection
|
|
3315
|
+
// if (f.subOptions?.length) {
|
|
3316
|
+
// return !!f.subSelection;
|
|
3317
|
+
// }
|
|
3318
|
+
// return true;
|
|
3319
|
+
// }
|
|
3320
|
+
// return false;
|
|
3321
|
+
// })
|
|
3322
|
+
// .map(f => {
|
|
3323
|
+
// const sub = f.subOptions?.find(s => s.value === f.subSelection) || null;
|
|
3324
|
+
// return {
|
|
3325
|
+
// label: f.label,
|
|
3326
|
+
// value: f.value,
|
|
3327
|
+
// subSelection: sub ? { label: sub.label, value: sub.value } : null
|
|
3328
|
+
// };
|
|
3329
|
+
// });
|
|
3330
|
+
// // Update reactive form value
|
|
3331
|
+
// this.form.patchValue({ findings: selected }, { emitEvent: false });
|
|
3332
|
+
// // Validation logic remains same
|
|
3333
|
+
// const invalidItems = this.findingsOptions.filter(
|
|
3334
|
+
// f => f.selected && f.subOptions && !f.subSelection
|
|
3335
|
+
// );
|
|
3336
|
+
// this.form.get('findings')?.setErrors(
|
|
3337
|
+
// invalidItems.length > 0 ? { missingSubSelection: true } : null
|
|
3338
|
+
// );
|
|
3339
|
+
// }
|
|
3340
|
+
updateFindings() {
|
|
3341
|
+
// Filter selected options with valid subSelection (if subOptions exist)
|
|
3342
|
+
const selected = this.findingsOptions
|
|
3343
|
+
.filter(f => {
|
|
3344
|
+
if (f.selected) {
|
|
3345
|
+
// Only include in final form if:
|
|
3346
|
+
// - no subOptions, or
|
|
3347
|
+
// - subOptions with valid subSelection
|
|
3348
|
+
if (f.subOptions?.length) {
|
|
3349
|
+
return !!f.subSelection;
|
|
3350
|
+
}
|
|
3351
|
+
return true;
|
|
3352
|
+
}
|
|
3353
|
+
return false;
|
|
3354
|
+
})
|
|
3355
|
+
.map(f => {
|
|
3356
|
+
const sub = f.subOptions?.find(s => s.value === f.subSelection) || null;
|
|
3357
|
+
return {
|
|
3358
|
+
label: f.label,
|
|
3359
|
+
value: f.value,
|
|
3360
|
+
subSelection: sub ? { label: sub.label, value: sub.value } : null
|
|
3361
|
+
};
|
|
3362
|
+
});
|
|
3363
|
+
// Update reactive form value
|
|
3364
|
+
this.form.patchValue({ findings: selected }, { emitEvent: false });
|
|
3365
|
+
// Validation logic:
|
|
3366
|
+
// Check if there are any selected options with subOptions but without subSelection
|
|
3367
|
+
const invalidItems = this.findingsOptions.filter(f => f.selected && f.subOptions && !f.subSelection);
|
|
3368
|
+
// If there are any invalid items, mark the form as invalid with a custom error
|
|
3369
|
+
if (invalidItems.length > 0) {
|
|
3370
|
+
this.form.get('findings')?.setErrors({ missingSubSelection: true });
|
|
3371
|
+
}
|
|
3372
|
+
else {
|
|
3373
|
+
// Clear the error if everything is valid
|
|
3374
|
+
this.form.get('findings')?.setErrors(null);
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
onSubmit() {
|
|
3378
|
+
this.formSubmitted = true;
|
|
3379
|
+
if (this.form.invalid) {
|
|
3380
|
+
console.warn('⚠️ Please select a sub-option for all selected findings with sub-options.');
|
|
3381
|
+
return;
|
|
3382
|
+
}
|
|
3383
|
+
console.log('✅ Form Value:', this.form.value);
|
|
3384
|
+
}
|
|
3385
|
+
// patchExistingValues(data: any[]) {
|
|
3386
|
+
// this.findingsOptions.forEach(opt => {
|
|
3387
|
+
// const match = data.find(x => x.value === opt.value);
|
|
3388
|
+
// opt.selected = !!match;
|
|
3389
|
+
// opt.subSelection = match?.severity?.value || null;
|
|
3390
|
+
// });
|
|
3391
|
+
// this.updateFindings();
|
|
3392
|
+
// }
|
|
3393
|
+
patchExistingValues(data) {
|
|
3394
|
+
// Iterate through the findingsOptions and find the corresponding option for each entry in data
|
|
3395
|
+
this.findingsOptions.forEach(opt => {
|
|
3396
|
+
const match = data.find(x => x.value === opt.value);
|
|
3397
|
+
if (match) {
|
|
3398
|
+
opt.selected = true;
|
|
3399
|
+
opt.subSelection = match.subSelection ? match.subSelection.value : null;
|
|
3400
|
+
// console.log("Matched Option:", opt);
|
|
3401
|
+
// console.log("SubSelection Set To:", this.findingsOptions);
|
|
3402
|
+
}
|
|
3403
|
+
else {
|
|
3404
|
+
opt.selected = false;
|
|
3405
|
+
opt.subSelection = null;
|
|
3406
|
+
}
|
|
3407
|
+
});
|
|
3408
|
+
// Manually trigger change detection if needed
|
|
3409
|
+
this.cdr.detectChanges();
|
|
3410
|
+
this.updateFindings();
|
|
3411
|
+
}
|
|
3412
|
+
selectSubOption(option, subOption) {
|
|
3413
|
+
// Set the subSelection to the clicked value
|
|
3414
|
+
option.subSelection = subOption.value;
|
|
3415
|
+
// Mark the option as touched, which will help in form validation
|
|
3416
|
+
option.touched = true;
|
|
3417
|
+
// Update the form state
|
|
3418
|
+
this.updateFindings();
|
|
3419
|
+
}
|
|
3420
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomizeDropdownComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.HttpClient }, { token: FxBuilderWrapperService }, { token: i3$2.ApiServiceRegistry }, { token: i5.FormBuilder }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3421
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CustomizeDropdownComponent, isStandalone: true, selector: "lib-customize-dropdown", viewQueries: [{ propertyName: "fxComponent", first: true, predicate: ["fxComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"container\">\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\" class=\"relative\">\r\n <!-- Header -->\r\n <label for=\"findings\" class=\"input-label\">\r\n {{ setting('findingLabel') }}\r\n <span *ngIf=\"isRequired\" class=\"field-required\">*</span>\r\n </label>\r\n <div #dropdownWrapper class=\"relative w-80\">\r\n <button\r\n type=\"button\"\r\n class=\"w-full border border-gray-300 rounded-md px-3 py-2 flex justify-between items-center bg-white text-gray-700 hover:border-blue-400\"\r\n (click)=\"toggleDropdown()\"\r\n >\r\n <span *ngIf=\"hasSelectedFindings; else placeholder\">\r\n {{ selectedFindingsLabel }}\r\n </span>\r\n <ng-template #placeholder>\r\n {{ setting('placeholderLabel') }}\r\n </ng-template>\r\n <svg\r\n class=\"w-5 h-5 ml-2 text-gray-500 transform transition-transform duration-200\"\r\n [class.rotate-180]=\"dropdownOpen\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- Panel -->\r\n <div\r\n *ngIf=\"dropdownOpen\"\r\n class=\"absolute mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg max-h-64 overflow-y-auto z-10\"\r\n >\r\n <div\r\n *ngFor=\"let option of findingsOptions\"\r\n class=\"border-b border-gray-100 last:border-none p-2 hover:bg-gray-50 cursor-pointer\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <!-- Checkbox + Label -->\r\n <div class=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"w-4 h-4 text-blue-500 border-gray-300 rounded cursor-pointer\"\r\n [(ngModel)]=\"option.selected\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n (click)=\"toggleOption(option, $event)\"\r\n />\r\n <label\r\n class=\"text-gray-800 font-medium cursor-pointer select-none\"\r\n (click)=\"toggleOption(option, $event)\"\r\n >\r\n {{ option.label }}\r\n </label>\r\n\r\n <span\r\n *ngIf=\"option.info\"\r\n class=\"ml-auto text-blue-500 text-sm cursor-pointer\"\r\n title=\"{{ option.info }}\"\r\n >\r\n \u24D8\r\n </span>\r\n </div>\r\n\r\n <!-- Radios -->\r\n <div\r\n class=\"flex items-center flex-wrap gap-4 ml-6 mt-2 text-sm\"\r\n *ngIf=\"option.selected && option.subOptions\"\r\n >\r\n <ng-container *ngFor=\"let s of option.subOptions\">\r\n <label\r\n class=\"flex items-center space-x-1 cursor-pointer\"\r\n (click)=\"selectSubOption(option, s)\"\r\n >\r\n <input\r\n type=\"radio\"\r\n [name]=\"option.value\"\r\n [value]=\"s.value\"\r\n [(ngModel)]=\"option.subSelection\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n class=\"text-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ s.label }}</span>\r\n </label>\r\n</ng-container>\r\n\r\n <!-- Validation Message -->\r\n <div\r\n *ngIf=\"option.selected && option.subOptions && !option.subSelection\"\r\n class=\"text-red-500 text-xs mt-1 w-full ml-1\"\r\n >\r\n Please select one option\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div>\r\n <small *ngIf=\"form.get('findings')?.touched && form.get('findings')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorFindingMessage') }}\r\n </small>\r\n </div>\r\n \r\n </form>\r\n </div>\r\n</fx-component>\r\n", styles: [".container{width:300px}.dropdown{position:relative;-webkit-user-select:none;user-select:none}.dropdown-header{border:1px solid #ccc;border-radius:4px;padding:6px 8px;background-color:#fff;cursor:pointer;display:flex;justify-content:space-between;align-items:center}.dropdown-panel{position:absolute;width:100%;background:#fff;border:1px solid #ddd;margin-top:4px;border-radius:4px;max-height:250px;overflow-y:auto;z-index:1000;box-shadow:0 2px 8px #0000001a}.dropdown-item{padding:4px 8px;border-bottom:1px solid #f1f1f1}.dropdown-item:last-child{border-bottom:none}.item-header{display:flex;align-items:center;gap:6px}.label{cursor:pointer;flex-grow:1}.info{margin-left:auto;cursor:help;font-size:12px;color:#666}.sub-options{display:flex;align-items:center;flex-wrap:wrap;padding-left:22px;font-size:13px;margin-top:4px}.error{color:#e63946;font-size:11px;margin-left:22px;margin-top:2px}.arrow{font-size:10px;color:#555}.submit-btn{margin-top:1rem;padding:6px 12px;background:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer}.field-required{color:red;font-size:1.1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FxComponent, selector: "fx-component", inputs: ["fxData"] }] });
|
|
3422
|
+
}
|
|
3423
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomizeDropdownComponent, decorators: [{
|
|
3424
|
+
type: Component,
|
|
3425
|
+
args: [{ selector: 'lib-customize-dropdown', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule, FxComponent], template: "<fx-component [fxData]=\"fxData\" #fxComponent>\r\n <div class=\"container\">\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\" class=\"relative\">\r\n <!-- Header -->\r\n <label for=\"findings\" class=\"input-label\">\r\n {{ setting('findingLabel') }}\r\n <span *ngIf=\"isRequired\" class=\"field-required\">*</span>\r\n </label>\r\n <div #dropdownWrapper class=\"relative w-80\">\r\n <button\r\n type=\"button\"\r\n class=\"w-full border border-gray-300 rounded-md px-3 py-2 flex justify-between items-center bg-white text-gray-700 hover:border-blue-400\"\r\n (click)=\"toggleDropdown()\"\r\n >\r\n <span *ngIf=\"hasSelectedFindings; else placeholder\">\r\n {{ selectedFindingsLabel }}\r\n </span>\r\n <ng-template #placeholder>\r\n {{ setting('placeholderLabel') }}\r\n </ng-template>\r\n <svg\r\n class=\"w-5 h-5 ml-2 text-gray-500 transform transition-transform duration-200\"\r\n [class.rotate-180]=\"dropdownOpen\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\" />\r\n </svg>\r\n </button>\r\n\r\n <!-- Panel -->\r\n <div\r\n *ngIf=\"dropdownOpen\"\r\n class=\"absolute mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg max-h-64 overflow-y-auto z-10\"\r\n >\r\n <div\r\n *ngFor=\"let option of findingsOptions\"\r\n class=\"border-b border-gray-100 last:border-none p-2 hover:bg-gray-50 cursor-pointer\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <!-- Checkbox + Label -->\r\n <div class=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"w-4 h-4 text-blue-500 border-gray-300 rounded cursor-pointer\"\r\n [(ngModel)]=\"option.selected\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n (click)=\"toggleOption(option, $event)\"\r\n />\r\n <label\r\n class=\"text-gray-800 font-medium cursor-pointer select-none\"\r\n (click)=\"toggleOption(option, $event)\"\r\n >\r\n {{ option.label }}\r\n </label>\r\n\r\n <span\r\n *ngIf=\"option.info\"\r\n class=\"ml-auto text-blue-500 text-sm cursor-pointer\"\r\n title=\"{{ option.info }}\"\r\n >\r\n \u24D8\r\n </span>\r\n </div>\r\n\r\n <!-- Radios -->\r\n <div\r\n class=\"flex items-center flex-wrap gap-4 ml-6 mt-2 text-sm\"\r\n *ngIf=\"option.selected && option.subOptions\"\r\n >\r\n <ng-container *ngFor=\"let s of option.subOptions\">\r\n <label\r\n class=\"flex items-center space-x-1 cursor-pointer\"\r\n (click)=\"selectSubOption(option, s)\"\r\n >\r\n <input\r\n type=\"radio\"\r\n [name]=\"option.value\"\r\n [value]=\"s.value\"\r\n [(ngModel)]=\"option.subSelection\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n class=\"text-blue-600 cursor-pointer\"\r\n />\r\n <span>{{ s.label }}</span>\r\n </label>\r\n</ng-container>\r\n\r\n <!-- Validation Message -->\r\n <div\r\n *ngIf=\"option.selected && option.subOptions && !option.subSelection\"\r\n class=\"text-red-500 text-xs mt-1 w-full ml-1\"\r\n >\r\n Please select one option\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div>\r\n <small *ngIf=\"form.get('findings')?.touched && form.get('findings')?.errors?.['required']\"\r\n class=\"text-red-500\">\r\n {{ setting('errorFindingMessage') }}\r\n </small>\r\n </div>\r\n \r\n </form>\r\n </div>\r\n</fx-component>\r\n", styles: [".container{width:300px}.dropdown{position:relative;-webkit-user-select:none;user-select:none}.dropdown-header{border:1px solid #ccc;border-radius:4px;padding:6px 8px;background-color:#fff;cursor:pointer;display:flex;justify-content:space-between;align-items:center}.dropdown-panel{position:absolute;width:100%;background:#fff;border:1px solid #ddd;margin-top:4px;border-radius:4px;max-height:250px;overflow-y:auto;z-index:1000;box-shadow:0 2px 8px #0000001a}.dropdown-item{padding:4px 8px;border-bottom:1px solid #f1f1f1}.dropdown-item:last-child{border-bottom:none}.item-header{display:flex;align-items:center;gap:6px}.label{cursor:pointer;flex-grow:1}.info{margin-left:auto;cursor:help;font-size:12px;color:#666}.sub-options{display:flex;align-items:center;flex-wrap:wrap;padding-left:22px;font-size:13px;margin-top:4px}.error{color:#e63946;font-size:11px;margin-left:22px;margin-top:2px}.arrow{font-size:10px;color:#555}.submit-btn{margin-top:1rem;padding:6px 12px;background:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer}.field-required{color:red;font-size:1.1em}\n"] }]
|
|
3426
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.HttpClient }, { type: FxBuilderWrapperService }, { type: i3$2.ApiServiceRegistry }, { type: i5.FormBuilder }, { type: i0.ElementRef }], propDecorators: { fxComponent: [{
|
|
3427
|
+
type: ViewChild,
|
|
3428
|
+
args: ['fxComponent']
|
|
3429
|
+
}] } });
|
|
3430
|
+
|
|
3120
3431
|
// import { CustomizeDropdownComponent } from './components/multiselect-with-form-fields/customize-dropdown.component';
|
|
3121
3432
|
class FxBuilderWrapperComponent {
|
|
3122
3433
|
fxWrapperService;
|
|
@@ -3170,9 +3481,9 @@ class FxBuilderWrapperComponent {
|
|
|
3170
3481
|
if (!Boolean(this.fxWrapperService.getComponent('lib-dropdown-with-search'))) {
|
|
3171
3482
|
this.fxWrapperService.registerCustomComponent('Dropdown with Search', 'lib-dropdown-with-search', DropdownWithSearchComponent);
|
|
3172
3483
|
}
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3484
|
+
if (!Boolean(this.fxWrapperService.getComponent('lib-customize-dropdown'))) {
|
|
3485
|
+
this.fxWrapperService.registerCustomComponent('Multiselect with Form', 'lib-customize-dropdown', CustomizeDropdownComponent);
|
|
3486
|
+
}
|
|
3176
3487
|
// if (!Boolean(this.fxWrapperService.getComponent('lib-accordian'))) {
|
|
3177
3488
|
// this.fxWrapperService.registerCustomComponent('Accordian', 'lib-accordian', AccordianComponent);
|
|
3178
3489
|
// }
|
|
@@ -3217,7 +3528,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
3217
3528
|
args: [{ alias: 'fx-form', required: true }]
|
|
3218
3529
|
}] } });
|
|
3219
3530
|
|
|
3220
|
-
// import { CustomizeDropdownComponent } from '../customize-dropdown/customize-dropdown.component';
|
|
3221
3531
|
// import { CustomizeDropdownComponent } from '../multiselect-with-form-fields/customize-dropdown.component';
|
|
3222
3532
|
class FxFormWrapperComponent {
|
|
3223
3533
|
fxWrapperService;
|
|
@@ -3268,7 +3578,7 @@ class FxFormWrapperComponent {
|
|
|
3268
3578
|
{ name: 'Multiselect Dropdown', key: 'lib-multiselect-dropdown', component: MultiselectDropdownComponent },
|
|
3269
3579
|
{ name: 'Multiselect Dropdown with Childs', key: 'lib-multiselect-dropdown-with-childs', component: MultiselectDropdownWithChildsComponent },
|
|
3270
3580
|
{ name: 'Dropdown with Search', key: 'lib-dropdown-with-search', component: DropdownWithSearchComponent },
|
|
3271
|
-
|
|
3581
|
+
{ name: 'Multiselect with Form ', key: 'lib-customize-dropdown', component: CustomizeDropdownComponent },
|
|
3272
3582
|
{ name: 'Summary', key: 'lib-summary', component: SummaryComponent },
|
|
3273
3583
|
];
|
|
3274
3584
|
components.forEach(({ name, key, component }) => {
|