@flusys/ng-form-builder 0.1.0-alpha.1
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.
|
@@ -0,0 +1,2269 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { Type, model } from '@angular/core';
|
|
3
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
4
|
+
import * as _flusys_ng_form_builder from '@flusys/ng-form-builder';
|
|
5
|
+
import { FileSelectEvent, FileRemoveEvent } from 'primeng/fileupload';
|
|
6
|
+
import { CdkDragStart, CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
7
|
+
import { MenuItem } from 'primeng/api';
|
|
8
|
+
import { Routes } from '@angular/router';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Supported field types for form builder
|
|
12
|
+
*/
|
|
13
|
+
declare enum FieldType {
|
|
14
|
+
TEXT = "text",
|
|
15
|
+
NUMBER = "number",
|
|
16
|
+
EMAIL = "email",
|
|
17
|
+
CHECKBOX = "checkbox",
|
|
18
|
+
RADIO = "radio",
|
|
19
|
+
DROPDOWN = "dropdown",
|
|
20
|
+
MULTI_SELECT = "multi_select",
|
|
21
|
+
DATE = "date",
|
|
22
|
+
LIKERT = "likert",
|
|
23
|
+
RATING = "rating",
|
|
24
|
+
FILE_UPLOAD = "file_upload"
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Field type metadata for UI display
|
|
28
|
+
*/
|
|
29
|
+
interface IFieldTypeInfo {
|
|
30
|
+
type: FieldType;
|
|
31
|
+
label: string;
|
|
32
|
+
icon: string;
|
|
33
|
+
category: 'input' | 'selection' | 'specialized';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Default field type information for palette display
|
|
37
|
+
*/
|
|
38
|
+
declare const FIELD_TYPE_INFO: IFieldTypeInfo[];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Section layout types
|
|
42
|
+
*/
|
|
43
|
+
declare enum LayoutType {
|
|
44
|
+
FLEX = "flex",
|
|
45
|
+
GRID = "grid"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validation rule types
|
|
50
|
+
*/
|
|
51
|
+
declare enum ValidationRuleType {
|
|
52
|
+
REQUIRED = "required",
|
|
53
|
+
MIN_LENGTH = "min_length",
|
|
54
|
+
MAX_LENGTH = "max_length",
|
|
55
|
+
MIN = "min",
|
|
56
|
+
MAX = "max",
|
|
57
|
+
PATTERN = "pattern",
|
|
58
|
+
EMAIL = "email",
|
|
59
|
+
CUSTOM = "custom"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Logic group operators for combining conditions
|
|
64
|
+
*/
|
|
65
|
+
declare enum LogicOperator {
|
|
66
|
+
AND = "AND",
|
|
67
|
+
OR = "OR"
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Comparison operators for field conditions
|
|
71
|
+
*/
|
|
72
|
+
declare enum ComparisonOperator {
|
|
73
|
+
EQUALS = "equals",
|
|
74
|
+
NOT_EQUALS = "not_equals",
|
|
75
|
+
CONTAINS = "contains",
|
|
76
|
+
NOT_CONTAINS = "not_contains",
|
|
77
|
+
GREATER_THAN = "greater_than",
|
|
78
|
+
LESS_THAN = "less_than",
|
|
79
|
+
GREATER_OR_EQUAL = "greater_or_equal",
|
|
80
|
+
LESS_OR_EQUAL = "less_or_equal",
|
|
81
|
+
IS_EMPTY = "is_empty",
|
|
82
|
+
IS_NOT_EMPTY = "is_not_empty",
|
|
83
|
+
IN = "in",
|
|
84
|
+
NOT_IN = "not_in"
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Actions that can be triggered by conditional logic
|
|
88
|
+
*/
|
|
89
|
+
declare enum LogicAction {
|
|
90
|
+
SHOW = "show",
|
|
91
|
+
HIDE = "hide",
|
|
92
|
+
REQUIRE = "require",
|
|
93
|
+
SKIP = "skip",
|
|
94
|
+
JUMP = "jump"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* ID-based option for selection fields (radio, dropdown, multi-select, etc.)
|
|
99
|
+
* Using ID-based approach allows safe logic evaluation and multi-language support.
|
|
100
|
+
*/
|
|
101
|
+
interface IFieldOption {
|
|
102
|
+
/** Unique identifier - stored as value in submissions */
|
|
103
|
+
id: string;
|
|
104
|
+
/** Display text shown to users */
|
|
105
|
+
label: string;
|
|
106
|
+
/** Sort order */
|
|
107
|
+
order: number;
|
|
108
|
+
/** Whether this option is selected by default */
|
|
109
|
+
isDefault?: boolean;
|
|
110
|
+
/** Whether this option is disabled */
|
|
111
|
+
disabled?: boolean;
|
|
112
|
+
/** Optional additional data */
|
|
113
|
+
value?: unknown;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Field validation configuration
|
|
118
|
+
*/
|
|
119
|
+
interface IFieldValidation {
|
|
120
|
+
rules: IValidationRule[];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Single validation rule
|
|
124
|
+
*/
|
|
125
|
+
interface IValidationRule {
|
|
126
|
+
/** Type of validation */
|
|
127
|
+
type: ValidationRuleType;
|
|
128
|
+
/** Rule-specific value (min, max, pattern, etc.) */
|
|
129
|
+
value?: unknown;
|
|
130
|
+
/** Custom error message */
|
|
131
|
+
message?: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Required validation rule
|
|
135
|
+
*/
|
|
136
|
+
interface IRequiredRule extends IValidationRule {
|
|
137
|
+
type: ValidationRuleType.REQUIRED;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Minimum length validation rule
|
|
141
|
+
*/
|
|
142
|
+
interface IMinLengthRule extends IValidationRule {
|
|
143
|
+
type: ValidationRuleType.MIN_LENGTH;
|
|
144
|
+
value: number;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Maximum length validation rule
|
|
148
|
+
*/
|
|
149
|
+
interface IMaxLengthRule extends IValidationRule {
|
|
150
|
+
type: ValidationRuleType.MAX_LENGTH;
|
|
151
|
+
value: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Minimum value validation rule
|
|
155
|
+
*/
|
|
156
|
+
interface IMinRule extends IValidationRule {
|
|
157
|
+
type: ValidationRuleType.MIN;
|
|
158
|
+
value: number;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Maximum value validation rule
|
|
162
|
+
*/
|
|
163
|
+
interface IMaxRule extends IValidationRule {
|
|
164
|
+
type: ValidationRuleType.MAX;
|
|
165
|
+
value: number;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Pattern validation rule
|
|
169
|
+
*/
|
|
170
|
+
interface IPatternRule extends IValidationRule {
|
|
171
|
+
type: ValidationRuleType.PATTERN;
|
|
172
|
+
value: string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Email validation rule
|
|
176
|
+
*/
|
|
177
|
+
interface IEmailRule extends IValidationRule {
|
|
178
|
+
type: ValidationRuleType.EMAIL;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Custom validation rule
|
|
182
|
+
*/
|
|
183
|
+
interface ICustomRule extends IValidationRule {
|
|
184
|
+
type: ValidationRuleType.CUSTOM;
|
|
185
|
+
/** Custom validator function name */
|
|
186
|
+
value: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Conditional rule for showing/hiding fields or sections
|
|
191
|
+
* Supports AND/OR logic with nested groups
|
|
192
|
+
*/
|
|
193
|
+
interface IConditionalRule {
|
|
194
|
+
/** Action to perform when conditions are met */
|
|
195
|
+
action: LogicAction;
|
|
196
|
+
/** Logic group containing conditions */
|
|
197
|
+
logic: ILogicGroup;
|
|
198
|
+
/** Target field or section ID (for jump/skip actions) */
|
|
199
|
+
targetId?: string;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Logic group - combines conditions with AND/OR
|
|
203
|
+
*/
|
|
204
|
+
interface ILogicGroup {
|
|
205
|
+
/** Operator to combine conditions */
|
|
206
|
+
operator: LogicOperator;
|
|
207
|
+
/** Array of conditions or nested groups */
|
|
208
|
+
conditions: Array<ICondition | ILogicGroup>;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Single condition - evaluates a field value
|
|
212
|
+
*/
|
|
213
|
+
interface ICondition {
|
|
214
|
+
/** Reference to the field being evaluated */
|
|
215
|
+
fieldId: string;
|
|
216
|
+
/** Comparison operator */
|
|
217
|
+
comparison: ComparisonOperator;
|
|
218
|
+
/** Value to compare against */
|
|
219
|
+
value: unknown;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Type guard to check if a condition is a nested group
|
|
223
|
+
*/
|
|
224
|
+
declare function isLogicGroup(item: ICondition | ILogicGroup): item is ILogicGroup;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Section layout configuration
|
|
228
|
+
*/
|
|
229
|
+
interface ISectionLayout {
|
|
230
|
+
/** Layout type */
|
|
231
|
+
type: LayoutType;
|
|
232
|
+
/** Layout-specific configuration */
|
|
233
|
+
config: IFlexLayout | IGridLayout;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Flex layout configuration
|
|
237
|
+
*/
|
|
238
|
+
interface IFlexLayout {
|
|
239
|
+
/** Flex direction */
|
|
240
|
+
direction: 'row' | 'column';
|
|
241
|
+
/** Whether items should wrap */
|
|
242
|
+
wrap: boolean;
|
|
243
|
+
/** Gap between items (CSS value) */
|
|
244
|
+
gap: string;
|
|
245
|
+
/** Align items property */
|
|
246
|
+
alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch';
|
|
247
|
+
/** Justify content property */
|
|
248
|
+
justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around';
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Grid layout configuration
|
|
252
|
+
*/
|
|
253
|
+
interface IGridLayout {
|
|
254
|
+
/** Number of columns */
|
|
255
|
+
columns: number;
|
|
256
|
+
/** Gap between items (CSS value) */
|
|
257
|
+
gap: string;
|
|
258
|
+
/** Row gap (optional, overrides gap for rows) */
|
|
259
|
+
rowGap?: string;
|
|
260
|
+
/** Column gap (optional, overrides gap for columns) */
|
|
261
|
+
columnGap?: string;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Default flex layout
|
|
265
|
+
*/
|
|
266
|
+
declare const DEFAULT_FLEX_LAYOUT: IFlexLayout;
|
|
267
|
+
/**
|
|
268
|
+
* Default grid layout
|
|
269
|
+
*/
|
|
270
|
+
declare const DEFAULT_GRID_LAYOUT: IGridLayout;
|
|
271
|
+
/**
|
|
272
|
+
* Default section layout
|
|
273
|
+
*/
|
|
274
|
+
declare const DEFAULT_SECTION_LAYOUT: ISectionLayout;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Field width options for responsive layouts
|
|
278
|
+
*/
|
|
279
|
+
type FieldWidth = 'full' | 'half' | 'third' | 'quarter';
|
|
280
|
+
/**
|
|
281
|
+
* Base field interface - all fields extend this
|
|
282
|
+
*/
|
|
283
|
+
interface IBaseField {
|
|
284
|
+
/** Unique field identifier */
|
|
285
|
+
id: string;
|
|
286
|
+
/** Field type */
|
|
287
|
+
type: FieldType;
|
|
288
|
+
/** Internal name (unique within form) */
|
|
289
|
+
name: string;
|
|
290
|
+
/** Display label */
|
|
291
|
+
label: string;
|
|
292
|
+
/** Optional description/help text */
|
|
293
|
+
description?: string;
|
|
294
|
+
/** Placeholder text */
|
|
295
|
+
placeholder?: string;
|
|
296
|
+
/** Default value */
|
|
297
|
+
defaultValue?: unknown;
|
|
298
|
+
/** Validation rules */
|
|
299
|
+
validation?: IFieldValidation;
|
|
300
|
+
/** Conditional logic for show/hide */
|
|
301
|
+
conditionalLogic?: IConditionalRule;
|
|
302
|
+
/** Sort order within section */
|
|
303
|
+
order: number;
|
|
304
|
+
/** Field width in grid layout */
|
|
305
|
+
width?: FieldWidth;
|
|
306
|
+
/** Whether the field is required */
|
|
307
|
+
required?: boolean;
|
|
308
|
+
/** Additional metadata */
|
|
309
|
+
metadata?: Record<string, unknown>;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Text field configuration
|
|
313
|
+
*/
|
|
314
|
+
interface ITextField extends IBaseField {
|
|
315
|
+
type: FieldType.TEXT;
|
|
316
|
+
defaultValue?: string;
|
|
317
|
+
/** Maximum character length */
|
|
318
|
+
maxLength?: number;
|
|
319
|
+
/** Minimum character length */
|
|
320
|
+
minLength?: number;
|
|
321
|
+
/** Number of rows (1 = single line, >1 = textarea) */
|
|
322
|
+
rows?: number;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Number field configuration
|
|
326
|
+
*/
|
|
327
|
+
interface INumberField extends IBaseField {
|
|
328
|
+
type: FieldType.NUMBER;
|
|
329
|
+
defaultValue?: number;
|
|
330
|
+
/** Minimum value */
|
|
331
|
+
min?: number;
|
|
332
|
+
/** Maximum value */
|
|
333
|
+
max?: number;
|
|
334
|
+
/** Step increment */
|
|
335
|
+
step?: number;
|
|
336
|
+
/** Prefix symbol (e.g., '$') */
|
|
337
|
+
prefix?: string;
|
|
338
|
+
/** Suffix symbol (e.g., 'kg') */
|
|
339
|
+
suffix?: string;
|
|
340
|
+
/** Show increment/decrement buttons */
|
|
341
|
+
showButtons?: boolean;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Email field configuration
|
|
345
|
+
*/
|
|
346
|
+
interface IEmailField extends IBaseField {
|
|
347
|
+
type: FieldType.EMAIL;
|
|
348
|
+
defaultValue?: string;
|
|
349
|
+
/** Regex pattern for custom email validation (e.g., '@company\\.com$' for company emails) */
|
|
350
|
+
pattern?: string;
|
|
351
|
+
/** Custom error message when pattern validation fails */
|
|
352
|
+
patternMessage?: string;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Checkbox field (single boolean)
|
|
356
|
+
*/
|
|
357
|
+
interface ICheckboxField extends IBaseField {
|
|
358
|
+
type: FieldType.CHECKBOX;
|
|
359
|
+
defaultValue?: boolean;
|
|
360
|
+
/** Label displayed next to checkbox */
|
|
361
|
+
checkboxLabel?: string;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Radio field - single selection from options
|
|
365
|
+
*/
|
|
366
|
+
interface IRadioField extends IBaseField {
|
|
367
|
+
type: FieldType.RADIO;
|
|
368
|
+
/** Available options */
|
|
369
|
+
options: IFieldOption[];
|
|
370
|
+
/** Default selected option ID */
|
|
371
|
+
defaultValue?: string;
|
|
372
|
+
/** Display layout */
|
|
373
|
+
displayLayout?: 'vertical' | 'horizontal';
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Dropdown field - single selection
|
|
377
|
+
*/
|
|
378
|
+
interface IDropdownField extends IBaseField {
|
|
379
|
+
type: FieldType.DROPDOWN;
|
|
380
|
+
/** Available options */
|
|
381
|
+
options: IFieldOption[];
|
|
382
|
+
/** Default selected option ID */
|
|
383
|
+
defaultValue?: string;
|
|
384
|
+
/** Enable search/filter */
|
|
385
|
+
searchable?: boolean;
|
|
386
|
+
/** Show clear button */
|
|
387
|
+
showClear?: boolean;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Multi-select field - multiple selection
|
|
391
|
+
*/
|
|
392
|
+
interface IMultiSelectField extends IBaseField {
|
|
393
|
+
type: FieldType.MULTI_SELECT;
|
|
394
|
+
/** Available options */
|
|
395
|
+
options: IFieldOption[];
|
|
396
|
+
/** Default selected option IDs */
|
|
397
|
+
defaultValue?: string[];
|
|
398
|
+
/** Maximum number of selections */
|
|
399
|
+
maxSelections?: number;
|
|
400
|
+
/** Display mode */
|
|
401
|
+
display?: 'comma' | 'chip';
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Date field configuration
|
|
405
|
+
*/
|
|
406
|
+
interface IDateField extends IBaseField {
|
|
407
|
+
type: FieldType.DATE;
|
|
408
|
+
/** Default date (ISO string) */
|
|
409
|
+
defaultValue?: string;
|
|
410
|
+
/** Minimum selectable date (ISO string) */
|
|
411
|
+
minDate?: string;
|
|
412
|
+
/** Maximum selectable date (ISO string) */
|
|
413
|
+
maxDate?: string;
|
|
414
|
+
/** Include time selection */
|
|
415
|
+
showTime?: boolean;
|
|
416
|
+
/** Date format string */
|
|
417
|
+
dateFormat?: string;
|
|
418
|
+
/** Selection mode */
|
|
419
|
+
selectionMode?: 'single' | 'range' | 'multiple';
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Likert scale row
|
|
423
|
+
*/
|
|
424
|
+
interface ILikertRow {
|
|
425
|
+
id: string;
|
|
426
|
+
label: string;
|
|
427
|
+
order: number;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Likert scale field configuration
|
|
431
|
+
*/
|
|
432
|
+
interface ILikertField extends IBaseField {
|
|
433
|
+
type: FieldType.LIKERT;
|
|
434
|
+
/** Row labels (questions) */
|
|
435
|
+
rows: ILikertRow[];
|
|
436
|
+
/** Scale labels (e.g., ['Strongly Disagree', ..., 'Strongly Agree']) */
|
|
437
|
+
scaleLabels: string[];
|
|
438
|
+
/** Minimum scale value */
|
|
439
|
+
scaleMin: number;
|
|
440
|
+
/** Maximum scale value */
|
|
441
|
+
scaleMax: number;
|
|
442
|
+
/** Default values by row ID */
|
|
443
|
+
defaultValue?: Record<string, number>;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Rating field configuration
|
|
447
|
+
*/
|
|
448
|
+
interface IRatingField extends IBaseField {
|
|
449
|
+
type: FieldType.RATING;
|
|
450
|
+
/** Maximum rating value (number of stars) */
|
|
451
|
+
maxRating: number;
|
|
452
|
+
/** Icon class (PrimeIcon) */
|
|
453
|
+
icon?: string;
|
|
454
|
+
/** Default rating value */
|
|
455
|
+
defaultValue?: number;
|
|
456
|
+
/** Allow half ratings */
|
|
457
|
+
allowHalf?: boolean;
|
|
458
|
+
/** Allow cancel/clear */
|
|
459
|
+
allowCancel?: boolean;
|
|
460
|
+
/** Label shown on the left (min) side */
|
|
461
|
+
minLabel?: string;
|
|
462
|
+
/** Label shown on the right (max) side */
|
|
463
|
+
maxLabel?: string;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* File upload field configuration
|
|
467
|
+
*/
|
|
468
|
+
interface IFileUploadField extends IBaseField {
|
|
469
|
+
type: FieldType.FILE_UPLOAD;
|
|
470
|
+
/** Accepted MIME types */
|
|
471
|
+
accept?: string[];
|
|
472
|
+
/** Maximum number of files */
|
|
473
|
+
maxFiles?: number;
|
|
474
|
+
/** Maximum file size in bytes */
|
|
475
|
+
maxFileSize?: number;
|
|
476
|
+
/** Allow multiple files */
|
|
477
|
+
multiple?: boolean;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Union type for all field types
|
|
481
|
+
*/
|
|
482
|
+
type IField = ITextField | INumberField | IEmailField | ICheckboxField | IRadioField | IDropdownField | IMultiSelectField | IDateField | ILikertField | IRatingField | IFileUploadField;
|
|
483
|
+
/**
|
|
484
|
+
* Type guard for fields with options
|
|
485
|
+
*/
|
|
486
|
+
declare function hasOptions(field: IField): field is IRadioField | IDropdownField | IMultiSelectField;
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Form section - groups fields with layout configuration
|
|
490
|
+
*/
|
|
491
|
+
interface ISection {
|
|
492
|
+
/** Unique section identifier */
|
|
493
|
+
id: string;
|
|
494
|
+
/** Section title */
|
|
495
|
+
name: string;
|
|
496
|
+
/** Optional description */
|
|
497
|
+
description?: string;
|
|
498
|
+
/** Fields within this section */
|
|
499
|
+
fields: IField[];
|
|
500
|
+
/** Layout configuration */
|
|
501
|
+
layout: ISectionLayout;
|
|
502
|
+
/** Conditional logic for show/hide */
|
|
503
|
+
conditionalLogic?: IConditionalRule;
|
|
504
|
+
/** Sort order within form */
|
|
505
|
+
order: number;
|
|
506
|
+
/** Whether section is collapsible */
|
|
507
|
+
isCollapsible?: boolean;
|
|
508
|
+
/** Whether section is initially collapsed */
|
|
509
|
+
isCollapsed?: boolean;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Create a new section with defaults
|
|
513
|
+
*/
|
|
514
|
+
declare function createSection(partial?: Partial<ISection>): ISection;
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Form settings
|
|
518
|
+
*/
|
|
519
|
+
interface IFormSettings {
|
|
520
|
+
/** Allow saving draft submissions */
|
|
521
|
+
allowSaveDraft?: boolean;
|
|
522
|
+
/** Show progress bar */
|
|
523
|
+
showProgressBar?: boolean;
|
|
524
|
+
/** Shuffle questions */
|
|
525
|
+
shuffleQuestions?: boolean;
|
|
526
|
+
/** Submit button text */
|
|
527
|
+
submitButtonText?: string;
|
|
528
|
+
/** Show section navigation */
|
|
529
|
+
showSectionNav?: boolean;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Root form schema - complete JSON representation of a form
|
|
533
|
+
*/
|
|
534
|
+
interface IFormSchema {
|
|
535
|
+
/** Unique form identifier */
|
|
536
|
+
id: string;
|
|
537
|
+
/** Schema version for migrations */
|
|
538
|
+
version: string;
|
|
539
|
+
/** Form name/title */
|
|
540
|
+
name: string;
|
|
541
|
+
/** Form description */
|
|
542
|
+
description?: string;
|
|
543
|
+
/** Form sections */
|
|
544
|
+
sections: ISection[];
|
|
545
|
+
/** Global conditional logic rules */
|
|
546
|
+
logic?: IConditionalRule[];
|
|
547
|
+
/** Form settings */
|
|
548
|
+
settings?: IFormSettings;
|
|
549
|
+
/** Additional metadata */
|
|
550
|
+
metadata?: Record<string, unknown>;
|
|
551
|
+
/** Creation timestamp */
|
|
552
|
+
createdAt?: string;
|
|
553
|
+
/** Last update timestamp */
|
|
554
|
+
updatedAt?: string;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Form submission data
|
|
558
|
+
*/
|
|
559
|
+
interface IFormSubmission {
|
|
560
|
+
/** Form schema ID */
|
|
561
|
+
schemaId: string;
|
|
562
|
+
/** Schema version at submission time */
|
|
563
|
+
schemaVersion: string;
|
|
564
|
+
/** Field values by field ID */
|
|
565
|
+
values: Record<string, unknown>;
|
|
566
|
+
/** Submission timestamp */
|
|
567
|
+
submittedAt: string;
|
|
568
|
+
/** Whether this is a draft */
|
|
569
|
+
isDraft?: boolean;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Default form settings
|
|
573
|
+
*/
|
|
574
|
+
declare const DEFAULT_FORM_SETTINGS: IFormSettings;
|
|
575
|
+
/**
|
|
576
|
+
* Create a new form schema with defaults
|
|
577
|
+
*/
|
|
578
|
+
declare function createFormSchema(partial?: Partial<IFormSchema>): IFormSchema;
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Manages the form builder UI state including schema, selection, and UI toggles.
|
|
582
|
+
* Should be provided at the FormBuilder component level (not root).
|
|
583
|
+
*/
|
|
584
|
+
declare class FormBuilderStateService {
|
|
585
|
+
private readonly _schema;
|
|
586
|
+
private readonly _isDirty;
|
|
587
|
+
private readonly _selectedSectionId;
|
|
588
|
+
private readonly _selectedFieldId;
|
|
589
|
+
private readonly _isPaletteOpen;
|
|
590
|
+
private readonly _isPropertiesOpen;
|
|
591
|
+
private readonly _previewMode;
|
|
592
|
+
readonly schema: _angular_core.Signal<IFormSchema>;
|
|
593
|
+
readonly isDirty: _angular_core.Signal<boolean>;
|
|
594
|
+
readonly selectedSectionId: _angular_core.Signal<string | null>;
|
|
595
|
+
readonly selectedFieldId: _angular_core.Signal<string | null>;
|
|
596
|
+
readonly isPaletteOpen: _angular_core.Signal<boolean>;
|
|
597
|
+
readonly isPropertiesOpen: _angular_core.Signal<boolean>;
|
|
598
|
+
readonly previewMode: _angular_core.Signal<boolean>;
|
|
599
|
+
readonly sections: _angular_core.Signal<ISection[]>;
|
|
600
|
+
readonly formName: _angular_core.Signal<string>;
|
|
601
|
+
readonly formSettings: _angular_core.Signal<IFormSettings>;
|
|
602
|
+
readonly selectedSection: _angular_core.Signal<ISection | null>;
|
|
603
|
+
readonly selectedField: _angular_core.Signal<IField | null>;
|
|
604
|
+
readonly allFields: _angular_core.Signal<IField[]>;
|
|
605
|
+
/**
|
|
606
|
+
* Load an existing schema into the builder
|
|
607
|
+
*/
|
|
608
|
+
loadSchema(schema: IFormSchema): void;
|
|
609
|
+
/**
|
|
610
|
+
* Create a new empty schema
|
|
611
|
+
*/
|
|
612
|
+
createNewSchema(name?: string): void;
|
|
613
|
+
/**
|
|
614
|
+
* Update form metadata
|
|
615
|
+
*/
|
|
616
|
+
updateFormMeta(updates: Partial<Pick<IFormSchema, 'name' | 'description' | 'settings'>>): void;
|
|
617
|
+
/**
|
|
618
|
+
* Mark schema as saved (clears dirty flag)
|
|
619
|
+
*/
|
|
620
|
+
markAsSaved(): void;
|
|
621
|
+
/**
|
|
622
|
+
* Add a new section
|
|
623
|
+
*/
|
|
624
|
+
addSection(section?: Partial<ISection>): string;
|
|
625
|
+
/**
|
|
626
|
+
* Update an existing section
|
|
627
|
+
*/
|
|
628
|
+
updateSection(sectionId: string, updates: Partial<ISection>): void;
|
|
629
|
+
/**
|
|
630
|
+
* Delete a section
|
|
631
|
+
*/
|
|
632
|
+
deleteSection(sectionId: string): void;
|
|
633
|
+
/**
|
|
634
|
+
* Reorder sections
|
|
635
|
+
*/
|
|
636
|
+
reorderSections(fromIndex: number, toIndex: number): void;
|
|
637
|
+
/**
|
|
638
|
+
* Duplicate a section
|
|
639
|
+
*/
|
|
640
|
+
duplicateSection(sectionId: string): string | null;
|
|
641
|
+
/**
|
|
642
|
+
* Add a field to a section
|
|
643
|
+
*/
|
|
644
|
+
addField(sectionId: string, fieldType: FieldType, field?: Partial<IField>): string | null;
|
|
645
|
+
/**
|
|
646
|
+
* Update a field
|
|
647
|
+
*/
|
|
648
|
+
updateField(sectionId: string, fieldId: string, updates: Partial<IField>): void;
|
|
649
|
+
/**
|
|
650
|
+
* Delete a field
|
|
651
|
+
*/
|
|
652
|
+
deleteField(sectionId: string, fieldId: string): void;
|
|
653
|
+
/**
|
|
654
|
+
* Reorder fields within a section
|
|
655
|
+
*/
|
|
656
|
+
reorderFields(sectionId: string, fromIndex: number, toIndex: number): void;
|
|
657
|
+
/**
|
|
658
|
+
* Move a field to a different section
|
|
659
|
+
*/
|
|
660
|
+
moveFieldToSection(fromSectionId: string, toSectionId: string, fieldId: string, toIndex: number): void;
|
|
661
|
+
/**
|
|
662
|
+
* Duplicate a field
|
|
663
|
+
*/
|
|
664
|
+
duplicateField(sectionId: string, fieldId: string): string | null;
|
|
665
|
+
/**
|
|
666
|
+
* Select a section
|
|
667
|
+
*/
|
|
668
|
+
selectSection(sectionId: string | null): void;
|
|
669
|
+
/**
|
|
670
|
+
* Select a field (also selects its parent section)
|
|
671
|
+
*/
|
|
672
|
+
selectField(fieldId: string | null): void;
|
|
673
|
+
/**
|
|
674
|
+
* Clear all selections
|
|
675
|
+
*/
|
|
676
|
+
clearSelection(): void;
|
|
677
|
+
/**
|
|
678
|
+
* Toggle palette visibility
|
|
679
|
+
*/
|
|
680
|
+
togglePalette(): void;
|
|
681
|
+
/**
|
|
682
|
+
* Toggle properties panel visibility
|
|
683
|
+
*/
|
|
684
|
+
toggleProperties(): void;
|
|
685
|
+
/**
|
|
686
|
+
* Set preview mode
|
|
687
|
+
*/
|
|
688
|
+
setPreviewMode(enabled: boolean): void;
|
|
689
|
+
/**
|
|
690
|
+
* Toggle preview mode
|
|
691
|
+
*/
|
|
692
|
+
togglePreviewMode(): void;
|
|
693
|
+
private getDefaultFieldLabel;
|
|
694
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormBuilderStateService, never>;
|
|
695
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<FormBuilderStateService>;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Service for evaluating conditional logic rules.
|
|
700
|
+
* Determines field/section visibility based on form values.
|
|
701
|
+
*/
|
|
702
|
+
declare class ConditionalLogicService {
|
|
703
|
+
private readonly _formValues;
|
|
704
|
+
private readonly _fieldVisibility;
|
|
705
|
+
private readonly _sectionVisibility;
|
|
706
|
+
readonly formValues: _angular_core.Signal<Record<string, unknown>>;
|
|
707
|
+
readonly fieldVisibility: _angular_core.Signal<Map<string, boolean>>;
|
|
708
|
+
readonly sectionVisibility: _angular_core.Signal<Map<string, boolean>>;
|
|
709
|
+
/**
|
|
710
|
+
* Update a single form value
|
|
711
|
+
*/
|
|
712
|
+
updateFormValue(fieldId: string, value: unknown): void;
|
|
713
|
+
/**
|
|
714
|
+
* Set all form values at once
|
|
715
|
+
*/
|
|
716
|
+
setFormValues(values: Record<string, unknown>): void;
|
|
717
|
+
/**
|
|
718
|
+
* Clear all form values
|
|
719
|
+
*/
|
|
720
|
+
clearFormValues(): void;
|
|
721
|
+
/**
|
|
722
|
+
* Evaluate visibility for a field based on its conditional logic
|
|
723
|
+
*/
|
|
724
|
+
evaluateFieldVisibility(field: IField): boolean;
|
|
725
|
+
/**
|
|
726
|
+
* Evaluate visibility for a section based on its conditional logic
|
|
727
|
+
*/
|
|
728
|
+
evaluateSectionVisibility(section: ISection): boolean;
|
|
729
|
+
/**
|
|
730
|
+
* Evaluate a conditional rule
|
|
731
|
+
*/
|
|
732
|
+
evaluateRule(rule: IConditionalRule): boolean;
|
|
733
|
+
/**
|
|
734
|
+
* Evaluate a logic group (AND/OR combination of conditions)
|
|
735
|
+
*/
|
|
736
|
+
evaluateLogicGroup(group: ILogicGroup): boolean;
|
|
737
|
+
/**
|
|
738
|
+
* Evaluate a single condition
|
|
739
|
+
*/
|
|
740
|
+
evaluateCondition(condition: ICondition): boolean;
|
|
741
|
+
/**
|
|
742
|
+
* Recalculate visibility for all fields
|
|
743
|
+
*/
|
|
744
|
+
recalculateFieldVisibility(fields: IField[]): Map<string, boolean>;
|
|
745
|
+
/**
|
|
746
|
+
* Recalculate visibility for all sections
|
|
747
|
+
*/
|
|
748
|
+
recalculateSectionVisibility(sections: ISection[]): Map<string, boolean>;
|
|
749
|
+
/**
|
|
750
|
+
* Check if a specific field is visible
|
|
751
|
+
*/
|
|
752
|
+
isFieldVisible(fieldId: string): boolean;
|
|
753
|
+
/**
|
|
754
|
+
* Check if a specific section is visible
|
|
755
|
+
*/
|
|
756
|
+
isSectionVisible(sectionId: string): boolean;
|
|
757
|
+
/**
|
|
758
|
+
* Deep equality check
|
|
759
|
+
*/
|
|
760
|
+
private deepEquals;
|
|
761
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ConditionalLogicService, never>;
|
|
762
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<ConditionalLogicService>;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Validation error result
|
|
767
|
+
*/
|
|
768
|
+
interface IValidationError {
|
|
769
|
+
fieldId: string;
|
|
770
|
+
fieldLabel: string;
|
|
771
|
+
message: string;
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Service for validating form field values
|
|
775
|
+
*/
|
|
776
|
+
declare class ValidationService {
|
|
777
|
+
private customValidators;
|
|
778
|
+
/**
|
|
779
|
+
* Register a custom validator
|
|
780
|
+
*/
|
|
781
|
+
registerCustomValidator(name: string, validator: (value: unknown, field: IField) => string | null): void;
|
|
782
|
+
/**
|
|
783
|
+
* Validate a single field
|
|
784
|
+
* @returns Error message or null if valid
|
|
785
|
+
*/
|
|
786
|
+
validateField(field: IField, value: unknown): string | null;
|
|
787
|
+
/**
|
|
788
|
+
* Validate all fields in a section
|
|
789
|
+
* @returns Map of field ID to error message
|
|
790
|
+
*/
|
|
791
|
+
validateSection(section: ISection, values: Record<string, unknown>, visibleFieldIds?: Set<string>): Map<string, string>;
|
|
792
|
+
/**
|
|
793
|
+
* Validate all fields in a form
|
|
794
|
+
* @returns Array of validation errors
|
|
795
|
+
*/
|
|
796
|
+
validateForm(sections: ISection[], values: Record<string, unknown>, visibleFieldIds?: Set<string>): IValidationError[];
|
|
797
|
+
/**
|
|
798
|
+
* Validate a single rule
|
|
799
|
+
*/
|
|
800
|
+
private validateRule;
|
|
801
|
+
/**
|
|
802
|
+
* Get default error message for a rule
|
|
803
|
+
*/
|
|
804
|
+
private getDefaultMessage;
|
|
805
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ValidationService, never>;
|
|
806
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<ValidationService>;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Extended field type metadata including component reference
|
|
811
|
+
*/
|
|
812
|
+
interface IFieldTypeMetadata extends IFieldTypeInfo {
|
|
813
|
+
/** Component class to render this field type */
|
|
814
|
+
component?: Type<unknown>;
|
|
815
|
+
/** Default configuration for new fields of this type */
|
|
816
|
+
defaultConfig?: Partial<IField>;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Registry for field types - supports extensibility with custom field types.
|
|
820
|
+
* Provided at root level for global access.
|
|
821
|
+
*/
|
|
822
|
+
declare class FieldRegistryService {
|
|
823
|
+
private readonly _registry;
|
|
824
|
+
readonly fieldTypes: _angular_core.Signal<Map<string, IFieldTypeMetadata>>;
|
|
825
|
+
readonly allFieldTypes: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
826
|
+
readonly inputFieldTypes: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
827
|
+
readonly selectionFieldTypes: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
828
|
+
readonly specializedFieldTypes: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
829
|
+
constructor();
|
|
830
|
+
/**
|
|
831
|
+
* Register a field type
|
|
832
|
+
*/
|
|
833
|
+
register(metadata: IFieldTypeMetadata): void;
|
|
834
|
+
/**
|
|
835
|
+
* Register multiple field types
|
|
836
|
+
*/
|
|
837
|
+
registerMany(metadataList: IFieldTypeMetadata[]): void;
|
|
838
|
+
/**
|
|
839
|
+
* Unregister a field type
|
|
840
|
+
*/
|
|
841
|
+
unregister(type: FieldType | string): void;
|
|
842
|
+
/**
|
|
843
|
+
* Get metadata for a field type
|
|
844
|
+
*/
|
|
845
|
+
getMetadata(type: FieldType | string): IFieldTypeMetadata | undefined;
|
|
846
|
+
/**
|
|
847
|
+
* Get all registered field types
|
|
848
|
+
*/
|
|
849
|
+
getAll(): IFieldTypeMetadata[];
|
|
850
|
+
/**
|
|
851
|
+
* Get field types by category
|
|
852
|
+
*/
|
|
853
|
+
getByCategory(category: 'input' | 'selection' | 'specialized'): IFieldTypeMetadata[];
|
|
854
|
+
/**
|
|
855
|
+
* Check if a field type is registered
|
|
856
|
+
*/
|
|
857
|
+
isRegistered(type: FieldType | string): boolean;
|
|
858
|
+
/**
|
|
859
|
+
* Get the component for a field type
|
|
860
|
+
*/
|
|
861
|
+
getComponent(type: FieldType | string): Type<unknown> | undefined;
|
|
862
|
+
/**
|
|
863
|
+
* Get default config for a field type
|
|
864
|
+
*/
|
|
865
|
+
getDefaultConfig(type: FieldType | string): Partial<IField> | undefined;
|
|
866
|
+
/**
|
|
867
|
+
* Register built-in field types
|
|
868
|
+
*/
|
|
869
|
+
private registerBuiltInTypes;
|
|
870
|
+
/**
|
|
871
|
+
* Get default config for built-in field types
|
|
872
|
+
*/
|
|
873
|
+
private getBuiltInDefaultConfig;
|
|
874
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldRegistryService, never>;
|
|
875
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<FieldRegistryService>;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Schema validation error
|
|
880
|
+
*/
|
|
881
|
+
interface ISchemaValidationError {
|
|
882
|
+
path: string;
|
|
883
|
+
message: string;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Schema validation result
|
|
887
|
+
*/
|
|
888
|
+
interface ISchemaValidationResult {
|
|
889
|
+
valid: boolean;
|
|
890
|
+
errors: ISchemaValidationError[];
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Service for importing and exporting form schemas as JSON
|
|
894
|
+
*/
|
|
895
|
+
declare class SchemaExportService {
|
|
896
|
+
/**
|
|
897
|
+
* Export schema to JSON string
|
|
898
|
+
*/
|
|
899
|
+
exportToJson(schema: IFormSchema, pretty?: boolean): string;
|
|
900
|
+
/**
|
|
901
|
+
* Export schema to downloadable file
|
|
902
|
+
*/
|
|
903
|
+
exportToFile(schema: IFormSchema, filename?: string): void;
|
|
904
|
+
/**
|
|
905
|
+
* Import schema from JSON string
|
|
906
|
+
*/
|
|
907
|
+
importFromJson(json: string): IFormSchema;
|
|
908
|
+
/**
|
|
909
|
+
* Import schema from File
|
|
910
|
+
*/
|
|
911
|
+
importFromFile(file: File): Promise<IFormSchema>;
|
|
912
|
+
/**
|
|
913
|
+
* Validate schema structure
|
|
914
|
+
*/
|
|
915
|
+
validateSchema(schema: unknown): ISchemaValidationResult;
|
|
916
|
+
/**
|
|
917
|
+
* Validate section structure
|
|
918
|
+
*/
|
|
919
|
+
private validateSection;
|
|
920
|
+
/**
|
|
921
|
+
* Validate field structure
|
|
922
|
+
*/
|
|
923
|
+
private validateField;
|
|
924
|
+
/**
|
|
925
|
+
* Clean schema for export (remove undefined values, etc.)
|
|
926
|
+
*/
|
|
927
|
+
private cleanSchema;
|
|
928
|
+
/**
|
|
929
|
+
* Normalize imported schema (add missing defaults, generate IDs if needed)
|
|
930
|
+
*/
|
|
931
|
+
private normalizeSchema;
|
|
932
|
+
/**
|
|
933
|
+
* Sanitize filename for download
|
|
934
|
+
*/
|
|
935
|
+
private sanitizeFilename;
|
|
936
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SchemaExportService, never>;
|
|
937
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SchemaExportService>;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* PDF export configuration
|
|
942
|
+
*/
|
|
943
|
+
interface IPdfExportConfig {
|
|
944
|
+
/** Document title (defaults to form name) */
|
|
945
|
+
title?: string;
|
|
946
|
+
/** Subtitle text */
|
|
947
|
+
subtitle?: string;
|
|
948
|
+
/** Show submission metadata (date, status) */
|
|
949
|
+
showMetadata?: boolean;
|
|
950
|
+
/** Show form description */
|
|
951
|
+
showDescription?: boolean;
|
|
952
|
+
/** Show section descriptions */
|
|
953
|
+
showSectionDescriptions?: boolean;
|
|
954
|
+
/** Show summary statistics */
|
|
955
|
+
showSummary?: boolean;
|
|
956
|
+
/** Primary color for headers (hex) */
|
|
957
|
+
primaryColor?: string;
|
|
958
|
+
/** Secondary/accent color (hex) */
|
|
959
|
+
accentColor?: string;
|
|
960
|
+
/** Page size */
|
|
961
|
+
pageSize?: 'A4' | 'LETTER' | 'LEGAL';
|
|
962
|
+
/** Page orientation */
|
|
963
|
+
pageOrientation?: 'portrait' | 'landscape';
|
|
964
|
+
/** Footer text */
|
|
965
|
+
footerText?: string;
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Default PDF export configuration
|
|
969
|
+
*/
|
|
970
|
+
declare const DEFAULT_PDF_CONFIG: IPdfExportConfig;
|
|
971
|
+
/**
|
|
972
|
+
* Service for exporting form results to PDF using pdfmake
|
|
973
|
+
*/
|
|
974
|
+
declare class PdfExportService {
|
|
975
|
+
private readonly platformId;
|
|
976
|
+
private readonly isBrowser;
|
|
977
|
+
private pdfMake;
|
|
978
|
+
/**
|
|
979
|
+
* Initialize pdfmake (lazy load for browser only)
|
|
980
|
+
*/
|
|
981
|
+
private initPdfMake;
|
|
982
|
+
/**
|
|
983
|
+
* Download form result as PDF
|
|
984
|
+
*/
|
|
985
|
+
downloadPdf(schema: IFormSchema, submission: IFormSubmission, config?: IPdfExportConfig): Promise<void>;
|
|
986
|
+
/**
|
|
987
|
+
* Open form result PDF in new tab
|
|
988
|
+
*/
|
|
989
|
+
openPdf(schema: IFormSchema, submission: IFormSubmission, config?: IPdfExportConfig): Promise<void>;
|
|
990
|
+
/**
|
|
991
|
+
* Get PDF as Blob
|
|
992
|
+
*/
|
|
993
|
+
getPdfBlob(schema: IFormSchema, submission: IFormSubmission, config?: IPdfExportConfig): Promise<Blob>;
|
|
994
|
+
/**
|
|
995
|
+
* Build pdfmake document definition
|
|
996
|
+
*/
|
|
997
|
+
private buildDocDefinition;
|
|
998
|
+
/**
|
|
999
|
+
* Build stat column for summary
|
|
1000
|
+
*/
|
|
1001
|
+
private buildStatColumn;
|
|
1002
|
+
/**
|
|
1003
|
+
* Build section content for PDF
|
|
1004
|
+
*/
|
|
1005
|
+
private buildSectionContent;
|
|
1006
|
+
/**
|
|
1007
|
+
* Count answered fields
|
|
1008
|
+
*/
|
|
1009
|
+
private countAnsweredFields;
|
|
1010
|
+
/**
|
|
1011
|
+
* Format field value for display in PDF
|
|
1012
|
+
*/
|
|
1013
|
+
private formatFieldValue;
|
|
1014
|
+
/**
|
|
1015
|
+
* Get label for single-select option
|
|
1016
|
+
*/
|
|
1017
|
+
private getOptionLabel;
|
|
1018
|
+
/**
|
|
1019
|
+
* Get labels for multi-select options
|
|
1020
|
+
*/
|
|
1021
|
+
private getMultiSelectLabels;
|
|
1022
|
+
/**
|
|
1023
|
+
* Format likert field value
|
|
1024
|
+
*/
|
|
1025
|
+
private formatLikertValue;
|
|
1026
|
+
/**
|
|
1027
|
+
* Format file upload value
|
|
1028
|
+
*/
|
|
1029
|
+
private formatFileValue;
|
|
1030
|
+
/**
|
|
1031
|
+
* Format date string
|
|
1032
|
+
*/
|
|
1033
|
+
private formatDate;
|
|
1034
|
+
/**
|
|
1035
|
+
* Sanitize filename for download
|
|
1036
|
+
*/
|
|
1037
|
+
private sanitizeFilename;
|
|
1038
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PdfExportService, never>;
|
|
1039
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<PdfExportService>;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Interface for items with an order property
|
|
1044
|
+
*/
|
|
1045
|
+
interface Orderable {
|
|
1046
|
+
order: number;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Sort items by their order property (ascending)
|
|
1050
|
+
*/
|
|
1051
|
+
declare function sortByOrder<T extends Orderable>(items: T[]): T[];
|
|
1052
|
+
/**
|
|
1053
|
+
* Sort fields by order
|
|
1054
|
+
*/
|
|
1055
|
+
declare function sortFields(fields: IField[]): IField[];
|
|
1056
|
+
/**
|
|
1057
|
+
* Sort sections by order
|
|
1058
|
+
*/
|
|
1059
|
+
declare function sortSections(sections: ISection[]): ISection[];
|
|
1060
|
+
/**
|
|
1061
|
+
* Sort options by order
|
|
1062
|
+
*/
|
|
1063
|
+
declare function sortOptions(options: IFieldOption[]): IFieldOption[];
|
|
1064
|
+
/**
|
|
1065
|
+
* Check if a value is considered empty
|
|
1066
|
+
*/
|
|
1067
|
+
declare function isEmpty(value: unknown): boolean;
|
|
1068
|
+
/**
|
|
1069
|
+
* Check if a value is considered answered/filled
|
|
1070
|
+
*/
|
|
1071
|
+
declare function hasValue(value: unknown): boolean;
|
|
1072
|
+
/**
|
|
1073
|
+
* Format bytes to human-readable file size
|
|
1074
|
+
*/
|
|
1075
|
+
declare function formatFileSize(bytes: number): string;
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Base class for all form builder field components.
|
|
1079
|
+
*
|
|
1080
|
+
* Supports three form patterns:
|
|
1081
|
+
* 1. Template-driven: [(value)]="signal" or [(ngModel)]="value"
|
|
1082
|
+
* 2. Reactive forms: [formControl]="ctrl" or formControlName="field"
|
|
1083
|
+
* 3. Signal forms: [formField]="formTree.field"
|
|
1084
|
+
*
|
|
1085
|
+
* @example
|
|
1086
|
+
* ```typescript
|
|
1087
|
+
* @Component({
|
|
1088
|
+
* providers: [provideFieldValueAccessor(TextFieldComponent)]
|
|
1089
|
+
* })
|
|
1090
|
+
* export class TextFieldComponent extends BaseFieldComponent<string> {
|
|
1091
|
+
* override readonly value = model<string | null>(null);
|
|
1092
|
+
* }
|
|
1093
|
+
* ```
|
|
1094
|
+
*/
|
|
1095
|
+
declare abstract class BaseFieldComponent<T = unknown> implements ControlValueAccessor {
|
|
1096
|
+
protected readonly logicService: ConditionalLogicService | null;
|
|
1097
|
+
readonly field: _angular_core.InputSignal<IField>;
|
|
1098
|
+
readonly disabled: _angular_core.ModelSignal<boolean>;
|
|
1099
|
+
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
1100
|
+
readonly showLabel: _angular_core.InputSignal<boolean>;
|
|
1101
|
+
readonly showHelpText: _angular_core.InputSignal<boolean>;
|
|
1102
|
+
readonly errors: _angular_core.InputSignal<string[]>;
|
|
1103
|
+
readonly valueChanged: _angular_core.OutputEmitterRef<T | null>;
|
|
1104
|
+
abstract readonly value: ReturnType<typeof model<T | null>>;
|
|
1105
|
+
private onChange;
|
|
1106
|
+
private onTouched;
|
|
1107
|
+
private isWritingValue;
|
|
1108
|
+
readonly label: _angular_core.Signal<string>;
|
|
1109
|
+
readonly placeholder: _angular_core.Signal<string>;
|
|
1110
|
+
readonly helpText: _angular_core.Signal<string | undefined>;
|
|
1111
|
+
readonly isRequired: _angular_core.Signal<boolean>;
|
|
1112
|
+
readonly fieldId: _angular_core.Signal<string>;
|
|
1113
|
+
readonly hasErrors: _angular_core.Signal<boolean>;
|
|
1114
|
+
readonly firstError: _angular_core.Signal<string>;
|
|
1115
|
+
readonly isVisible: _angular_core.Signal<boolean>;
|
|
1116
|
+
/**
|
|
1117
|
+
* Hook for subclass-specific form control initialization.
|
|
1118
|
+
* Override in subclasses if additional setup is needed.
|
|
1119
|
+
*/
|
|
1120
|
+
protected initializeFormControl(): void;
|
|
1121
|
+
/**
|
|
1122
|
+
* Emit value change to external consumers
|
|
1123
|
+
*/
|
|
1124
|
+
protected emitValue(value: T | null): void;
|
|
1125
|
+
/**
|
|
1126
|
+
* Handle value change - updates signal and emits to external consumers.
|
|
1127
|
+
* Use this in field components instead of duplicating the pattern.
|
|
1128
|
+
*/
|
|
1129
|
+
protected handleValueChange(value: T | null): void;
|
|
1130
|
+
/**
|
|
1131
|
+
* Mark the control as touched
|
|
1132
|
+
*/
|
|
1133
|
+
protected markAsTouched(): void;
|
|
1134
|
+
writeValue(value: T | null): void;
|
|
1135
|
+
registerOnChange(fn: (value: T | null) => void): void;
|
|
1136
|
+
registerOnTouched(fn: () => void): void;
|
|
1137
|
+
setDisabledState(isDisabled: boolean): void;
|
|
1138
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseFieldComponent<any>, never>;
|
|
1139
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseFieldComponent<any>, never, never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "showLabel": { "alias": "showLabel"; "required": false; "isSignal": true; }; "showHelpText": { "alias": "showHelpText"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; "touched": "touchedChange"; "valueChanged": "valueChanged"; }, never, never, true, never>;
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Factory function to provide NG_VALUE_ACCESSOR for a field component.
|
|
1143
|
+
*/
|
|
1144
|
+
declare function provideFieldValueAccessor<T extends new (...args: unknown[]) => ControlValueAccessor>(component: T): {
|
|
1145
|
+
provide: _angular_core.InjectionToken<readonly ControlValueAccessor[]>;
|
|
1146
|
+
useExisting: T;
|
|
1147
|
+
multi: boolean;
|
|
1148
|
+
};
|
|
1149
|
+
|
|
1150
|
+
/**
|
|
1151
|
+
* Text field component supporting single-line and multi-line input.
|
|
1152
|
+
*
|
|
1153
|
+
* Uses pInputText for single-line (rows <= 1) and pTextarea for multi-line (rows > 1).
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
* ```html
|
|
1157
|
+
* <fb-text-field [field]="textField" [(value)]="textValue" />
|
|
1158
|
+
* ```
|
|
1159
|
+
*/
|
|
1160
|
+
declare class TextFieldComponent extends BaseFieldComponent<string> {
|
|
1161
|
+
readonly value: _angular_core.ModelSignal<string | null>;
|
|
1162
|
+
readonly textField: _angular_core.Signal<ITextField>;
|
|
1163
|
+
readonly isMultiLine: _angular_core.Signal<boolean>;
|
|
1164
|
+
readonly rows: _angular_core.Signal<number>;
|
|
1165
|
+
readonly maxLength: _angular_core.Signal<number | null>;
|
|
1166
|
+
constructor();
|
|
1167
|
+
onValueChange(value: string | null): void;
|
|
1168
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TextFieldComponent, never>;
|
|
1169
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<TextFieldComponent, "fb-text-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/**
|
|
1173
|
+
* Number field component with support for min/max, step, prefix/suffix, and buttons.
|
|
1174
|
+
*
|
|
1175
|
+
* Uses p-inputNumber from PrimeNG.
|
|
1176
|
+
*
|
|
1177
|
+
* @example
|
|
1178
|
+
* ```html
|
|
1179
|
+
* <fb-number-field [field]="numberField" [(value)]="numberValue" />
|
|
1180
|
+
* ```
|
|
1181
|
+
*/
|
|
1182
|
+
declare class NumberFieldComponent extends BaseFieldComponent<number> {
|
|
1183
|
+
readonly value: _angular_core.ModelSignal<number | null>;
|
|
1184
|
+
readonly numberField: _angular_core.Signal<INumberField>;
|
|
1185
|
+
readonly min: _angular_core.Signal<number | undefined>;
|
|
1186
|
+
readonly max: _angular_core.Signal<number | undefined>;
|
|
1187
|
+
readonly step: _angular_core.Signal<number>;
|
|
1188
|
+
readonly prefix: _angular_core.Signal<string>;
|
|
1189
|
+
readonly suffix: _angular_core.Signal<string>;
|
|
1190
|
+
readonly showButtons: _angular_core.Signal<boolean>;
|
|
1191
|
+
constructor();
|
|
1192
|
+
onValueChange(value: number | null): void;
|
|
1193
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NumberFieldComponent, never>;
|
|
1194
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NumberFieldComponent, "fb-number-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
/**
|
|
1198
|
+
* Email field component with type="email" for browser validation hints.
|
|
1199
|
+
*
|
|
1200
|
+
* Uses pInputText with type="email" from PrimeNG.
|
|
1201
|
+
*
|
|
1202
|
+
* @example
|
|
1203
|
+
* ```html
|
|
1204
|
+
* <fb-email-field [field]="emailField" [(value)]="emailValue" />
|
|
1205
|
+
* ```
|
|
1206
|
+
*/
|
|
1207
|
+
declare class EmailFieldComponent extends BaseFieldComponent<string> {
|
|
1208
|
+
readonly value: _angular_core.ModelSignal<string | null>;
|
|
1209
|
+
constructor();
|
|
1210
|
+
onValueChange(value: string | null): void;
|
|
1211
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EmailFieldComponent, never>;
|
|
1212
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EmailFieldComponent, "fb-email-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* Checkbox field component with binary mode for boolean values.
|
|
1217
|
+
*
|
|
1218
|
+
* Uses p-checkbox from PrimeNG in binary mode.
|
|
1219
|
+
*
|
|
1220
|
+
* @example
|
|
1221
|
+
* ```html
|
|
1222
|
+
* <fb-checkbox-field [field]="checkboxField" [(value)]="checked" />
|
|
1223
|
+
* ```
|
|
1224
|
+
*/
|
|
1225
|
+
declare class CheckboxFieldComponent extends BaseFieldComponent<boolean> {
|
|
1226
|
+
readonly value: _angular_core.ModelSignal<boolean | null>;
|
|
1227
|
+
readonly checkboxField: _angular_core.Signal<ICheckboxField>;
|
|
1228
|
+
readonly checkboxLabel: _angular_core.Signal<string>;
|
|
1229
|
+
constructor();
|
|
1230
|
+
onValueChange(value: boolean | null): void;
|
|
1231
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<CheckboxFieldComponent, never>;
|
|
1232
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<CheckboxFieldComponent, "fb-checkbox-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
/**
|
|
1236
|
+
* Radio field component for single selection from multiple options.
|
|
1237
|
+
*
|
|
1238
|
+
* Supports vertical and horizontal layout modes.
|
|
1239
|
+
* Uses p-radioButton from PrimeNG.
|
|
1240
|
+
*
|
|
1241
|
+
* @example
|
|
1242
|
+
* ```html
|
|
1243
|
+
* <fb-radio-field [field]="radioField" [(value)]="selectedOptionId" />
|
|
1244
|
+
* ```
|
|
1245
|
+
*/
|
|
1246
|
+
declare class RadioFieldComponent extends BaseFieldComponent<string> {
|
|
1247
|
+
readonly value: _angular_core.ModelSignal<string | null>;
|
|
1248
|
+
readonly radioField: _angular_core.Signal<IRadioField>;
|
|
1249
|
+
readonly isHorizontal: _angular_core.Signal<boolean>;
|
|
1250
|
+
readonly sortedOptions: _angular_core.Signal<_flusys_ng_form_builder.IFieldOption[]>;
|
|
1251
|
+
constructor();
|
|
1252
|
+
onValueChange(value: string | null): void;
|
|
1253
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RadioFieldComponent, never>;
|
|
1254
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<RadioFieldComponent, "fb-radio-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
/**
|
|
1258
|
+
* Dropdown field component for single selection with optional search.
|
|
1259
|
+
*
|
|
1260
|
+
* Uses p-dropdown from PrimeNG with searchable and clear options.
|
|
1261
|
+
*
|
|
1262
|
+
* @example
|
|
1263
|
+
* ```html
|
|
1264
|
+
* <fb-dropdown-field [field]="dropdownField" [(value)]="selectedOptionId" />
|
|
1265
|
+
* ```
|
|
1266
|
+
*/
|
|
1267
|
+
declare class DropdownFieldComponent extends BaseFieldComponent<string> {
|
|
1268
|
+
readonly value: _angular_core.ModelSignal<string | null>;
|
|
1269
|
+
readonly dropdownField: _angular_core.Signal<IDropdownField>;
|
|
1270
|
+
readonly searchable: _angular_core.Signal<boolean>;
|
|
1271
|
+
readonly showClear: _angular_core.Signal<boolean>;
|
|
1272
|
+
readonly sortedOptions: _angular_core.Signal<_flusys_ng_form_builder.IFieldOption[]>;
|
|
1273
|
+
constructor();
|
|
1274
|
+
onValueChange(value: string | null): void;
|
|
1275
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DropdownFieldComponent, never>;
|
|
1276
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownFieldComponent, "fb-dropdown-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
/**
|
|
1280
|
+
* Multi-select field component for selecting multiple options.
|
|
1281
|
+
*
|
|
1282
|
+
* Uses p-multiSelect from PrimeNG with chip display mode.
|
|
1283
|
+
*
|
|
1284
|
+
* @example
|
|
1285
|
+
* ```html
|
|
1286
|
+
* <fb-multi-select-field [field]="multiSelectField" [(value)]="selectedOptionIds" />
|
|
1287
|
+
* ```
|
|
1288
|
+
*/
|
|
1289
|
+
declare class MultiSelectFieldComponent extends BaseFieldComponent<string[]> {
|
|
1290
|
+
readonly value: _angular_core.ModelSignal<string[] | null>;
|
|
1291
|
+
readonly multiSelectField: _angular_core.Signal<IMultiSelectField>;
|
|
1292
|
+
readonly maxSelections: _angular_core.Signal<number | undefined>;
|
|
1293
|
+
readonly display: _angular_core.Signal<"comma" | "chip">;
|
|
1294
|
+
readonly sortedOptions: _angular_core.Signal<_flusys_ng_form_builder.IFieldOption[]>;
|
|
1295
|
+
constructor();
|
|
1296
|
+
onValueChange(value: string[] | null): void;
|
|
1297
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MultiSelectFieldComponent, never>;
|
|
1298
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MultiSelectFieldComponent, "fb-multi-select-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
/**
|
|
1302
|
+
* Date field component with optional time selection and range mode.
|
|
1303
|
+
*
|
|
1304
|
+
* Uses p-calendar from PrimeNG with configurable date format and selection mode.
|
|
1305
|
+
*
|
|
1306
|
+
* @example
|
|
1307
|
+
* ```html
|
|
1308
|
+
* <fb-date-field [field]="dateField" [(value)]="dateValue" />
|
|
1309
|
+
* ```
|
|
1310
|
+
*/
|
|
1311
|
+
declare class DateFieldComponent extends BaseFieldComponent<string | string[]> {
|
|
1312
|
+
readonly value: _angular_core.ModelSignal<string | string[] | null>;
|
|
1313
|
+
readonly dateField: _angular_core.Signal<IDateField>;
|
|
1314
|
+
readonly showTime: _angular_core.Signal<boolean>;
|
|
1315
|
+
readonly dateFormat: _angular_core.Signal<string>;
|
|
1316
|
+
readonly selectionMode: _angular_core.Signal<"single" | "range" | "multiple">;
|
|
1317
|
+
readonly minDate: _angular_core.Signal<Date | undefined>;
|
|
1318
|
+
readonly maxDate: _angular_core.Signal<Date | undefined>;
|
|
1319
|
+
/**
|
|
1320
|
+
* Convert stored ISO string(s) to Date object(s) for the calendar
|
|
1321
|
+
*/
|
|
1322
|
+
readonly dateValue: _angular_core.Signal<Date | Date[] | null>;
|
|
1323
|
+
constructor();
|
|
1324
|
+
/**
|
|
1325
|
+
* Convert Date object(s) to ISO string(s) for storage
|
|
1326
|
+
*/
|
|
1327
|
+
onDateChange(value: Date | Date[] | null): void;
|
|
1328
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DateFieldComponent, never>;
|
|
1329
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DateFieldComponent, "fb-date-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
/**
|
|
1333
|
+
* Likert scale field component using a matrix table with radio buttons.
|
|
1334
|
+
*
|
|
1335
|
+
* Displays rows (questions) on the left and scale columns with radio buttons.
|
|
1336
|
+
* Value is stored as a Record<rowId, scaleValue>.
|
|
1337
|
+
*
|
|
1338
|
+
* @example
|
|
1339
|
+
* ```html
|
|
1340
|
+
* <fb-likert-field [field]="likertField" [(value)]="likertValues" />
|
|
1341
|
+
* ```
|
|
1342
|
+
*/
|
|
1343
|
+
declare class LikertFieldComponent extends BaseFieldComponent<Record<string, number>> {
|
|
1344
|
+
readonly value: _angular_core.ModelSignal<Record<string, number> | null>;
|
|
1345
|
+
/** Local selections signal for reactive template binding */
|
|
1346
|
+
readonly selections: _angular_core.WritableSignal<Record<string, number>>;
|
|
1347
|
+
readonly likertField: _angular_core.Signal<ILikertField>;
|
|
1348
|
+
readonly sortedRows: _angular_core.Signal<ILikertRow[]>;
|
|
1349
|
+
readonly scaleLabels: _angular_core.Signal<string[]>;
|
|
1350
|
+
readonly scaleMin: _angular_core.Signal<number>;
|
|
1351
|
+
readonly scaleMax: _angular_core.Signal<number>;
|
|
1352
|
+
/**
|
|
1353
|
+
* Generate array of scale values from min to max
|
|
1354
|
+
*/
|
|
1355
|
+
readonly scaleValues: _angular_core.Signal<number[]>;
|
|
1356
|
+
constructor();
|
|
1357
|
+
/**
|
|
1358
|
+
* Get the label for a scale value
|
|
1359
|
+
*/
|
|
1360
|
+
getScaleLabel(scaleValue: number): string;
|
|
1361
|
+
/**
|
|
1362
|
+
* Handle value change for a specific row (stores row ID -> scale value)
|
|
1363
|
+
*/
|
|
1364
|
+
onRowValueChange(rowId: string, scaleValue: number): void;
|
|
1365
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<LikertFieldComponent, never>;
|
|
1366
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LikertFieldComponent, "fb-likert-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
/**
|
|
1370
|
+
* Rating field component using star icons.
|
|
1371
|
+
*
|
|
1372
|
+
* Uses p-rating from PrimeNG with configurable max rating and cancel option.
|
|
1373
|
+
*
|
|
1374
|
+
* @example
|
|
1375
|
+
* ```html
|
|
1376
|
+
* <fb-rating-field [field]="ratingField" [(value)]="ratingValue" />
|
|
1377
|
+
* ```
|
|
1378
|
+
*/
|
|
1379
|
+
declare class RatingFieldComponent extends BaseFieldComponent<number> {
|
|
1380
|
+
readonly value: _angular_core.ModelSignal<number | null>;
|
|
1381
|
+
readonly ratingField: _angular_core.Signal<IRatingField>;
|
|
1382
|
+
readonly maxRating: _angular_core.Signal<number>;
|
|
1383
|
+
readonly allowCancel: _angular_core.Signal<boolean>;
|
|
1384
|
+
readonly minLabel: _angular_core.Signal<string>;
|
|
1385
|
+
readonly maxLabel: _angular_core.Signal<string>;
|
|
1386
|
+
readonly iconClass: _angular_core.Signal<string>;
|
|
1387
|
+
readonly iconOffClass: _angular_core.Signal<string>;
|
|
1388
|
+
constructor();
|
|
1389
|
+
onValueChange(value: number | null): void;
|
|
1390
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RatingFieldComponent, never>;
|
|
1391
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<RatingFieldComponent, "fb-rating-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
/**
|
|
1395
|
+
* Uploaded file info stored in value
|
|
1396
|
+
*/
|
|
1397
|
+
interface IUploadedFile {
|
|
1398
|
+
name: string;
|
|
1399
|
+
size: number;
|
|
1400
|
+
type: string;
|
|
1401
|
+
/** Base64 data URL or file ID from backend */
|
|
1402
|
+
data: string;
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* File upload field component with custom handler.
|
|
1406
|
+
*
|
|
1407
|
+
* Uses p-fileUpload from PrimeNG in advanced mode with custom upload handling.
|
|
1408
|
+
* Value stores an array of IUploadedFile objects.
|
|
1409
|
+
*
|
|
1410
|
+
* @example
|
|
1411
|
+
* ```html
|
|
1412
|
+
* <fb-file-upload-field
|
|
1413
|
+
* [field]="fileUploadField"
|
|
1414
|
+
* [(value)]="uploadedFiles"
|
|
1415
|
+
* (filesSelected)="handleFilesSelected($event)"
|
|
1416
|
+
* />
|
|
1417
|
+
* ```
|
|
1418
|
+
*/
|
|
1419
|
+
declare class FileUploadFieldComponent extends BaseFieldComponent<IUploadedFile[]> {
|
|
1420
|
+
readonly value: _angular_core.ModelSignal<IUploadedFile[] | null>;
|
|
1421
|
+
/**
|
|
1422
|
+
* Emits when files are selected for custom upload handling
|
|
1423
|
+
*/
|
|
1424
|
+
readonly filesSelected: _angular_core.OutputEmitterRef<File[]>;
|
|
1425
|
+
readonly fileUploadField: _angular_core.Signal<IFileUploadField>;
|
|
1426
|
+
readonly multiple: _angular_core.Signal<boolean>;
|
|
1427
|
+
readonly maxFiles: _angular_core.Signal<number>;
|
|
1428
|
+
readonly maxFileSize: _angular_core.Signal<number>;
|
|
1429
|
+
readonly acceptString: _angular_core.Signal<string>;
|
|
1430
|
+
constructor();
|
|
1431
|
+
/**
|
|
1432
|
+
* Handle file selection
|
|
1433
|
+
*/
|
|
1434
|
+
onFilesSelect(event: FileSelectEvent): Promise<void>;
|
|
1435
|
+
/**
|
|
1436
|
+
* Handle file removal
|
|
1437
|
+
*/
|
|
1438
|
+
onFileRemove(event: FileRemoveEvent): void;
|
|
1439
|
+
/**
|
|
1440
|
+
* Handle clear all files
|
|
1441
|
+
*/
|
|
1442
|
+
onClear(): void;
|
|
1443
|
+
/**
|
|
1444
|
+
* Read file as base64 data URL
|
|
1445
|
+
*/
|
|
1446
|
+
private readFileAsDataUrl;
|
|
1447
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileUploadFieldComponent, never>;
|
|
1448
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FileUploadFieldComponent, "fb-file-upload-field", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "filesSelected": "filesSelected"; }, never, never, true, never>;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
/**
|
|
1452
|
+
* Main form builder component with three-panel layout.
|
|
1453
|
+
*
|
|
1454
|
+
* - Left: Field palette (draggable field types)
|
|
1455
|
+
* - Center: Canvas (sections and fields preview)
|
|
1456
|
+
* - Right: Properties panel (field/section configuration)
|
|
1457
|
+
*
|
|
1458
|
+
* Provides FormBuilderStateService at component level for isolated state management.
|
|
1459
|
+
*
|
|
1460
|
+
* @example
|
|
1461
|
+
* ```html
|
|
1462
|
+
* <fb-form-builder
|
|
1463
|
+
* [schema]="formSchema"
|
|
1464
|
+
* (schemaChange)="onSchemaChange($event)"
|
|
1465
|
+
* (schemaSave)="onSave($event)"
|
|
1466
|
+
* (schemaExport)="onExport($event)"
|
|
1467
|
+
* />
|
|
1468
|
+
* ```
|
|
1469
|
+
*/
|
|
1470
|
+
declare class FormBuilderComponent {
|
|
1471
|
+
readonly state: FormBuilderStateService;
|
|
1472
|
+
readonly schema: _angular_core.InputSignal<IFormSchema | null>;
|
|
1473
|
+
readonly schemaChange: _angular_core.OutputEmitterRef<IFormSchema>;
|
|
1474
|
+
readonly schemaSave: _angular_core.OutputEmitterRef<IFormSchema>;
|
|
1475
|
+
readonly schemaExport: _angular_core.OutputEmitterRef<IFormSchema>;
|
|
1476
|
+
readonly panelSizes: _angular_core.Signal<number[]>;
|
|
1477
|
+
readonly minSizes: _angular_core.Signal<number[]>;
|
|
1478
|
+
readonly sectionDropListIds: _angular_core.Signal<string[]>;
|
|
1479
|
+
readonly paletteConnectedTo: _angular_core.Signal<string[]>;
|
|
1480
|
+
constructor();
|
|
1481
|
+
handleSave(): void;
|
|
1482
|
+
handlePreviewToggle(): void;
|
|
1483
|
+
handleImport(): void;
|
|
1484
|
+
handleExport(): void;
|
|
1485
|
+
handleSectionReorder(event: {
|
|
1486
|
+
fromIndex: number;
|
|
1487
|
+
toIndex: number;
|
|
1488
|
+
}): void;
|
|
1489
|
+
handleFieldUpdate(updates: {
|
|
1490
|
+
fieldId: string;
|
|
1491
|
+
changes: Record<string, unknown>;
|
|
1492
|
+
}): void;
|
|
1493
|
+
handleSectionUpdate(updates: {
|
|
1494
|
+
sectionId: string;
|
|
1495
|
+
changes: Record<string, unknown>;
|
|
1496
|
+
}): void;
|
|
1497
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormBuilderComponent, never>;
|
|
1498
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormBuilderComponent, "fb-form-builder", never, { "schema": { "alias": "schema"; "required": false; "isSignal": true; }; }, { "schemaChange": "schemaChange"; "schemaSave": "schemaSave"; "schemaExport": "schemaExport"; }, never, never, true, never>;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
/**
|
|
1502
|
+
* Builder toolbar component with form name, dirty indicator, and action buttons.
|
|
1503
|
+
*
|
|
1504
|
+
* Actions:
|
|
1505
|
+
* - Preview: Toggle preview mode
|
|
1506
|
+
* - Import: Trigger import dialog (handled by parent)
|
|
1507
|
+
* - Export: Export current schema
|
|
1508
|
+
* - Save: Save current schema
|
|
1509
|
+
*
|
|
1510
|
+
* @example
|
|
1511
|
+
* ```html
|
|
1512
|
+
* <fb-builder-toolbar
|
|
1513
|
+
* (save)="onSave()"
|
|
1514
|
+
* (preview)="onPreviewToggle()"
|
|
1515
|
+
* (import)="onImport()"
|
|
1516
|
+
* (export)="onExport()"
|
|
1517
|
+
* />
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
declare class BuilderToolbarComponent {
|
|
1521
|
+
readonly state: FormBuilderStateService;
|
|
1522
|
+
readonly save: _angular_core.OutputEmitterRef<void>;
|
|
1523
|
+
readonly preview: _angular_core.OutputEmitterRef<void>;
|
|
1524
|
+
readonly import: _angular_core.OutputEmitterRef<void>;
|
|
1525
|
+
readonly export: _angular_core.OutputEmitterRef<void>;
|
|
1526
|
+
readonly formTitle: _angular_core.Signal<string>;
|
|
1527
|
+
readonly sectionCount: _angular_core.Signal<number>;
|
|
1528
|
+
readonly fieldCount: _angular_core.Signal<number>;
|
|
1529
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BuilderToolbarComponent, never>;
|
|
1530
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BuilderToolbarComponent, "fb-builder-toolbar", never, {}, { "save": "save"; "preview": "preview"; "import": "import"; "export": "export"; }, never, never, true, never>;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
/**
|
|
1534
|
+
* Field palette component with draggable field types grouped by category.
|
|
1535
|
+
*
|
|
1536
|
+
* Categories:
|
|
1537
|
+
* - Input: Text, Number, Email, Date
|
|
1538
|
+
* - Selection: Checkbox, Radio, Dropdown, Multi-Select
|
|
1539
|
+
* - Specialized: Likert, Rating, File Upload
|
|
1540
|
+
*
|
|
1541
|
+
* Each field type is draggable (CDK Drag) and can be dropped onto the canvas.
|
|
1542
|
+
*
|
|
1543
|
+
* @example
|
|
1544
|
+
* ```html
|
|
1545
|
+
* <fb-field-palette
|
|
1546
|
+
* (fieldDragStart)="onFieldDragStart($event)"
|
|
1547
|
+
* />
|
|
1548
|
+
* ```
|
|
1549
|
+
*/
|
|
1550
|
+
declare class FieldPaletteComponent {
|
|
1551
|
+
private readonly fieldRegistry;
|
|
1552
|
+
readonly connectedDropLists: _angular_core.InputSignal<string[]>;
|
|
1553
|
+
readonly fieldDragStart: _angular_core.OutputEmitterRef<{
|
|
1554
|
+
fieldType: FieldType;
|
|
1555
|
+
metadata: IFieldTypeMetadata;
|
|
1556
|
+
}>;
|
|
1557
|
+
readonly searchQuery: _angular_core.WritableSignal<string>;
|
|
1558
|
+
readonly allFieldTypes: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
1559
|
+
readonly filteredInputFields: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
1560
|
+
readonly filteredSelectionFields: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
1561
|
+
readonly filteredSpecializedFields: _angular_core.Signal<IFieldTypeMetadata[]>;
|
|
1562
|
+
readonly noResultsFound: _angular_core.Signal<boolean>;
|
|
1563
|
+
onDragStart(event: CdkDragStart, metadata: IFieldTypeMetadata): void;
|
|
1564
|
+
private filterFields;
|
|
1565
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldPaletteComponent, never>;
|
|
1566
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FieldPaletteComponent, "fb-field-palette", never, { "connectedDropLists": { "alias": "connectedDropLists"; "required": false; "isSignal": true; }; }, { "fieldDragStart": "fieldDragStart"; }, never, never, true, never>;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
/**
|
|
1570
|
+
* Section editor component - card representation of a form section in the canvas.
|
|
1571
|
+
*
|
|
1572
|
+
* Features:
|
|
1573
|
+
* - Section title/description display (editing via right panel)
|
|
1574
|
+
* - Field drop zone (CDK Drop List)
|
|
1575
|
+
* - Field list with drag reorder
|
|
1576
|
+
* - Section actions (duplicate, delete, move up/down)
|
|
1577
|
+
*
|
|
1578
|
+
* @example
|
|
1579
|
+
* ```html
|
|
1580
|
+
* <fb-section-editor
|
|
1581
|
+
* [section]="section"
|
|
1582
|
+
* [isSelected]="isSelected"
|
|
1583
|
+
* [selectedFieldId]="selectedFieldId"
|
|
1584
|
+
* (sectionSelect)="onSectionSelect($event)"
|
|
1585
|
+
* (sectionUpdate)="onSectionUpdate($event)"
|
|
1586
|
+
* (sectionDelete)="onSectionDelete($event)"
|
|
1587
|
+
* (fieldSelect)="onFieldSelect($event)"
|
|
1588
|
+
* (fieldDrop)="onFieldDrop($event)"
|
|
1589
|
+
* />
|
|
1590
|
+
* ```
|
|
1591
|
+
*/
|
|
1592
|
+
declare class SectionEditorComponent {
|
|
1593
|
+
readonly section: _angular_core.InputSignal<ISection>;
|
|
1594
|
+
readonly isSelected: _angular_core.InputSignal<boolean>;
|
|
1595
|
+
readonly selectedFieldId: _angular_core.InputSignal<string | null>;
|
|
1596
|
+
readonly isFirst: _angular_core.InputSignal<boolean>;
|
|
1597
|
+
readonly isLast: _angular_core.InputSignal<boolean>;
|
|
1598
|
+
readonly connectedDropLists: _angular_core.InputSignal<string[]>;
|
|
1599
|
+
readonly sectionSelect: _angular_core.OutputEmitterRef<string>;
|
|
1600
|
+
readonly sectionUpdate: _angular_core.OutputEmitterRef<{
|
|
1601
|
+
sectionId: string;
|
|
1602
|
+
changes: Partial<ISection>;
|
|
1603
|
+
}>;
|
|
1604
|
+
readonly sectionDelete: _angular_core.OutputEmitterRef<string>;
|
|
1605
|
+
readonly sectionDuplicate: _angular_core.OutputEmitterRef<string>;
|
|
1606
|
+
readonly moveUp: _angular_core.OutputEmitterRef<string>;
|
|
1607
|
+
readonly moveDown: _angular_core.OutputEmitterRef<string>;
|
|
1608
|
+
readonly fieldSelect: _angular_core.OutputEmitterRef<string>;
|
|
1609
|
+
readonly fieldDrop: _angular_core.OutputEmitterRef<{
|
|
1610
|
+
sectionId: string;
|
|
1611
|
+
fieldType?: FieldType;
|
|
1612
|
+
fromIndex?: number;
|
|
1613
|
+
toIndex: number;
|
|
1614
|
+
fromSectionId?: string;
|
|
1615
|
+
}>;
|
|
1616
|
+
readonly fieldDelete: _angular_core.OutputEmitterRef<{
|
|
1617
|
+
sectionId: string;
|
|
1618
|
+
fieldId: string;
|
|
1619
|
+
}>;
|
|
1620
|
+
readonly fieldDuplicate: _angular_core.OutputEmitterRef<{
|
|
1621
|
+
sectionId: string;
|
|
1622
|
+
fieldId: string;
|
|
1623
|
+
}>;
|
|
1624
|
+
readonly sectionId: _angular_core.Signal<string>;
|
|
1625
|
+
readonly dropListId: _angular_core.Signal<string>;
|
|
1626
|
+
readonly sectionColumns: _angular_core.Signal<number>;
|
|
1627
|
+
readonly layoutStyles: _angular_core.Signal<{
|
|
1628
|
+
display: string;
|
|
1629
|
+
gridTemplateColumns: string;
|
|
1630
|
+
gap: string;
|
|
1631
|
+
flexWrap?: undefined;
|
|
1632
|
+
} | {
|
|
1633
|
+
display: string;
|
|
1634
|
+
flexWrap: string;
|
|
1635
|
+
gap: string;
|
|
1636
|
+
gridTemplateColumns?: undefined;
|
|
1637
|
+
}>;
|
|
1638
|
+
onSectionClick(event: MouseEvent): void;
|
|
1639
|
+
onFieldDropped(event: CdkDragDrop<IField[], IField[] | IFieldTypeMetadata[]>): void;
|
|
1640
|
+
onFieldDelete(fieldId: string): void;
|
|
1641
|
+
onFieldDuplicate(fieldId: string): void;
|
|
1642
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SectionEditorComponent, never>;
|
|
1643
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SectionEditorComponent, "fb-section-editor", never, { "section": { "alias": "section"; "required": true; "isSignal": true; }; "isSelected": { "alias": "isSelected"; "required": false; "isSignal": true; }; "selectedFieldId": { "alias": "selectedFieldId"; "required": false; "isSignal": true; }; "isFirst": { "alias": "isFirst"; "required": false; "isSignal": true; }; "isLast": { "alias": "isLast"; "required": false; "isSignal": true; }; "connectedDropLists": { "alias": "connectedDropLists"; "required": false; "isSignal": true; }; }, { "sectionSelect": "sectionSelect"; "sectionUpdate": "sectionUpdate"; "sectionDelete": "sectionDelete"; "sectionDuplicate": "sectionDuplicate"; "moveUp": "moveUp"; "moveDown": "moveDown"; "fieldSelect": "fieldSelect"; "fieldDrop": "fieldDrop"; "fieldDelete": "fieldDelete"; "fieldDuplicate": "fieldDuplicate"; }, never, never, true, never>;
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
interface IWidthOption {
|
|
1647
|
+
label: string;
|
|
1648
|
+
value: FieldWidth;
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Field editor component - right panel for configuring fields and sections.
|
|
1652
|
+
*
|
|
1653
|
+
* Tabs:
|
|
1654
|
+
* - General: Label, placeholder, required, help text, width
|
|
1655
|
+
* - Validation: Type-specific validation rules
|
|
1656
|
+
* - Logic: Conditional visibility rules
|
|
1657
|
+
*
|
|
1658
|
+
* @example
|
|
1659
|
+
* ```html
|
|
1660
|
+
* <fb-field-editor
|
|
1661
|
+
* [field]="selectedField"
|
|
1662
|
+
* [section]="selectedSection"
|
|
1663
|
+
* (fieldUpdated)="onFieldUpdate($event)"
|
|
1664
|
+
* (sectionUpdated)="onSectionUpdate($event)"
|
|
1665
|
+
* />
|
|
1666
|
+
* ```
|
|
1667
|
+
*/
|
|
1668
|
+
declare class FieldEditorComponent {
|
|
1669
|
+
readonly FieldType: typeof FieldType;
|
|
1670
|
+
readonly field: _angular_core.InputSignal<IField | null>;
|
|
1671
|
+
readonly section: _angular_core.InputSignal<ISection>;
|
|
1672
|
+
readonly fieldUpdated: _angular_core.OutputEmitterRef<{
|
|
1673
|
+
fieldId: string;
|
|
1674
|
+
changes: Partial<IField>;
|
|
1675
|
+
}>;
|
|
1676
|
+
readonly sectionUpdated: _angular_core.OutputEmitterRef<{
|
|
1677
|
+
sectionId: string;
|
|
1678
|
+
changes: Partial<ISection>;
|
|
1679
|
+
}>;
|
|
1680
|
+
activeTab: string;
|
|
1681
|
+
readonly widthOptions: IWidthOption[];
|
|
1682
|
+
readonly columnOptions: {
|
|
1683
|
+
label: string;
|
|
1684
|
+
value: number;
|
|
1685
|
+
}[];
|
|
1686
|
+
readonly gapOptions: {
|
|
1687
|
+
label: string;
|
|
1688
|
+
value: string;
|
|
1689
|
+
}[];
|
|
1690
|
+
private readonly _formData;
|
|
1691
|
+
readonly formData: _angular_core.Signal<Record<string, unknown>>;
|
|
1692
|
+
private readonly _sectionFormData;
|
|
1693
|
+
readonly sectionFormData: _angular_core.Signal<Record<string, unknown>>;
|
|
1694
|
+
readonly fieldIcon: _angular_core.Signal<string>;
|
|
1695
|
+
readonly fieldTypeLabel: _angular_core.Signal<string>;
|
|
1696
|
+
readonly hasFieldOptions: _angular_core.Signal<boolean>;
|
|
1697
|
+
/** Fields that have actual validation options */
|
|
1698
|
+
readonly hasValidationOptions: _angular_core.Signal<boolean>;
|
|
1699
|
+
readonly fieldOptions: _angular_core.Signal<IFieldOption[]>;
|
|
1700
|
+
readonly maxFileSizeMB: _angular_core.Signal<number>;
|
|
1701
|
+
readonly sectionColumns: _angular_core.Signal<number>;
|
|
1702
|
+
readonly sectionGap: _angular_core.Signal<string>;
|
|
1703
|
+
readonly likertScaleLabels: _angular_core.Signal<string[]>;
|
|
1704
|
+
readonly likertRows: _angular_core.Signal<ILikertRow[]>;
|
|
1705
|
+
constructor();
|
|
1706
|
+
updateFormData(key: string, value: unknown): void;
|
|
1707
|
+
updateSectionData(key: string, value: unknown): void;
|
|
1708
|
+
updateSectionLayout(key: 'columns' | 'gap', value: number | string): void;
|
|
1709
|
+
updateMaxFileSize(mb: number): void;
|
|
1710
|
+
updateOption(index: number, key: keyof IFieldOption, value: unknown): void;
|
|
1711
|
+
addOption(): void;
|
|
1712
|
+
removeOption(index: number): void;
|
|
1713
|
+
updateScaleLabel(index: number, value: string): void;
|
|
1714
|
+
addScaleLabel(): void;
|
|
1715
|
+
removeScaleLabel(index: number): void;
|
|
1716
|
+
updateRowLabel(index: number, value: string): void;
|
|
1717
|
+
addRow(): void;
|
|
1718
|
+
removeRow(index: number): void;
|
|
1719
|
+
private emitFieldUpdate;
|
|
1720
|
+
private emitSectionUpdate;
|
|
1721
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldEditorComponent, never>;
|
|
1722
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FieldEditorComponent, "fb-field-editor", never, { "field": { "alias": "field"; "required": false; "isSignal": true; }; "section": { "alias": "section"; "required": true; "isSignal": true; }; }, { "fieldUpdated": "fieldUpdated"; "sectionUpdated": "sectionUpdated"; }, never, never, true, never>;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
/**
|
|
1726
|
+
* Builder canvas component - center panel displaying all sections.
|
|
1727
|
+
*
|
|
1728
|
+
* Features:
|
|
1729
|
+
* - Section list with CDK drag reorder
|
|
1730
|
+
* - Add section button
|
|
1731
|
+
* - Empty state for no sections
|
|
1732
|
+
* - Preview mode support
|
|
1733
|
+
*
|
|
1734
|
+
* @example
|
|
1735
|
+
* ```html
|
|
1736
|
+
* <fb-builder-canvas
|
|
1737
|
+
* [sections]="sections"
|
|
1738
|
+
* [selectedSectionId]="selectedSectionId"
|
|
1739
|
+
* [selectedFieldId]="selectedFieldId"
|
|
1740
|
+
* [previewMode]="previewMode"
|
|
1741
|
+
* (sectionSelected)="onSectionSelect($event)"
|
|
1742
|
+
* (fieldSelected)="onFieldSelect($event)"
|
|
1743
|
+
* (sectionReorder)="onSectionReorder($event)"
|
|
1744
|
+
* />
|
|
1745
|
+
* ```
|
|
1746
|
+
*/
|
|
1747
|
+
declare class BuilderCanvasComponent {
|
|
1748
|
+
private readonly state;
|
|
1749
|
+
readonly sections: _angular_core.InputSignal<ISection[]>;
|
|
1750
|
+
readonly selectedSectionId: _angular_core.InputSignal<string | null>;
|
|
1751
|
+
readonly selectedFieldId: _angular_core.InputSignal<string | null>;
|
|
1752
|
+
readonly previewMode: _angular_core.InputSignal<boolean>;
|
|
1753
|
+
readonly sectionSelected: _angular_core.OutputEmitterRef<string>;
|
|
1754
|
+
readonly fieldSelected: _angular_core.OutputEmitterRef<string>;
|
|
1755
|
+
readonly sectionReorder: _angular_core.OutputEmitterRef<{
|
|
1756
|
+
fromIndex: number;
|
|
1757
|
+
toIndex: number;
|
|
1758
|
+
}>;
|
|
1759
|
+
readonly connectedDropListIds: _angular_core.Signal<string[]>;
|
|
1760
|
+
addSection(): void;
|
|
1761
|
+
onSectionDropped(event: CdkDragDrop<ISection[]>): void;
|
|
1762
|
+
onSectionUpdate(event: {
|
|
1763
|
+
sectionId: string;
|
|
1764
|
+
changes: Partial<ISection>;
|
|
1765
|
+
}): void;
|
|
1766
|
+
onSectionDelete(sectionId: string): void;
|
|
1767
|
+
onSectionDuplicate(sectionId: string): void;
|
|
1768
|
+
onMoveUp(sectionId: string): void;
|
|
1769
|
+
onMoveDown(sectionId: string): void;
|
|
1770
|
+
onFieldDrop(event: {
|
|
1771
|
+
sectionId: string;
|
|
1772
|
+
fieldType?: FieldType;
|
|
1773
|
+
fromIndex?: number;
|
|
1774
|
+
toIndex: number;
|
|
1775
|
+
fromSectionId?: string;
|
|
1776
|
+
}): void;
|
|
1777
|
+
onFieldDelete(event: {
|
|
1778
|
+
sectionId: string;
|
|
1779
|
+
fieldId: string;
|
|
1780
|
+
}): void;
|
|
1781
|
+
onFieldDuplicate(event: {
|
|
1782
|
+
sectionId: string;
|
|
1783
|
+
fieldId: string;
|
|
1784
|
+
}): void;
|
|
1785
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BuilderCanvasComponent, never>;
|
|
1786
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BuilderCanvasComponent, "fb-builder-canvas", never, { "sections": { "alias": "sections"; "required": true; "isSignal": true; }; "selectedSectionId": { "alias": "selectedSectionId"; "required": false; "isSignal": true; }; "selectedFieldId": { "alias": "selectedFieldId"; "required": false; "isSignal": true; }; "previewMode": { "alias": "previewMode"; "required": false; "isSignal": true; }; }, { "sectionSelected": "sectionSelected"; "fieldSelected": "fieldSelected"; "sectionReorder": "sectionReorder"; }, never, never, true, never>;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
/**
|
|
1790
|
+
* Field preview component - displays a field representation in the canvas.
|
|
1791
|
+
*
|
|
1792
|
+
* Features:
|
|
1793
|
+
* - Field label and type icon
|
|
1794
|
+
* - Selected state styling
|
|
1795
|
+
* - Drag handle for reordering
|
|
1796
|
+
* - Click to select
|
|
1797
|
+
* - Delete and duplicate actions
|
|
1798
|
+
*
|
|
1799
|
+
* @example
|
|
1800
|
+
* ```html
|
|
1801
|
+
* <fb-field-preview
|
|
1802
|
+
* [field]="field"
|
|
1803
|
+
* [isSelected]="isSelected"
|
|
1804
|
+
* (fieldSelect)="onFieldSelect($event)"
|
|
1805
|
+
* (fieldDelete)="onFieldDelete($event)"
|
|
1806
|
+
* (fieldDuplicate)="onFieldDuplicate($event)"
|
|
1807
|
+
* />
|
|
1808
|
+
* ```
|
|
1809
|
+
*/
|
|
1810
|
+
declare class FieldPreviewComponent {
|
|
1811
|
+
readonly field: _angular_core.InputSignal<IField>;
|
|
1812
|
+
readonly columns: _angular_core.InputSignal<number>;
|
|
1813
|
+
readonly isSelected: _angular_core.InputSignal<boolean>;
|
|
1814
|
+
readonly fieldSelect: _angular_core.OutputEmitterRef<string>;
|
|
1815
|
+
readonly fieldDelete: _angular_core.OutputEmitterRef<string>;
|
|
1816
|
+
readonly fieldDuplicate: _angular_core.OutputEmitterRef<string>;
|
|
1817
|
+
readonly fieldIcon: _angular_core.Signal<string>;
|
|
1818
|
+
readonly fieldTypeLabel: _angular_core.Signal<string>;
|
|
1819
|
+
readonly fieldStyles: _angular_core.Signal<{
|
|
1820
|
+
gridColumn: string;
|
|
1821
|
+
}>;
|
|
1822
|
+
onFieldClick(event: MouseEvent): void;
|
|
1823
|
+
onDelete(event: MouseEvent): void;
|
|
1824
|
+
onDuplicate(event: MouseEvent): void;
|
|
1825
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldPreviewComponent, never>;
|
|
1826
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FieldPreviewComponent, "fb-field-preview", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "isSelected": { "alias": "isSelected"; "required": false; "isSignal": true; }; }, { "fieldSelect": "fieldSelect"; "fieldDelete": "fieldDelete"; "fieldDuplicate": "fieldDuplicate"; }, never, never, true, never>;
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
/**
|
|
1830
|
+
* Form viewer component for runtime form rendering.
|
|
1831
|
+
*
|
|
1832
|
+
* Features:
|
|
1833
|
+
* - Renders form from IFormSchema
|
|
1834
|
+
* - Section-based navigation with steps (p-steps)
|
|
1835
|
+
* - Progress bar (p-progressbar)
|
|
1836
|
+
* - Validates on next/submit
|
|
1837
|
+
* - Logic evaluation for field/section visibility
|
|
1838
|
+
* - Provides ConditionalLogicService at component level
|
|
1839
|
+
*
|
|
1840
|
+
* @example
|
|
1841
|
+
* ```html
|
|
1842
|
+
* <fb-form-viewer
|
|
1843
|
+
* [schema]="formSchema"
|
|
1844
|
+
* [initialValues]="savedValues"
|
|
1845
|
+
* [disabled]="isReadOnly"
|
|
1846
|
+
* (submitted)="onFormSubmit($event)"
|
|
1847
|
+
* (valueChanged)="onValueChange($event)"
|
|
1848
|
+
* />
|
|
1849
|
+
* ```
|
|
1850
|
+
*/
|
|
1851
|
+
declare class FormViewerComponent {
|
|
1852
|
+
private readonly logicService;
|
|
1853
|
+
private readonly validationService;
|
|
1854
|
+
readonly schema: _angular_core.InputSignal<IFormSchema>;
|
|
1855
|
+
readonly initialValues: _angular_core.InputSignal<Record<string, unknown>>;
|
|
1856
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
1857
|
+
readonly showHeader: _angular_core.InputSignal<boolean>;
|
|
1858
|
+
readonly showSubmit: _angular_core.InputSignal<boolean>;
|
|
1859
|
+
readonly submitLabel: _angular_core.InputSignal<string>;
|
|
1860
|
+
readonly isSubmitting: _angular_core.InputSignal<boolean>;
|
|
1861
|
+
readonly valueChanged: _angular_core.OutputEmitterRef<Record<string, unknown>>;
|
|
1862
|
+
readonly submitted: _angular_core.OutputEmitterRef<Record<string, unknown>>;
|
|
1863
|
+
readonly validityChanged: _angular_core.OutputEmitterRef<boolean>;
|
|
1864
|
+
readonly saveDraft: _angular_core.OutputEmitterRef<Record<string, unknown>>;
|
|
1865
|
+
private readonly _formValues;
|
|
1866
|
+
private readonly _activeStepIndex;
|
|
1867
|
+
private readonly _errors;
|
|
1868
|
+
private readonly _touched;
|
|
1869
|
+
readonly formValues: _angular_core.Signal<Record<string, unknown>>;
|
|
1870
|
+
readonly activeStepIndex: _angular_core.Signal<number>;
|
|
1871
|
+
readonly settings: _angular_core.Signal<IFormSettings>;
|
|
1872
|
+
readonly visibleSections: _angular_core.Signal<ISection[]>;
|
|
1873
|
+
readonly currentSection: _angular_core.Signal<ISection | null>;
|
|
1874
|
+
readonly stepsItems: _angular_core.Signal<MenuItem[]>;
|
|
1875
|
+
readonly progressValue: _angular_core.Signal<number>;
|
|
1876
|
+
readonly hasPreviousSection: _angular_core.Signal<boolean>;
|
|
1877
|
+
readonly hasNextSection: _angular_core.Signal<boolean>;
|
|
1878
|
+
readonly sectionErrors: _angular_core.Signal<Map<string, string>>;
|
|
1879
|
+
readonly isFormValid: _angular_core.Signal<boolean>;
|
|
1880
|
+
constructor();
|
|
1881
|
+
/**
|
|
1882
|
+
* Handle field value changes
|
|
1883
|
+
*/
|
|
1884
|
+
onFieldValueChange(event: {
|
|
1885
|
+
fieldId: string;
|
|
1886
|
+
value: unknown;
|
|
1887
|
+
}): void;
|
|
1888
|
+
/**
|
|
1889
|
+
* Navigate to a specific section
|
|
1890
|
+
*/
|
|
1891
|
+
goToSection(index: number): void;
|
|
1892
|
+
/**
|
|
1893
|
+
* Navigate to previous section
|
|
1894
|
+
*/
|
|
1895
|
+
goToPreviousSection(): void;
|
|
1896
|
+
/**
|
|
1897
|
+
* Navigate to next section with validation
|
|
1898
|
+
*/
|
|
1899
|
+
goToNextSection(): void;
|
|
1900
|
+
/**
|
|
1901
|
+
* Handle step change from p-steps
|
|
1902
|
+
*/
|
|
1903
|
+
onStepChange(index: number): void;
|
|
1904
|
+
/**
|
|
1905
|
+
* Handle form submission
|
|
1906
|
+
*/
|
|
1907
|
+
onSubmit(): void;
|
|
1908
|
+
/**
|
|
1909
|
+
* Handle save draft
|
|
1910
|
+
*/
|
|
1911
|
+
onSaveDraft(): void;
|
|
1912
|
+
/**
|
|
1913
|
+
* Validate a single field
|
|
1914
|
+
*/
|
|
1915
|
+
private validateField;
|
|
1916
|
+
/**
|
|
1917
|
+
* Validate current section
|
|
1918
|
+
*/
|
|
1919
|
+
private validateCurrentSection;
|
|
1920
|
+
/**
|
|
1921
|
+
* Validate all sections
|
|
1922
|
+
*/
|
|
1923
|
+
private validateAllSections;
|
|
1924
|
+
/**
|
|
1925
|
+
* Find section index containing a field
|
|
1926
|
+
*/
|
|
1927
|
+
private findSectionIndexByFieldId;
|
|
1928
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormViewerComponent, never>;
|
|
1929
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormViewerComponent, "fb-form-viewer", never, { "schema": { "alias": "schema"; "required": true; "isSignal": true; }; "initialValues": { "alias": "initialValues"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "showHeader": { "alias": "showHeader"; "required": false; "isSignal": true; }; "showSubmit": { "alias": "showSubmit"; "required": false; "isSignal": true; }; "submitLabel": { "alias": "submitLabel"; "required": false; "isSignal": true; }; "isSubmitting": { "alias": "isSubmitting"; "required": false; "isSignal": true; }; }, { "valueChanged": "valueChanged"; "submitted": "submitted"; "validityChanged": "validityChanged"; "saveDraft": "saveDraft"; }, never, never, true, never>;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
/**
|
|
1933
|
+
* Section viewer component for rendering form sections.
|
|
1934
|
+
*
|
|
1935
|
+
* Features:
|
|
1936
|
+
* - Renders fields with configured layout (flex/grid)
|
|
1937
|
+
* - Supports collapsible sections
|
|
1938
|
+
* - Applies field visibility based on logic
|
|
1939
|
+
*
|
|
1940
|
+
* @example
|
|
1941
|
+
* ```html
|
|
1942
|
+
* <fb-section-viewer
|
|
1943
|
+
* [section]="section"
|
|
1944
|
+
* [values]="formValues"
|
|
1945
|
+
* [errors]="sectionErrors"
|
|
1946
|
+
* [disabled]="isDisabled"
|
|
1947
|
+
* (valueChanged)="onValueChange($event)"
|
|
1948
|
+
* />
|
|
1949
|
+
* ```
|
|
1950
|
+
*/
|
|
1951
|
+
declare class SectionViewerComponent {
|
|
1952
|
+
readonly section: _angular_core.InputSignal<ISection>;
|
|
1953
|
+
readonly values: _angular_core.InputSignal<Record<string, unknown>>;
|
|
1954
|
+
readonly errors: _angular_core.InputSignal<Map<string, string>>;
|
|
1955
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
1956
|
+
readonly valueChanged: _angular_core.OutputEmitterRef<{
|
|
1957
|
+
fieldId: string;
|
|
1958
|
+
value: unknown;
|
|
1959
|
+
}>;
|
|
1960
|
+
readonly collapsed: _angular_core.WritableSignal<boolean>;
|
|
1961
|
+
readonly isCollapsible: _angular_core.Signal<boolean>;
|
|
1962
|
+
constructor();
|
|
1963
|
+
readonly sortedFields: _angular_core.Signal<_flusys_ng_form_builder.IField[]>;
|
|
1964
|
+
readonly gridColumns: _angular_core.Signal<number>;
|
|
1965
|
+
readonly layoutGap: _angular_core.Signal<string>;
|
|
1966
|
+
/**
|
|
1967
|
+
* Get value for a specific field
|
|
1968
|
+
*/
|
|
1969
|
+
getValue(fieldId: string): unknown;
|
|
1970
|
+
/**
|
|
1971
|
+
* Get errors for a specific field as string array
|
|
1972
|
+
*/
|
|
1973
|
+
getFieldErrors(fieldId: string): string[];
|
|
1974
|
+
/**
|
|
1975
|
+
* Handle field value change
|
|
1976
|
+
*/
|
|
1977
|
+
onFieldValueChange(fieldId: string, value: unknown): void;
|
|
1978
|
+
/**
|
|
1979
|
+
* Handle collapsed state change
|
|
1980
|
+
*/
|
|
1981
|
+
onCollapsedChange(collapsed: boolean): void;
|
|
1982
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SectionViewerComponent, never>;
|
|
1983
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SectionViewerComponent, "fb-section-viewer", never, { "section": { "alias": "section"; "required": true; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "valueChanged": "valueChanged"; }, never, never, true, never>;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
/**
|
|
1987
|
+
* Field viewer component for dynamic field rendering.
|
|
1988
|
+
*
|
|
1989
|
+
* Features:
|
|
1990
|
+
* - Switches on field type to render appropriate field component
|
|
1991
|
+
* - Passes value and handles changes
|
|
1992
|
+
* - Uses @switch for field type selection
|
|
1993
|
+
* - Respects conditional logic visibility
|
|
1994
|
+
*
|
|
1995
|
+
* @example
|
|
1996
|
+
* ```html
|
|
1997
|
+
* <fb-field-viewer
|
|
1998
|
+
* [field]="field"
|
|
1999
|
+
* [value]="fieldValue"
|
|
2000
|
+
* [disabled]="isDisabled"
|
|
2001
|
+
* [errors]="fieldErrors"
|
|
2002
|
+
* (valueChanged)="onValueChange($event)"
|
|
2003
|
+
* />
|
|
2004
|
+
* ```
|
|
2005
|
+
*/
|
|
2006
|
+
declare class FieldViewerComponent {
|
|
2007
|
+
private readonly logicService;
|
|
2008
|
+
protected readonly FieldType: typeof FieldType;
|
|
2009
|
+
readonly field: _angular_core.InputSignal<IField>;
|
|
2010
|
+
readonly value: _angular_core.InputSignal<unknown>;
|
|
2011
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
2012
|
+
readonly errors: _angular_core.InputSignal<string[]>;
|
|
2013
|
+
readonly valueChanged: _angular_core.OutputEmitterRef<unknown>;
|
|
2014
|
+
readonly fieldType: _angular_core.Signal<FieldType>;
|
|
2015
|
+
readonly isVisible: _angular_core.Signal<boolean>;
|
|
2016
|
+
/**
|
|
2017
|
+
* Handle value change from field components
|
|
2018
|
+
*/
|
|
2019
|
+
onValueChange(value: unknown): void;
|
|
2020
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldViewerComponent, never>;
|
|
2021
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FieldViewerComponent, "fb-field-viewer", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; }, { "valueChanged": "valueChanged"; }, never, never, true, never>;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
/**
|
|
2025
|
+
* Form result viewer component for post-submission display.
|
|
2026
|
+
*
|
|
2027
|
+
* Features:
|
|
2028
|
+
* - Shows form name and submission date
|
|
2029
|
+
* - Accordion sections (p-accordion)
|
|
2030
|
+
* - Status badge (completed/draft)
|
|
2031
|
+
* - Optional analytics display
|
|
2032
|
+
*
|
|
2033
|
+
* @example
|
|
2034
|
+
* ```html
|
|
2035
|
+
* <fb-form-result-viewer
|
|
2036
|
+
* [schema]="formSchema"
|
|
2037
|
+
* [result]="submissionResult"
|
|
2038
|
+
* [showAnalytics]="true"
|
|
2039
|
+
* (fieldClick)="onFieldClick($event)"
|
|
2040
|
+
* />
|
|
2041
|
+
* ```
|
|
2042
|
+
*/
|
|
2043
|
+
declare class FormResultViewerComponent {
|
|
2044
|
+
readonly schema: _angular_core.InputSignal<IFormSchema>;
|
|
2045
|
+
readonly result: _angular_core.InputSignal<IFormSubmission>;
|
|
2046
|
+
readonly showAnalytics: _angular_core.InputSignal<boolean>;
|
|
2047
|
+
readonly fieldClick: _angular_core.OutputEmitterRef<{
|
|
2048
|
+
field: IField;
|
|
2049
|
+
value: unknown;
|
|
2050
|
+
}>;
|
|
2051
|
+
readonly sortedSections: _angular_core.Signal<ISection[]>;
|
|
2052
|
+
readonly isDraft: _angular_core.Signal<boolean>;
|
|
2053
|
+
readonly statusLabel: _angular_core.Signal<string>;
|
|
2054
|
+
readonly statusSeverity: _angular_core.Signal<"success" | "warn" | "info" | "danger" | "secondary" | "contrast">;
|
|
2055
|
+
readonly statusIcon: _angular_core.Signal<string>;
|
|
2056
|
+
readonly formattedDate: _angular_core.Signal<string>;
|
|
2057
|
+
readonly totalFieldCount: _angular_core.Signal<number>;
|
|
2058
|
+
readonly answeredCount: _angular_core.Signal<number>;
|
|
2059
|
+
readonly activeValues: _angular_core.Signal<string[]>;
|
|
2060
|
+
/**
|
|
2061
|
+
* Get answered count for a specific section
|
|
2062
|
+
*/
|
|
2063
|
+
getSectionAnsweredCount(section: ISection): number;
|
|
2064
|
+
/**
|
|
2065
|
+
* Handle field click event
|
|
2066
|
+
*/
|
|
2067
|
+
onFieldClick(event: {
|
|
2068
|
+
field: IField;
|
|
2069
|
+
value: unknown;
|
|
2070
|
+
}): void;
|
|
2071
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormResultViewerComponent, never>;
|
|
2072
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormResultViewerComponent, "fb-form-result-viewer", never, { "schema": { "alias": "schema"; "required": true; "isSignal": true; }; "result": { "alias": "result"; "required": true; "isSignal": true; }; "showAnalytics": { "alias": "showAnalytics"; "required": false; "isSignal": true; }; }, { "fieldClick": "fieldClick"; }, never, never, true, never>;
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
/**
|
|
2076
|
+
* Section result component for displaying section answers.
|
|
2077
|
+
*
|
|
2078
|
+
* Features:
|
|
2079
|
+
* - Renders fields as label/value pairs
|
|
2080
|
+
* - Handles field click events
|
|
2081
|
+
* - Used inside accordion panels (no internal collapsible wrapper)
|
|
2082
|
+
*
|
|
2083
|
+
* @example
|
|
2084
|
+
* ```html
|
|
2085
|
+
* <fb-section-result
|
|
2086
|
+
* [section]="section"
|
|
2087
|
+
* [values]="submissionValues"
|
|
2088
|
+
* (fieldClick)="onFieldClick($event)"
|
|
2089
|
+
* />
|
|
2090
|
+
* ```
|
|
2091
|
+
*/
|
|
2092
|
+
declare class SectionResultComponent {
|
|
2093
|
+
readonly section: _angular_core.InputSignal<ISection>;
|
|
2094
|
+
readonly values: _angular_core.InputSignal<Record<string, unknown>>;
|
|
2095
|
+
readonly fieldClick: _angular_core.OutputEmitterRef<{
|
|
2096
|
+
field: IField;
|
|
2097
|
+
value: unknown;
|
|
2098
|
+
}>;
|
|
2099
|
+
readonly sortedFields: _angular_core.Signal<IField[]>;
|
|
2100
|
+
/**
|
|
2101
|
+
* Get value for a specific field
|
|
2102
|
+
*/
|
|
2103
|
+
getValue(fieldId: string): unknown;
|
|
2104
|
+
/**
|
|
2105
|
+
* Handle field click
|
|
2106
|
+
*/
|
|
2107
|
+
onFieldClick(field: IField): void;
|
|
2108
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SectionResultComponent, never>;
|
|
2109
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SectionResultComponent, "fb-section-result", never, { "section": { "alias": "section"; "required": true; "isSignal": true; }; "values": { "alias": "values"; "required": false; "isSignal": true; }; }, { "fieldClick": "fieldClick"; }, never, never, true, never>;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
/**
|
|
2113
|
+
* Field result component for displaying individual answer values.
|
|
2114
|
+
*
|
|
2115
|
+
* Features:
|
|
2116
|
+
* - Resolves option IDs to labels for display
|
|
2117
|
+
* - Shows multi-select as chips
|
|
2118
|
+
* - Shows likert as row:value pairs
|
|
2119
|
+
* - Clean, read-only display format
|
|
2120
|
+
*
|
|
2121
|
+
* @example
|
|
2122
|
+
* ```html
|
|
2123
|
+
* <fb-field-result
|
|
2124
|
+
* [field]="field"
|
|
2125
|
+
* [value]="fieldValue"
|
|
2126
|
+
* (click)="onFieldClick()"
|
|
2127
|
+
* />
|
|
2128
|
+
* ```
|
|
2129
|
+
*/
|
|
2130
|
+
declare class FieldResultComponent {
|
|
2131
|
+
protected readonly FieldType: typeof FieldType;
|
|
2132
|
+
readonly field: _angular_core.InputSignal<IField>;
|
|
2133
|
+
readonly value: _angular_core.InputSignal<unknown>;
|
|
2134
|
+
readonly click: _angular_core.OutputEmitterRef<void>;
|
|
2135
|
+
/**
|
|
2136
|
+
* Get label for single-select fields (radio, dropdown)
|
|
2137
|
+
*/
|
|
2138
|
+
readonly singleOptionLabel: _angular_core.Signal<string>;
|
|
2139
|
+
/**
|
|
2140
|
+
* Get labels for multi-select field
|
|
2141
|
+
*/
|
|
2142
|
+
readonly multiSelectLabels: _angular_core.Signal<string[]>;
|
|
2143
|
+
/**
|
|
2144
|
+
* Get display data for likert field
|
|
2145
|
+
*/
|
|
2146
|
+
readonly likertDisplay: _angular_core.Signal<{
|
|
2147
|
+
rowId: string;
|
|
2148
|
+
rowLabel: string;
|
|
2149
|
+
scaleLabel: string;
|
|
2150
|
+
}[]>;
|
|
2151
|
+
/**
|
|
2152
|
+
* Get display data for file upload field
|
|
2153
|
+
*/
|
|
2154
|
+
readonly fileDisplay: _angular_core.Signal<{
|
|
2155
|
+
name: string;
|
|
2156
|
+
size: string;
|
|
2157
|
+
type: string;
|
|
2158
|
+
} | null>;
|
|
2159
|
+
/**
|
|
2160
|
+
* Format file size to human readable string
|
|
2161
|
+
*/
|
|
2162
|
+
private formatFileSize;
|
|
2163
|
+
/**
|
|
2164
|
+
* Default display value for simple fields
|
|
2165
|
+
*/
|
|
2166
|
+
readonly displayValue: _angular_core.Signal<string>;
|
|
2167
|
+
/**
|
|
2168
|
+
* Handle click
|
|
2169
|
+
*/
|
|
2170
|
+
onClick(): void;
|
|
2171
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldResultComponent, never>;
|
|
2172
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FieldResultComponent, "fb-field-result", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "click": "click"; }, never, never, true, never>;
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
interface ITab {
|
|
2176
|
+
id: string;
|
|
2177
|
+
label: string;
|
|
2178
|
+
icon: string;
|
|
2179
|
+
route: string;
|
|
2180
|
+
}
|
|
2181
|
+
/**
|
|
2182
|
+
* Form Builder Container Component
|
|
2183
|
+
*
|
|
2184
|
+
* Main container with tab navigation for form builder demo
|
|
2185
|
+
* Tabs: Builder | Viewer | Result Viewer
|
|
2186
|
+
*/
|
|
2187
|
+
declare class FormBuilderContainerComponent {
|
|
2188
|
+
readonly tabs: ITab[];
|
|
2189
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormBuilderContainerComponent, never>;
|
|
2190
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormBuilderContainerComponent, "lib-form-builder-container", never, {}, {}, never, never, true, never>;
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
/**
|
|
2194
|
+
* Builder Page Component
|
|
2195
|
+
*
|
|
2196
|
+
* Demo page for testing the FormBuilderComponent
|
|
2197
|
+
*/
|
|
2198
|
+
declare class BuilderPageComponent {
|
|
2199
|
+
private readonly platformId;
|
|
2200
|
+
private readonly messageService;
|
|
2201
|
+
private readonly isBrowser;
|
|
2202
|
+
readonly formSchema: _angular_core.WritableSignal<IFormSchema>;
|
|
2203
|
+
onSchemaChange(schema: IFormSchema): void;
|
|
2204
|
+
onSave(schema: IFormSchema): void;
|
|
2205
|
+
onExport(schema: IFormSchema): void;
|
|
2206
|
+
private createSampleSchema;
|
|
2207
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BuilderPageComponent, never>;
|
|
2208
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BuilderPageComponent, "lib-builder-page", never, {}, {}, never, never, true, never>;
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
/**
|
|
2212
|
+
* Viewer Page Component
|
|
2213
|
+
*
|
|
2214
|
+
* Demo page for testing the FormViewerComponent
|
|
2215
|
+
*/
|
|
2216
|
+
declare class ViewerPageComponent {
|
|
2217
|
+
private readonly platformId;
|
|
2218
|
+
private readonly router;
|
|
2219
|
+
private readonly route;
|
|
2220
|
+
private readonly messageService;
|
|
2221
|
+
private readonly isBrowser;
|
|
2222
|
+
readonly formSchema: _angular_core.WritableSignal<IFormSchema | null>;
|
|
2223
|
+
readonly initialValues: _angular_core.WritableSignal<Record<string, unknown>>;
|
|
2224
|
+
readonly hasSchema: _angular_core.Signal<boolean>;
|
|
2225
|
+
onValueChange(values: Record<string, unknown>): void;
|
|
2226
|
+
onSubmit(values: Record<string, unknown>): void;
|
|
2227
|
+
onSaveDraft(values: Record<string, unknown>): void;
|
|
2228
|
+
goToBuilder(): void;
|
|
2229
|
+
private loadSchema;
|
|
2230
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ViewerPageComponent, never>;
|
|
2231
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ViewerPageComponent, "lib-viewer-page", never, {}, {}, never, never, true, never>;
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
/**
|
|
2235
|
+
* Result Page Component
|
|
2236
|
+
*
|
|
2237
|
+
* Demo page for testing the FormResultViewerComponent
|
|
2238
|
+
*/
|
|
2239
|
+
declare class ResultPageComponent {
|
|
2240
|
+
private readonly platformId;
|
|
2241
|
+
private readonly router;
|
|
2242
|
+
private readonly route;
|
|
2243
|
+
private readonly pdfExportService;
|
|
2244
|
+
private readonly isBrowser;
|
|
2245
|
+
readonly formSchema: _angular_core.WritableSignal<IFormSchema | null>;
|
|
2246
|
+
readonly submission: _angular_core.WritableSignal<IFormSubmission | null>;
|
|
2247
|
+
readonly hasSubmission: _angular_core.Signal<boolean>;
|
|
2248
|
+
downloadPdf(): Promise<void>;
|
|
2249
|
+
goToViewer(): void;
|
|
2250
|
+
goToBuilder(): void;
|
|
2251
|
+
clearSubmission(): void;
|
|
2252
|
+
private loadSchema;
|
|
2253
|
+
private loadSubmission;
|
|
2254
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ResultPageComponent, never>;
|
|
2255
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ResultPageComponent, "lib-result-page", never, {}, {}, never, never, true, never>;
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
/**
|
|
2259
|
+
* Form Builder Routes Configuration
|
|
2260
|
+
*
|
|
2261
|
+
* Demo routes for testing form builder components
|
|
2262
|
+
* - Builder: Visual form creation
|
|
2263
|
+
* - Viewer: Runtime form filling
|
|
2264
|
+
* - Result: View submitted answers
|
|
2265
|
+
*/
|
|
2266
|
+
declare const FORM_BUILDER_ROUTES: Routes;
|
|
2267
|
+
|
|
2268
|
+
export { BaseFieldComponent, BuilderCanvasComponent, BuilderPageComponent, BuilderToolbarComponent, CheckboxFieldComponent, ComparisonOperator, ConditionalLogicService, DEFAULT_FLEX_LAYOUT, DEFAULT_FORM_SETTINGS, DEFAULT_GRID_LAYOUT, DEFAULT_PDF_CONFIG, DEFAULT_SECTION_LAYOUT, DateFieldComponent, DropdownFieldComponent, EmailFieldComponent, FIELD_TYPE_INFO, FORM_BUILDER_ROUTES, FieldEditorComponent, FieldPaletteComponent, FieldPreviewComponent, FieldRegistryService, FieldResultComponent, FieldType, FieldViewerComponent, FileUploadFieldComponent, FormBuilderComponent, FormBuilderContainerComponent, FormBuilderStateService, FormResultViewerComponent, FormViewerComponent, LayoutType, LikertFieldComponent, LogicAction, LogicOperator, MultiSelectFieldComponent, NumberFieldComponent, PdfExportService, RadioFieldComponent, RatingFieldComponent, ResultPageComponent, SchemaExportService, SectionEditorComponent, SectionResultComponent, SectionViewerComponent, TextFieldComponent, ValidationRuleType, ValidationService, ViewerPageComponent, createFormSchema, createSection, formatFileSize, hasOptions, hasValue, isEmpty, isLogicGroup, provideFieldValueAccessor, sortByOrder, sortFields, sortOptions, sortSections };
|
|
2269
|
+
export type { FieldWidth, IBaseField, ICheckboxField, ICondition, IConditionalRule, ICustomRule, IDateField, IDropdownField, IEmailField, IEmailRule, IField, IFieldOption, IFieldTypeInfo, IFieldTypeMetadata, IFieldValidation, IFileUploadField, IFlexLayout, IFormSchema, IFormSettings, IFormSubmission, IGridLayout, ILikertField, ILikertRow, ILogicGroup, IMaxLengthRule, IMaxRule, IMinLengthRule, IMinRule, IMultiSelectField, INumberField, IPatternRule, IPdfExportConfig, IRadioField, IRatingField, IRequiredRule, ISchemaValidationError, ISchemaValidationResult, ISection, ISectionLayout, ITextField, IUploadedFile, IValidationError, IValidationRule };
|