@5minds/node-red-dashboard-2-processcube-dynamic-form 2.1.0-develop-9ef07a-mdiwhikf → 2.1.0-file-preview-6b0a6e-mdmztpfy
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/resources/ui-dynamic-form.umd.js +39 -19
- package/ui/components/UIDynamicForm.vue +352 -71
|
@@ -1,60 +1,140 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div className="ui-dynamic-form-external-sizing-wrapper" :style="props.card_size_styling">
|
|
3
3
|
<!-- Component must be wrapped in a block so props such as className and style can be passed in from parent -->
|
|
4
|
-
<UIDynamicFormTitleText
|
|
5
|
-
|
|
6
|
-
:
|
|
7
|
-
:
|
|
4
|
+
<UIDynamicFormTitleText
|
|
5
|
+
v-if="props.title_style === 'outside' && hasUserTask"
|
|
6
|
+
:style="props.title_style"
|
|
7
|
+
:title="effectiveTitle"
|
|
8
|
+
:customStyles="props.title_custom_text_styling"
|
|
9
|
+
:titleIcon="props.title_icon"
|
|
10
|
+
:collapsible="props.collapsible || (props.collapse_when_finished && formIsFinished)"
|
|
11
|
+
:collapsed="collapsed"
|
|
12
|
+
:toggleCollapse="toggleCollapse"
|
|
13
|
+
/>
|
|
8
14
|
<div className="ui-dynamic-form-wrapper">
|
|
9
15
|
<p v-if="hasUserTask" style="margin-bottom: 0px">
|
|
10
16
|
<v-form ref="form" v-model="form" :class="dynamicClass">
|
|
11
|
-
<UIDynamicFormTitleText
|
|
12
|
-
|
|
17
|
+
<UIDynamicFormTitleText
|
|
18
|
+
v-if="props.title_style != 'outside'"
|
|
19
|
+
:style="props.title_style"
|
|
20
|
+
:title="effectiveTitle"
|
|
21
|
+
:customStyles="props.title_custom_text_styling"
|
|
13
22
|
:titleIcon="props.title_icon"
|
|
14
23
|
:collapsible="props.collapsible || (props.collapse_when_finished && formIsFinished)"
|
|
15
|
-
:collapsed="collapsed"
|
|
24
|
+
:collapsed="collapsed"
|
|
25
|
+
:toggleCollapse="toggleCollapse"
|
|
26
|
+
/>
|
|
16
27
|
<Transition name="cardCollapse">
|
|
17
28
|
<div v-if="!collapsed">
|
|
18
|
-
<div
|
|
19
|
-
|
|
29
|
+
<div
|
|
30
|
+
className="ui-dynamic-form-formfield-positioner"
|
|
31
|
+
:style="props.inner_card_styling"
|
|
32
|
+
:data-columns="props.form_columns || 1"
|
|
33
|
+
>
|
|
20
34
|
<FormKit id="form" type="group">
|
|
21
|
-
<v-row
|
|
35
|
+
<v-row
|
|
36
|
+
v-for="(field, index) in fields()"
|
|
37
|
+
:key="field"
|
|
22
38
|
:class="field.type === 'header' ? 'ui-dynamic-form-header-row' : ''"
|
|
23
|
-
:style="getRowWidthStyling(field, index)"
|
|
39
|
+
:style="getRowWidthStyling(field, index)"
|
|
40
|
+
>
|
|
24
41
|
<v-col cols="12">
|
|
25
|
-
<component
|
|
26
|
-
|
|
27
|
-
v-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
<component
|
|
43
|
+
:is="getFieldComponent(field).type"
|
|
44
|
+
v-if="getFieldComponent(field).innerHTML"
|
|
45
|
+
v-bind="getFieldComponent(field).props"
|
|
46
|
+
:class="getFieldComponent(field).class"
|
|
47
|
+
v-html="getFieldComponent(field).innerHTML"
|
|
48
|
+
:ref="
|
|
49
|
+
(el) => {
|
|
50
|
+
if (index === 0) firstFormFieldRef = el;
|
|
51
|
+
}
|
|
52
|
+
"
|
|
53
|
+
/>
|
|
54
|
+
<component
|
|
55
|
+
:is="getFieldComponent(field).type"
|
|
56
|
+
v-else-if="getFieldComponent(field).innerText"
|
|
57
|
+
v-bind="getFieldComponent(field).props"
|
|
58
|
+
:ref="
|
|
59
|
+
(el) => {
|
|
60
|
+
if (index === 0) firstFormFieldRef = el;
|
|
61
|
+
}
|
|
62
|
+
"
|
|
63
|
+
v-model="formData[field.id]"
|
|
64
|
+
>
|
|
65
|
+
{{ getFieldComponent(field).innerText }}
|
|
40
66
|
</component>
|
|
41
|
-
<div v-else-if="
|
|
67
|
+
<div v-else-if="getFieldComponent(field).type == 'v-slider'">
|
|
42
68
|
<p class="formkit-label">{{ field.label }}</p>
|
|
43
|
-
<component
|
|
44
|
-
|
|
69
|
+
<component
|
|
70
|
+
:is="getFieldComponent(field).type"
|
|
71
|
+
v-bind="getFieldComponent(field).props"
|
|
72
|
+
:ref="
|
|
73
|
+
(el) => {
|
|
74
|
+
if (index === 0) firstFormFieldRef = el;
|
|
75
|
+
}
|
|
76
|
+
"
|
|
77
|
+
v-model="field.defaultValue"
|
|
78
|
+
/>
|
|
79
|
+
<p class="formkit-help">
|
|
80
|
+
{{
|
|
81
|
+
field.customForm ? JSON.parse(field.customForm).hint : undefined
|
|
82
|
+
}}
|
|
83
|
+
</p>
|
|
84
|
+
</div>
|
|
85
|
+
<component
|
|
86
|
+
:is="getFieldComponent(field).type"
|
|
87
|
+
v-else
|
|
88
|
+
v-bind="getFieldComponent(field).props"
|
|
89
|
+
:ref="
|
|
90
|
+
(el) => {
|
|
45
91
|
if (index === 0) firstFormFieldRef = el;
|
|
46
92
|
}
|
|
47
|
-
|
|
93
|
+
"
|
|
94
|
+
v-model="formData[field.id]"
|
|
95
|
+
/>
|
|
96
|
+
<!-- <component
|
|
97
|
+
:is="getFieldComponent(field).type"
|
|
98
|
+
v-if="getFieldComponent(field).innerText"
|
|
99
|
+
v-bind="getFieldComponent(field).props"
|
|
100
|
+
:ref="
|
|
101
|
+
(el) => {
|
|
102
|
+
if (index === 0) firstFormFieldRef = el;
|
|
103
|
+
}
|
|
104
|
+
"
|
|
105
|
+
v-model="formData[field.id]"
|
|
106
|
+
>
|
|
107
|
+
{{ getFieldComponent(field).innerText }}
|
|
108
|
+
</component>
|
|
109
|
+
<div v-else-if="getFieldComponent(field).type == 'v-slider'">
|
|
110
|
+
<p class="formkit-label">{{ field.label }}</p>
|
|
111
|
+
<component
|
|
112
|
+
:is="getFieldComponent(field).type"
|
|
113
|
+
v-bind="getFieldComponent(field).props"
|
|
114
|
+
:ref="
|
|
115
|
+
(el) => {
|
|
116
|
+
if (index === 0) firstFormFieldRef = el;
|
|
117
|
+
}
|
|
118
|
+
"
|
|
119
|
+
v-model="field.defaultValue"
|
|
120
|
+
/>
|
|
48
121
|
<p class="formkit-help">
|
|
49
|
-
{{
|
|
122
|
+
{{
|
|
123
|
+
field.customForm ? JSON.parse(field.customForm).hint : undefined
|
|
50
124
|
}}
|
|
51
125
|
</p>
|
|
52
126
|
</div>
|
|
53
|
-
<component
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
127
|
+
<component
|
|
128
|
+
:is="getFieldComponent(field).type"
|
|
129
|
+
v-else
|
|
130
|
+
v-bind="getFieldComponent(field).props"
|
|
131
|
+
:ref="
|
|
132
|
+
(el) => {
|
|
133
|
+
if (index === 0) firstFormFieldRef = el;
|
|
134
|
+
}
|
|
135
|
+
"
|
|
136
|
+
v-model="formData[field.id]"
|
|
137
|
+
/> -->
|
|
58
138
|
</v-col>
|
|
59
139
|
</v-row>
|
|
60
140
|
</FormKit>
|
|
@@ -63,17 +143,24 @@
|
|
|
63
143
|
<v-row v-if="errorMsg.length > 0" style="padding: 12px">
|
|
64
144
|
<v-alert type="error">Error: {{ errorMsg }}</v-alert>
|
|
65
145
|
</v-row>
|
|
66
|
-
<UIDynamicFormFooterAction
|
|
67
|
-
|
|
68
|
-
|
|
146
|
+
<UIDynamicFormFooterAction
|
|
147
|
+
v-if="props.actions_inside_card && actions.length > 0"
|
|
148
|
+
:actions="actions"
|
|
149
|
+
:actionCallback="actionFn"
|
|
150
|
+
:formIsFinished="formIsFinished"
|
|
151
|
+
style="padding: 16px; padding-top: 0px"
|
|
152
|
+
/>
|
|
69
153
|
</v-row>
|
|
70
154
|
</div>
|
|
71
155
|
</Transition>
|
|
72
156
|
</v-form>
|
|
73
157
|
</p>
|
|
74
158
|
<p v-else>
|
|
75
|
-
<v-alert
|
|
76
|
-
|
|
159
|
+
<v-alert
|
|
160
|
+
v-if="props.waiting_info.length > 0 || props.waiting_title.length > 0"
|
|
161
|
+
:text="props.waiting_info"
|
|
162
|
+
:title="props.waiting_title"
|
|
163
|
+
/>
|
|
77
164
|
</p>
|
|
78
165
|
</div>
|
|
79
166
|
<div v-if="!props.actions_inside_card && actions.length > 0 && hasUserTask" style="padding-top: 32px">
|
|
@@ -182,6 +269,7 @@ export default {
|
|
|
182
269
|
msg: null,
|
|
183
270
|
collapsed: false,
|
|
184
271
|
firstFormFieldRef: null,
|
|
272
|
+
componentCache: new Map(), // Add caching for components
|
|
185
273
|
};
|
|
186
274
|
},
|
|
187
275
|
computed: {
|
|
@@ -282,6 +370,26 @@ export default {
|
|
|
282
370
|
this.$socket?.off('msg-input:' + this.id);
|
|
283
371
|
},
|
|
284
372
|
methods: {
|
|
373
|
+
// Performance optimized component caching
|
|
374
|
+
getFieldComponent(field) {
|
|
375
|
+
const cacheKey = `${field.id}_${JSON.stringify(this.formData[field.id])}_${this.formIsFinished}_${
|
|
376
|
+
this.theme
|
|
377
|
+
}`;
|
|
378
|
+
|
|
379
|
+
if (this.componentCache.has(cacheKey)) {
|
|
380
|
+
return this.componentCache.get(cacheKey);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const component = this.createComponent(field);
|
|
384
|
+
this.componentCache.set(cacheKey, component);
|
|
385
|
+
return component;
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
// Clear cache when form data changes
|
|
389
|
+
clearComponentCache() {
|
|
390
|
+
this.componentCache.clear();
|
|
391
|
+
},
|
|
392
|
+
|
|
285
393
|
createComponent(field) {
|
|
286
394
|
console.debug('Creating component for field:', field);
|
|
287
395
|
const customForm = field.customForm ? JSON.parse(field.customForm) : {};
|
|
@@ -292,8 +400,10 @@ export default {
|
|
|
292
400
|
const customProperties = customForm.customProperties ?? [];
|
|
293
401
|
const isReadOnly =
|
|
294
402
|
this.props.readonly ||
|
|
295
|
-
|
|
296
|
-
|
|
403
|
+
this.formIsFinished ||
|
|
404
|
+
customProperties.find(
|
|
405
|
+
(entry) => ['readOnly', 'readonly'].includes(entry.name) && entry.value === 'true'
|
|
406
|
+
)
|
|
297
407
|
? 'true'
|
|
298
408
|
: undefined;
|
|
299
409
|
switch (field.type) {
|
|
@@ -314,7 +424,9 @@ export default {
|
|
|
314
424
|
wrapperClass: '$remove:formkit-wrapper',
|
|
315
425
|
labelClass: 'ui-dynamic-form-input-label',
|
|
316
426
|
inputClass: `input-${this.theme}`,
|
|
317
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
427
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
428
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
429
|
+
}`,
|
|
318
430
|
readonly: isReadOnly,
|
|
319
431
|
validationVisibility: 'live',
|
|
320
432
|
},
|
|
@@ -337,7 +449,9 @@ export default {
|
|
|
337
449
|
wrapperClass: '$remove:formkit-wrapper',
|
|
338
450
|
labelClass: 'ui-dynamic-form-input-label',
|
|
339
451
|
inputClass: `input-${this.theme}`,
|
|
340
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
452
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
453
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
454
|
+
}`,
|
|
341
455
|
readonly: isReadOnly,
|
|
342
456
|
validationVisibility: 'live',
|
|
343
457
|
},
|
|
@@ -356,7 +470,9 @@ export default {
|
|
|
356
470
|
wrapperClass: '$remove:formkit-wrapper',
|
|
357
471
|
labelClass: 'ui-dynamic-form-input-label',
|
|
358
472
|
inputClass: `input-${this.theme}`,
|
|
359
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
473
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
474
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
475
|
+
}`,
|
|
360
476
|
readonly: isReadOnly,
|
|
361
477
|
validation,
|
|
362
478
|
validationVisibility: 'live',
|
|
@@ -380,7 +496,9 @@ export default {
|
|
|
380
496
|
wrapperClass: '$remove:formkit-wrapper',
|
|
381
497
|
labelClass: 'ui-dynamic-form-input-label',
|
|
382
498
|
inputClass: `input-${this.theme}`,
|
|
383
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
499
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
500
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
501
|
+
}`,
|
|
384
502
|
readonly: isReadOnly,
|
|
385
503
|
disabled: isReadOnly,
|
|
386
504
|
validation,
|
|
@@ -406,7 +524,9 @@ export default {
|
|
|
406
524
|
wrapperClass: '$remove:formkit-wrapper',
|
|
407
525
|
labelClass: 'ui-dynamic-form-input-label',
|
|
408
526
|
inputClass: `input-${this.theme}`,
|
|
409
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
527
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
528
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
529
|
+
}`,
|
|
410
530
|
readonly: isReadOnly,
|
|
411
531
|
disabled: isReadOnly,
|
|
412
532
|
validation,
|
|
@@ -428,7 +548,9 @@ export default {
|
|
|
428
548
|
wrapperClass: '$remove:formkit-wrapper',
|
|
429
549
|
labelClass: 'ui-dynamic-form-input-label',
|
|
430
550
|
inputClass: `input-${this.theme}`,
|
|
431
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
551
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
552
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
553
|
+
}`,
|
|
432
554
|
readonly: isReadOnly,
|
|
433
555
|
validation,
|
|
434
556
|
validationVisibility: 'live',
|
|
@@ -452,13 +574,131 @@ export default {
|
|
|
452
574
|
help: hint,
|
|
453
575
|
labelClass: 'ui-dynamic-form-input-label',
|
|
454
576
|
inputClass: `input-${this.theme}`,
|
|
455
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
577
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
578
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
579
|
+
}`,
|
|
456
580
|
readonly: isReadOnly,
|
|
457
581
|
disabled: isReadOnly,
|
|
458
582
|
validation,
|
|
459
583
|
validationVisibility: 'live',
|
|
460
584
|
},
|
|
461
585
|
};
|
|
586
|
+
case 'file-preview':
|
|
587
|
+
// Handle file preview display only (no upload functionality)
|
|
588
|
+
const originalFieldId = field.id.replace('_preview', '');
|
|
589
|
+
if (this.formData && this.formData[originalFieldId] && this.formData[originalFieldId].length != 0) {
|
|
590
|
+
const fileDataArray = Array.isArray(this.formData[originalFieldId])
|
|
591
|
+
? this.formData[originalFieldId]
|
|
592
|
+
: [this.formData[originalFieldId]];
|
|
593
|
+
|
|
594
|
+
// Separate images from other files
|
|
595
|
+
const images = [];
|
|
596
|
+
const otherFiles = [];
|
|
597
|
+
|
|
598
|
+
fileDataArray.forEach((fileData) => {
|
|
599
|
+
const fileName = fileData.name || '';
|
|
600
|
+
const isImage = fileName.toLowerCase().match(/\.(png|jpg|jpeg|gif|webp)$/);
|
|
601
|
+
|
|
602
|
+
if (isImage && fileData.file && fileData.file.data) {
|
|
603
|
+
// Convert buffer to base64 data URL for image display - safe for large files
|
|
604
|
+
const uint8Array = new Uint8Array(fileData.file.data);
|
|
605
|
+
let binaryString = '';
|
|
606
|
+
|
|
607
|
+
// Process in chunks to avoid call stack overflow
|
|
608
|
+
const chunkSize = 1024;
|
|
609
|
+
for (let i = 0; i < uint8Array.length; i += chunkSize) {
|
|
610
|
+
const chunk = uint8Array.slice(i, i + chunkSize);
|
|
611
|
+
binaryString += String.fromCharCode.apply(null, chunk);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
const base64String = btoa(binaryString);
|
|
615
|
+
const mimeType = fileName.toLowerCase().endsWith('.png')
|
|
616
|
+
? 'image/png'
|
|
617
|
+
: fileName.toLowerCase().endsWith('.gif')
|
|
618
|
+
? 'image/gif'
|
|
619
|
+
: 'image/jpeg';
|
|
620
|
+
const dataURL = `data:${mimeType};base64,${base64String}`;
|
|
621
|
+
|
|
622
|
+
images.push({ fileName, dataURL, fileData });
|
|
623
|
+
} else {
|
|
624
|
+
otherFiles.push({ fileName, fileData });
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
let content = `<label class="ui-dynamic-form-input-label">${field.label} (Vorschau)${
|
|
629
|
+
field.required ? ' *' : ''
|
|
630
|
+
}</label>`;
|
|
631
|
+
|
|
632
|
+
// Display images
|
|
633
|
+
if (images.length > 0) {
|
|
634
|
+
content += '<div style="margin-top: 8px;">';
|
|
635
|
+
content += '<div style="font-weight: bold; margin-bottom: 8px;">Bilder:</div>';
|
|
636
|
+
images.forEach((img, index) => {
|
|
637
|
+
const downloadId = `download-img-${field.id}-${index}`;
|
|
638
|
+
content += `
|
|
639
|
+
<div style="display: inline-block; margin: 8px; text-align: center; vertical-align: top;">
|
|
640
|
+
<img src="${img.dataURL}" alt="${img.fileName}"
|
|
641
|
+
style="max-width: 300px; max-height: 200px; border: 1px solid #ccc; display: block; cursor: pointer;"
|
|
642
|
+
onclick="document.getElementById('${downloadId}').click();" />
|
|
643
|
+
<div style="margin-top: 4px; font-size: 0.9em; color: #666; max-width: 300px; word-break: break-word;">
|
|
644
|
+
${img.fileName}
|
|
645
|
+
</div>
|
|
646
|
+
<a id="${downloadId}" href="${img.dataURL}" download="${img.fileName}" style="display: none;"></a>
|
|
647
|
+
</div>
|
|
648
|
+
`;
|
|
649
|
+
});
|
|
650
|
+
content += '</div>';
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Display other files as list
|
|
654
|
+
if (otherFiles.length > 0) {
|
|
655
|
+
content +=
|
|
656
|
+
'<div style="margin-top: 12px; padding: 12px; border: 1px solid #ddd; border-radius: 4px; background: #f9f9f9;">';
|
|
657
|
+
content += '<div style="font-weight: bold; margin-bottom: 8px;">Weitere Dateien:</div>';
|
|
658
|
+
otherFiles.forEach((file, index) => {
|
|
659
|
+
const downloadId = `download-file-${field.id}-${index}`;
|
|
660
|
+
const uint8Array = new Uint8Array(file.fileData.file.data);
|
|
661
|
+
let binaryString = '';
|
|
662
|
+
|
|
663
|
+
// Process in chunks for download
|
|
664
|
+
const chunkSize = 1024;
|
|
665
|
+
for (let i = 0; i < uint8Array.length; i += chunkSize) {
|
|
666
|
+
const chunk = uint8Array.slice(i, i + chunkSize);
|
|
667
|
+
binaryString += String.fromCharCode.apply(null, chunk);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
const base64String = btoa(binaryString);
|
|
671
|
+
const dataURL = `data:application/octet-stream;base64,${base64String}`;
|
|
672
|
+
|
|
673
|
+
content += `
|
|
674
|
+
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 4px; padding: 4px; border-radius: 3px; cursor: pointer;"
|
|
675
|
+
onclick="document.getElementById('${downloadId}').click();"
|
|
676
|
+
onmouseover="this.style.backgroundColor='#e6e6e6';"
|
|
677
|
+
onmouseout="this.style.backgroundColor='transparent';">
|
|
678
|
+
<span style="font-size: 1.2em;">📎</span>
|
|
679
|
+
<span style="flex: 1; word-break: break-word;">${file.fileName}</span>
|
|
680
|
+
<span style="font-size: 0.8em; color: #007bff;">Download</span>
|
|
681
|
+
<a id="${downloadId}" href="${dataURL}" download="${file.fileName}" style="display: none;"></a>
|
|
682
|
+
</div>
|
|
683
|
+
`;
|
|
684
|
+
});
|
|
685
|
+
content += '</div>';
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
return {
|
|
689
|
+
type: 'div',
|
|
690
|
+
props: {
|
|
691
|
+
innerHTML: content,
|
|
692
|
+
},
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
// If no files to preview, return empty div
|
|
696
|
+
return {
|
|
697
|
+
type: 'div',
|
|
698
|
+
props: {
|
|
699
|
+
style: 'display: none;',
|
|
700
|
+
},
|
|
701
|
+
};
|
|
462
702
|
case 'file':
|
|
463
703
|
const multiple = field.customForm ? JSON.parse(field.customForm).multiple === 'true' : false;
|
|
464
704
|
return {
|
|
@@ -469,13 +709,11 @@ export default {
|
|
|
469
709
|
name,
|
|
470
710
|
label: field.label,
|
|
471
711
|
required: field.required,
|
|
472
|
-
value: this.formData[field.id],
|
|
473
712
|
help: hint,
|
|
474
713
|
innerClass: 'reset-background',
|
|
475
714
|
wrapperClass: '$remove:formkit-wrapper',
|
|
476
715
|
labelClass: 'ui-dynamic-form-input-label',
|
|
477
716
|
inputClass: `input-${this.theme}`,
|
|
478
|
-
// innerClass: ui-dynamic-form-input-outlines `${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
|
|
479
717
|
readonly: isReadOnly,
|
|
480
718
|
disabled: isReadOnly,
|
|
481
719
|
multiple,
|
|
@@ -501,7 +739,9 @@ export default {
|
|
|
501
739
|
fieldsetClass: 'custom-fieldset',
|
|
502
740
|
labelClass: 'ui-dynamic-form-input-label',
|
|
503
741
|
inputClass: `input-${this.theme}`,
|
|
504
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
742
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
743
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
744
|
+
}`,
|
|
505
745
|
readonly: isReadOnly,
|
|
506
746
|
disabled: isReadOnly,
|
|
507
747
|
validation,
|
|
@@ -539,7 +779,9 @@ export default {
|
|
|
539
779
|
wrapperClass: '$remove:formkit-wrapper',
|
|
540
780
|
labelClass: 'ui-dynamic-form-input-label',
|
|
541
781
|
inputClass: `input-${this.theme}`,
|
|
542
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
782
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
783
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
784
|
+
}`,
|
|
543
785
|
readonly: isReadOnly,
|
|
544
786
|
validation,
|
|
545
787
|
validationVisibility: 'live',
|
|
@@ -560,7 +802,9 @@ export default {
|
|
|
560
802
|
wrapperClass: '$remove:formkit-wrapper',
|
|
561
803
|
labelClass: 'ui-dynamic-form-input-label',
|
|
562
804
|
inputClass: `input-${this.theme}`,
|
|
563
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
805
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
806
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
807
|
+
}`,
|
|
564
808
|
readonly: isReadOnly,
|
|
565
809
|
validation,
|
|
566
810
|
validationVisibility: 'live',
|
|
@@ -600,7 +844,9 @@ export default {
|
|
|
600
844
|
wrapperClass: '$remove:formkit-wrapper',
|
|
601
845
|
labelClass: 'ui-dynamic-form-input-label',
|
|
602
846
|
inputClass: `input-${this.theme}`,
|
|
603
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
847
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
848
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
849
|
+
}`,
|
|
604
850
|
readonly: isReadOnly,
|
|
605
851
|
validation,
|
|
606
852
|
validationVisibility: 'live',
|
|
@@ -629,7 +875,9 @@ export default {
|
|
|
629
875
|
wrapperClass: '$remove:formkit-wrapper',
|
|
630
876
|
labelClass: 'ui-dynamic-form-input-label',
|
|
631
877
|
inputClass: `input-${this.theme}`,
|
|
632
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
878
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
879
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
880
|
+
}`,
|
|
633
881
|
readonly: isReadOnly,
|
|
634
882
|
validation,
|
|
635
883
|
validationVisibility: 'live',
|
|
@@ -653,7 +901,9 @@ export default {
|
|
|
653
901
|
fieldsetClass: 'custom-fieldset',
|
|
654
902
|
labelClass: 'ui-dynamic-form-input-label',
|
|
655
903
|
inputClass: `input-${this.theme}`,
|
|
656
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
904
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
905
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
906
|
+
}`,
|
|
657
907
|
readonly: isReadOnly,
|
|
658
908
|
disabled: isReadOnly,
|
|
659
909
|
validation,
|
|
@@ -700,7 +950,9 @@ export default {
|
|
|
700
950
|
wrapperClass: '$remove:formkit-wrapper',
|
|
701
951
|
labelClass: 'ui-dynamic-form-input-label',
|
|
702
952
|
inputClass: `input-${this.theme}`,
|
|
703
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
953
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
954
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
955
|
+
}`,
|
|
704
956
|
readonly: isReadOnly,
|
|
705
957
|
validation,
|
|
706
958
|
validationVisibility: 'live',
|
|
@@ -723,7 +975,9 @@ export default {
|
|
|
723
975
|
wrapperClass: '$remove:formkit-wrapper',
|
|
724
976
|
labelClass: 'ui-dynamic-form-input-label',
|
|
725
977
|
inputClass: `input-${this.theme}`,
|
|
726
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
978
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
979
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
980
|
+
}`,
|
|
727
981
|
readonly: isReadOnly,
|
|
728
982
|
validation,
|
|
729
983
|
validationVisibility: 'live',
|
|
@@ -744,7 +998,9 @@ export default {
|
|
|
744
998
|
wrapperClass: '$remove:formkit-wrapper',
|
|
745
999
|
labelClass: 'ui-dynamic-form-input-label',
|
|
746
1000
|
inputClass: `input-${this.theme}`,
|
|
747
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1001
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1002
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
1003
|
+
}`,
|
|
748
1004
|
readonly: isReadOnly,
|
|
749
1005
|
validation,
|
|
750
1006
|
validationVisibility: 'live',
|
|
@@ -765,7 +1021,9 @@ export default {
|
|
|
765
1021
|
wrapperClass: '$remove:formkit-wrapper',
|
|
766
1022
|
labelClass: 'ui-dynamic-form-input-label',
|
|
767
1023
|
inputClass: `input-${this.theme}`,
|
|
768
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1024
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1025
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
1026
|
+
}`,
|
|
769
1027
|
readonly: isReadOnly,
|
|
770
1028
|
validation,
|
|
771
1029
|
validationVisibility: 'live',
|
|
@@ -786,7 +1044,9 @@ export default {
|
|
|
786
1044
|
wrapperClass: '$remove:formkit-wrapper',
|
|
787
1045
|
labelClass: 'ui-dynamic-form-input-label',
|
|
788
1046
|
inputClass: `input-${this.theme}`,
|
|
789
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1047
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1048
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
1049
|
+
}`,
|
|
790
1050
|
readonly: isReadOnly,
|
|
791
1051
|
validation,
|
|
792
1052
|
validationVisibility: 'live',
|
|
@@ -805,7 +1065,9 @@ export default {
|
|
|
805
1065
|
help: hint,
|
|
806
1066
|
labelClass: 'ui-dynamic-form-input-label',
|
|
807
1067
|
inputClass: `input-${this.theme}`,
|
|
808
|
-
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1068
|
+
innerClass: `ui-dynamic-form-input-outlines ${
|
|
1069
|
+
this.theme === 'dark' ? '$remove:formkit-inner' : ''
|
|
1070
|
+
}`,
|
|
809
1071
|
readonly: isReadOnly,
|
|
810
1072
|
validation,
|
|
811
1073
|
validationVisibility: 'live',
|
|
@@ -848,6 +1110,9 @@ export default {
|
|
|
848
1110
|
},
|
|
849
1111
|
init(msg) {
|
|
850
1112
|
this.msg = msg;
|
|
1113
|
+
// Clear component cache when form data changes for performance
|
|
1114
|
+
this.clearComponentCache();
|
|
1115
|
+
|
|
851
1116
|
if (!msg) {
|
|
852
1117
|
return;
|
|
853
1118
|
}
|
|
@@ -897,14 +1162,28 @@ export default {
|
|
|
897
1162
|
];
|
|
898
1163
|
}
|
|
899
1164
|
});
|
|
1165
|
+
|
|
1166
|
+
// Check for file fields and duplicate them as file-preview if initial values exist
|
|
1167
|
+
// Insert preview fields directly before their corresponding file fields
|
|
1168
|
+
for (let i = formFields.length - 1; i >= 0; i--) {
|
|
1169
|
+
const field = formFields[i];
|
|
1170
|
+
if (field.type === 'file' && initialValues && initialValues[field.id]) {
|
|
1171
|
+
const previewField = { ...field };
|
|
1172
|
+
previewField.type = 'file-preview';
|
|
1173
|
+
previewField.id = `${field.id}_preview`; // Give it a unique ID
|
|
1174
|
+
this.userTask.userTaskConfig.formFields.splice(i, 0, previewField);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
900
1177
|
}
|
|
901
1178
|
|
|
902
1179
|
if (initialValues) {
|
|
903
|
-
|
|
904
|
-
.
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1180
|
+
if (initialValues) {
|
|
1181
|
+
Object.keys(initialValues)
|
|
1182
|
+
.filter((key) => formFieldIds.includes(key))
|
|
1183
|
+
.forEach((key) => {
|
|
1184
|
+
this.formData[key] = initialValues[key];
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
908
1187
|
}
|
|
909
1188
|
|
|
910
1189
|
if (this.formIsFinished) {
|
|
@@ -967,7 +1246,7 @@ export default {
|
|
|
967
1246
|
this.send(
|
|
968
1247
|
msg,
|
|
969
1248
|
this.actions.findIndex((element) => element.label === action.label) +
|
|
970
|
-
|
|
1249
|
+
(this.isConfirmDialog ? this.props.options.length : 0)
|
|
971
1250
|
);
|
|
972
1251
|
// TODO: mm - end
|
|
973
1252
|
} else {
|
|
@@ -1003,7 +1282,9 @@ export default {
|
|
|
1003
1282
|
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(this.firstFormFieldRef.$el.tagName)) {
|
|
1004
1283
|
inputElement = this.firstFormFieldRef.$el;
|
|
1005
1284
|
} else {
|
|
1006
|
-
inputElement = this.firstFormFieldRef.$el.querySelector(
|
|
1285
|
+
inputElement = this.firstFormFieldRef.$el.querySelector(
|
|
1286
|
+
'input:not([type="hidden"]), textarea, select'
|
|
1287
|
+
);
|
|
1007
1288
|
}
|
|
1008
1289
|
}
|
|
1009
1290
|
|