ngx-histaff-alpha 5.1.8 → 5.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/fesm2022/ngx-histaff-alpha-core-form-design.component-BVDW_HiI.mjs +1851 -0
  2. package/fesm2022/ngx-histaff-alpha-core-form-design.component-BVDW_HiI.mjs.map +1 -0
  3. package/fesm2022/ngx-histaff-alpha-email-props.component-Cf35Pexq.mjs +14 -0
  4. package/fesm2022/ngx-histaff-alpha-email-props.component-Cf35Pexq.mjs.map +1 -0
  5. package/fesm2022/ngx-histaff-alpha-ngx-histaff-alpha-BuRoId1C.mjs +36991 -0
  6. package/fesm2022/ngx-histaff-alpha-ngx-histaff-alpha-BuRoId1C.mjs.map +1 -0
  7. package/fesm2022/ngx-histaff-alpha-wf-basic-info.component-Df5VXIxJ.mjs +186 -0
  8. package/fesm2022/ngx-histaff-alpha-wf-basic-info.component-Df5VXIxJ.mjs.map +1 -0
  9. package/fesm2022/ngx-histaff-alpha-wf-form-assign.component-COeQxhkD.mjs +64 -0
  10. package/fesm2022/ngx-histaff-alpha-wf-form-assign.component-COeQxhkD.mjs.map +1 -0
  11. package/fesm2022/ngx-histaff-alpha-wf-process-design.component-BWYpAG57.mjs +905 -0
  12. package/fesm2022/ngx-histaff-alpha-wf-process-design.component-BWYpAG57.mjs.map +1 -0
  13. package/fesm2022/ngx-histaff-alpha.mjs +1 -35161
  14. package/fesm2022/ngx-histaff-alpha.mjs.map +1 -1
  15. package/lib/app/http-interceptors/logging-interceptor.d.ts +1 -1
  16. package/lib/app/libraries/animations/slide-animations.d.ts +1 -0
  17. package/lib/app/libraries/base-component/base/base.component.d.ts +2 -2
  18. package/lib/app/libraries/core-attachment/core-attachment/core-attachment.component.d.ts +2 -1
  19. package/lib/app/libraries/core-button-group-vns/core-button-group-vns/EnumCoreButtonVNSCode.d.ts +3 -0
  20. package/lib/app/libraries/core-control/core-control/core-control.component.d.ts +4 -2
  21. package/lib/app/libraries/core-currency-input/core-currency-input/core-currency-input.component.d.ts +2 -1
  22. package/lib/app/libraries/core-date-picker/core-date-picker/core-date-picker.component.d.ts +2 -1
  23. package/lib/app/libraries/core-dropdown/core-dropdown/core-dropdown.component.d.ts +0 -1
  24. package/lib/app/libraries/core-employee-seeker/core-employee-seeker/core-employee-seeker.component.d.ts +1 -2
  25. package/lib/app/libraries/core-form/core-form/core-form.component.d.ts +3 -2
  26. package/lib/app/libraries/core-form/core-form/enum-interfaces.d.ts +25 -14
  27. package/lib/app/libraries/core-form-control-seeker/EnumCoreFormControlSeekerSourceType.d.ts +2 -1
  28. package/lib/app/libraries/core-form-control-seeker/EnumCoreSeekerColumn.d.ts +5 -0
  29. package/lib/app/libraries/core-form-control-seeker/core-form-control-seeker/core-form-control-seeker.component.d.ts +8 -4
  30. package/lib/app/libraries/core-form-design/constants/ControlTypeToValidatorMap.d.ts +3 -0
  31. package/lib/app/libraries/core-form-design/constants/ValidatorErrorMessageMap.d.ts +2 -0
  32. package/lib/app/libraries/core-form-design/constants/defaultValidatorsByControl.d.ts +13 -0
  33. package/lib/app/libraries/core-form-design/core-form-design-list.component.d.ts +21 -0
  34. package/lib/app/libraries/core-form-design/core-form-design.component.d.ts +77 -0
  35. package/lib/app/libraries/core-form-design/core-form-design.routes.d.ts +2 -0
  36. package/lib/app/libraries/core-form-design/core-form-design.service.d.ts +83 -0
  37. package/lib/app/libraries/core-form-design/enums/EnumFormDesignMode.d.ts +4 -0
  38. package/lib/app/libraries/core-form-design/enums/EnumLeftPanelMode.d.ts +4 -0
  39. package/lib/app/libraries/core-form-design/enums/EnumSupportedRuntimeValidator.d.ts +11 -0
  40. package/lib/app/libraries/core-form-design/field-setting/base-props/base-props.component.d.ts +18 -0
  41. package/lib/app/libraries/core-form-design/field-setting/field-setting.component.d.ts +23 -0
  42. package/lib/app/libraries/core-form-design/field-setting/mandatory-props/mandatory-props.component.d.ts +8 -0
  43. package/lib/app/libraries/core-form-design/field-setting/optional-props/optional-props.component.d.ts +11 -0
  44. package/lib/app/libraries/core-form-design/field-setting/type-specific/attachment-props/attachment-field-helper.service.d.ts +22 -0
  45. package/lib/app/libraries/core-form-design/field-setting/type-specific/attachment-props/attachment-props.component.d.ts +8 -0
  46. package/lib/app/libraries/core-form-design/field-setting/type-specific/checklist-props/checklist-props.component.d.ts +10 -0
  47. package/lib/app/libraries/core-form-design/field-setting/type-specific/datepicker-props/datepicker-props.component.d.ts +10 -0
  48. package/lib/app/libraries/core-form-design/field-setting/type-specific/dropdown-props/dropdown-props.component.d.ts +10 -0
  49. package/lib/app/libraries/core-form-design/field-setting/type-specific/email-props/email-props.component.d.ts +5 -0
  50. package/lib/app/libraries/core-form-design/field-setting/type-specific/grid-buffer-props/grid-buffer-props.component.d.ts +10 -0
  51. package/lib/app/libraries/core-form-design/field-setting/type-specific/list-props/list-props.component.d.ts +10 -0
  52. package/lib/app/libraries/core-form-design/field-setting/type-specific/mcc-props/mcc-props.component.d.ts +10 -0
  53. package/lib/app/libraries/core-form-design/field-setting/type-specific/number-props/number-props.component.d.ts +10 -0
  54. package/lib/app/libraries/core-form-design/field-setting/type-specific/radio-group-props/radio-group-props.component.d.ts +10 -0
  55. package/lib/app/libraries/core-form-design/field-setting/type-specific/seeker-props/seeker-props.component.d.ts +10 -0
  56. package/lib/app/libraries/core-form-design/field-setting/type-specific/textarea-props/textarea-props.component.d.ts +10 -0
  57. package/lib/app/libraries/core-form-design/field-setting/type-specific/uploader-props/uploader-props.component.d.ts +10 -0
  58. package/lib/app/libraries/core-form-design/field-setting/validator-editor/validator-editor.component.d.ts +18 -0
  59. package/lib/app/libraries/core-form-design/form-metadata/form-metadata.component.d.ts +40 -0
  60. package/lib/app/libraries/core-form-design/interfaces.d.ts +66 -0
  61. package/lib/app/libraries/core-form-design/props-host/props-host.component.d.ts +13 -0
  62. package/lib/app/libraries/core-form-design/save-live-json/save-live-json.component.d.ts +13 -0
  63. package/lib/app/libraries/core-form-seeker/core-form-seeker.component.d.ts +37 -0
  64. package/lib/app/libraries/core-list/core-list/core-list.component.d.ts +2 -2
  65. package/lib/app/libraries/core-mcc/core-mcc/core-mcc.component.d.ts +3 -2
  66. package/lib/app/libraries/core-month-selector/core-month-selector/core-month-selector.component.d.ts +2 -1
  67. package/lib/app/libraries/core-rule-tree/core-rule-tree.component.d.ts +25 -0
  68. package/lib/app/libraries/core-table/EnumCoreTablePipeType.d.ts +2 -1
  69. package/lib/app/libraries/core-workflow-builder/core-workflow-builder.component.d.ts +7 -0
  70. package/lib/app/libraries/core-workflow-builder/core-workflow-group-edit/core-workflow-group-edit.component.d.ts +30 -0
  71. package/lib/app/libraries/core-workflow-builder/core-workflow-list/core-workflow-list.component.d.ts +27 -0
  72. package/lib/app/libraries/core-workflow-builder/core-workflow.service.d.ts +41 -0
  73. package/lib/app/libraries/core-workflow-builder/enums/EnumLogicalOperator.d.ts +5 -0
  74. package/lib/app/libraries/core-workflow-builder/enums/EnumWorkflowBranch.d.ts +1 -0
  75. package/lib/app/libraries/core-workflow-builder/enums/EnumWorkflowFilterMode.d.ts +5 -0
  76. package/lib/app/libraries/core-workflow-builder/enums/EnumWorkflowStepType.d.ts +10 -0
  77. package/lib/app/libraries/core-workflow-builder/interfaces/IAfField.d.ts +5 -0
  78. package/lib/app/libraries/core-workflow-builder/interfaces/IInsertStepEvent.d.ts +5 -0
  79. package/lib/app/libraries/core-workflow-builder/interfaces/IRuleNodeDto.d.ts +11 -0
  80. package/lib/app/libraries/core-workflow-builder/interfaces/IStep.d.ts +14 -0
  81. package/lib/app/libraries/core-workflow-builder/interfaces/IStepConfig.d.ts +5 -0
  82. package/lib/app/libraries/core-workflow-builder/interfaces/IWfWorkflow.d.ts +10 -0
  83. package/lib/app/libraries/core-workflow-builder/interfaces/IWfWorkflowGroup.d.ts +8 -0
  84. package/lib/app/libraries/core-workflow-builder/interfaces/IWorkflowBranch.d.ts +10 -0
  85. package/lib/app/libraries/core-workflow-builder/interfaces/IWorkflowInsertPoint.d.ts +4 -0
  86. package/lib/app/libraries/core-workflow-builder/wf-basic-info/wf-basic-info.component.d.ts +34 -0
  87. package/lib/app/libraries/core-workflow-builder/wf-form-assign/wf-form-assign.component.d.ts +15 -0
  88. package/lib/app/libraries/core-workflow-builder/wf-process-design/bridge-line.directive.d.ts +17 -0
  89. package/lib/app/libraries/core-workflow-builder/wf-process-design/bridge-line.service.d.ts +9 -0
  90. package/lib/app/libraries/core-workflow-builder/wf-process-design/wf-bottom-v-insert/wf-bottom-v-insert.component.d.ts +24 -0
  91. package/lib/app/libraries/core-workflow-builder/wf-process-design/wf-insert-menu/wf-insert-menu.component.d.ts +29 -0
  92. package/lib/app/libraries/core-workflow-builder/wf-process-design/wf-node/wf-node.component.d.ts +45 -0
  93. package/lib/app/libraries/core-workflow-builder/wf-process-design/wf-process-design.component.d.ts +10 -0
  94. package/lib/app/libraries/core-workflow-builder/wf-process-design/wf-step-config-shell/wf-step-config-shell.component.d.ts +26 -0
  95. package/lib/app/libraries/core-workflow-builder/wf-process-design/wf-workflow-canvas.component.d.ts +33 -0
  96. package/lib/app/libraries/core-workflow-builder/workflow.route.d.ts +2 -0
  97. package/package.json +1 -1
  98. package/public-api.d.ts +7 -0
