@5minds/node-red-dashboard-2-processcube-dynamic-form 2.0.4-feature-e6de27-mcerd06i → 2.0.4

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.
@@ -1,50 +1,62 @@
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 v-if="props.title_style === 'outside' && hasUserTask" :style="props.title_style"
5
- :title="effectiveTitle" :customStyles="props.title_custom_text_styling" :titleIcon="props.title_icon"
4
+ <UIDynamicFormTitleText
5
+ v-if="props.title_style === 'outside' && hasUserTask" :style="props.title_style"
6
+ :title="props.title_text" :customStyles="props.title_custom_text_styling" :titleIcon="props.title_icon"
6
7
  :collapsible="props.collapsible || (props.collapse_when_finished && formIsFinished)" :collapsed="collapsed"
7
- :toggleCollapse="toggleCollapse" />
8
+ :toggleCollapse="toggleCollapse"
9
+ />
8
10
  <div className="ui-dynamic-form-wrapper">
9
11
  <p v-if="hasUserTask" style="margin-bottom: 0px">
10
12
  <v-form ref="form" v-model="form" :class="dynamicClass">
11
- <UIDynamicFormTitleText v-if="props.title_style != 'outside'" :style="props.title_style"
12
- :title="effectiveTitle" :customStyles="props.title_custom_text_styling"
13
+ <UIDynamicFormTitleText
14
+ v-if="props.title_style != 'outside'" :style="props.title_style"
15
+ :title="props.title_text" :customStyles="props.title_custom_text_styling"
13
16
  :titleIcon="props.title_icon"
14
17
  :collapsible="props.collapsible || (props.collapse_when_finished && formIsFinished)"
15
- :collapsed="collapsed" :toggleCollapse="toggleCollapse" />
18
+ :collapsed="collapsed" :toggleCollapse="toggleCollapse"
19
+ />
16
20
  <Transition name="cardCollapse">
17
21
  <div v-if="!collapsed">
18
22
  <div className="ui-dynamic-form-formfield-positioner" :style="props.inner_card_styling">
19
23
  <FormKit id="form" type="group">
20
- <v-row v-for="(field, index) in fields()" :key="field"
21
- :style="getRowWidthStyling(field, index)">
24
+ <v-row
25
+ v-for="(field, index) in fields()" :key="field"
26
+ :style="getRowWidthStyling(field, index)"
27
+ >
22
28
  <v-col cols="12">
23
- <component :is="createComponent(field).type"
29
+ <component
30
+ :is="createComponent(field).type"
24
31
  v-if="createComponent(field).innerText"
25
32
  v-bind="createComponent(field).props" :ref="(el) => {
26
33
  if (index === 0) firstFormFieldRef = el;
27
34
  }
28
- " v-model="formData[field.id]">
35
+ " v-model="formData[field.id]"
36
+ >
29
37
  {{ createComponent(field).innerText }}
30
38
  </component>
31
39
  <div v-else-if="createComponent(field).type == 'v-slider'">
32
40
  <p class="formkit-label">{{ field.label }}</p>
33
- <component :is="createComponent(field).type"
41
+ <component
42
+ :is="createComponent(field).type"
34
43
  v-bind="createComponent(field).props" :ref="(el) => {
35
44
  if (index === 0) firstFormFieldRef = el;
36
45
  }
37
- " v-model="field.defaultValue" />
46
+ " v-model="field.defaultValue"
47
+ />
38
48
  <p class="formkit-help">
39
49
  {{ field.customForm ? JSON.parse(field.customForm).hint : undefined
40
50
  }}
41
51
  </p>
42
52
  </div>
43
- <component :is="createComponent(field).type" v-else
53
+ <component
54
+ :is="createComponent(field).type" v-else
44
55
  v-bind="createComponent(field).props" :ref="(el) => {
45
56
  if (index === 0) firstFormFieldRef = el;
46
57
  }
47
- " v-model="formData[field.id]" />
58
+ " v-model="formData[field.id]"
59
+ />
48
60
  </v-col>
49
61
  </v-row>
50
62
  </FormKit>
@@ -53,17 +65,21 @@
53
65
  <v-row v-if="errorMsg.length > 0" style="padding: 12px">
54
66
  <v-alert type="error">Error: {{ errorMsg }}</v-alert>
55
67
  </v-row>
56
- <UIDynamicFormFooterAction v-if="props.actions_inside_card && actions.length > 0"
68
+ <UIDynamicFormFooterAction
69
+ v-if="props.actions_inside_card && actions.length > 0"
57
70
  :actions="actions" :actionCallback="actionFn" :formIsFinished="formIsFinished"
58
- style="padding: 16px; padding-top: 0px" />
71
+ style="padding: 16px; padding-top: 0px"
72
+ />
59
73
  </v-row>
60
74
  </div>
61
75
  </Transition>
62
76
  </v-form>
63
77
  </p>
64
78
  <p v-else>
65
- <v-alert v-if="props.waiting_info.length > 0 || props.waiting_title.length > 0"
66
- :text="props.waiting_info" :title="props.waiting_title" />
79
+ <v-alert
80
+ v-if="props.waiting_info.length > 0 || props.waiting_title.length > 0"
81
+ :text="props.waiting_info" :title="props.waiting_title"
82
+ />
67
83
  </p>
68
84
  </div>
69
85
  <div v-if="!props.actions_inside_card && actions.length > 0 && hasUserTask" style="padding-top: 32px">