@@ -0,0 +1,1851 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, ChangeDetectorRef, computed, Component, signal, effect, HostListener, ChangeDetectionStrategy, Injectable, ViewContainerRef, Input, EventEmitter, Output, Renderer2, ViewChild } from '@angular/core';
3
+ import { trigger, state, transition, style, animate } from '@angular/animations';
4
+ import { C as CoreFormDesignService, B as BaseEditComponent, A as AlertService, E as EnumCorePageEditMode, a as EnumFormBaseContolType, b as EnumCoreButtonVNSCode, n as noneAutoClosedAlertOptions, D as DialogService, c as CorePageHeaderComponent, d as CoreFormComponent, e as CoreButtonGroupVnsComponent, T as TranslatePipe, f as BaseComponent, g as EnumCoreTablePipeType, h as CoreCheckboxComponent, i as CoreDropdownComponent, M as MultiLanguageService, j as TooltipDirective, k as EnumFormDesignMode, l as EnumCoreFormControlSeekerSourceType, F as FullscreenModalLoaderComponent, m as TableCellPipe, o as CoreControlComponent, p as CoreChecklistComponent, q as CoreFormControlSeekerComponent, r as CoreAttachmentComponent, s as CoreDatePickerComponent, t as CoreRadioGroupComponent, u as CoreMonthSelectorComponent, v as CoreCurrencyInputComponent } from './ngx-histaff-alpha-ngx-histaff-alpha-BuRoId1C.mjs';
5
+ import * as i1 from '@angular/forms';
6
+ import { Validators, FormsModule, FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
7
+ import { NgStyle, NgTemplateOutlet } from '@angular/common';
8
+ import { BehaviorSubject, catchError, of } from 'rxjs';
9
+ import { EnumTranslateKey } from 'alpha-global-constants';
10
+ import { ActivatedRoute } from '@angular/router';
11
+
12
+ const slideFromTopFadeIn = trigger('slideFromTopFadeIn', [
13
+ state('in', style({ opacity: 1, transform: 'translateY(0)' })),
14
+ state('out', style({ opacity: 0, transform: 'translateY(-50vh)' })),
15
+ transition('out => in', [
16
+ animate('200ms ease-out')
17
+ ]),
18
+ transition('in => out', [
19
+ animate('150ms ease-in')
20
+ ])
21
+ ]);
22
+
23
+ class SaveLiveJsonComponent {
24
+ constructor() {
25
+ this.coreFormDesignService = inject(CoreFormDesignService);
26
+ this.cdr = inject(ChangeDetectorRef);
27
+ this.json$ = computed(() => {
28
+ const removeSignalKeysDeep = (obj) => {
29
+ if (Array.isArray(obj)) {
30
+ return obj.map(removeSignalKeysDeep);
31
+ }
32
+ if (obj && typeof obj === 'object') {
33
+ return Object.entries(obj)
34
+ .filter(([key]) => !key.endsWith('$'))
35
+ .reduce((acc, [key, value]) => {
36
+ acc[key] = removeSignalKeysDeep(value);
37
+ return acc;
38
+ }, {});
39
+ }
40
+ return obj;
41
+ };
42
+ const instance = this.coreFormDesignService.$afInstance();
43
+ const cleanedInstance = removeSignalKeysDeep(instance); // Remove signals or $ fields
44
+ return JSON.stringify(cleanedInstance, null, 2);
45
+ });
46
+ }
47
+ copyToClipboard() {
48
+ navigator.clipboard.writeText(this.json$());
49
+ }
50
+ download() {
51
+ const blob = new Blob([this.json$()], { type: 'application/json' });
52
+ const url = URL.createObjectURL(blob);
53
+ const link = document.createElement('a');
54
+ link.href = url;
55
+ link.download = `${this.coreFormDesignService.$afInstance().name || 'form'}.json`;
56
+ link.click();
57
+ }
58
+ ngAfterViewInit() {
59
+ setTimeout(() => this.cdr.markForCheck());
60
+ }
61
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: SaveLiveJsonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
62
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: SaveLiveJsonComponent, isStandalone: true, selector: "save-live-json", ngImport: i0, template: "<pre class=\"json-preview\">{{ json$() }}</pre>", styles: [".json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;border-radius:10px;box-shadow:0 2px 6px #00000014;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;overflow-x:auto;line-height:1.5;width:390px;height:calc(100vh - 230px);margin:0}\n"] }); }
63
+ }
64
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: SaveLiveJsonComponent, decorators: [{
65
+ type: Component,
66
+ args: [{ selector: 'save-live-json', imports: [], template: "<pre class=\"json-preview\">{{ json$() }}</pre>", styles: [".json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;border-radius:10px;box-shadow:0 2px 6px #00000014;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;overflow-x:auto;line-height:1.5;width:390px;height:calc(100vh - 230px);margin:0}\n"] }]
67
+ }] });
68
+
69
+ const URL_PATTERN = '^(https?:\\/\\/[^\\s]+|\\/api(\\/[-\\w._]+)+)$';
70
+ class FormMetadataComponent extends BaseEditComponent {
71
+ onEscape() {
72
+ this.coreFormDesignService.$showFormMetadata.set(false);
73
+ }
74
+ onWindowClick(_) {
75
+ /*
76
+ Trigger What Happens
77
+ 🖱️ First Click: Opens checklist overlay, but Angular hasn’t re-checked the DOM yet → markForCheck() is called, but view not updated yet
78
+ 🖱️ Second Click: Now DOM is updated, click is registered inside the actual rendered checklist, interaction works
79
+ */
80
+ //This lets Angular finish updating the DOM before running change detection.
81
+ setTimeout(() => this.cdr.markForCheck());
82
+ }
83
+ constructor(dialogService) {
84
+ super(dialogService);
85
+ this.dialogService = dialogService;
86
+ this.coreFormDesignService = inject(CoreFormDesignService);
87
+ this.cdr = inject(ChangeDetectorRef);
88
+ this.alertService = inject(AlertService);
89
+ this.$loading = signal(false);
90
+ this.checkError$ = new BehaviorSubject(false);
91
+ this.mode$ = new BehaviorSubject(EnumCorePageEditMode.UPDATE);
92
+ this.customButtonChecklistOptions$ = new BehaviorSubject([]);
93
+ this.$sections = signal([
94
+ {
95
+ caption: 'Primary properties',
96
+ rows: [
97
+ [
98
+ {
99
+ field: 'id',
100
+ flexSize: 0,
101
+ hidden: true,
102
+ value: null,
103
+ controlType: EnumFormBaseContolType.TEXTBOX,
104
+ label: 'ID'
105
+ },
106
+ {
107
+ field: 'name',
108
+ flexSize: 4,
109
+ value: '',
110
+ controlType: EnumFormBaseContolType.TEXTBOX,
111
+ label: 'Form Name',
112
+ type: 'string',
113
+ validators: [
114
+ {
115
+ name: 'required',
116
+ validator: Validators.required,
117
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
118
+ },
119
+ {
120
+ name: 'minLength',
121
+ validator: Validators.minLength(5),
122
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_MIN_LENGTH
123
+ }
124
+ ]
125
+ },
126
+ {
127
+ field: 'captionCode',
128
+ flexSize: 4,
129
+ value: '',
130
+ hint: 'Helps to display form caption in multi languages',
131
+ controlType: EnumFormBaseContolType.TEXTBOX,
132
+ label: 'Caption Code',
133
+ type: 'string',
134
+ validators: [
135
+ {
136
+ name: 'required',
137
+ validator: Validators.required,
138
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
139
+ },
140
+ {
141
+ name: 'minLength',
142
+ validator: Validators.minLength(10),
143
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_MIN_LENGTH
144
+ }
145
+ ]
146
+ },
147
+ {
148
+ field: 'entityTable',
149
+ flexSize: 4,
150
+ controlType: EnumFormBaseContolType.TEXTBOX,
151
+ value: '',
152
+ hint: "The primary table name related to the form",
153
+ label: 'Entity Table Name',
154
+ type: 'string'
155
+ },
156
+ ],
157
+ [
158
+ {
159
+ field: 'submitApi',
160
+ flexSize: 4,
161
+ value: '',
162
+ controlType: EnumFormBaseContolType.TEXTBOX,
163
+ label: 'Submit API URL',
164
+ hint: 'This is an API endpoint with [HttpPost] verb',
165
+ type: 'string',
166
+ validators: [
167
+ {
168
+ name: 'required',
169
+ validator: Validators.required,
170
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
171
+ },
172
+ {
173
+ name: 'minLength',
174
+ validator: Validators.minLength(10),
175
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_MIN_LENGTH
176
+ },
177
+ {
178
+ name: 'pattern',
179
+ validator: Validators.pattern(URL_PATTERN),
180
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
181
+ }
182
+ ]
183
+ },
184
+ {
185
+ field: 'postSubmitRoute',
186
+ flexSize: 4,
187
+ value: '',
188
+ hint: 'After success submition, the App will redirect to this route (full URL)',
189
+ controlType: EnumFormBaseContolType.TEXTBOX,
190
+ label: 'Post Submit Route',
191
+ type: 'string',
192
+ validators: [
193
+ {
194
+ name: 'pattern',
195
+ validator: Validators.pattern(URL_PATTERN),
196
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
197
+ }
198
+ ]
199
+ },
200
+ {
201
+ field: 'postCancelRoute',
202
+ flexSize: 4,
203
+ value: '',
204
+ hint: 'After cancelation, the App will redirect to this route (full URL)',
205
+ controlType: EnumFormBaseContolType.TEXTBOX,
206
+ label: 'Post Cancel Route',
207
+ type: 'string',
208
+ validators: [
209
+ {
210
+ name: 'pattern',
211
+ validator: Validators.pattern(URL_PATTERN),
212
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
213
+ }
214
+ ]
215
+ }
216
+ ],
217
+ [
218
+ {
219
+ field: 'normalMode',
220
+ flexSize: 4,
221
+ value: false,
222
+ controlType: EnumFormBaseContolType.CHECKBOX,
223
+ hint: 'If normal mode is set to false, the form will be displayed as a modal popup',
224
+ label: 'Normal Display Mode',
225
+ type: 'boolean'
226
+ },
227
+ {
228
+ field: 'autoGetByIdOff',
229
+ flexSize: 4,
230
+ value: false,
231
+ hint: "If checked, the form won't call the GetById API ayt its startup",
232
+ controlType: EnumFormBaseContolType.CHECKBOX,
233
+ label: 'Disable Auto Get By ID',
234
+ type: 'checkbox'
235
+ },
236
+ {
237
+ field: 'hasIdOfStringType',
238
+ flexSize: 4,
239
+ value: false,
240
+ controlType: EnumFormBaseContolType.CHECKBOX,
241
+ label: 'ID is String?',
242
+ type: 'checkbox'
243
+ }
244
+ ],
245
+ ]
246
+ },
247
+ {
248
+ caption: 'CRUD',
249
+ rows: [
250
+ [
251
+ {
252
+ field: 'crudCreate',
253
+ value: '',
254
+ label: 'Create Endpoint',
255
+ controlType: EnumFormBaseContolType.TEXTBOX,
256
+ flexSize: 4,
257
+ type: 'string',
258
+ hint: 'POST endpoint for creating new records',
259
+ validators: [
260
+ {
261
+ name: 'pattern',
262
+ validator: Validators.pattern(URL_PATTERN),
263
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
264
+ }
265
+ ]
266
+ },
267
+ {
268
+ field: 'crudRead',
269
+ label: 'Read (GetById) Endpoint',
270
+ value: '',
271
+ controlType: EnumFormBaseContolType.TEXTBOX,
272
+ flexSize: 4,
273
+ type: 'string',
274
+ hint: 'GET endpoint to retrieve by ID',
275
+ validators: [
276
+ {
277
+ name: 'required',
278
+ validator: Validators.required,
279
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
280
+ },
281
+ {
282
+ name: 'minLength',
283
+ validator: Validators.minLength(5),
284
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_MIN_LENGTH
285
+ },
286
+ {
287
+ name: 'pattern',
288
+ validator: Validators.pattern(URL_PATTERN),
289
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
290
+ }
291
+ ]
292
+ },
293
+ {
294
+ field: 'crudUpdate',
295
+ label: 'Update Endpoint',
296
+ value: '',
297
+ controlType: EnumFormBaseContolType.TEXTBOX,
298
+ flexSize: 4,
299
+ type: 'string',
300
+ hint: 'POST endpoint for updates',
301
+ validators: [
302
+ {
303
+ name: 'required',
304
+ validator: Validators.required,
305
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_REQUIRED
306
+ },
307
+ {
308
+ name: 'minLength',
309
+ validator: Validators.minLength(5),
310
+ errorMessage: EnumTranslateKey.UI_FORM_CONTROL_ERROR_MIN_LENGTH
311
+ },
312
+ {
313
+ name: 'pattern',
314
+ validator: Validators.pattern(URL_PATTERN),
315
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
316
+ }
317
+ ]
318
+ },
319
+ ],
320
+ [
321
+ {
322
+ field: 'crudReadChildren',
323
+ value: '',
324
+ label: 'Read Children Endpoint',
325
+ controlType: EnumFormBaseContolType.TEXTBOX,
326
+ flexSize: 4,
327
+ type: 'string',
328
+ hint: 'Optional endpoint to fetch related child records',
329
+ validators: [
330
+ {
331
+ name: 'pattern',
332
+ validator: Validators.pattern(URL_PATTERN),
333
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
334
+ }
335
+ ]
336
+ },
337
+ {
338
+ field: 'crudDelete',
339
+ value: '',
340
+ label: 'Delete Endpoint',
341
+ controlType: EnumFormBaseContolType.TEXTBOX,
342
+ flexSize: 4,
343
+ type: 'string',
344
+ hint: 'Optional DELETE endpoint',
345
+ validators: [
346
+ {
347
+ name: 'pattern',
348
+ validator: Validators.pattern(URL_PATTERN),
349
+ errorMessage: 'UI_FORM_CONTROL_ERROR_PATTERN'
350
+ }
351
+ ]
352
+ },
353
+ ]
354
+ ]
355
+ },
356
+ {
357
+ caption: 'Buttons & Actions',
358
+ rows: [
359
+ [
360
+ {
361
+ field: 'customFormButtonItems',
362
+ flexSize: 8,
363
+ controlType: EnumFormBaseContolType.CHECKLIST,
364
+ hint: "If you want to replace the default [Cancel, Submit] buttons",
365
+ checklistOptions$: this.customButtonChecklistOptions$,
366
+ getByIdObject$: new BehaviorSubject({}),
367
+ shownFrom: '_',
368
+ value: null,
369
+ label: 'Custom Buttons',
370
+ type: 'string[]'
371
+ },
372
+ {
373
+ field: 'width',
374
+ flexSize: 4,
375
+ controlType: EnumFormBaseContolType.TEXTBOX,
376
+ hint: "Width of the form",
377
+ value: null,
378
+ label: 'Width',
379
+ type: 'number'
380
+ },
381
+ /*
382
+ // Simply ignored for now
383
+ {
384
+ field: 'entityUniqueIndexesJson',
385
+ flexSize: 4,
386
+ controlType: EnumFormBaseContolType.TEXTAREA,
387
+ textareaRows: 1,
388
+ hint: "It helps to detect duplicated values if needed",
389
+ value: '',
390
+ label: 'Entity Unique Indexes (JSON)',
391
+ type: 'string'
392
+ }
393
+ */
394
+ ]
395
+ ]
396
+ }
397
+ ]);
398
+ this.customButtons = [
399
+ EnumCoreButtonVNSCode.NONE_HEADER_SAVE,
400
+ ];
401
+ effect(() => {
402
+ if (this.coreFormDesignService.$shouldPatchMetadataForm()) {
403
+ this.patchFormFromInstance();
404
+ this.coreFormDesignService.$shouldPatchMetadataForm.set(false); // ✅ reset
405
+ }
406
+ });
407
+ }
408
+ patchFormFromInstance() {
409
+ const instance = this.coreFormDesignService.$afInstance();
410
+ this.form.patchValue({
411
+ name: instance.name,
412
+ captionCode: instance.captionCode,
413
+ entityTable: instance.entityTable ?? '',
414
+ submitApi: instance.submitApi,
415
+ postSubmitRoute: instance.postSubmitRoute ?? '',
416
+ postCancelRoute: instance.postCancelRoute ?? '',
417
+ normalMode: instance.normalMode ?? false,
418
+ autoGetByIdOff: instance.autoGetByIdOff ?? false,
419
+ hasIdOfStringType: instance.hasIdOfStringType ?? false,
420
+ customFormButtonItems: instance.customFormButtonItems ?? [],
421
+ crudCreate: instance.crud?.c ?? '',
422
+ crudRead: instance.crud?.r ?? '',
423
+ crudUpdate: instance.crud?.u ?? '',
424
+ crudDelete: instance.crud?.d ?? '',
425
+ crudReadChildren: instance.crud?.rChildren ?? '',
426
+ entityUniqueIndexesJson: JSON.stringify(instance.entityUniqueIndexes ?? [])
427
+ });
428
+ }
429
+ onButtonClick(e) {
430
+ if (e.code === EnumCoreButtonVNSCode.NONE_HEADER_SAVE) {
431
+ if (this.form.valid) {
432
+ this.$loading.set(true);
433
+ const apiObject = this.coreFormDesignService.editMode$.value === EnumCorePageEditMode.CREATE ?
434
+ this.coreFormDesignService.createFormInstance(this.coreFormDesignService.$afInstance()) :
435
+ this.coreFormDesignService.updateFormInstance(this.coreFormDesignService.$afInstance());
436
+ const apiObservable = apiObject.pipe(catchError(err => {
437
+ this.$loading.set(false);
438
+ const msg = err?.error?.message || // API-defined message
439
+ err?.message || // Native JS or HttpErrorResponse
440
+ err?.statusText || // Fallback
441
+ 'An unknown error occurred.';
442
+ this.alertService.error(msg, noneAutoClosedAlertOptions);
443
+ return of(msg);
444
+ }));
445
+ apiObservable.subscribe(x => {
446
+ this.$loading.set(false);
447
+ if (x.ok && x.status === 200 && x.body?.statusCode === 200) {
448
+ //this.alertService.success('Success!', alertOptions)
449
+ }
450
+ });
451
+ }
452
+ else {
453
+ this.checkError$.next(!this.checkError$.value);
454
+ setTimeout(() => this.cdr.markForCheck());
455
+ }
456
+ }
457
+ }
458
+ onClose() {
459
+ this.coreFormDesignService.$showFormMetadata.set(false);
460
+ }
461
+ onSave(e) {
462
+ }
463
+ onFormCreated(event) {
464
+ const form = event.formGroup;
465
+ /*form.valueChanges.subscribe(value => {
466
+ const current = this.coreFormDesignService.$afInstance();
467
+
468
+ const safeKeys = Object.keys(value).filter(key => !key.endsWith('$'));
469
+ const safeUpdate = Object.fromEntries(
470
+ safeKeys.map(key => [key, value[key]])
471
+ );
472
+
473
+ this.coreFormDesignService.$afInstance.set({
474
+ ...current,
475
+ ...safeUpdate
476
+ });
477
+ });*/
478
+ form.valueChanges.subscribe(value => {
479
+ const current = this.coreFormDesignService.$afInstance();
480
+ const { crudCreate, crudRead, crudUpdate, crudDelete, crudReadChildren,
481
+ // ES6 destructuring: Pull id out of the object and throw it away under the name _ignored — don’t include it in rest
482
+ id: _ignored, ...rest } = value;
483
+ const updatedCrud = {
484
+ ...current.crud,
485
+ ...(crudCreate !== undefined ? { c: crudCreate } : {}),
486
+ ...(crudRead !== undefined ? { r: crudRead } : {}),
487
+ ...(crudUpdate !== undefined ? { u: crudUpdate } : {}),
488
+ ...(crudDelete !== undefined ? { d: crudDelete } : {}),
489
+ ...(crudReadChildren !== undefined ? { rChildren: crudReadChildren } : {})
490
+ };
491
+ const next = {
492
+ ...current,
493
+ ...rest,
494
+ crud: updatedCrud
495
+ };
496
+ this.coreFormDesignService.$afInstance.set(next);
497
+ });
498
+ form.statusChanges.subscribe(status => {
499
+ // Optional: Save status if you want to show error summary, disable save button, etc.
500
+ this.formStatus = status; // string: 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED'
501
+ });
502
+ this.form = form;
503
+ }
504
+ ngAfterViewInit() {
505
+ // Defer to next tick to avoid ExpressionChangedAfterItHasBeenCheckedError
506
+ setTimeout(() => {
507
+ const allButtons = Object.values(EnumCoreButtonVNSCode);
508
+ const noneHeaderOptions = allButtons
509
+ .filter(value => value.startsWith('NONE_HEADER_') && value !== 'NONE_HEADER_IMPORT_OPTION')
510
+ .map(value => ({
511
+ value,
512
+ text: value,
513
+ checked: false
514
+ }));
515
+ this.customButtonChecklistOptions$.next(noneHeaderOptions);
516
+ const sections = this.coreFormDesignService.$placeholderSections();
517
+ // 🔥 DO NOT READ this.$afInstance()
518
+ this.coreFormDesignService.$afInstance.update(instance => ({
519
+ ...instance,
520
+ formDesignSections: sections
521
+ }));
522
+ // Inform Angular to re-check since values arrived late
523
+ this.cdr.markForCheck();
524
+ });
525
+ }
526
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FormMetadataComponent, deps: [{ token: DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
527
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: FormMetadataComponent, isStandalone: true, selector: "form-metadata", host: { listeners: { "document:keydown.escape": "onEscape($event)", "window:click": "onWindowClick($event)" } }, usesInheritance: true, ngImport: i0, template: "<div class=\"form-metadata-container\">\r\n <div class=\"header-wrapper\">\r\n <core-page-header [title]=\"'FORM OVERVIEW'\" [hideButtonGroup]=\"true\"></core-page-header>\r\n <div class=\"close-wrapper\" (click)=\"onClose()\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"af-instance\">\r\n\r\n <div class=\"af-instance-left\">\r\n <core-form \r\n [inputSections]=\"$sections()\" \r\n [width]=\"800\" [mode$]=\"mode$\" \r\n [checkError$]=\"checkError$\" \r\n [hideButtons]=\"true\"\r\n (onFormCreated)=\"onFormCreated($event)\"></core-form>\r\n </div>\r\n <div class=\"af-instance-right\">\r\n <save-live-json></save-live-json>\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n\r\n <div class=\"h15\"></div>\r\n <div class=\"d-flex d-flex-end w-100 pr1rem\">\r\n <core-button-group-vns [showCaption]=\"true\" [forHeader]=\"false\"\r\n (buttonClick)=\"onButtonClick($event)\" [shownItems]=\"customButtons\"\r\n class=\"buttonGroupCustom\"></core-button-group-vns>\r\n </div>\r\n\r\n\r\n\r\n</div>", styles: [".form-metadata-container .header-wrapper{padding:0 15px}.form-metadata-container .header-wrapper .close-wrapper{display:flex;position:absolute;right:7px;top:8px;width:24px;height:24px;color:#848484;cursor:pointer}.form-metadata-container .header-wrapper .close-wrapper i{font-size:24px}.form-metadata-container .af-instance{display:flex}.form-metadata-container .h15{height:15px!important}.form-metadata-container .pr1rem{padding-right:1rem}\n"], dependencies: [{ kind: "component", type: CorePageHeaderComponent, selector: "core-page-header", inputs: ["instanceNumber", "shownItems", "title", "hideButtonGroup"], outputs: ["buttonClick"] }, { kind: "component", type: CoreFormComponent, selector: "core-form", inputs: ["formName", "width", "submitText", "leftInputSections", "leftInputSectionsFlexSize", "inputSections", "mode$", "bottomTemplateRef", "customFormButtonItems", "showCaptionButton", "disableSaveButton", "disableCancelButton", "checkError$", "hideButtons"], outputs: ["onFormCreated", "onFormRefCreated", "onSubmit", "onSave", "onCancal", "buttonClick"] }, { kind: "component", type: SaveLiveJsonComponent, selector: "save-live-json" }, { kind: "component", type: CoreButtonGroupVnsComponent, selector: "core-button-group-vns", inputs: ["height", "instanceNumber", "forHeader", "fixedShow", "shownItems", "showCaption", "lastChildEffectOff"], outputs: ["buttonClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
528
+ }
529
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FormMetadataComponent, decorators: [{
530
+ type: Component,
531
+ args: [{ selector: 'form-metadata', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
532
+ TranslatePipe,
533
+ CorePageHeaderComponent,
534
+ CoreFormComponent,
535
+ SaveLiveJsonComponent,
536
+ CoreButtonGroupVnsComponent
537
+ ], template: "<div class=\"form-metadata-container\">\r\n <div class=\"header-wrapper\">\r\n <core-page-header [title]=\"'FORM OVERVIEW'\" [hideButtonGroup]=\"true\"></core-page-header>\r\n <div class=\"close-wrapper\" (click)=\"onClose()\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"af-instance\">\r\n\r\n <div class=\"af-instance-left\">\r\n <core-form \r\n [inputSections]=\"$sections()\" \r\n [width]=\"800\" [mode$]=\"mode$\" \r\n [checkError$]=\"checkError$\" \r\n [hideButtons]=\"true\"\r\n (onFormCreated)=\"onFormCreated($event)\"></core-form>\r\n </div>\r\n <div class=\"af-instance-right\">\r\n <save-live-json></save-live-json>\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n\r\n <div class=\"h15\"></div>\r\n <div class=\"d-flex d-flex-end w-100 pr1rem\">\r\n <core-button-group-vns [showCaption]=\"true\" [forHeader]=\"false\"\r\n (buttonClick)=\"onButtonClick($event)\" [shownItems]=\"customButtons\"\r\n class=\"buttonGroupCustom\"></core-button-group-vns>\r\n </div>\r\n\r\n\r\n\r\n</div>", styles: [".form-metadata-container .header-wrapper{padding:0 15px}.form-metadata-container .header-wrapper .close-wrapper{display:flex;position:absolute;right:7px;top:8px;width:24px;height:24px;color:#848484;cursor:pointer}.form-metadata-container .header-wrapper .close-wrapper i{font-size:24px}.form-metadata-container .af-instance{display:flex}.form-metadata-container .h15{height:15px!important}.form-metadata-container .pr1rem{padding-right:1rem}\n"] }]
538
+ }], ctorParameters: () => [{ type: DialogService }], propDecorators: { onEscape: [{
539
+ type: HostListener,
540
+ args: ['document:keydown.escape', ['$event']]
541
+ }], onWindowClick: [{
542
+ type: HostListener,
543
+ args: ['window:click', ['$event']]
544
+ }] } });
545
+
546
+ class AttachmentFieldHelperService {
547
+ static isAttachment(control) {
548
+ return control.controlType === 'ATTACHMENT';
549
+ }
550
+ static autoGenerateAttachmentNames(baseName) {
551
+ return {
552
+ field: baseName + 'Buffer',
553
+ assignTo: baseName
554
+ };
555
+ }
556
+ static buildHiddenAssignToField(baseFieldName) {
557
+ return {
558
+ field: baseFieldName,
559
+ controlType: EnumFormBaseContolType.TEXTBOX,
560
+ type: 'string',
561
+ label: '',
562
+ value: '',
563
+ hidden: true,
564
+ flexSize: 0
565
+ };
566
+ }
567
+ static injectAssignToFieldIntoRow(row, assignToField) {
568
+ row.cells.push({ flexSize: assignToField.flexSize ?? 12, control: assignToField });
569
+ }
570
+ /**
571
+ * Called when user edits the "field" of an ATTACHMENT control
572
+ */
573
+ static handleFieldNameChangeForAttachment(control, form, typedFieldName) {
574
+ const { field, assignTo } = this.autoGenerateAttachmentNames(typedFieldName);
575
+ control.field = field;
576
+ control.assignTo = assignTo;
577
+ }
578
+ /**
579
+ * Called in drop handler when user drops a new ATTACHMENT
580
+ */
581
+ static setupAttachmentOnDrop(newControl, form) {
582
+ if (this.isAttachment(newControl)) {
583
+ const baseName = newControl.field.replace(/Buffer$/, '');
584
+ const { field, assignTo } = this.autoGenerateAttachmentNames(baseName);
585
+ newControl.field = field;
586
+ newControl.assignTo = assignTo;
587
+ }
588
+ }
589
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AttachmentFieldHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
590
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AttachmentFieldHelperService, providedIn: 'root' }); }
591
+ }
592
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AttachmentFieldHelperService, decorators: [{
593
+ type: Injectable,
594
+ args: [{
595
+ providedIn: 'root'
596
+ }]
597
+ }] });
598
+
599
+ class BasePropsComponent extends BaseComponent {
600
+ constructor() {
601
+ super(...arguments);
602
+ this.coreFormDesignService = inject(CoreFormDesignService);
603
+ this.$selectedCell = this.coreFormDesignService.$selectedCell;
604
+ this.$formContext = this.coreFormDesignService.$formContext;
605
+ this.form = this.coreFormDesignService.formDesign;
606
+ this.patchControl = this.coreFormDesignService.patchControl.bind(this.coreFormDesignService);
607
+ this.normalize = this.coreFormDesignService.normalize.bind(this.coreFormDesignService);
608
+ this.cdr = inject(ChangeDetectorRef);
609
+ this.setControlProp = this.coreFormDesignService.setControlProp.bind(this.coreFormDesignService);
610
+ this.$control = computed(() => {
611
+ const cell = this.$selectedCell();
612
+ if (!cell?.control)
613
+ throw new Error('No control selected!');
614
+ return this.normalize(cell.control);
615
+ });
616
+ }
617
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: BasePropsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
618
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: BasePropsComponent, isStandalone: true, selector: "base-props", usesInheritance: true, ngImport: i0, template: './base-props.component.html', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
619
+ }
620
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: BasePropsComponent, decorators: [{
621
+ type: Component,
622
+ args: [{
623
+ selector: 'base-props',
624
+ changeDetection: ChangeDetectionStrategy.OnPush,
625
+ template: './base-props.component.html'
626
+ }]
627
+ }] });
628
+
629
+ class MandatoryPropsComponent extends BasePropsComponent {
630
+ constructor() {
631
+ super(...arguments);
632
+ this.$typedField = computed(() => {
633
+ const control = this.$control();
634
+ return AttachmentFieldHelperService.isAttachment(control)
635
+ ? control.assignTo || ''
636
+ : control.field;
637
+ });
638
+ }
639
+ setTypedField(val) {
640
+ const control = this.$control();
641
+ const context = this.$formContext();
642
+ const toCamelCase = (input) => {
643
+ return input
644
+ .replace(/[^a-zA-Z0-9 ]/g, ' ') // remove special characters
645
+ .replace(/([a-z])([A-Z])/g, '$1 $2') // split camelCase
646
+ .replace(/\s+/g, ' ') // collapse multiple spaces
647
+ .trim()
648
+ .split(' ')
649
+ .map((word, index) => index === 0
650
+ ? word.toLowerCase()
651
+ : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
652
+ .join('');
653
+ };
654
+ const corrected = toCamelCase(val);
655
+ const current = AttachmentFieldHelperService.isAttachment(control)
656
+ ? control.assignTo || ''
657
+ : control.field;
658
+ if (current === corrected)
659
+ return;
660
+ if (AttachmentFieldHelperService.isAttachment(control)) {
661
+ AttachmentFieldHelperService.handleFieldNameChangeForAttachment(control, context, corrected);
662
+ }
663
+ else {
664
+ control.field = corrected;
665
+ }
666
+ this.patchControl(control);
667
+ }
668
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: MandatoryPropsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
669
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: MandatoryPropsComponent, isStandalone: true, selector: "mandatory-props", usesInheritance: true, ngImport: i0, template: "<div class=\"setting-group mandatory-group\">\r\n\r\n <div class=\"setting-row\">\r\n <label>Field</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$typedField()\" (ngModelChange)=\"setControlProp('field', $event)\" />\r\n </div>\r\n\r\n <!-- Label -->\r\n <div class=\"setting-row\">\r\n <label>Label</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$control()?.label\" (ngModelChange)=\"setControlProp('label', $event)\" />\r\n </div>\r\n\r\n <!-- Default -->\r\n <div class=\"setting-row\">\r\n <label>Default</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$control()?.value\" (ngModelChange)=\"setControlProp('value', $event)\" />\r\n </div>\r\n\r\n</div>", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
670
+ }
671
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: MandatoryPropsComponent, decorators: [{
672
+ type: Component,
673
+ args: [{ selector: 'mandatory-props', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule], template: "<div class=\"setting-group mandatory-group\">\r\n\r\n <div class=\"setting-row\">\r\n <label>Field</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$typedField()\" (ngModelChange)=\"setControlProp('field', $event)\" />\r\n </div>\r\n\r\n <!-- Label -->\r\n <div class=\"setting-row\">\r\n <label>Label</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$control()?.label\" (ngModelChange)=\"setControlProp('label', $event)\" />\r\n </div>\r\n\r\n <!-- Default -->\r\n <div class=\"setting-row\">\r\n <label>Default</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$control()?.value\" (ngModelChange)=\"setControlProp('value', $event)\" />\r\n </div>\r\n\r\n</div>", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"] }]
674
+ }] });
675
+
676
+ class OptionalPropsComponent extends BasePropsComponent {
677
+ constructor() {
678
+ super(...arguments);
679
+ this.pipeOptions = Object.values(EnumCoreTablePipeType);
680
+ this.pipeOptions$ = new BehaviorSubject(Object.values(EnumCoreTablePipeType).map(x => ({ value: x, text: x })));
681
+ }
682
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: OptionalPropsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
683
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: OptionalPropsComponent, isStandalone: true, selector: "optional-props", usesInheritance: true, ngImport: i0, template: "<div class=\"setting-group optional-group\">\r\n\r\n <!-- \uD83D\uDD18 Boolean flags -->\r\n <div class=\"setting-row optional-bool\">\r\n <label>Readonly</label>\r\n <core-checkbox ngModel ngDefaultControl [ngModel]=\"$control().readonly\" (ngModelChange)=\"setControlProp('readonly', $event)\" />\r\n </div>\r\n\r\n <div class=\"setting-row optional-bool\">\r\n <label>Hidden</label>\r\n <core-checkbox [ngModel]=\"$control().hidden\" (ngModelChange)=\"setControlProp('hidden', $event)\" />\r\n </div>\r\n\r\n <div class=\"setting-row optional-bool\">\r\n <label>Disabled</label>\r\n <core-checkbox [ngModel]=\"$control().disabled\" (ngModelChange)=\"setControlProp('disabled', $event)\" /> \r\n </div>\r\n\r\n <!-- \uD83D\uDCA1 Hint -->\r\n <div class=\"setting-row\">\r\n <label>Hint</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$control().hint\" (ngModelChange)=\"setControlProp('hint', $event)\" />\r\n </div>\r\n\r\n <div class=\"setting-row\">\r\n <label>Pipe</label>\r\n <div class=\"control-wrapper\">\r\n <core-dropdown [ngModel]=\"$control().pipe\" (ngModelChange)=\"setControlProp('pipe', $event)\"\r\n [paramMode]=\"true\"\r\n [options$]=\"pipeOptions$\"\r\n >\r\n </core-dropdown>\r\n </div>\r\n </div>\r\n\r\n</div>", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CoreCheckboxComponent, selector: "core-checkbox", inputs: ["text", "tooltipPosition", "tooltip", "inputValue", "disabled"], outputs: ["onClick"] }, { kind: "component", type: CoreDropdownComponent, selector: "core-dropdown", inputs: ["getByIdObject$", "paramMode", "shownFrom", "options$", "height", "placeholder", "loading", "warningDisable", "clearDisable", "fitHeightWithItemCount", "itemHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
684
+ }
685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: OptionalPropsComponent, decorators: [{
686
+ type: Component,
687
+ args: [{ selector: 'optional-props', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
688
+ FormsModule,
689
+ CoreCheckboxComponent,
690
+ CoreDropdownComponent
691
+ ], template: "<div class=\"setting-group optional-group\">\r\n\r\n <!-- \uD83D\uDD18 Boolean flags -->\r\n <div class=\"setting-row optional-bool\">\r\n <label>Readonly</label>\r\n <core-checkbox ngModel ngDefaultControl [ngModel]=\"$control().readonly\" (ngModelChange)=\"setControlProp('readonly', $event)\" />\r\n </div>\r\n\r\n <div class=\"setting-row optional-bool\">\r\n <label>Hidden</label>\r\n <core-checkbox [ngModel]=\"$control().hidden\" (ngModelChange)=\"setControlProp('hidden', $event)\" />\r\n </div>\r\n\r\n <div class=\"setting-row optional-bool\">\r\n <label>Disabled</label>\r\n <core-checkbox [ngModel]=\"$control().disabled\" (ngModelChange)=\"setControlProp('disabled', $event)\" /> \r\n </div>\r\n\r\n <!-- \uD83D\uDCA1 Hint -->\r\n <div class=\"setting-row\">\r\n <label>Hint</label>\r\n <input class=\"form-control\" type=\"text\" [ngModel]=\"$control().hint\" (ngModelChange)=\"setControlProp('hint', $event)\" />\r\n </div>\r\n\r\n <div class=\"setting-row\">\r\n <label>Pipe</label>\r\n <div class=\"control-wrapper\">\r\n <core-dropdown [ngModel]=\"$control().pipe\" (ngModelChange)=\"setControlProp('pipe', $event)\"\r\n [paramMode]=\"true\"\r\n [options$]=\"pipeOptions$\"\r\n >\r\n </core-dropdown>\r\n </div>\r\n </div>\r\n\r\n</div>", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"] }]
692
+ }] });
693
+
694
+ class PropsHostComponent {
695
+ constructor() {
696
+ this.vcRef = inject(ViewContainerRef);
697
+ }
698
+ set props(value) {
699
+ this._props = value;
700
+ this.assignInputs();
701
+ }
702
+ async ngOnInit() {
703
+ if (this.loadComponent) {
704
+ const componentType = await this.loadComponent();
705
+ this.componentRef = this.vcRef.createComponent(componentType);
706
+ this.assignInputs();
707
+ }
708
+ }
709
+ assignInputs() {
710
+ if (this.componentRef && this._props) {
711
+ Object.assign(this.componentRef.instance, this._props);
712
+ this.componentRef.changeDetectorRef.markForCheck();
713
+ }
714
+ }
715
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: PropsHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
716
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: PropsHostComponent, isStandalone: true, selector: "props-host", inputs: { loadComponent: "loadComponent", props: "props" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
717
+ }
718
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: PropsHostComponent, decorators: [{
719
+ type: Component,
720
+ args: [{
721
+ selector: 'props-host',
722
+ standalone: true,
723
+ template: '',
724
+ changeDetection: ChangeDetectionStrategy.OnPush
725
+ }]
726
+ }], propDecorators: { loadComponent: [{
727
+ type: Input
728
+ }], props: [{
729
+ type: Input
730
+ }] } });
731
+
732
+ class AttachmentPropsComponent extends BasePropsComponent {
733
+ constructor() {
734
+ super(...arguments);
735
+ this.$typedField = computed(() => {
736
+ const control = this.$control();
737
+ return AttachmentFieldHelperService.isAttachment(control)
738
+ ? control.assignTo || ''
739
+ : control.field;
740
+ });
741
+ }
742
+ setTypedField(val) {
743
+ const control = this.$control();
744
+ const context = this.$formContext();
745
+ if (AttachmentFieldHelperService.isAttachment(control)) {
746
+ AttachmentFieldHelperService.handleFieldNameChangeForAttachment(control, context, val);
747
+ }
748
+ else {
749
+ control.field = val;
750
+ }
751
+ this.patchControl(control);
752
+ }
753
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AttachmentPropsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
754
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: AttachmentPropsComponent, isStandalone: true, selector: "attachment-props", usesInheritance: true, ngImport: i0, template: "<p>attachment-props works!</p>\r\n", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"] }); }
755
+ }
756
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: AttachmentPropsComponent, decorators: [{
757
+ type: Component,
758
+ args: [{ selector: 'attachment-props', imports: [], template: "<p>attachment-props works!</p>\r\n", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"] }]
759
+ }] });
760
+
761
+ class ChecklistPropsComponent {
762
+ constructor() {
763
+ this.controlChange = new EventEmitter();
764
+ }
765
+ update() {
766
+ this.controlChange.emit(this.control);
767
+ }
768
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ChecklistPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
769
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: ChecklistPropsComponent, isStandalone: true, selector: "checklist-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>checklist-props works!</p>\r\n", styles: [""] }); }
770
+ }
771
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ChecklistPropsComponent, decorators: [{
772
+ type: Component,
773
+ args: [{ selector: 'checklist-props', imports: [], template: "<p>checklist-props works!</p>\r\n" }]
774
+ }], propDecorators: { control: [{
775
+ type: Input
776
+ }], controlChange: [{
777
+ type: Output
778
+ }] } });
779
+
780
+ class DatepickerPropsComponent {
781
+ constructor() {
782
+ this.controlChange = new EventEmitter();
783
+ }
784
+ update() {
785
+ this.controlChange.emit(this.control);
786
+ }
787
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DatepickerPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
788
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DatepickerPropsComponent, isStandalone: true, selector: "datepicker-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>datepicker-props works!</p>\r\n", styles: [""] }); }
789
+ }
790
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DatepickerPropsComponent, decorators: [{
791
+ type: Component,
792
+ args: [{ selector: 'datepicker-props', imports: [], template: "<p>datepicker-props works!</p>\r\n" }]
793
+ }], propDecorators: { control: [{
794
+ type: Input
795
+ }], controlChange: [{
796
+ type: Output
797
+ }] } });
798
+
799
+ class DropdownPropsComponent {
800
+ constructor() {
801
+ this.controlChange = new EventEmitter();
802
+ }
803
+ update() {
804
+ this.controlChange.emit(this.control);
805
+ }
806
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DropdownPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
807
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: DropdownPropsComponent, isStandalone: true, selector: "dropdown-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>dropdown-props works!</p>\r\n", styles: [""] }); }
808
+ }
809
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: DropdownPropsComponent, decorators: [{
810
+ type: Component,
811
+ args: [{ selector: 'dropdown-props', imports: [], template: "<p>dropdown-props works!</p>\r\n" }]
812
+ }], propDecorators: { control: [{
813
+ type: Input
814
+ }], controlChange: [{
815
+ type: Output
816
+ }] } });
817
+
818
+ class GridBufferPropsComponent {
819
+ constructor() {
820
+ this.controlChange = new EventEmitter();
821
+ }
822
+ update() {
823
+ this.controlChange.emit(this.control);
824
+ }
825
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: GridBufferPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
826
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: GridBufferPropsComponent, isStandalone: true, selector: "grid-buffer-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>grid-buffer-props works!</p>\r\n", styles: [""] }); }
827
+ }
828
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: GridBufferPropsComponent, decorators: [{
829
+ type: Component,
830
+ args: [{ selector: 'grid-buffer-props', imports: [], template: "<p>grid-buffer-props works!</p>\r\n" }]
831
+ }], propDecorators: { control: [{
832
+ type: Input
833
+ }], controlChange: [{
834
+ type: Output
835
+ }] } });
836
+
837
+ class ListPropsComponent {
838
+ constructor() {
839
+ this.controlChange = new EventEmitter();
840
+ }
841
+ update() {
842
+ this.controlChange.emit(this.control);
843
+ }
844
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ListPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
845
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: ListPropsComponent, isStandalone: true, selector: "list-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>list-props works!</p>\r\n", styles: [""] }); }
846
+ }
847
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ListPropsComponent, decorators: [{
848
+ type: Component,
849
+ args: [{ selector: 'list-props', imports: [], template: "<p>list-props works!</p>\r\n" }]
850
+ }], propDecorators: { control: [{
851
+ type: Input
852
+ }], controlChange: [{
853
+ type: Output
854
+ }] } });
855
+
856
+ class MccPropsComponent {
857
+ constructor() {
858
+ this.controlChange = new EventEmitter();
859
+ }
860
+ update() {
861
+ this.controlChange.emit(this.control);
862
+ }
863
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: MccPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
864
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: MccPropsComponent, isStandalone: true, selector: "mcc-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>mcc-props works!</p>\r\n", styles: [""] }); }
865
+ }
866
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: MccPropsComponent, decorators: [{
867
+ type: Component,
868
+ args: [{ selector: 'mcc-props', imports: [], template: "<p>mcc-props works!</p>\r\n" }]
869
+ }], propDecorators: { control: [{
870
+ type: Input
871
+ }], controlChange: [{
872
+ type: Output
873
+ }] } });
874
+
875
+ class NumberPropsComponent {
876
+ constructor() {
877
+ this.controlChange = new EventEmitter();
878
+ }
879
+ update() {
880
+ this.controlChange.emit(this.control);
881
+ }
882
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: NumberPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
883
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: NumberPropsComponent, isStandalone: true, selector: "number-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>number-props works!</p>\r\n", styles: [""] }); }
884
+ }
885
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: NumberPropsComponent, decorators: [{
886
+ type: Component,
887
+ args: [{ selector: 'number-props', imports: [], template: "<p>number-props works!</p>\r\n" }]
888
+ }], propDecorators: { control: [{
889
+ type: Input
890
+ }], controlChange: [{
891
+ type: Output
892
+ }] } });
893
+
894
+ var numberProps_component = /*#__PURE__*/Object.freeze({
895
+ __proto__: null,
896
+ NumberPropsComponent: NumberPropsComponent
897
+ });
898
+
899
+ class RadioGroupPropsComponent {
900
+ constructor() {
901
+ this.controlChange = new EventEmitter();
902
+ }
903
+ update() {
904
+ this.controlChange.emit(this.control);
905
+ }
906
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: RadioGroupPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
907
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: RadioGroupPropsComponent, isStandalone: true, selector: "radio-group-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>radio-group-props works!</p>\r\n", styles: [""] }); }
908
+ }
909
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: RadioGroupPropsComponent, decorators: [{
910
+ type: Component,
911
+ args: [{ selector: 'radio-group-props', imports: [], template: "<p>radio-group-props works!</p>\r\n" }]
912
+ }], propDecorators: { control: [{
913
+ type: Input
914
+ }], controlChange: [{
915
+ type: Output
916
+ }] } });
917
+
918
+ class SeekerPropsComponent {
919
+ constructor() {
920
+ this.controlChange = new EventEmitter();
921
+ }
922
+ update() {
923
+ this.controlChange.emit(this.control);
924
+ }
925
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: SeekerPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
926
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: SeekerPropsComponent, isStandalone: true, selector: "seeker-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>seeker-props works!</p>\r\n", styles: [""] }); }
927
+ }
928
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: SeekerPropsComponent, decorators: [{
929
+ type: Component,
930
+ args: [{ selector: 'seeker-props', imports: [], template: "<p>seeker-props works!</p>\r\n" }]
931
+ }], propDecorators: { control: [{
932
+ type: Input
933
+ }], controlChange: [{
934
+ type: Output
935
+ }] } });
936
+
937
+ class TextareaPropsComponent {
938
+ constructor() {
939
+ this.controlChange = new EventEmitter();
940
+ }
941
+ update() {
942
+ this.controlChange.emit(this.control);
943
+ }
944
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TextareaPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
945
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: TextareaPropsComponent, isStandalone: true, selector: "textarea-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>textarea-props works!</p>\r\n", styles: [""] }); }
946
+ }
947
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: TextareaPropsComponent, decorators: [{
948
+ type: Component,
949
+ args: [{ selector: 'textarea-props', imports: [], template: "<p>textarea-props works!</p>\r\n" }]
950
+ }], propDecorators: { control: [{
951
+ type: Input
952
+ }], controlChange: [{
953
+ type: Output
954
+ }] } });
955
+
956
+ class UploaderPropsComponent {
957
+ constructor() {
958
+ this.controlChange = new EventEmitter();
959
+ }
960
+ update() {
961
+ this.controlChange.emit(this.control);
962
+ }
963
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: UploaderPropsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
964
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.5", type: UploaderPropsComponent, isStandalone: true, selector: "uploader-props", inputs: { control: "control" }, outputs: { controlChange: "controlChange" }, ngImport: i0, template: "<p>uploader-props works!</p>\r\n", styles: [""] }); }
965
+ }
966
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: UploaderPropsComponent, decorators: [{
967
+ type: Component,
968
+ args: [{ selector: 'uploader-props', imports: [], template: "<p>uploader-props works!</p>\r\n" }]
969
+ }], propDecorators: { control: [{
970
+ type: Input
971
+ }], controlChange: [{
972
+ type: Output
973
+ }] } });
974
+
975
+ class ValidatorEditorComponent extends BasePropsComponent {
976
+ constructor(mls) {
977
+ super(mls);
978
+ this.mls = mls;
979
+ // 🔹 Computed list based on controlType
980
+ this.$availableValidators = computed(() => this.coreFormDesignService.getSupportedValidators(this.$control()));
981
+ // 🔹 Signal for selected validators with their values
982
+ this.$selectedValidators = signal({});
983
+ effect(() => {
984
+ const c = this.$control(); // will re-run when selection changes
985
+ this.syncFromControl();
986
+ });
987
+ }
988
+ // ✅ Check if a validator is enabled
989
+ isChecked(v) {
990
+ return this.$selectedValidators()[v] !== undefined;
991
+ }
992
+ syncFromControl() {
993
+ const control = this.$control();
994
+ const validators = control.validators ?? [];
995
+ const validatorMap = {};
996
+ for (const v of validators) {
997
+ validatorMap[v.name] = v;
998
+ }
999
+ this.$selectedValidators.set(validatorMap);
1000
+ }
1001
+ toggleValidator(v) {
1002
+ const current = { ...this.$selectedValidators() };
1003
+ const requiresValue = ['minLength', 'maxLength', 'min', 'max', 'pattern'];
1004
+ const isAlreadyChecked = !!current[v];
1005
+ if (isAlreadyChecked) {
1006
+ delete current[v]; // ❌ Remove validator
1007
+ }
1008
+ else {
1009
+ const validator = {
1010
+ name: v,
1011
+ errorMessage: this.coreFormDesignService.getErrorMessageFor(v),
1012
+ validator: this.coreFormDesignService.getValidatorFn(v, null), // stub until value is filled
1013
+ value: requiresValue.includes(v) ? '' : true
1014
+ };
1015
+ current[v] = validator;
1016
+ }
1017
+ this.$selectedValidators.set(current);
1018
+ // ✅ Skip update if validator requires value but it's still empty
1019
+ const shouldSkip = !isAlreadyChecked &&
1020
+ requiresValue.includes(v) &&
1021
+ current[v]?.value === '';
1022
+ if (shouldSkip)
1023
+ return;
1024
+ const validatorArray = this.coreFormDesignService.toIValidatorArray(current);
1025
+ this.setControlProp('validators', validatorArray);
1026
+ }
1027
+ updateValidatorValue(v, raw) {
1028
+ const value = raw?.toString().trim();
1029
+ const updated = { ...this.$selectedValidators() };
1030
+ if (value === '') {
1031
+ // 👇 Remove the validator if it was cleared
1032
+ delete updated[v];
1033
+ }
1034
+ else {
1035
+ updated[v] = value;
1036
+ }
1037
+ this.$selectedValidators.set(updated);
1038
+ // ✅ Only update the control if it's valid or fully removed
1039
+ const validatorArray = this.coreFormDesignService.toIValidatorArray(updated);
1040
+ this.setControlProp('validators', validatorArray);
1041
+ }
1042
+ isReadOnlyValidator(v) {
1043
+ return this.$selectedValidators()[v]?.readOnly === true;
1044
+ }
1045
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ValidatorEditorComponent, deps: [{ token: MultiLanguageService }], target: i0.ɵɵFactoryTarget.Component }); }
1046
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: ValidatorEditorComponent, isStandalone: true, selector: "validator-editor", usesInheritance: true, ngImport: i0, template: "<div class=\"setting-group validator-group\">\r\n @for (v of $availableValidators(); track v) {\r\n <div class=\"setting-row\">\r\n\r\n <label>\r\n {{ v }}\r\n @if (isReadOnlyValidator(v)) {\r\n <i class=\"feather-lock tiny-lock\" title=\"Read-only system validator\"></i>\r\n }\r\n </label>\r\n\r\n <div class=\"control-wrapper\">\r\n <core-checkbox ngModel ngDefaultControl [ngModel]=\"isChecked(v)\" [disabled]=\"isReadOnlyValidator(v)\"\r\n [appTooltip]=\"isReadOnlyValidator(v) ? 'System validator' : ''\" (ngModelChange)=\"toggleValidator(v)\" />\r\n\r\n @if (isChecked(v) && ['minLength', 'maxLength', 'min', 'max'].includes(v)) {\r\n <input class=\"form-control validator-value\" [type]=\"'number'\"\r\n [value]=\"$selectedValidators()[v]?.value || ''\"\r\n (input)=\"updateValidatorValue(v, $any($event.target).value)\"\r\n [placeholder]=\"'Enter value' | translate: lang\" [disabled]=\"isReadOnlyValidator(v)\"\r\n [appTooltip]=\"isReadOnlyValidator(v) ? 'Default validator \u2014 cannot be modified' : ''\" />\r\n }\r\n\r\n @else if (isChecked(v) && v === 'pattern') {\r\n <input class=\"form-control validator-value\" type=\"text\" [value]=\"$selectedValidators()[v]?.value || ''\"\r\n (input)=\"updateValidatorValue(v, $any($event.target).value)\" [placeholder]=\"'Enter regex'\"\r\n [disabled]=\"isReadOnlyValidator(v)\"\r\n [appTooltip]=\"isReadOnlyValidator(v) ? 'Default validator \u2014 cannot be modified' : ''\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "directive", type: TooltipDirective, selector: "[appTooltip]", inputs: ["color", "backgroundColor", "appTooltip", "showAnyway", "position"] }, { kind: "component", type: CoreCheckboxComponent, selector: "core-checkbox", inputs: ["text", "tooltipPosition", "tooltip", "inputValue", "disabled"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1047
+ }
1048
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: ValidatorEditorComponent, decorators: [{
1049
+ type: Component,
1050
+ args: [{ selector: 'validator-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1051
+ FormsModule,
1052
+ TranslatePipe,
1053
+ TooltipDirective,
1054
+ CoreCheckboxComponent
1055
+ ], template: "<div class=\"setting-group validator-group\">\r\n @for (v of $availableValidators(); track v) {\r\n <div class=\"setting-row\">\r\n\r\n <label>\r\n {{ v }}\r\n @if (isReadOnlyValidator(v)) {\r\n <i class=\"feather-lock tiny-lock\" title=\"Read-only system validator\"></i>\r\n }\r\n </label>\r\n\r\n <div class=\"control-wrapper\">\r\n <core-checkbox ngModel ngDefaultControl [ngModel]=\"isChecked(v)\" [disabled]=\"isReadOnlyValidator(v)\"\r\n [appTooltip]=\"isReadOnlyValidator(v) ? 'System validator' : ''\" (ngModelChange)=\"toggleValidator(v)\" />\r\n\r\n @if (isChecked(v) && ['minLength', 'maxLength', 'min', 'max'].includes(v)) {\r\n <input class=\"form-control validator-value\" [type]=\"'number'\"\r\n [value]=\"$selectedValidators()[v]?.value || ''\"\r\n (input)=\"updateValidatorValue(v, $any($event.target).value)\"\r\n [placeholder]=\"'Enter value' | translate: lang\" [disabled]=\"isReadOnlyValidator(v)\"\r\n [appTooltip]=\"isReadOnlyValidator(v) ? 'Default validator \u2014 cannot be modified' : ''\" />\r\n }\r\n\r\n @else if (isChecked(v) && v === 'pattern') {\r\n <input class=\"form-control validator-value\" type=\"text\" [value]=\"$selectedValidators()[v]?.value || ''\"\r\n (input)=\"updateValidatorValue(v, $any($event.target).value)\" [placeholder]=\"'Enter regex'\"\r\n [disabled]=\"isReadOnlyValidator(v)\"\r\n [appTooltip]=\"isReadOnlyValidator(v) ? 'Default validator \u2014 cannot be modified' : ''\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".setting-group{display:flex;flex-direction:column}.setting-row{display:flex;justify-content:flex-start;align-items:center;height:50px}.setting-row label{width:30%}.setting-row .control-wrapper,.setting-row input,.setting-row .readonly-field{width:65%}.setting-row .readonly-field{font-style:italic;color:#666}.setting-row input.validator-value{text-align:right}.setting-row input.validator-value.pattern{text-align:left}.setting-row .control-wrapper{display:flex;align-items:center;justify-content:flex-start}.validator-group .setting-row{justify-content:flex-start}.validator-group .setting-row input{margin-left:15px;width:100%}.tiny-lock{margin-left:6px;font-size:12px;color:#888}\n"] }]
1056
+ }], ctorParameters: () => [{ type: MultiLanguageService }] });
1057
+
1058
+ class FieldSettingComponent extends BaseComponent {
1059
+ constructor() {
1060
+ super(...arguments);
1061
+ this.coreFormDesignService = inject(CoreFormDesignService);
1062
+ this.enumControlType = EnumFormBaseContolType;
1063
+ this.renderer = inject(Renderer2);
1064
+ this.cdr = inject(ChangeDetectorRef);
1065
+ // 🔹 Reactive normalized control (always derived from selected cell)
1066
+ this.$control = computed(() => {
1067
+ const cell = this.coreFormDesignService.$selectedCell();
1068
+ if (!cell?.control)
1069
+ throw new Error('No control selected!');
1070
+ return this.coreFormDesignService.normalize(cell.control);
1071
+ });
1072
+ // 🔹 Context (flat control list)
1073
+ this.$formContext = computed(() => this.coreFormDesignService.$formContext());
1074
+ this.componentLoaderMap = {
1075
+ 'number-props': () => Promise.resolve().then(function () { return numberProps_component; }).then(m => m.NumberPropsComponent),
1076
+ 'email-props': () => import('./ngx-histaff-alpha-email-props.component-Cf35Pexq.mjs').then(m => m.EmailPropsComponent),
1077
+ // etc...
1078
+ };
1079
+ }
1080
+ // 🔹 Optional trigger for downstream side-effects (no longer emits)
1081
+ onControlParamsChange() {
1082
+ const updated = this.$control();
1083
+ this.coreFormDesignService.patchControl(updated);
1084
+ }
1085
+ getFriendlyControlLabel(control) {
1086
+ if (!control)
1087
+ return 'Control';
1088
+ // 🧠 Detailed mapping: "controlType:type" → Friendly Name
1089
+ const fullTypeMap = {
1090
+ 'TEXTBOX:string': 'String Box',
1091
+ 'TEXTBOX:number': 'Number Box',
1092
+ 'TEXTBOX:email': 'Email Field',
1093
+ 'DROPDOWN': 'Dropdown',
1094
+ 'CHECKLIST': 'Checklist',
1095
+ 'SEEKER': 'Seeker',
1096
+ 'DATEPICKER': 'Date Picker',
1097
+ 'TEXTAREA': 'Text Area',
1098
+ 'CHECKBOX': 'Checkbox'
1099
+ // Add more mappings as needed
1100
+ };
1101
+ const controlType = control.controlType?.toUpperCase() ?? '';
1102
+ const inputType = control.type?.toLowerCase();
1103
+ const fullKey = inputType ? `${controlType}:${inputType}` : controlType;
1104
+ return fullTypeMap[fullKey] ?? this.camelToTitle(control.controlType ?? 'Control');
1105
+ }
1106
+ camelToTitle(input) {
1107
+ return input
1108
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
1109
+ .replace(/^./, str => str.toUpperCase());
1110
+ }
1111
+ ngAfterViewInit() {
1112
+ this.listenerFn = this.renderer.listen('window', 'click', (e) => {
1113
+ this.cdr.markForCheck();
1114
+ });
1115
+ }
1116
+ ngOnDestroy() {
1117
+ this.subscriptions.forEach(x => x?.unsubscribe());
1118
+ if (this.listenerFn)
1119
+ this.listenerFn();
1120
+ }
1121
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FieldSettingComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1122
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: FieldSettingComponent, isStandalone: true, selector: "field-setting", usesInheritance: true, ngImport: i0, template: "<div class=\"field-setting-container\">\r\n\r\n @if (!!$control()) {\r\n\r\n <div class=\"panel-caption\">\r\n Editing: {{ $control()?.controlType }} - {{ $control()?.field || 'Unnamed' }}\r\n </div>\r\n\r\n <div class=\"group-title mandatory\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Mandatory</div>\r\n </div>\r\n <mandatory-props></mandatory-props>\r\n\r\n <div class=\"setting-divider\"></div>\r\n\r\n <div class=\"group-title optional\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-sliders\"></i>\r\n </div>\r\n <div class=\"group-name\">Optional</div>\r\n </div>\r\n <optional-props></optional-props>\r\n\r\n <div class=\"setting-divider\"></div>\r\n\r\n <div class=\"group-title validators\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-check-square\"></i>\r\n </div>\r\n <div class=\"group-name\">Validators</div>\r\n </div>\r\n <validator-editor></validator-editor>\r\n\r\n @if (!($control().controlType === 'TEXTBOX' && ['string', 'text', 'email'].includes(($control().type || '').toLowerCase()))) {\r\n\r\n <div class=\"setting-divider\">\r\n {{ getFriendlyControlLabel($control()) }} Settings\r\n </div>\r\n \r\n <props-host [loadComponent]=\"componentLoaderMap[coreFormDesignService.$currentPropsComponent()]\"\r\n [props]=\"{ control: $control(), controlChange: onControlParamsChange.bind(this) }\">\r\n </props-host>\r\n }\r\n\r\n }\r\n\r\n</div>", styles: [".field-setting-container{padding:15px;max-height:100%;overflow:scroll}.field-setting-container .panel-caption{font-weight:700;margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd}.field-setting-container .setting-divider{margin:1.5rem 0 .75rem;color:#555;border-top:1px dashed #ccc;padding-top:.5rem}.field-setting-container .group-title{display:flex;align-items:center;gap:8px;background-color:#87ceeb;padding:6px 12px;font-weight:600;color:#1f2937;font-size:13px;margin:12px 0 4px;box-shadow:0 1px 2px #0000000d}.field-setting-container .group-title .icon-wrapper{display:flex;align-items:center;justify-content:center;width:18px;height:18px;color:#1f2937}.field-setting-container .group-title .icon-wrapper i{width:16px;height:16px;stroke-width:2}.field-setting-container .group-title.mandatory{background-color:#ffecb3}.field-setting-container .group-title.optional{background-color:#d0f0fd}.field-setting-container .group-title.validators{background-color:#e8f5e9}.field-setting-container .group-title .group-name{flex:1}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: MandatoryPropsComponent, selector: "mandatory-props" }, { kind: "component", type: OptionalPropsComponent, selector: "optional-props" }, { kind: "component", type: ValidatorEditorComponent, selector: "validator-editor" }, { kind: "component", type: PropsHostComponent, selector: "props-host", inputs: ["loadComponent", "props"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1123
+ }
1124
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: FieldSettingComponent, decorators: [{
1125
+ type: Component,
1126
+ args: [{ selector: 'field-setting', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1127
+ FormsModule,
1128
+ MandatoryPropsComponent,
1129
+ OptionalPropsComponent,
1130
+ ValidatorEditorComponent,
1131
+ PropsHostComponent,
1132
+ AttachmentPropsComponent,
1133
+ ChecklistPropsComponent,
1134
+ DatepickerPropsComponent,
1135
+ DropdownPropsComponent,
1136
+ GridBufferPropsComponent,
1137
+ ListPropsComponent,
1138
+ MccPropsComponent,
1139
+ NumberPropsComponent,
1140
+ RadioGroupPropsComponent,
1141
+ SeekerPropsComponent,
1142
+ TextareaPropsComponent,
1143
+ UploaderPropsComponent
1144
+ ], template: "<div class=\"field-setting-container\">\r\n\r\n @if (!!$control()) {\r\n\r\n <div class=\"panel-caption\">\r\n Editing: {{ $control()?.controlType }} - {{ $control()?.field || 'Unnamed' }}\r\n </div>\r\n\r\n <div class=\"group-title mandatory\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-lock\"></i>\r\n </div>\r\n <div class=\"group-name\">Mandatory</div>\r\n </div>\r\n <mandatory-props></mandatory-props>\r\n\r\n <div class=\"setting-divider\"></div>\r\n\r\n <div class=\"group-title optional\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-sliders\"></i>\r\n </div>\r\n <div class=\"group-name\">Optional</div>\r\n </div>\r\n <optional-props></optional-props>\r\n\r\n <div class=\"setting-divider\"></div>\r\n\r\n <div class=\"group-title validators\">\r\n <div class=\"icon-wrapper\">\r\n <i class=\"feather-check-square\"></i>\r\n </div>\r\n <div class=\"group-name\">Validators</div>\r\n </div>\r\n <validator-editor></validator-editor>\r\n\r\n @if (!($control().controlType === 'TEXTBOX' && ['string', 'text', 'email'].includes(($control().type || '').toLowerCase()))) {\r\n\r\n <div class=\"setting-divider\">\r\n {{ getFriendlyControlLabel($control()) }} Settings\r\n </div>\r\n \r\n <props-host [loadComponent]=\"componentLoaderMap[coreFormDesignService.$currentPropsComponent()]\"\r\n [props]=\"{ control: $control(), controlChange: onControlParamsChange.bind(this) }\">\r\n </props-host>\r\n }\r\n\r\n }\r\n\r\n</div>", styles: [".field-setting-container{padding:15px;max-height:100%;overflow:scroll}.field-setting-container .panel-caption{font-weight:700;margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd}.field-setting-container .setting-divider{margin:1.5rem 0 .75rem;color:#555;border-top:1px dashed #ccc;padding-top:.5rem}.field-setting-container .group-title{display:flex;align-items:center;gap:8px;background-color:#87ceeb;padding:6px 12px;font-weight:600;color:#1f2937;font-size:13px;margin:12px 0 4px;box-shadow:0 1px 2px #0000000d}.field-setting-container .group-title .icon-wrapper{display:flex;align-items:center;justify-content:center;width:18px;height:18px;color:#1f2937}.field-setting-container .group-title .icon-wrapper i{width:16px;height:16px;stroke-width:2}.field-setting-container .group-title.mandatory{background-color:#ffecb3}.field-setting-container .group-title.optional{background-color:#d0f0fd}.field-setting-container .group-title.validators{background-color:#e8f5e9}.field-setting-container .group-title .group-name{flex:1}\n"] }]
1145
+ }] });
1146
+
1147
+ var EnumLeftPanelMode;
1148
+ (function (EnumLeftPanelMode) {
1149
+ EnumLeftPanelMode["FieldCollection"] = "FieldCollection";
1150
+ EnumLeftPanelMode["SelectedFieldJson"] = "SelectedFieldJson";
1151
+ })(EnumLeftPanelMode || (EnumLeftPanelMode = {}));
1152
+
1153
+ class CoreFormDesignComponent extends BaseComponent {
1154
+ constructor(mls) {
1155
+ super(mls);
1156
+ this.mls = mls;
1157
+ this.enumType = EnumFormDesignMode;
1158
+ this.enumLeftPanelMode = EnumLeftPanelMode;
1159
+ this.$leftPanelMode = computed(() => {
1160
+ if (this.coreFormDesignService.$fieldSettingPanelOpen()) {
1161
+ return this.enumLeftPanelMode.SelectedFieldJson;
1162
+ }
1163
+ else {
1164
+ return this.enumLeftPanelMode.FieldCollection;
1165
+ }
1166
+ });
1167
+ this.previewMode$ = new BehaviorSubject(EnumCorePageEditMode.CREATE);
1168
+ this.$loading = signal(false);
1169
+ this.coreFormDesignService = inject(CoreFormDesignService);
1170
+ this.renderer = inject(Renderer2);
1171
+ this.cdr = inject(ChangeDetectorRef);
1172
+ this.route = inject(ActivatedRoute);
1173
+ this.alertService = inject(AlertService);
1174
+ this.formDesign = this.coreFormDesignService.formDesign;
1175
+ this.setControlProp = this.coreFormDesignService.setControlProp.bind(this.coreFormDesignService);
1176
+ this.isDragOverMap = {};
1177
+ this.form = new FormGroup({
1178
+ stringBox: new FormControl(),
1179
+ email: new FormControl(),
1180
+ textarea: new FormControl(),
1181
+ number: new FormControl(),
1182
+ currency: new FormControl(),
1183
+ dropdown: new FormControl(),
1184
+ employeeSeeker: new FormControl(),
1185
+ checklist: new FormControl(),
1186
+ employeeSeekerMultiple: new FormControl(),
1187
+ datePicker: new FormControl(),
1188
+ monthSelector: new FormControl(),
1189
+ attachment: new FormControl(),
1190
+ attachmentBuffer: new FormControl(),
1191
+ checkbox: new FormControl(),
1192
+ });
1193
+ // 🔹 Computed signal for live preview
1194
+ /*$sections = computed(() => {
1195
+ return this.coreFormDesignService.sanitizeSectionsForSaving(this.coreFormDesignService.$placeholderSections());
1196
+ });*/
1197
+ this.$sections = computed(() => {
1198
+ const hydrated = this.coreFormDesignService.rehydrateSections(this.coreFormDesignService.$placeholderSections());
1199
+ let sections = this.coreFormDesignService.toCoreFormSections(hydrated);
1200
+ // ✅ Inject hidden "id" field into the first cell row of the first section
1201
+ sections = this.coreFormDesignService.injectSystemControls(sections, this.coreFormDesignService.$afInstance().hasIdOfStringType ?? false);
1202
+ return sections;
1203
+ });
1204
+ this.checkError$ = new BehaviorSubject(false);
1205
+ this.controlCategories = [
1206
+ {
1207
+ name: 'Text',
1208
+ controls: [
1209
+ {
1210
+ flexSize: 12,
1211
+ controlType: EnumFormBaseContolType.TEXTBOX,
1212
+ type: 'string',
1213
+ field: 'stringBox',
1214
+ label: '',
1215
+ value: '',
1216
+ placeholder: 'String box',
1217
+ headless: true,
1218
+ },
1219
+ {
1220
+ flexSize: 12,
1221
+ controlType: EnumFormBaseContolType.TEXTBOX,
1222
+ type: 'email',
1223
+ field: 'email',
1224
+ label: '',
1225
+ value: '',
1226
+ placeholder: 'Email',
1227
+ headless: true,
1228
+ },
1229
+ {
1230
+ flexSize: 12,
1231
+ controlType: EnumFormBaseContolType.TEXTAREA,
1232
+ type: 'string',
1233
+ field: 'textarea',
1234
+ label: '',
1235
+ value: '',
1236
+ textareaRows: 2,
1237
+ placeholder: 'Text area',
1238
+ headless: true,
1239
+ }
1240
+ ]
1241
+ },
1242
+ {
1243
+ name: 'Numerical',
1244
+ controls: [
1245
+ {
1246
+ flexSize: 12,
1247
+ controlType: EnumFormBaseContolType.TEXTBOX,
1248
+ type: 'number',
1249
+ field: 'number',
1250
+ label: '',
1251
+ value: 100,
1252
+ placeholder: 'Number',
1253
+ headless: true,
1254
+ },
1255
+ {
1256
+ flexSize: 12,
1257
+ controlType: EnumFormBaseContolType.CURRENCY,
1258
+ type: 'number',
1259
+ field: 'currency',
1260
+ label: '',
1261
+ value: '',
1262
+ placeholder: 'Currency',
1263
+ headless: true,
1264
+ },
1265
+ ]
1266
+ },
1267
+ {
1268
+ name: 'Single selection',
1269
+ controls: [
1270
+ {
1271
+ flexSize: 12,
1272
+ controlType: EnumFormBaseContolType.DROPDOWN,
1273
+ type: 'any',
1274
+ field: 'dropdown',
1275
+ label: '',
1276
+ value: '',
1277
+ dropdownOptions$: new BehaviorSubject([]),
1278
+ shownFrom: 'name',
1279
+ getByIdObject$: new BehaviorSubject({}),
1280
+ placeholder: 'Dropdown',
1281
+ headless: true,
1282
+ },
1283
+ {
1284
+ flexSize: 12,
1285
+ controlType: EnumFormBaseContolType.SEEKER,
1286
+ seekerSourceType: EnumCoreFormControlSeekerSourceType.EMPLOYEE_SEEK,
1287
+ type: 'any[]',
1288
+ field: 'employeeSeeker',
1289
+ label: '',
1290
+ value: ['Nguyễn A'],
1291
+ boundFrom: 'id',
1292
+ shownFrom: 'fullname',
1293
+ getByIdObject$: new BehaviorSubject({}),
1294
+ placeholder: 'Employee seeker',
1295
+ headless: true,
1296
+ }
1297
+ ]
1298
+ },
1299
+ {
1300
+ name: 'Multiple Selection',
1301
+ controls: [
1302
+ {
1303
+ flexSize: 12,
1304
+ controlType: EnumFormBaseContolType.CHECKLIST,
1305
+ type: 'any[]',
1306
+ field: 'checklist',
1307
+ label: '',
1308
+ value: [],
1309
+ checklistOptions$: new BehaviorSubject([]),
1310
+ shownFrom: 'name',
1311
+ getByIdObject$: new BehaviorSubject({}),
1312
+ placeholder: 'Check list',
1313
+ headless: true,
1314
+ },
1315
+ {
1316
+ flexSize: 12,
1317
+ controlType: EnumFormBaseContolType.SEEKER,
1318
+ seekerSourceType: EnumCoreFormControlSeekerSourceType.EMPLOYEE_SEEK,
1319
+ multiMode: true,
1320
+ type: 'any[]',
1321
+ field: 'employeeSeekerMultiple',
1322
+ label: '',
1323
+ value: [],
1324
+ objectList$: new BehaviorSubject([]),
1325
+ boundFrom: 'id',
1326
+ shownFrom: 'fullname',
1327
+ getByIdObject$: new BehaviorSubject({}),
1328
+ multiModeTableHeight: 100,
1329
+ placeholder: 'Employee seeker (multi mode)',
1330
+ headless: true,
1331
+ }
1332
+ ]
1333
+ },
1334
+ {
1335
+ name: 'Date',
1336
+ controls: [
1337
+ {
1338
+ flexSize: 12,
1339
+ controlType: EnumFormBaseContolType.DATEPICKER,
1340
+ type: 'date',
1341
+ field: 'datePicker',
1342
+ label: '',
1343
+ value: '',
1344
+ placeholder: 'Date picker',
1345
+ showPlaceholder: true,
1346
+ headless: true,
1347
+ },
1348
+ {
1349
+ flexSize: 12,
1350
+ controlType: EnumFormBaseContolType.MONTHSELECTOR,
1351
+ type: 'string',
1352
+ field: 'monthSelector',
1353
+ label: '',
1354
+ value: '',
1355
+ placeholder: 'Month selector',
1356
+ headless: true,
1357
+ },
1358
+ ]
1359
+ },
1360
+ {
1361
+ name: 'Other',
1362
+ controls: [
1363
+ {
1364
+ flexSize: 12,
1365
+ controlType: EnumFormBaseContolType.ATTACHMENT,
1366
+ type: 'string',
1367
+ field: 'attachment',
1368
+ label: '',
1369
+ value: '',
1370
+ assignTo: 'unknown',
1371
+ placeholder: 'Attachment',
1372
+ headless: true,
1373
+ },
1374
+ {
1375
+ flexSize: 12,
1376
+ controlType: EnumFormBaseContolType.CHECKBOX,
1377
+ type: 'boolean',
1378
+ field: 'checkbox',
1379
+ label: '',
1380
+ value: '',
1381
+ placeholder: 'Checkbox',
1382
+ headless: true,
1383
+ },
1384
+ ]
1385
+ }
1386
+ ];
1387
+ this.generateFieldNameFor = this.coreFormDesignService.generateFieldNameFor.bind(this.coreFormDesignService);
1388
+ this.generateLabelNameFor = this.coreFormDesignService.generateLabelNameFor.bind(this.coreFormDesignService);
1389
+ this.getAllControlsFromSections = this.coreFormDesignService.getAllControlsFromSections.bind(this.coreFormDesignService);
1390
+ this.getControl = this.coreFormDesignService.getControl.bind(this.coreFormDesignService);
1391
+ this.coreFormDesignService.resetFormDesignState();
1392
+ effect(() => {
1393
+ const _ = this.coreFormDesignService.$placeholderSections();
1394
+ this.syncFormDesignWithSections();
1395
+ });
1396
+ }
1397
+ onDragStart(event, control) {
1398
+ this.coreFormDesignService.beginDragTemplate(control);
1399
+ }
1400
+ onDragOver(event) {
1401
+ event.preventDefault(); // necessary to allow drop
1402
+ }
1403
+ onDragEnter(placeholderId) {
1404
+ //if (this.coreFormDesignService.$isDragging()) {
1405
+ this.isDragOverMap[placeholderId] = true;
1406
+ //}
1407
+ }
1408
+ onDragLeave(placeholderId) {
1409
+ this.isDragOverMap[placeholderId] = false;
1410
+ }
1411
+ onDropIntoCell(event, sectionIndex, rowIndex, colIndex) {
1412
+ event.preventDefault();
1413
+ const template = this.coreFormDesignService.$currentControlTemplate();
1414
+ if (!template)
1415
+ return;
1416
+ const normalized = this.coreFormDesignService.normalize({
1417
+ ...template,
1418
+ field: this.generateFieldNameFor(template),
1419
+ label: this.generateLabelNameFor(template),
1420
+ value: null
1421
+ });
1422
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1423
+ const section = sections[sectionIndex];
1424
+ const row = section?.rows[rowIndex];
1425
+ if (!row || row.cells.length <= colIndex)
1426
+ return sections;
1427
+ const usedFlex = row.cells.reduce((sum, cell) => sum + (cell?.control?.flexSize ?? 0), 0);
1428
+ const remainingFlex = 12 - usedFlex;
1429
+ const flexSize = Math.max(1, remainingFlex);
1430
+ normalized.flexSize = flexSize;
1431
+ const previous = row.cells[colIndex]?.control;
1432
+ if (previous && previous.flexSize !== undefined) {
1433
+ /*
1434
+ AttachmentFieldHelperService.handleAttachmentOverwrite(
1435
+ previous as IFormBaseControl,
1436
+ this.coreFormDesignService.getAllControlsFromSections()
1437
+ );
1438
+ */
1439
+ }
1440
+ const previousField = row.cells[colIndex]?.control?.field ?? null;
1441
+ this.coreFormDesignService.replaceControl(previousField, normalized);
1442
+ // 🔹 INSERT FIRST
1443
+ row.cells[colIndex] = { ...row.cells[colIndex], control: normalized };
1444
+ this.coreFormDesignService.$selectedCell.set(row.cells[colIndex]);
1445
+ // 🔹 THEN CALL setup
1446
+ if (AttachmentFieldHelperService.isAttachment(normalized)) {
1447
+ const assignToField = AttachmentFieldHelperService.buildHiddenAssignToField(normalized.field);
1448
+ normalized.field = `${normalized.field}Buffer`;
1449
+ normalized.assignTo = assignToField.field;
1450
+ AttachmentFieldHelperService.injectAssignToFieldIntoRow(row, assignToField);
1451
+ }
1452
+ setTimeout(() => {
1453
+ this.coreFormDesignService.setControlPropDirectly('validators', normalized.validators ?? [], normalized);
1454
+ });
1455
+ return sections;
1456
+ });
1457
+ this.triggerUpdateSections();
1458
+ this.isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex] = false;
1459
+ this.coreFormDesignService.endDrag();
1460
+ }
1461
+ // isAnyDragging(): boolean {
1462
+ // return this.coreFormDesignService.$isDragging();
1463
+ // }
1464
+ addSection() {
1465
+ this.coreFormDesignService.$placeholderSections.update(sections => [
1466
+ ...sections,
1467
+ {
1468
+ caption: `Section ${sections.length + 1}`,
1469
+ rows: [{ cells: [{ flexSize: 12 }] }]
1470
+ }
1471
+ ]);
1472
+ }
1473
+ /*deleteRow(sectionIndex: number, rowIndex: number): void {
1474
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1475
+ const section = sections[sectionIndex];
1476
+ if (section) {
1477
+ section.rows = section.rows.filter((x, index) => index !== rowIndex);
1478
+ }
1479
+ return sections;
1480
+ });
1481
+ }*/
1482
+ deleteSection(sectionIndex) {
1483
+ const sections = this.coreFormDesignService.$placeholderSections();
1484
+ const section = sections[sectionIndex];
1485
+ const hasControls = section?.rows?.some(row => row?.cells?.some(cell => !!cell?.control));
1486
+ if (hasControls) {
1487
+ const confirmed = confirm('This section contains controls. Are you sure you want to delete it?');
1488
+ if (!confirmed)
1489
+ return;
1490
+ }
1491
+ this.coreFormDesignService.$placeholderSections.update(prev => prev.filter((_, idx) => idx !== sectionIndex));
1492
+ }
1493
+ deleteRow(sectionIndex, rowIndex) {
1494
+ const sections = this.coreFormDesignService.$placeholderSections();
1495
+ const section = sections[sectionIndex];
1496
+ const row = section?.rows?.[rowIndex];
1497
+ if (!row)
1498
+ return; // safety check
1499
+ const hasControls = row.cells?.some(cell => !!cell?.control);
1500
+ if (hasControls) {
1501
+ const confirmed = confirm('This row contains controls. Are you sure you want to delete it?');
1502
+ if (!confirmed)
1503
+ return; // user canceled
1504
+ }
1505
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1506
+ return sections.map((section, sIdx) => {
1507
+ if (sIdx !== sectionIndex)
1508
+ return section;
1509
+ return {
1510
+ ...section,
1511
+ rows: (section.rows ?? []).filter((_, rIdx) => rIdx !== rowIndex)
1512
+ };
1513
+ });
1514
+ });
1515
+ }
1516
+ addRow(sectionIndex) {
1517
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1518
+ const section = sections[sectionIndex];
1519
+ if (section) {
1520
+ section.rows.push({ cells: [{ flexSize: 12 }] });
1521
+ }
1522
+ return sections;
1523
+ });
1524
+ }
1525
+ addColumn(row) {
1526
+ if (!row || row.cells.length >= 4)
1527
+ return;
1528
+ const usedFlex = row.cells.reduce((sum, c) => sum + (c.flexSize ?? 0), 0);
1529
+ // ✅ Case 1: Normal case – still space available
1530
+ if (usedFlex < 12) {
1531
+ const remaining = 12 - usedFlex;
1532
+ row.cells.push({ flexSize: Math.min(3, remaining) });
1533
+ return;
1534
+ }
1535
+ // 💥 Case 2: Full row — try to rebalance
1536
+ if (usedFlex === 12) {
1537
+ const count = row.cells.length;
1538
+ if (count === 1) {
1539
+ // 12 → 6 + 6
1540
+ row.cells[0].flexSize = 6;
1541
+ row.cells.push({ flexSize: 6 });
1542
+ return;
1543
+ }
1544
+ if (count === 2) {
1545
+ // 6 + 6 → 4 + 4 + 4
1546
+ row.cells.forEach(c => (c.flexSize = 4));
1547
+ row.cells.push({ flexSize: 4 });
1548
+ return;
1549
+ }
1550
+ if (count === 3) {
1551
+ // 4 + 4 + 4 → 3 + 3 + 3 + 3
1552
+ row.cells.forEach(c => (c.flexSize = 3));
1553
+ row.cells.push({ flexSize: 3 });
1554
+ return;
1555
+ }
1556
+ // ❌ Already 4 cells, each 3 — can’t split further
1557
+ return;
1558
+ }
1559
+ // 🔧 Optional fallback logic for unknown edge cases
1560
+ const maxIndex = row.cells.reduce((maxI, c, i, arr) => (c.flexSize ?? 0) > (arr[maxI]?.flexSize ?? 0) ? i : maxI, 0);
1561
+ const maxCell = row.cells[maxIndex];
1562
+ if ((maxCell?.flexSize ?? 0) <= 3)
1563
+ return; // nothing to shrink
1564
+ maxCell.flexSize -= 3;
1565
+ row.cells.push({ flexSize: 3 });
1566
+ }
1567
+ onCorePageHeaderButtonClicked(e) {
1568
+ if (e.code === EnumCoreButtonVNSCode.HEADER_SWITCH_VIEW) {
1569
+ this.coreFormDesignService.$mode.set(this.coreFormDesignService.$mode() === EnumFormDesignMode.Preview ? EnumFormDesignMode.Default : EnumFormDesignMode.Preview);
1570
+ }
1571
+ else if (e.code === EnumCoreButtonVNSCode.HEADER_SAVE) {
1572
+ }
1573
+ }
1574
+ closePreview() {
1575
+ this.coreFormDesignService.$mode.set(EnumFormDesignMode.Default);
1576
+ }
1577
+ onPreviewSubmit(e) {
1578
+ alert(JSON.stringify(e, null, 2));
1579
+ }
1580
+ onCellClicked(sectionIndex, rowIndex, colIndex) {
1581
+ const row = this.coreFormDesignService.$placeholderSections()[sectionIndex].rows[rowIndex];
1582
+ if (!!row) {
1583
+ // Toggle selection
1584
+ if (!!row.cells && row.cells.length > colIndex) {
1585
+ row.cells[colIndex].selected = !row.cells[colIndex].selected;
1586
+ }
1587
+ // Only allow max 2 selections
1588
+ const selected = row.cells.filter(c => c?.selected);
1589
+ if (selected.length > 2) {
1590
+ row.cells.forEach(c => c && (c.selected = false));
1591
+ row[colIndex].selected = true;
1592
+ }
1593
+ }
1594
+ }
1595
+ canMergeCells(sectionIndex, rowIndex) {
1596
+ const row = this.coreFormDesignService.$placeholderSections()[sectionIndex].rows[rowIndex];
1597
+ const selected = row?.cells.map((c, i) => ({ c, i })).filter(x => x.c?.selected);
1598
+ if (selected?.length !== 2)
1599
+ return false;
1600
+ const [a, b] = selected;
1601
+ if (a.c.control || b.c.control)
1602
+ return false;
1603
+ return Math.abs(a.i - b.i) === 1; // Must be neighbors
1604
+ }
1605
+ mergeCells(sectionIndex, rowIndex) {
1606
+ const row = this.coreFormDesignService.$placeholderSections()[sectionIndex].rows[rowIndex];
1607
+ if (!row)
1608
+ return;
1609
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1610
+ const selected = row.cells
1611
+ .map((c, i) => ({ c, i }))
1612
+ .filter(x => x.c?.selected);
1613
+ if (selected.length !== 2)
1614
+ return sections;
1615
+ const [a, b] = selected.sort((a, b) => a.i - b.i);
1616
+ const mergedFlex = (typeof a.c.flexSize === 'number' ? a.c.flexSize : 3) +
1617
+ (typeof b.c.flexSize === 'number' ? b.c.flexSize : 3);
1618
+ const mergedCell = {
1619
+ //control: { ...a.c.control, flexSize: mergedFlex }, // keep control data
1620
+ flexSize: mergedFlex,
1621
+ selected: false
1622
+ };
1623
+ row.cells.splice(a.i, 2, mergedCell); // replace both cells with one
1624
+ return sections;
1625
+ });
1626
+ }
1627
+ openSettingsForCell(cell) {
1628
+ this.coreFormDesignService.$selectedCell.set({ ...cell });
1629
+ }
1630
+ deleteField(row, colIndex) {
1631
+ if (!row || !row.cells[colIndex])
1632
+ return;
1633
+ const cellToDelete = row.cells[colIndex];
1634
+ if (!cellToDelete.control)
1635
+ return;
1636
+ if (confirm('Are you sure to remove the field?')) {
1637
+ // 🧠 Check if it's selected
1638
+ const selectedCell = this.coreFormDesignService.$selectedCell();
1639
+ const shouldClearSelection = selectedCell === cellToDelete;
1640
+ let deletedControl = null;
1641
+ // ✅ Update the reactive state
1642
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1643
+ for (const section of sections) {
1644
+ for (const r of section.rows) {
1645
+ if (r === row) {
1646
+ const control = r.cells[colIndex].control;
1647
+ if (control && control.field && control.flexSize !== undefined) {
1648
+ deletedControl = control; // ✅ Save before removing
1649
+ }
1650
+ r.cells[colIndex].control = undefined; // ❌ Clear after
1651
+ break;
1652
+ }
1653
+ }
1654
+ }
1655
+ return sections;
1656
+ });
1657
+ if (deletedControl) {
1658
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1659
+ for (const section of sections) {
1660
+ for (const row of section.rows) {
1661
+ if (!!row) {
1662
+ row.cells = row.cells.filter(cell => cell.control?.field !== deletedControl?.assignTo);
1663
+ }
1664
+ }
1665
+ }
1666
+ return sections;
1667
+ });
1668
+ }
1669
+ // ❌ Clear selection if needed
1670
+ if (shouldClearSelection) {
1671
+ this.coreFormDesignService.$selectedCell.set(null);
1672
+ }
1673
+ this.triggerUpdateSections();
1674
+ }
1675
+ }
1676
+ onCaptionEditEnd(index, event) {
1677
+ const newCaption = event.target.innerText.trim();
1678
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1679
+ sections[index].caption = newCaption;
1680
+ return sections;
1681
+ });
1682
+ }
1683
+ onFieldCaptionEditEnd(cell, event) {
1684
+ const element = event.target;
1685
+ const newLabel = element.innerText.trim();
1686
+ // Fallback if empty
1687
+ cell.control.label = newLabel || 'Unnamed Field';
1688
+ this.triggerUpdateSections();
1689
+ }
1690
+ insertSection() {
1691
+ }
1692
+ insertRow(sectionIndex, rowIndex) {
1693
+ const sections = this.coreFormDesignService.$placeholderSections();
1694
+ const section = sections[sectionIndex];
1695
+ if (!section)
1696
+ return;
1697
+ const newRow = {
1698
+ cells: [
1699
+ { flexSize: 12 },
1700
+ ]
1701
+ };
1702
+ section.rows.splice(rowIndex + 1, 0, newRow);
1703
+ this.coreFormDesignService.$placeholderSections.set([...sections]);
1704
+ }
1705
+ ngAfterViewInit() {
1706
+ this.listenerFn = this.renderer.listen('window', 'click', (e) => {
1707
+ const target = e.target;
1708
+ if (!this.settingPanel?.nativeElement.contains(target) &&
1709
+ !target.closest('.feather-settings') && !target.closest('.json-preview')) {
1710
+ this.coreFormDesignService.$fieldSettingPanelOpen.set(false);
1711
+ this.coreFormDesignService.$selectedCell.set(null);
1712
+ this.coreFormDesignService.$currentControlTemplate.set(null);
1713
+ this.coreFormDesignService.$currentControl.set(null);
1714
+ }
1715
+ this.cdr.markForCheck();
1716
+ });
1717
+ setTimeout(() => {
1718
+ this.subscriptions.push(this.route.params.subscribe(x => {
1719
+ let id = '0';
1720
+ try {
1721
+ id = atob(x['id']);
1722
+ this.coreFormDesignService.$afInstance.update(instance => ({
1723
+ ...instance,
1724
+ id
1725
+ }));
1726
+ }
1727
+ catch {
1728
+ return;
1729
+ }
1730
+ if (id !== '0') {
1731
+ this.coreFormDesignService.editMode$.next(EnumCorePageEditMode.UPDATE);
1732
+ this.coreFormDesignService.$submitText.set(EnumTranslateKey.UI_EDIT_FORM_BUTTON_SAVE);
1733
+ this.$loading.set(true);
1734
+ this.subscriptions.push(this.coreFormDesignService.getById(id)
1735
+ .pipe(catchError(err => {
1736
+ this.$loading.set(false);
1737
+ const msg = err?.error?.message || // API-defined message
1738
+ err?.message || // Native JS or HttpErrorResponse
1739
+ err?.statusText || // Fallback
1740
+ 'An unknown error occurred.';
1741
+ this.alertService.error(msg, noneAutoClosedAlertOptions);
1742
+ return of(msg);
1743
+ }))
1744
+ .subscribe(x => {
1745
+ this.$loading.set(false);
1746
+ if (x.ok && x.status === 200 && x.body?.statusCode === 200) {
1747
+ this.coreFormDesignService.$afInstance.set(this.coreFormDesignService.mapFromAfInstanceDTO(x.body.innerBody));
1748
+ this.coreFormDesignService.syncPlaceholderSectionsFromInstance();
1749
+ this.coreFormDesignService.$shouldPatchMetadataForm.set(true);
1750
+ }
1751
+ }));
1752
+ }
1753
+ else {
1754
+ }
1755
+ }));
1756
+ });
1757
+ }
1758
+ onControlParamsChange(updated) {
1759
+ this.coreFormDesignService.$placeholderSections.update(sections => {
1760
+ const cell = this.coreFormDesignService.$selectedCell();
1761
+ if (!cell)
1762
+ return sections;
1763
+ // Patch the selected cell
1764
+ Object.assign(cell.control, updated);
1765
+ return sections;
1766
+ });
1767
+ }
1768
+ get normalizedSelectedControl() {
1769
+ const cell = this.coreFormDesignService.$selectedCell();
1770
+ if (!cell?.control) {
1771
+ throw new Error('No control is currently selected.');
1772
+ }
1773
+ return this.coreFormDesignService.normalize(cell.control);
1774
+ }
1775
+ ngOnDestroy() {
1776
+ this.subscriptions.forEach(x => x?.unsubscribe());
1777
+ if (!!this.listenerFn)
1778
+ this.listenerFn();
1779
+ }
1780
+ triggerUpdateSections() {
1781
+ this.coreFormDesignService.$placeholderSections.set([...this.coreFormDesignService.$placeholderSections()]);
1782
+ }
1783
+ syncFormDesignWithSections() {
1784
+ const existingControls = Object.keys(this.formDesign.controls);
1785
+ const expectedControls = [];
1786
+ for (const section of this.coreFormDesignService.$placeholderSections()) {
1787
+ for (const row of section.rows) {
1788
+ for (const cell of row?.cells || []) {
1789
+ const control = cell?.control;
1790
+ if (control?.field) {
1791
+ expectedControls.push(control.field);
1792
+ if (!this.formDesign.contains(control.field)) {
1793
+ this.formDesign.addControl(control.field, new FormControl(control.value ?? null));
1794
+ }
1795
+ }
1796
+ }
1797
+ }
1798
+ }
1799
+ // 🧹 Remove controls that no longer exist
1800
+ for (const field of existingControls) {
1801
+ if (!expectedControls.includes(field)) {
1802
+ this.formDesign.removeControl(field);
1803
+ }
1804
+ }
1805
+ }
1806
+ isRequired(control) {
1807
+ if (!control || !control.validators)
1808
+ return false;
1809
+ return control.validators.some((v) => v.name === 'required' || v.name === 'requiredTrue');
1810
+ }
1811
+ filteredCells(row) {
1812
+ if (!row)
1813
+ return [];
1814
+ return row.cells.filter(cell => (cell?.flexSize ?? 0) > 0);
1815
+ }
1816
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormDesignComponent, deps: [{ token: MultiLanguageService }], target: i0.ɵɵFactoryTarget.Component }); }
1817
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.5", type: CoreFormDesignComponent, isStandalone: true, selector: "core-form-design", viewQueries: [{ propertyName: "settingPanel", first: true, predicate: ["settingPanel"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"core-form-design-container fs-13\">\r\n\r\n <core-page-header title=\"UI.COMPONENT_TITLE.WORKFLOW_FORM_DESIGN\" (buttonClick)=\"onCorePageHeaderButtonClicked($event)\"></core-page-header>\r\n\r\n <ng-template #formMetadata>\r\n <form-metadata></form-metadata>\r\n </ng-template>\r\n\r\n <aside class=\"af-metadata-overlay\" [@slideFromTopFadeIn]=\"coreFormDesignService.$showFormMetadata() ? 'in' : 'out'\"\r\n [class.shown]=\"coreFormDesignService.$showFormMetadata()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"formMetadata\"></ng-container>\r\n </aside>\r\n\r\n <div class=\"field-setting-panel\" [class.open]=\"coreFormDesignService.$fieldSettingPanelOpen()\" #settingPanel>\r\n @if (!!(this.coreFormDesignService.$selectedCell())) {\r\n <field-setting></field-setting>\r\n }\r\n </div>\r\n\r\n <div class=\"form-design-left\">\r\n\r\n @switch ($leftPanelMode()) {\r\n @case (enumLeftPanelMode.FieldCollection) {\r\n @for (category of controlCategories; track $index) {\r\n <div class=\"category-name\">\r\n {{ category.name }}\r\n </div>\r\n <ul>\r\n @for (control of category.controls; track $index) {\r\n <li draggable=\"true\" (dragstart)=\"onDragStart($event, control)\" [class.full-width]=\"control.controlType === 'SEEKER' || control.controlType === 'ATTACHMENT'\">\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n </li>\r\n <div class=\"space\"></div>\r\n }\r\n </ul>\r\n }\r\n }\r\n @case (enumLeftPanelMode.SelectedFieldJson) {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$currentControlJson() | tableCell : 'TRIM' : lang }}</pre>\r\n }\r\n }\r\n\r\n </div>\r\n\r\n <div class=\"form-design-right\">\r\n\r\n @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\">\r\n\r\n <div class=\"form-tool-bar\">\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\"></div>\r\n </div>\r\n\r\n <label contenteditable=\"true\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 3) + ' 1 0%' }\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"placeholder\">Drop here</div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete column'\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Insert row'\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <div class=\"form-wrapper live-form\" [ngStyle]=\"{\r\n width: !!coreFormDesignService.$afInstance().width ? coreFormDesignService.$afInstance().width + 'px' : 'unset'\r\n }\">\r\n <div class=\"live-form-header\">\r\n <core-page-header [title]=\"coreFormDesignService.$afInstance().captionCode | translate : lang\" [hideButtonGroup]=\"true\"></core-page-header>\r\n </div>\r\n <core-form [submitText]=\"'Kickoff'\" [inputSections]=\"$sections()\" [showCaptionButton]=\"true\" (onSubmit)=\"onPreviewSubmit($event)\" [mode$]=\"previewMode$\"></core-form>\r\n </div>\r\n } @else {\r\n\r\n <div class=\"modal-container\">\r\n <div class=\"modal-content-root no-padding\">\r\n\r\n <div class=\"form-wrapper live-form\" [ngStyle]=\"{\r\n width: !!coreFormDesignService.$afInstance().width ? coreFormDesignService.$afInstance().width + 'px' : 'unset'\r\n }\">\r\n <div class=\"live-form-header\">\r\n <core-page-header [title]=\"coreFormDesignService.$afInstance().captionCode | translate : lang\" [hideButtonGroup]=\"true\"></core-page-header>\r\n <div class=\"preview-close-icon\" (click)=\"closePreview()\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </div>\r\n <core-form [submitText]=\"'Kickoff'\" [inputSections]=\"$sections()\" [showCaptionButton]=\"true\" (onSubmit)=\"onPreviewSubmit($event)\" [mode$]=\"previewMode$\"></core-form>\r\n </div>\r\n \r\n </div>\r\n </div>\r\n }\r\n\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n }\r\n\r\n\r\n \r\n </div>\r\n @if ($loading()) {\r\n <app-fullscreen-modal-loader></app-fullscreen-modal-loader>\r\n }\r\n \r\n</div>", styles: ["@charset \"UTF-8\";.core-form-design-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-design-container .core-button-vns-container{background-color:#000;color:#fff}.core-form-design-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-design-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-design-container *{border-radius:0}.core-form-design-container ul,.core-form-design-container li{padding:0}.core-form-design-container li{max-width:200px}.core-form-design-container ul div.space{display:block;height:15px}.core-form-design-container li.full-width{max-width:100%}.core-form-design-container .field-setting-panel{display:block;position:fixed;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-core-page-header-height));top:calc(var(--size-core-page-header-height) + var(--size-header-height));right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out;z-index:99}.core-form-design-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-design-container .field-setting-panel.open{right:0}.core-form-design-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;color:#fff;overflow-y:hidden}.core-form-design-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-design-container .form-design-left .category-name{margin-bottom:15px}.core-form-design-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;border-radius:10px;box-shadow:0 2px 6px #00000014;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;overflow-x:auto;line-height:1.5;width:330px;height:calc(100vh - 155px)}.core-form-design-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-design-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px 15px 15px 375px}.core-form-design-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-design-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-design-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-design-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-design-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-design-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-design-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-design-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-design-container .no-padding{padding:0!important}.core-form-design-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FullscreenModalLoaderComponent, selector: "app-fullscreen-modal-loader", inputs: ["content"] }, { kind: "component", type: CorePageHeaderComponent, selector: "core-page-header", inputs: ["instanceNumber", "shownItems", "title", "hideButtonGroup"], outputs: ["buttonClick"] }, { kind: "component", type: FormMetadataComponent, selector: "form-metadata" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: TableCellPipe, name: "tableCell" }, { kind: "directive", type: TooltipDirective, selector: "[appTooltip]", inputs: ["color", "backgroundColor", "appTooltip", "showAnyway", "position"] }, { kind: "component", type: CoreFormComponent, selector: "core-form", inputs: ["formName", "width", "submitText", "leftInputSections", "leftInputSectionsFlexSize", "inputSections", "mode$", "bottomTemplateRef", "customFormButtonItems", "showCaptionButton", "disableSaveButton", "disableCancelButton", "checkError$", "hideButtons"], outputs: ["onFormCreated", "onFormRefCreated", "onSubmit", "onSave", "onCancal", "buttonClick"] }, { kind: "component", type: CoreControlComponent, selector: "core-control", inputs: ["control", "form", "checkError$", "rangeLimit"] }, { kind: "component", type: FieldSettingComponent, selector: "field-setting" }], animations: [slideFromTopFadeIn], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1818
+ }
1819
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.5", ngImport: i0, type: CoreFormDesignComponent, decorators: [{
1820
+ type: Component,
1821
+ args: [{ selector: 'core-form-design', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1822
+ NgStyle,
1823
+ NgTemplateOutlet,
1824
+ FullscreenModalLoaderComponent,
1825
+ CorePageHeaderComponent,
1826
+ FormMetadataComponent,
1827
+ ReactiveFormsModule,
1828
+ TranslatePipe,
1829
+ TableCellPipe,
1830
+ TooltipDirective,
1831
+ CoreFormComponent,
1832
+ CoreControlComponent,
1833
+ CoreDropdownComponent,
1834
+ CoreChecklistComponent,
1835
+ CoreFormControlSeekerComponent,
1836
+ CoreCheckboxComponent,
1837
+ CoreAttachmentComponent,
1838
+ CoreDatePickerComponent,
1839
+ CoreRadioGroupComponent,
1840
+ CoreMonthSelectorComponent,
1841
+ TooltipDirective,
1842
+ CoreCurrencyInputComponent,
1843
+ FieldSettingComponent,
1844
+ ], animations: [slideFromTopFadeIn], template: "<div class=\"core-form-design-container fs-13\">\r\n\r\n <core-page-header title=\"UI.COMPONENT_TITLE.WORKFLOW_FORM_DESIGN\" (buttonClick)=\"onCorePageHeaderButtonClicked($event)\"></core-page-header>\r\n\r\n <ng-template #formMetadata>\r\n <form-metadata></form-metadata>\r\n </ng-template>\r\n\r\n <aside class=\"af-metadata-overlay\" [@slideFromTopFadeIn]=\"coreFormDesignService.$showFormMetadata() ? 'in' : 'out'\"\r\n [class.shown]=\"coreFormDesignService.$showFormMetadata()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"formMetadata\"></ng-container>\r\n </aside>\r\n\r\n <div class=\"field-setting-panel\" [class.open]=\"coreFormDesignService.$fieldSettingPanelOpen()\" #settingPanel>\r\n @if (!!(this.coreFormDesignService.$selectedCell())) {\r\n <field-setting></field-setting>\r\n }\r\n </div>\r\n\r\n <div class=\"form-design-left\">\r\n\r\n @switch ($leftPanelMode()) {\r\n @case (enumLeftPanelMode.FieldCollection) {\r\n @for (category of controlCategories; track $index) {\r\n <div class=\"category-name\">\r\n {{ category.name }}\r\n </div>\r\n <ul>\r\n @for (control of category.controls; track $index) {\r\n <li draggable=\"true\" (dragstart)=\"onDragStart($event, control)\" [class.full-width]=\"control.controlType === 'SEEKER' || control.controlType === 'ATTACHMENT'\">\r\n <core-control [control]=\"control\" [form]=\"form\" [checkError$]=\"checkError$\"></core-control>\r\n </li>\r\n <div class=\"space\"></div>\r\n }\r\n </ul>\r\n }\r\n }\r\n @case (enumLeftPanelMode.SelectedFieldJson) {\r\n <pre class=\"json-preview\">{{ coreFormDesignService.$currentControlJson() | tableCell : 'TRIM' : lang }}</pre>\r\n }\r\n }\r\n\r\n </div>\r\n\r\n <div class=\"form-design-right\">\r\n\r\n @if (coreFormDesignService.$mode() === enumType.Default) {\r\n <div class=\"form-wrapper\">\r\n <form [formGroup]=\"formDesign\" autocomplete=\"off\">\r\n <div class=\"form-cells\">\r\n\r\n <div class=\"form-tool-bar\">\r\n <button class=\"core-button-vns-container\" (click)=\"addSection()\">+ Add Section</button>\r\n </div>\r\n \r\n @for (section of coreFormDesignService.$placeholderSections(); track $index; let sectionIndex = $index) {\r\n <div class=\"form-section-placeholder\">\r\n\r\n <div class=\"section-header\">\r\n\r\n <div class=\"section-img-wrapper\">\r\n <div class=\"section-img\"></div>\r\n </div>\r\n\r\n <label contenteditable=\"true\"\r\n (blur)=\"onCaptionEditEnd(sectionIndex, $event)\"\r\n (keydown.enter)=\"onCaptionEditEnd(sectionIndex, $event); $event.preventDefault()\"\r\n >{{ section.caption }}</label>\r\n\r\n <div class=\"section-tool pointer\" (click)=\"deleteSection(sectionIndex)\" [appTooltip]=\"'Delete section'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n \r\n </div>\r\n \r\n @for (row of section.rows; track $index; let rowIndex = $index) {\r\n\r\n <div class=\"form-row-wrapper\">\r\n <div class=\"form-row\">\r\n @for (cell of filteredCells(row); track $index; let colIndex = $index) {\r\n <div class=\"form-cell drop-target\" \r\n [ngStyle]=\"{ flex: (cell.flexSize ?? 3) + ' 1 0%' }\"\r\n (drop)=\"onDropIntoCell($event, sectionIndex, rowIndex, colIndex)\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragenter)=\"onDragEnter(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n (dragleave)=\"onDragLeave(sectionIndex + '_' + rowIndex + '_' + colIndex)\"\r\n [class.selected]=\"cell?.selected\"\r\n [class.dragging-over]=\"isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]\"\r\n [class.has-control]=\"!!cell && !!cell.control && !!getControl(cell)\"\r\n (click)=\"onCellClicked(sectionIndex, rowIndex, colIndex)\"\r\n >\r\n\r\n\r\n @if (!isDragOverMap[sectionIndex + '_' + rowIndex + '_' + colIndex]) {\r\n\r\n @if (!!cell && !!cell.control && !!getControl(cell)) {\r\n <label contenteditable=\"true\"\r\n (blur)=\"onFieldCaptionEditEnd(cell, $event)\"\r\n (keydown.enter)=\"onFieldCaptionEditEnd(cell, $event); $event.preventDefault()\"\r\n [class.d-none]=\"!!getControl(cell)?.hidden\"\r\n [class.required]=\"!!cell && !!cell.control && !!getControl(cell) && isRequired(getControl(cell))\"\r\n >{{ cell.control.label || 'label' }}</label>\r\n <core-control \r\n [control]=\"getControl(cell)!\" \r\n [form]=\"formDesign\"\r\n [checkError$]=\"checkError$\" />\r\n \r\n <div class=\"field-toolbar\">\r\n <ul>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"openSettingsForCell(cell)\" [appTooltip]=\"'Show settings'\">\r\n <i class=\"feather-settings\"></i>\r\n </div>\r\n </li>\r\n <li>\r\n <div class=\"field-tool pointer\" (click)=\"deleteField(row, colIndex)\" [appTooltip]=\"'Remove field from cell'\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n \r\n } @else {\r\n <div class=\"placeholder\">Drop here</div>\r\n }\r\n\r\n @if (cell?.selected && canMergeCells(sectionIndex, rowIndex)) {\r\n <div class=\"merge-toolbar\">\r\n <button (click)=\"mergeCells(sectionIndex, rowIndex)\">\uD83D\uDD17 Merge</button>\r\n </div>\r\n }\r\n \r\n }\r\n\r\n </div>\r\n }\r\n </div>\r\n <div class=\"row-tool-bar\">\r\n <div class=\"icon-wrapper\" (click)=\"deleteRow(sectionIndex, rowIndex)\" [appTooltip]=\"'Delete column'\"><i class=\"feather-x\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Add row'\"><i class=\"feather-arrow-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addRow(sectionIndex)\" [appTooltip]=\"'Insert row'\"><i class=\"feather-corner-right-down\"></i></div>\r\n <div class=\"icon-wrapper\" (click)=\"addColumn(row)\" [appTooltip]=\"'Add column'\"><i class=\"feather-arrow-right\"></i></div>\r\n </div>\r\n </div>\r\n\r\n }\r\n </div>\r\n }\r\n \r\n \r\n </div>\r\n </form>\r\n </div>\r\n } @else if (!!$sections()) {\r\n\r\n\r\n @if (!!coreFormDesignService.$afInstance().normalMode) {\r\n <div class=\"form-wrapper live-form\" [ngStyle]=\"{\r\n width: !!coreFormDesignService.$afInstance().width ? coreFormDesignService.$afInstance().width + 'px' : 'unset'\r\n }\">\r\n <div class=\"live-form-header\">\r\n <core-page-header [title]=\"coreFormDesignService.$afInstance().captionCode | translate : lang\" [hideButtonGroup]=\"true\"></core-page-header>\r\n </div>\r\n <core-form [submitText]=\"'Kickoff'\" [inputSections]=\"$sections()\" [showCaptionButton]=\"true\" (onSubmit)=\"onPreviewSubmit($event)\" [mode$]=\"previewMode$\"></core-form>\r\n </div>\r\n } @else {\r\n\r\n <div class=\"modal-container\">\r\n <div class=\"modal-content-root no-padding\">\r\n\r\n <div class=\"form-wrapper live-form\" [ngStyle]=\"{\r\n width: !!coreFormDesignService.$afInstance().width ? coreFormDesignService.$afInstance().width + 'px' : 'unset'\r\n }\">\r\n <div class=\"live-form-header\">\r\n <core-page-header [title]=\"coreFormDesignService.$afInstance().captionCode | translate : lang\" [hideButtonGroup]=\"true\"></core-page-header>\r\n <div class=\"preview-close-icon\" (click)=\"closePreview()\">\r\n <i class=\"feather-x\"></i>\r\n </div>\r\n </div>\r\n <core-form [submitText]=\"'Kickoff'\" [inputSections]=\"$sections()\" [showCaptionButton]=\"true\" (onSubmit)=\"onPreviewSubmit($event)\" [mode$]=\"previewMode$\"></core-form>\r\n </div>\r\n \r\n </div>\r\n </div>\r\n }\r\n\r\n\r\n } @else {\r\n <h2>$sections() empty / null / undefined</h2>\r\n }\r\n\r\n\r\n \r\n </div>\r\n @if ($loading()) {\r\n <app-fullscreen-modal-loader></app-fullscreen-modal-loader>\r\n }\r\n \r\n</div>", styles: ["@charset \"UTF-8\";.core-form-design-container{position:relative;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));width:100%;overflow:hidden;background-color:#eff0f1;font-size:13px}.core-form-design-container .core-button-vns-container{background-color:#000;color:#fff}.core-form-design-container .af-metadata-overlay{position:fixed;top:60px;left:66px;background:#fff;box-shadow:.4rem 0 2rem #0000002e;z-index:1000;width:1214px;height:calc(100vh - 75px);overflow-y:auto;pointer-events:none}.core-form-design-container .af-metadata-overlay.shown{pointer-events:auto}.core-form-design-container *{border-radius:0}.core-form-design-container ul,.core-form-design-container li{padding:0}.core-form-design-container li{max-width:200px}.core-form-design-container ul div.space{display:block;height:15px}.core-form-design-container li.full-width{max-width:100%}.core-form-design-container .field-setting-panel{display:block;position:fixed;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-core-page-header-height));top:calc(var(--size-core-page-header-height) + var(--size-header-height));right:-360px;background-color:#fff;box-shadow:.4rem 0 2rem #0000002e;transition:right .5s ease-out;z-index:99}.core-form-design-container .field-setting-panel .panel-caption{margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid #ddd;width:100%;overflow:hidden;text-wrap:nowrap;text-overflow:ellipsis}.core-form-design-container .field-setting-panel.open{right:0}.core-form-design-container .form-design-left{position:absolute;top:var(--size-core-page-header-height);bottom:0;left:0;z-index:1;width:360px;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px;padding-right:calc(15px + var(--size-scrollbar-width));background-color:#87ceeb;color:#fff;overflow-y:hidden}.core-form-design-container .form-design-left ul:last-child{padding-bottom:400px}.core-form-design-container .form-design-left .category-name{margin-bottom:15px}.core-form-design-container .form-design-left .json-preview{background-color:#fff;color:#333;padding:1rem 1.5rem;border-radius:10px;box-shadow:0 2px 6px #00000014;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;overflow-x:auto;line-height:1.5;width:330px;height:calc(100vh - 155px)}.core-form-design-container .form-design-left:hover{overflow-y:auto;padding-right:15px}.core-form-design-container .form-design-right{width:100%;height:calc(100vh - var(--size-header-height) - var(--size-layout-block-cell-spacing));padding:15px 15px 15px 375px}.core-form-design-container .form-design-right .form-wrapper{width:100%;overflow-y:visible;background-color:#fff}.core-form-design-container .form-design-right .form-wrapper button{margin-left:12px;padding:4px 10px;border:1px solid #ccc;cursor:pointer;transition:all .2s;width:110px}.core-form-design-container .form-design-right .form-wrapper button:hover{background-color:#e4f0ff;border-color:#007bff;color:#007bff}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar{display:flex;align-items:center;justify-content:flex-end}.core-form-design-container .form-design-right .form-wrapper .form-tool-bar>button{width:150px;margin:0}.core-form-design-container .form-design-right .form-wrapper .form-cells{display:flex;flex-direction:column;gap:32px;padding:20px 15px 15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder{padding:12px 15px;border:1px dashed #ccc;background-color:#fff;box-shadow:0 2px 6px #0000000a}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header{display:flex;align-items:center;justify-content:flex-start;font-weight:600;margin-bottom:12px;color:#333}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-img{width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center;margin-right:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-section-placeholder .section-header .section-tool i{font-size:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .row-tool-bar{display:flex;align-items:center;justify-content:flex-end;margin-bottom:8px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-row{display:flex;gap:15px;margin-bottom:15px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell{flex:1;min-height:90px;background-color:#fcfcfc;border:1px dashed #ccc;position:relative;padding:20px 10px 10px;transition:border .2s ease-in-out}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell label.required:after{content:\" *\";color:#ff040b}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar{position:absolute;right:7px;top:6px;display:none;z-index:2;color:gray}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div{display:flex;width:24px;height:24px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell .field-toolbar ul li div i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.has-control:hover .field-toolbar{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .form-cell.active-drop{border-color:#007bff;background-color:#eef6ff;transition:.2s}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .placeholder{display:flex;align-items:center;justify-content:center;background-color:#fff;color:#007bff;padding:15px 0;width:100%;cursor:default}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper{width:24px;height:24px;border-radius:50%;padding:0;cursor:pointer;display:none;color:gray;border:1px solid gray;margin-left:8px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper .icon-wrapper i{font-size:18px;width:18px;height:18px}.core-form-design-container .form-design-right .form-wrapper .form-cells .form-row-wrapper:hover .icon-wrapper{display:flex}.core-form-design-container .form-design-right .form-wrapper .form-cell.selected{background-color:#dff6dd}.core-form-design-container .form-design-right .form-wrapper .merge-toolbar{text-align:center;margin-top:4px}.core-form-design-container .form-design-right .form-wrapper.live-form{padding-bottom:15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header{padding:0 15px}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon{position:absolute;right:7px;top:6px;z-index:2;color:gray;cursor:pointer}.core-form-design-container .form-design-right .form-wrapper.live-form .live-form-header .preview-close-icon i{font-size:18px}.core-form-design-container .drop-target{min-height:50px;min-width:50px;border:2px dashed transparent;transition:border .2s ease}.core-form-design-container .drop-target.active-drop{border-color:#007bff;background-color:#eaf4ff}.core-form-design-container .no-padding{padding:0!important}.core-form-design-container .modal-content-root{overflow:visible}\n", ".core-form-container{overflow-x:visible}.core-form-container>form .section{margin-top:var(--size-layout-block-cell-spacing)}.core-form-container>form .section:not(:first-child){margin-top:calc(var(--size-layout-block-cell-spacing) * 2)}.core-form-container>form .section .section-header-label{display:block;height:34px;line-height:34px;margin-bottom:15px;margin-left:12px}.core-form-container>form .section .section-header-label .section-img-wrapper{position:relative}.core-form-container>form .section .section-header-label .section-img-wrapper .section-img{position:absolute;width:34px;height:34px;border-radius:50%;background-color:#d3d3d3;float:left;background-image:url(/assets/images/info.svg);background-repeat:no-repeat;background-position:center}.core-form-container>form .section .section-header-label .section-caption{padding-left:40px;font-weight:700;color:#696969}.core-form-container .row{margin-left:var(--size-layout-block-cell-spacing) 0px;margin-right:var(--size-layout-block-cell-spacing) 0px}.core-form-container .row .grid-buffer{border:dotted 2px darkgray}.core-form-container .row .button-control{display:flex;align-items:flex-end}.core-form-container .form-row{margin:var(--size-layout-block-cell-spacing) 0px;display:flex;align-items:center;justify-content:center}.core-form-container .form-row>button{cursor:pointer;border-radius:0}.core-form-container .form-row>button:not(:first-child){margin-left:var(--size-layout-block-cell-spacing)}.core-form-container .dev-button{cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;padding:8px;width:120px;border-radius:18px;box-shadow:.4rem 0 2rem #0000002e}.core-form-container .dev-button:not(:last-child){margin-right:15px}.core-form-container .dev-button:first-child{background-color:#dff6dd;border:1px #9fdc9d solid}.core-form-container .dev-button:last-child{background-color:#fff4ce;border:1px #ffda6a solid}.core-form-container .payload-preview{display:block;width:calc(100% - 48px);height:200px;white-space:pre-wrap;overflow-x:hidden;overflow-y:auto;background-color:#dff6dd;padding:24px;margin:24px;text-indent:-58px;color:#333!important;font-family:Fira Code,monospace;font-size:.85rem;word-break:keep-all;line-height:1.5}.core-form-container .payload-preview.validator-preview{background-color:#fff4ce}.core-form-container .bottom-template-wrapper{padding-left:12px;padding-right:12px}.core-form-container .w-100{width:100%}.core-form-container .pr18{padding-right:18px}\n", ".core-button-vns-container{height:30px;display:flex;align-items:center;justify-content:center;min-width:30px}.core-button-vns-container .action-wrapper{height:30px!important;width:30px!important;display:flex;align-items:center;justify-content:center}.core-button-vns-container .action-wrapper:has(i:hover){background-color:#e7e7e7;border-radius:50%}.core-button-vns-container .btn-for-form{border:none;border-radius:0;background-color:transparent;color:#000;min-width:120px}.core-button-vns-container button.last-child{background-color:#000;color:#fff}.core-button-vns-container .action-wrapper.last-child{background-color:var(--color-basic-orange);color:#fff;border-radius:50%}.core-button-vns-container .action-wrapper.last-child:hover{background-color:var(--color-basic-orange);box-shadow:0 1rem 3rem #0000002e}.core-button-vns-container .temporary-unavailable{user-select:none;-moz-user-select:none;-webkit-user-select:none;cursor:not-allowed!important;opacity:.5}.core-button-vns-container .temporary-unavailable:hover{background-color:transparent!important}\n"] }]
1845
+ }], ctorParameters: () => [{ type: MultiLanguageService }], propDecorators: { settingPanel: [{
1846
+ type: ViewChild,
1847
+ args: ['settingPanel']
1848
+ }] } });
1849
+
1850
+ export { CoreFormDesignComponent };
1851
+ //# sourceMappingURL=ngx-histaff-alpha-core-form-design.component-BVDW_HiI.mjs.map