@@ -84,7 +100,7 @@ import UIDynamicFormFooterAction from './FooterActions.vue'
84
100
  import UIDynamicFormTitleText from './TitleText.vue'
85
101
 
86
102
  // eslint-disable-next-line no-unused-vars
87
- function requiredIf({ value }, [targetField, expectedValue], node) {
103
+ function requiredIf ({ value }, [targetField, expectedValue], node) {
88
104
  console.debug(arguments)
89
105
 
90
106
  const actual = node?.root?.value?.[targetField]
@@ -114,7 +130,7 @@ export default {
114
130
  default: () => ({ enabled: false, visible: false })
115
131
  }
116
132
  },
117
- setup(props) {
133
+ setup (props) {
118
134
  console.info('UIDynamicForm setup with:', props)
119
135
  console.debug('Vue function loaded correctly', markRaw)
120
136
 
@@ -130,7 +146,7 @@ export default {
130
146
  })
131
147
  app.use(plugin, formkitConfig)
132
148
  },
133
- data() {
149
+ data () {
134
150
  return {
135
151
  actions: [],
136
152
  formData: {},
@@ -144,51 +160,42 @@ export default {
144
160
  }
145
161
  },
146
162
  computed: {
147
- dynamicClass() {
163
+ dynamicClass () {
148
164
  return `ui-dynamic-form-${this.theme} ui-dynamic-form-common`
149
165
  },
150
- dynamicFooterClass() {
166
+ dynamicFooterClass () {
151
167
  return `ui-dynamic-form-footer-${this.theme} ui-dynamic-form-footer-common`
152
168
  },
153
- hasUserTask() {
169
+ hasUserTask () {
154
170
  return !!this.userTask
155
171
  },
156
- totalOutputs() {
172
+ totalOutputs () {
157
173
  return (
158
174
  this.props.options.length +
159
175
  (this.props.handle_confirmation_dialogs ? 2 : 0) +
160
176
  (this.props.trigger_on_change ? 1 : 0)
161
177
  )
162
178
  },
163
- isConfirmDialog() {
179
+ isConfirmDialog () {
164
180
  return this.userTask.userTaskConfig.formFields.some((field) => field.type === 'confirm')
165
- },
166
- effectiveTitle() {
167
- if (this.props.title_text_type === 'str') {
168
- return this.props.title_text
169
- } else if (this.props.title_text_type === 'msg') {
170
- return this.msg.dynamicTitle
171
- } else {
172
- return ''
173
- }
174
181
  }
175
182
  },
176
183
  watch: {
177
184
  formData: {
178
- handler(newData, oldData) {
185
+ handler (newData, oldData) {
179
186
  if (this.props.trigger_on_change) {
180
187
  const res = { payload: { formData: newData, userTask: this.userTask } }
181
188
  this.send(res, this.totalOutputs - 1)
182
189
  }
183
190
  },
184
- collapsed(newVal) {
191
+ collapsed (newVal) {
185
192
  if (!newVal && this.hasUserTask) {
186
193
  nextTick(() => {
187
194
  this.focusFirstFormField()
188
195
  })
189
196
  }
190
197
  },
191
- userTask(newVal) {
198
+ userTask (newVal) {
192
199
  if (newVal && !this.collapsed) {
193
200
  nextTick(() => {
194
201
  this.focusFirstFormField()
@@ -198,7 +205,7 @@ export default {
198
205
  deep: true
199
206
  }
200
207
  },
201
- created() {
208
+ created () {
202
209
  const currentPath = window.location.pathname
203
210
  const lastPart = currentPath.substring(currentPath.lastIndexOf('/'))
204
211
 
@@ -218,7 +225,7 @@ export default {
218
225
  }
219
226
  }
220
227
  },
221
- mounted() {
228
+ mounted () {
222
229
  const elements = document.querySelectorAll('.formkit-input')
223
230
 
224
231
  elements.forEach((element) => {
@@ -235,13 +242,13 @@ export default {
235
242
  // tell Node-RED that we're loading a new instance of this widget
236
243
  this.$socket.emit('widget-load', this.id)
237
244
  },
238
- unmounted() {
245
+ unmounted () {
239
246
  /* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */
240
247
  this.$socket?.off('widget-load' + this.id)
241
248
  this.$socket?.off('msg-input:' + this.id)
242
249
  },
243
250
  methods: {
244
- createComponent(field) {
251
+ createComponent (field) {
245
252
  const customForm = field.customForm ? JSON.parse(field.customForm) : {}
246
253
  const hint = customForm.hint
247
254
  const placeholder = customForm.placeholder
@@ -255,521 +262,521 @@ export default {
255
262
  ? 'true'
256
263
  : undefined
257
264
  switch (field.type) {
258
- case 'long':
259
- return {
260
- type: 'FormKit',
261
- props: {
262
- type: 'number',
263
- id: field.id,
264
- name,
265
- label: field.label,
266
- required: field.required,
267
- value: this.formData[field.id],
268
- number: 'integer',
269
- help: hint,
270
- wrapperClass: '$remove:formkit-wrapper',
271
- labelClass: 'ui-dynamic-form-input-label',
272
- inputClass: `input-${this.theme}`,
273
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
274
- readonly: isReadOnly,
275
- validation,
276
- validationVisibility: 'live'
277
- }
265
+ case 'long':
266
+ return {
267
+ type: 'FormKit',
268
+ props: {
269
+ type: 'number',
270
+ id: field.id,
271
+ name,
272
+ label: field.label,
273
+ required: field.required,
274
+ value: this.formData[field.id],
275
+ number: 'integer',
276
+ help: hint,
277
+ wrapperClass: '$remove:formkit-wrapper',
278
+ labelClass: 'ui-dynamic-form-input-label',
279
+ inputClass: `input-${this.theme}`,
280
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
281
+ readonly: isReadOnly,
282
+ validation,
283
+ validationVisibility: 'live'
278
284
  }
279
- case 'number':
280
- const step = field.customForm ? JSON.parse(field.customForm).step : undefined
281
- return {
282
- type: 'FormKit',
283
- props: {
284
- type: 'number',
285
- id: field.id,
286
- name,
287
- label: field.label,
288
- required: field.required,
289
- value: this.formData[field.id],
290
- step,
291
- help: hint,
292
- wrapperClass: '$remove:formkit-wrapper',
293
- labelClass: 'ui-dynamic-form-input-label',
294
- inputClass: `input-${this.theme}`,
295
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
296
- readonly: isReadOnly,
297
- validation,
298
- validationVisibility: 'live'
299
- }
300
- }
301
- case 'date':
302
- return {
303
- type: 'FormKit',
304
- props: {
305
- type: 'date',
306
- id: field.id,
307
- name,
308
- label: field.label,
309
- required: field.required,
310
- value: this.formData[field.id],
311
- help: hint,
312
- wrapperClass: '$remove:formkit-wrapper',
313
- labelClass: 'ui-dynamic-form-input-label',
314
- inputClass: `input-${this.theme}`,
315
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
316
- readonly: isReadOnly,
317
- validation,
318
- validationVisibility: 'live'
319
- }
320
- }
321
- case 'enum':
322
- const enums = field.enumValues.map((obj) => {
323
- return { value: obj.id, label: obj.name }
324
- })
325
- return {
326
- type: 'FormKit',
327
- props: {
328
- type: 'select', // JSON.parse(field.customForm).displayAs
329
- id: field.id,
330
- name,
331
- label: field.label,
332
- required: field.required,
333
- value: this.formData[field.id],
334
- options: enums,
335
- help: hint,
336
- wrapperClass: '$remove:formkit-wrapper',
337
- labelClass: 'ui-dynamic-form-input-label',
338
- inputClass: `input-${this.theme}`,
339
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
340
- readonly: isReadOnly,
341
- disabled: isReadOnly,
342
- validation,
343
- validationVisibility: 'live'
344
- }
345
- }
346
- case 'select':
347
- const selections = JSON.parse(field.customForm).entries.map((obj) => {
348
- return { value: obj.key, label: obj.value }
349
- })
350
- return {
351
- type: 'FormKit',
352
- props: {
353
- type: 'select', // JSON.parse(field.customForm).displayAs
354
- id: field.id,
355
- name,
356
- label: field.label,
357
- required: field.required,
358
- value: this.formData[field.id],
359
- options: selections,
360
- placeholder,
361
- help: hint,
362
- wrapperClass: '$remove:formkit-wrapper',
363
- labelClass: 'ui-dynamic-form-input-label',
364
- inputClass: `input-${this.theme}`,
365
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
366
- readonly: isReadOnly,
367
- disabled: isReadOnly,
368
- validation,
369
- validationVisibility: 'live'
370
- }
371
- }
372
- case 'string':
373
- return {
374
- type: 'FormKit',
375
- props: {
376
- type: 'text',
377
- id: field.id,
378
- name,
379
- label: field.label,
380
- required: field.required,
381
- value: this.formData[field.id],
382
- help: hint,
383
- placeholder,
384
- wrapperClass: '$remove:formkit-wrapper',
385
- labelClass: 'ui-dynamic-form-input-label',
386
- inputClass: `input-${this.theme}`,
387
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
388
- readonly: isReadOnly,
389
- validation,
390
- validationVisibility: 'live'
391
- }
392
- }
393
- case 'confirm':
394
- return {
395
- type: 'h3',
396
- innerText: field.label
285
+ }
286
+ case 'number':
287
+ const step = field.customForm ? JSON.parse(field.customForm).step : undefined
288
+ return {
289
+ type: 'FormKit',
290
+ props: {
291
+ type: 'number',
292
+ id: field.id,
293
+ name,
294
+ label: field.label,
295
+ required: field.required,
296
+ value: this.formData[field.id],
297
+ step,
298
+ help: hint,
299
+ wrapperClass: '$remove:formkit-wrapper',
300
+ labelClass: 'ui-dynamic-form-input-label',
301
+ inputClass: `input-${this.theme}`,
302
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
303
+ readonly: isReadOnly,
304
+ validation,
305
+ validationVisibility: 'live'
397
306
  }
398
- case 'boolean':
399
- return {
400
- type: 'FormKit',
401
- props: {
402
- type: 'checkbox',
403
- id: field.id,
404
- name,
405
- label: field.label,
406
- required: field.required,
407
- value: this.formData[field.id],
408
- help: hint,
409
- labelClass: 'ui-dynamic-form-input-label',
410
- inputClass: `input-${this.theme}`,
411
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
412
- readonly: isReadOnly,
413
- disabled: isReadOnly,
414
- validation,
415
- validationVisibility: 'live'
416
- }
307
+ }
308
+ case 'date':
309
+ return {
310
+ type: 'FormKit',
311
+ props: {
312
+ type: 'date',
313
+ id: field.id,
314
+ name,
315
+ label: field.label,
316
+ required: field.required,
317
+ value: this.formData[field.id],
318
+ help: hint,
319
+ wrapperClass: '$remove:formkit-wrapper',
320
+ labelClass: 'ui-dynamic-form-input-label',
321
+ inputClass: `input-${this.theme}`,
322
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
323
+ readonly: isReadOnly,
324
+ validation,
325
+ validationVisibility: 'live'
417
326
  }
418
- case 'file':
419
- const multiple = field.customForm ? JSON.parse(field.customForm).multiple === 'true' : false
420
- return {
421
- type: 'FormKit',
422
- props: {
423
- type: 'file',
424
- id: field.id,
425
- name,
426
- label: field.label,
427
- required: field.required,
428
- value: this.formData[field.id],
429
- help: hint,
430
- innerClass: 'reset-background',
431
- wrapperClass: '$remove:formkit-wrapper',
432
- labelClass: 'ui-dynamic-form-input-label',
433
- inputClass: `input-${this.theme}`,
434
- // innerClass: ui-dynamic-form-input-outlines `${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
435
- readonly: isReadOnly,
436
- disabled: isReadOnly,
437
- multiple,
438
- validation,
439
- validationVisibility: 'live'
440
- }
327
+ }
328
+ case 'enum':
329
+ const enums = field.enumValues.map((obj) => {
330
+ return { value: obj.id, label: obj.name }
331
+ })
332
+ return {
333
+ type: 'FormKit',
334
+ props: {
335
+ type: 'select', // JSON.parse(field.customForm).displayAs
336
+ id: field.id,
337
+ name,
338
+ label: field.label,
339
+ required: field.required,
340
+ value: this.formData[field.id],
341
+ options: enums,
342
+ help: hint,
343
+ wrapperClass: '$remove:formkit-wrapper',
344
+ labelClass: 'ui-dynamic-form-input-label',
345
+ inputClass: `input-${this.theme}`,
346
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
347
+ readonly: isReadOnly,
348
+ disabled: isReadOnly,
349
+ validation,
350
+ validationVisibility: 'live'
441
351
  }
442
- case 'checkbox':
443
- const options = JSON.parse(field.customForm).entries.map((obj) => {
444
- return { value: obj.key, label: obj.value }
445
- })
446
- return {
447
- type: 'FormKit',
448
- props: {
449
- type: 'checkbox',
450
- id: field.id,
451
- name,
452
- label: field.label,
453
- required: field.required,
454
- value: this.formData[field.id],
455
- options,
456
- help: hint,
457
- fieldsetClass: 'custom-fieldset',
458
- labelClass: 'ui-dynamic-form-input-label',
459
- inputClass: `input-${this.theme}`,
460
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
461
- readonly: isReadOnly,
462
- disabled: isReadOnly,
463
- validation,
464
- validationVisibility: 'live'
465
- }
352
+ }
353
+ case 'select':
354
+ const selections = JSON.parse(field.customForm).entries.map((obj) => {
355
+ return { value: obj.key, label: obj.value }
356
+ })
357
+ return {
358
+ type: 'FormKit',
359
+ props: {
360
+ type: 'select', // JSON.parse(field.customForm).displayAs
361
+ id: field.id,
362
+ name,
363
+ label: field.label,
364
+ required: field.required,
365
+ value: this.formData[field.id],
366
+ options: selections,
367
+ placeholder,
368
+ help: hint,
369
+ wrapperClass: '$remove:formkit-wrapper',
370
+ labelClass: 'ui-dynamic-form-input-label',
371
+ inputClass: `input-${this.theme}`,
372
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
373
+ readonly: isReadOnly,
374
+ disabled: isReadOnly,
375
+ validation,
376
+ validationVisibility: 'live'
466
377
  }
467
- case 'color':
468
- return {
469
- type: 'FormKit',
470
- props: {
471
- type: 'color',
472
- id: field.id,
473
- name,
474
- label: field.label,
475
- required: field.required,
476
- value: this.formData[field.id],
477
- help: hint,
478
- readonly: isReadOnly,
479
- disabled: isReadOnly,
480
- validation,
481
- validationVisibility: 'live'
482
- }
378
+ }
379
+ case 'string':
380
+ return {
381
+ type: 'FormKit',
382
+ props: {
383
+ type: 'text',
384
+ id: field.id,
385
+ name,
386
+ label: field.label,
387
+ required: field.required,
388
+ value: this.formData[field.id],
389
+ help: hint,
390
+ placeholder,
391
+ wrapperClass: '$remove:formkit-wrapper',
392
+ labelClass: 'ui-dynamic-form-input-label',
393
+ inputClass: `input-${this.theme}`,
394
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
395
+ readonly: isReadOnly,
396
+ validation,
397
+ validationVisibility: 'live'
483
398
  }
484
- case 'datetime-local':
485
- return {
486
- type: 'FormKit',
487
- props: {
488
- type: 'datetime-local',
489
- id: field.id,
490
- name,
491
- label: field.label,
492
- required: field.required,
493
- value: this.formData[field.id],
494
- help: hint,
495
- wrapperClass: '$remove:formkit-wrapper',
496
- labelClass: 'ui-dynamic-form-input-label',
497
- inputClass: `input-${this.theme}`,
498
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
499
- readonly: isReadOnly,
500
- validation,
501
- validationVisibility: 'live'
502
- }
399
+ }
400
+ case 'confirm':
401
+ return {
402
+ type: 'h3',
403
+ innerText: field.label
404
+ }
405
+ case 'boolean':
406
+ return {
407
+ type: 'FormKit',
408
+ props: {
409
+ type: 'checkbox',
410
+ id: field.id,
411
+ name,
412
+ label: field.label,
413
+ required: field.required,
414
+ value: this.formData[field.id],
415
+ help: hint,
416
+ labelClass: 'ui-dynamic-form-input-label',
417
+ inputClass: `input-${this.theme}`,
418
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
419
+ readonly: isReadOnly,
420
+ disabled: isReadOnly,
421
+ validation,
422
+ validationVisibility: 'live'
503
423
  }
504
- case 'email':
505
- return {
506
- type: 'FormKit',
507
- props: {
508
- type: 'email',
509
- id: field.id,
510
- name,
511
- label: field.label,
512
- required: field.required,
513
- value: this.formData[field.id],
514
- help: hint,
515
- placeholder,
516
- wrapperClass: '$remove:formkit-wrapper',
517
- labelClass: 'ui-dynamic-form-input-label',
518
- inputClass: `input-${this.theme}`,
519
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
520
- readonly: isReadOnly,
521
- validation,
522
- validationVisibility: 'live'
523
- }
424
+ }
425
+ case 'file':
426
+ const multiple = field.customForm ? JSON.parse(field.customForm).multiple === 'true' : false
427
+ return {
428
+ type: 'FormKit',
429
+ props: {
430
+ type: 'file',
431
+ id: field.id,
432
+ name,
433
+ label: field.label,
434
+ required: field.required,
435
+ value: this.formData[field.id],
436
+ help: hint,
437
+ innerClass: 'reset-background',
438
+ wrapperClass: '$remove:formkit-wrapper',
439
+ labelClass: 'ui-dynamic-form-input-label',
440
+ inputClass: `input-${this.theme}`,
441
+ // innerClass: ui-dynamic-form-input-outlines `${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
442
+ readonly: isReadOnly,
443
+ disabled: isReadOnly,
444
+ multiple,
445
+ validation,
446
+ validationVisibility: 'live'
524
447
  }
525
- case 'header':
526
- let typeToUse = 'h1'
527
- if (field.customForm && JSON.parse(field.customForm).style === 'heading_2') {
528
- typeToUse = 'h2'
448
+ }
449
+ case 'checkbox':
450
+ const options = JSON.parse(field.customForm).entries.map((obj) => {
451
+ return { value: obj.key, label: obj.value }
452
+ })
453
+ return {
454
+ type: 'FormKit',
455
+ props: {
456
+ type: 'checkbox',
457
+ id: field.id,
458
+ name,
459
+ label: field.label,
460
+ required: field.required,
461
+ value: this.formData[field.id],
462
+ options,
463
+ help: hint,
464
+ fieldsetClass: 'custom-fieldset',
465
+ labelClass: 'ui-dynamic-form-input-label',
466
+ inputClass: `input-${this.theme}`,
467
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
468
+ readonly: isReadOnly,
469
+ disabled: isReadOnly,
470
+ validation,
471
+ validationVisibility: 'live'
529
472
  }
530
- if (field.customForm && JSON.parse(field.customForm).style === 'heading_3') {
531
- typeToUse = 'h3'
473
+ }
474
+ case 'color':
475
+ return {
476
+ type: 'FormKit',
477
+ props: {
478
+ type: 'color',
479
+ id: field.id,
480
+ name,
481
+ label: field.label,
482
+ required: field.required,
483
+ value: this.formData[field.id],
484
+ help: hint,
485
+ readonly: isReadOnly,
486
+ disabled: isReadOnly,
487
+ validation,
488
+ validationVisibility: 'live'
532
489
  }
533
- return {
534
- type: typeToUse,
535
- innerText: this.formData[field.id]
490
+ }
491
+ case 'datetime-local':
492
+ return {
493
+ type: 'FormKit',
494
+ props: {
495
+ type: 'datetime-local',
496
+ id: field.id,
497
+ name,
498
+ label: field.label,
499
+ required: field.required,
500
+ value: this.formData[field.id],
501
+ help: hint,
502
+ wrapperClass: '$remove:formkit-wrapper',
503
+ labelClass: 'ui-dynamic-form-input-label',
504
+ inputClass: `input-${this.theme}`,
505
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
506
+ readonly: isReadOnly,
507
+ validation,
508
+ validationVisibility: 'live'
536
509
  }
537
- case 'hidden':
538
- return {
539
- type: 'input',
540
- props: {
541
- type: 'hidden',
542
- value: this.formData[field.id]
543
- }
510
+ }
511
+ case 'email':
512
+ return {
513
+ type: 'FormKit',
514
+ props: {
515
+ type: 'email',
516
+ id: field.id,
517
+ name,
518
+ label: field.label,
519
+ required: field.required,
520
+ value: this.formData[field.id],
521
+ help: hint,
522
+ placeholder,
523
+ wrapperClass: '$remove:formkit-wrapper',
524
+ labelClass: 'ui-dynamic-form-input-label',
525
+ inputClass: `input-${this.theme}`,
526
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
527
+ readonly: isReadOnly,
528
+ validation,
529
+ validationVisibility: 'live'
544
530
  }
545
- case 'month':
546
- return {
547
- type: 'FormKit',
548
- props: {
549
- type: 'month',
550
- id: field.id,
551
- name,
552
- label: field.label,
553
- required: field.required,
554
- value: this.formData[field.id],
555
- help: hint,
556
- wrapperClass: '$remove:formkit-wrapper',
557
- labelClass: 'ui-dynamic-form-input-label',
558
- inputClass: `input-${this.theme}`,
559
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
560
- readonly: isReadOnly,
561
- validation,
562
- validationVisibility: 'live'
563
- }
531
+ }
532
+ case 'header':
533
+ let typeToUse = 'h1'
534
+ if (field.customForm && JSON.parse(field.customForm).style === 'heading_2') {
535
+ typeToUse = 'h2'
536
+ }
537
+ if (field.customForm && JSON.parse(field.customForm).style === 'heading_3') {
538
+ typeToUse = 'h3'
539
+ }
540
+ return {
541
+ type: typeToUse,
542
+ innerText: this.formData[field.id]
543
+ }
544
+ case 'hidden':
545
+ return {
546
+ type: 'input',
547
+ props: {
548
+ type: 'hidden',
549
+ value: this.formData[field.id]
564
550
  }
565
- case 'paragraph':
566
- return {
567
- type: 'p',
568
- innerText: this.formData[field.id]
551
+ }
552
+ case 'month':
553
+ return {
554
+ type: 'FormKit',
555
+ props: {
556
+ type: 'month',
557
+ id: field.id,
558
+ name,
559
+ label: field.label,
560
+ required: field.required,
561
+ value: this.formData[field.id],
562
+ help: hint,
563
+ wrapperClass: '$remove:formkit-wrapper',
564
+ labelClass: 'ui-dynamic-form-input-label',
565
+ inputClass: `input-${this.theme}`,
566
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
567
+ readonly: isReadOnly,
568
+ validation,
569
+ validationVisibility: 'live'
569
570
  }
570
- case 'password':
571
- return {
572
- type: 'FormKit',
573
- props: {
574
- type: 'password',
575
- id: field.id,
576
- name,
577
- label: field.label,
578
- required: field.required,
579
- value: this.formData[field.id],
580
- help: hint,
581
- placeholder,
582
- wrapperClass: '$remove:formkit-wrapper',
583
- labelClass: 'ui-dynamic-form-input-label',
584
- inputClass: `input-${this.theme}`,
585
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
586
- readonly: isReadOnly,
587
- validation,
588
- validationVisibility: 'live'
589
- }
571
+ }
572
+ case 'paragraph':
573
+ return {
574
+ type: 'p',
575
+ innerText: this.formData[field.id]
576
+ }
577
+ case 'password':
578
+ return {
579
+ type: 'FormKit',
580
+ props: {
581
+ type: 'password',
582
+ id: field.id,
583
+ name,
584
+ label: field.label,
585
+ required: field.required,
586
+ value: this.formData[field.id],
587
+ help: hint,
588
+ placeholder,
589
+ wrapperClass: '$remove:formkit-wrapper',
590
+ labelClass: 'ui-dynamic-form-input-label',
591
+ inputClass: `input-${this.theme}`,
592
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
593
+ readonly: isReadOnly,
594
+ validation,
595
+ validationVisibility: 'live'
590
596
  }
591
- case 'radio':
592
- const radioOptions = JSON.parse(field.customForm).entries.map((obj) => {
593
- return { value: obj.key, label: obj.value }
594
- })
595
- return {
596
- type: 'FormKit',
597
- props: {
598
- type: 'radio',
599
- id: field.id,
600
- name,
601
- label: field.label,
602
- required: field.required,
603
- value: this.formData[field.id],
604
- options: radioOptions,
605
- help: hint,
606
- fieldsetClass: 'custom-fieldset',
607
- labelClass: 'ui-dynamic-form-input-label',
608
- inputClass: `input-${this.theme}`,
609
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
610
- readonly: isReadOnly,
611
- disabled: isReadOnly,
612
- validation,
613
- validationVisibility: 'live'
614
- }
597
+ }
598
+ case 'radio':
599
+ const radioOptions = JSON.parse(field.customForm).entries.map((obj) => {
600
+ return { value: obj.key, label: obj.value }
601
+ })
602
+ return {
603
+ type: 'FormKit',
604
+ props: {
605
+ type: 'radio',
606
+ id: field.id,
607
+ name,
608
+ label: field.label,
609
+ required: field.required,
610
+ value: this.formData[field.id],
611
+ options: radioOptions,
612
+ help: hint,
613
+ fieldsetClass: 'custom-fieldset',
614
+ labelClass: 'ui-dynamic-form-input-label',
615
+ inputClass: `input-${this.theme}`,
616
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
617
+ readonly: isReadOnly,
618
+ disabled: isReadOnly,
619
+ validation,
620
+ validationVisibility: 'live'
615
621
  }
616
- case 'range':
617
- const customForm = JSON.parse(field.customForm)
618
- return {
619
- type: 'v-slider',
620
- props: {
621
- id: field.id,
622
- name,
623
- // label: field.label,
624
- required: field.required,
625
- // value: this.formData[field.id],
626
- // help: hint,
627
- min: customForm.min,
628
- max: customForm.max,
629
- step: customForm.step,
630
- thumbLabel: true,
631
- // wrapperClass: '$remove:formkit-wrapper',
632
- labelClass: 'ui-dynamic-form-input-label',
633
- // inputClass: `input-${this.theme}`,
634
- // innerClass: ui-dynamic-form-input-outlines `${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
635
- readonly: isReadOnly,
636
- disabled: isReadOnly,
637
- validation,
638
- validationVisibility: 'live'
639
- }
622
+ }
623
+ case 'range':
624
+ const customForm = JSON.parse(field.customForm)
625
+ return {
626
+ type: 'v-slider',
627
+ props: {
628
+ id: field.id,
629
+ name,
630
+ // label: field.label,
631
+ required: field.required,
632
+ // value: this.formData[field.id],
633
+ // help: hint,
634
+ min: customForm.min,
635
+ max: customForm.max,
636
+ step: customForm.step,
637
+ thumbLabel: true,
638
+ // wrapperClass: '$remove:formkit-wrapper',
639
+ labelClass: 'ui-dynamic-form-input-label',
640
+ // inputClass: `input-${this.theme}`,
641
+ // innerClass: ui-dynamic-form-input-outlines `${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
642
+ readonly: isReadOnly,
643
+ disabled: isReadOnly,
644
+ validation,
645
+ validationVisibility: 'live'
640
646
  }
641
- case 'tel':
642
- return {
643
- type: 'FormKit',
644
- props: {
645
- type: 'tel' /* with pro component mask more good */,
646
- id: field.id,
647
- name,
648
- label: field.label,
649
- required: field.required,
650
- value: this.formData[field.id],
651
- help: hint,
652
- placeholder,
653
- wrapperClass: '$remove:formkit-wrapper',
654
- labelClass: 'ui-dynamic-form-input-label',
655
- inputClass: `input-${this.theme}`,
656
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
657
- readonly: isReadOnly,
658
- validation,
659
- validationVisibility: 'live'
660
- }
647
+ }
648
+ case 'tel':
649
+ return {
650
+ type: 'FormKit',
651
+ props: {
652
+ type: 'tel' /* with pro component mask more good */,
653
+ id: field.id,
654
+ name,
655
+ label: field.label,
656
+ required: field.required,
657
+ value: this.formData[field.id],
658
+ help: hint,
659
+ placeholder,
660
+ wrapperClass: '$remove:formkit-wrapper',
661
+ labelClass: 'ui-dynamic-form-input-label',
662
+ inputClass: `input-${this.theme}`,
663
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
664
+ readonly: isReadOnly,
665
+ validation,
666
+ validationVisibility: 'live'
661
667
  }
662
- case 'textarea':
663
- const rows = field.customForm ? JSON.parse(field.customForm).rows : undefined
664
- return {
665
- type: 'FormKit',
666
- props: {
667
- type: 'textarea' /* with pro component mask more good */,
668
- id: field.id,
669
- name,
670
- label: field.label,
671
- required: field.required,
672
- value: this.formData[field.id],
673
- rows,
674
- help: hint,
675
- placeholder,
676
- wrapperClass: '$remove:formkit-wrapper',
677
- labelClass: 'ui-dynamic-form-input-label',
678
- inputClass: `input-${this.theme}`,
679
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
680
- readonly: isReadOnly,
681
- validation,
682
- validationVisibility: 'live'
683
- }
668
+ }
669
+ case 'textarea':
670
+ const rows = field.customForm ? JSON.parse(field.customForm).rows : undefined
671
+ return {
672
+ type: 'FormKit',
673
+ props: {
674
+ type: 'textarea' /* with pro component mask more good */,
675
+ id: field.id,
676
+ name,
677
+ label: field.label,
678
+ required: field.required,
679
+ value: this.formData[field.id],
680
+ rows,
681
+ help: hint,
682
+ placeholder,
683
+ wrapperClass: '$remove:formkit-wrapper',
684
+ labelClass: 'ui-dynamic-form-input-label',
685
+ inputClass: `input-${this.theme}`,
686
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
687
+ readonly: isReadOnly,
688
+ validation,
689
+ validationVisibility: 'live'
684
690
  }
685
- case 'time':
686
- return {
687
- type: 'FormKit',
688
- props: {
689
- type: 'time' /* with pro component mask more good */,
690
- id: field.id,
691
- name,
692
- label: field.label,
693
- required: field.required,
694
- value: this.formData[field.id],
695
- help: hint,
696
- placeholder,
697
- wrapperClass: '$remove:formkit-wrapper',
698
- labelClass: 'ui-dynamic-form-input-label',
699
- inputClass: `input-${this.theme}`,
700
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
701
- readonly: isReadOnly,
702
- validation,
703
- validationVisibility: 'live'
704
- }
691
+ }
692
+ case 'time':
693
+ return {
694
+ type: 'FormKit',
695
+ props: {
696
+ type: 'time' /* with pro component mask more good */,
697
+ id: field.id,
698
+ name,
699
+ label: field.label,
700
+ required: field.required,
701
+ value: this.formData[field.id],
702
+ help: hint,
703
+ placeholder,
704
+ wrapperClass: '$remove:formkit-wrapper',
705
+ labelClass: 'ui-dynamic-form-input-label',
706
+ inputClass: `input-${this.theme}`,
707
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
708
+ readonly: isReadOnly,
709
+ validation,
710
+ validationVisibility: 'live'
705
711
  }
706
- case 'url':
707
- return {
708
- type: 'FormKit',
709
- props: {
710
- type: 'url',
711
- id: field.id,
712
- name,
713
- label: field.label,
714
- required: field.required,
715
- value: this.formData[field.id],
716
- help: hint,
717
- placeholder,
718
- wrapperClass: '$remove:formkit-wrapper',
719
- labelClass: 'ui-dynamic-form-input-label',
720
- inputClass: `input-${this.theme}`,
721
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
722
- readonly: isReadOnly,
723
- validation,
724
- validationVisibility: 'live'
725
- }
712
+ }
713
+ case 'url':
714
+ return {
715
+ type: 'FormKit',
716
+ props: {
717
+ type: 'url',
718
+ id: field.id,
719
+ name,
720
+ label: field.label,
721
+ required: field.required,
722
+ value: this.formData[field.id],
723
+ help: hint,
724
+ placeholder,
725
+ wrapperClass: '$remove:formkit-wrapper',
726
+ labelClass: 'ui-dynamic-form-input-label',
727
+ inputClass: `input-${this.theme}`,
728
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
729
+ readonly: isReadOnly,
730
+ validation,
731
+ validationVisibility: 'live'
726
732
  }
727
- case 'week':
728
- return {
729
- type: 'FormKit',
730
- props: {
731
- type: 'week',
732
- id: field.id,
733
- name,
734
- label: field.label,
735
- required: field.required,
736
- value: this.formData[field.id],
737
- help: hint,
738
- placeholder,
739
- wrapperClass: '$remove:formkit-wrapper',
740
- labelClass: 'ui-dynamic-form-input-label',
741
- inputClass: `input-${this.theme}`,
742
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
743
- readonly: isReadOnly,
744
- validation,
745
- validationVisibility: 'live'
746
- }
733
+ }
734
+ case 'week':
735
+ return {
736
+ type: 'FormKit',
737
+ props: {
738
+ type: 'week',
739
+ id: field.id,
740
+ name,
741
+ label: field.label,
742
+ required: field.required,
743
+ value: this.formData[field.id],
744
+ help: hint,
745
+ placeholder,
746
+ wrapperClass: '$remove:formkit-wrapper',
747
+ labelClass: 'ui-dynamic-form-input-label',
748
+ inputClass: `input-${this.theme}`,
749
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
750
+ readonly: isReadOnly,
751
+ validation,
752
+ validationVisibility: 'live'
747
753
  }
748
- default:
749
- return {
750
- type: 'FormKit',
751
- props: {
752
- type: field.type,
753
- id: field.id,
754
- name,
755
- label: field.label,
756
- required: field.required,
757
- value: this.formData[field.id],
758
- help: hint,
759
- labelClass: 'ui-dynamic-form-input-label',
760
- inputClass: `input-${this.theme}`,
761
- innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
762
- readonly: isReadOnly,
763
- validation,
764
- validationVisibility: 'live'
765
- }
754
+ }
755
+ default:
756
+ return {
757
+ type: 'FormKit',
758
+ props: {
759
+ type: field.type,
760
+ id: field.id,
761
+ name,
762
+ label: field.label,
763
+ required: field.required,
764
+ value: this.formData[field.id],
765
+ help: hint,
766
+ labelClass: 'ui-dynamic-form-input-label',
767
+ inputClass: `input-${this.theme}`,
768
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
769
+ readonly: isReadOnly,
770
+ validation,
771
+ validationVisibility: 'live'
766
772
  }
773
+ }
767
774
  }
768
775
  },
769
- toggleCollapse() {
776
+ toggleCollapse () {
770
777
  this.collapsed = !this.collapsed
771
778
  },
772
- getRowWidthStyling(field, index) {
779
+ getRowWidthStyling (field, index) {
773
780
  let style = ''
774
781
  if (index === 0) {
775
782
  style += 'margin-top: 12px;'
@@ -781,7 +788,7 @@ export default {
781
788
  }
782
789
  return style
783
790
  },
784
- fields() {
791
+ fields () {
785
792
  const aFields = this.userTask.userTaskConfig?.formFields ?? []
786
793
  const fieldMap = aFields.map((field) => ({
787
794
  ...field,
@@ -794,12 +801,12 @@ export default {
794
801
  widget-action just sends a msg to Node-RED, it does not store the msg state server-side
795
802
  alternatively, you can use widget-change, which will also store the msg in the Node's datastore
796
803
  */
797
- send(msg, index) {
804
+ send (msg, index) {
798
805
  const msgArr = []
799
806
  msgArr[index] = msg
800
807
  this.$socket.emit('widget-action', this.id, msgArr)
801
808
  },
802
- init(msg) {
809
+ init (msg) {
803
810
  this.msg = msg
804
811
  if (!msg) {
805
812
  return
@@ -872,7 +879,7 @@ export default {
872
879
  this.focusFirstFormField()
873
880
  })
874
881
  },
875
- actionFn(action) {
882
+ actionFn (action) {
876
883
  if (action.label === 'Speichern' || action.label === 'Speichern und nächster') {
877
884
  const formkitInputs = this.$refs.form.$el.querySelectorAll('.formkit-outer')
878
885
  let allComplete = true
@@ -908,7 +915,7 @@ export default {
908
915
  this.showError(action.errorMessage)
909
916
  }
910
917
  },
911
- checkCondition(condition) {
918
+ checkCondition (condition) {
912
919
  if (condition === '') return true
913
920
  try {
914
921
  // eslint-disable-next-line no-new-func
@@ -920,10 +927,10 @@ export default {
920
927
  return false
921
928
  }
922
929
  },
923
- showError(errMsg) {
930
+ showError (errMsg) {
924
931
  this.errorMsg = errMsg
925
932
  },
926
- focusFirstFormField() {
933
+ focusFirstFormField () {
927
934
  if (this.collapsed || !this.hasUserTask) {
928
935
  return
929
936
  }
@@ -951,7 +958,7 @@ export default {
951
958
  }
952
959
  }
953
960
 
954
- function mapItems(type, field) {
961
+ function mapItems (type, field) {
955
962
  if (type === 'enum') {
956
963
  return field.enumValues.map((enumValue) => ({
957
964
  title: enumValue.name,