@5minds/node-red-dashboard-2-processcube-dynamic-form 2.0.4 → 2.0.5-feature-2f01ec-mcergl3n

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,62 +1,50 @@
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
- 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"
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"
7
6
  :collapsible="props.collapsible || (props.collapse_when_finished && formIsFinished)" :collapsed="collapsed"
8
- :toggleCollapse="toggleCollapse"
9
- />
7
+ :toggleCollapse="toggleCollapse" />
10
8
  <div className="ui-dynamic-form-wrapper">
11
9
  <p v-if="hasUserTask" style="margin-bottom: 0px">
12
10
  <v-form ref="form" v-model="form" :class="dynamicClass">
13
- <UIDynamicFormTitleText
14
- v-if="props.title_style != 'outside'" :style="props.title_style"
15
- :title="props.title_text" :customStyles="props.title_custom_text_styling"
11
+ <UIDynamicFormTitleText v-if="props.title_style != 'outside'" :style="props.title_style"
12
+ :title="effectiveTitle" :customStyles="props.title_custom_text_styling"
16
13
  :titleIcon="props.title_icon"
17
14
  :collapsible="props.collapsible || (props.collapse_when_finished && formIsFinished)"
18
- :collapsed="collapsed" :toggleCollapse="toggleCollapse"
19
- />
15
+ :collapsed="collapsed" :toggleCollapse="toggleCollapse" />
20
16
  <Transition name="cardCollapse">
21
17
  <div v-if="!collapsed">
22
18
  <div className="ui-dynamic-form-formfield-positioner" :style="props.inner_card_styling">
23
19
  <FormKit id="form" type="group">
24
- <v-row
25
- v-for="(field, index) in fields()" :key="field"
26
- :style="getRowWidthStyling(field, index)"
27
- >
20
+ <v-row v-for="(field, index) in fields()" :key="field"
21
+ :style="getRowWidthStyling(field, index)">
28
22
  <v-col cols="12">
29
- <component
30
- :is="createComponent(field).type"
23
+ <component :is="createComponent(field).type"
31
24
  v-if="createComponent(field).innerText"
32
25
  v-bind="createComponent(field).props" :ref="(el) => {
33
26
  if (index === 0) firstFormFieldRef = el;
34
27
  }
35
- " v-model="formData[field.id]"
36
- >
28
+ " v-model="formData[field.id]">
37
29
  {{ createComponent(field).innerText }}
38
30
  </component>
39
31
  <div v-else-if="createComponent(field).type == 'v-slider'">
40
32
  <p class="formkit-label">{{ field.label }}</p>
41
- <component
42
- :is="createComponent(field).type"
33
+ <component :is="createComponent(field).type"
43
34
  v-bind="createComponent(field).props" :ref="(el) => {
44
35
  if (index === 0) firstFormFieldRef = el;
45
36
  }
46
- " v-model="field.defaultValue"
47
- />
37
+ " v-model="field.defaultValue" />
48
38
  <p class="formkit-help">
49
39
  {{ field.customForm ? JSON.parse(field.customForm).hint : undefined
50
40
  }}
51
41
  </p>
52
42
  </div>
53
- <component
54
- :is="createComponent(field).type" v-else
43
+ <component :is="createComponent(field).type" v-else
55
44
  v-bind="createComponent(field).props" :ref="(el) => {
56
45
  if (index === 0) firstFormFieldRef = el;
57
46
  }
58
- " v-model="formData[field.id]"
59
- />
47
+ " v-model="formData[field.id]" />
60
48
  </v-col>
61
49
  </v-row>
62
50
  </FormKit>
@@ -65,21 +53,17 @@
65
53
  <v-row v-if="errorMsg.length > 0" style="padding: 12px">
66
54
  <v-alert type="error">Error: {{ errorMsg }}</v-alert>
67
55
  </v-row>
68
- <UIDynamicFormFooterAction
69
- v-if="props.actions_inside_card && actions.length > 0"
56
+ <UIDynamicFormFooterAction v-if="props.actions_inside_card && actions.length > 0"
70
57
  :actions="actions" :actionCallback="actionFn" :formIsFinished="formIsFinished"
71
- style="padding: 16px; padding-top: 0px"
72
- />
58
+ style="padding: 16px; padding-top: 0px" />
73
59
  </v-row>
74
60
  </div>
75
61
  </Transition>
76
62
  </v-form>
77
63
  </p>
78
64
  <p v-else>
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
- />
65
+ <v-alert v-if="props.waiting_info.length > 0 || props.waiting_title.length > 0"
66
+ :text="props.waiting_info" :title="props.waiting_title" />
83
67
  </p>
84
68
  </div>
85
69
  <div v-if="!props.actions_inside_card && actions.length > 0 && hasUserTask" style="padding-top: 32px">
@@ -100,7 +84,7 @@ import UIDynamicFormFooterAction from './FooterActions.vue'
100
84
  import UIDynamicFormTitleText from './TitleText.vue'
101
85
 
102
86
  // eslint-disable-next-line no-unused-vars
103
- function requiredIf ({ value }, [targetField, expectedValue], node) {
87
+ function requiredIf({ value }, [targetField, expectedValue], node) {
104
88
  console.debug(arguments)
105
89
 
106
90
  const actual = node?.root?.value?.[targetField]
@@ -130,7 +114,7 @@ export default {
130
114
  default: () => ({ enabled: false, visible: false })
131
115
  }
132
116
  },
133
- setup (props) {
117
+ setup(props) {
134
118
  console.info('UIDynamicForm setup with:', props)
135
119
  console.debug('Vue function loaded correctly', markRaw)
136
120
 
@@ -146,7 +130,7 @@ export default {
146
130
  })
147
131
  app.use(plugin, formkitConfig)
148
132
  },
149
- data () {
133
+ data() {
150
134
  return {
151
135
  actions: [],
152
136
  formData: {},
@@ -160,42 +144,51 @@ export default {
160
144
  }
161
145
  },
162
146
  computed: {
163
- dynamicClass () {
147
+ dynamicClass() {
164
148
  return `ui-dynamic-form-${this.theme} ui-dynamic-form-common`
165
149
  },
166
- dynamicFooterClass () {
150
+ dynamicFooterClass() {
167
151
  return `ui-dynamic-form-footer-${this.theme} ui-dynamic-form-footer-common`
168
152
  },
169
- hasUserTask () {
153
+ hasUserTask() {
170
154
  return !!this.userTask
171
155
  },
172
- totalOutputs () {
156
+ totalOutputs() {
173
157
  return (
174
158
  this.props.options.length +
175
159
  (this.props.handle_confirmation_dialogs ? 2 : 0) +
176
160
  (this.props.trigger_on_change ? 1 : 0)
177
161
  )
178
162
  },
179
- isConfirmDialog () {
163
+ isConfirmDialog() {
180
164
  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
+ }
181
174
  }
182
175
  },
183
176
  watch: {
184
177
  formData: {
185
- handler (newData, oldData) {
178
+ handler(newData, oldData) {
186
179
  if (this.props.trigger_on_change) {
187
180
  const res = { payload: { formData: newData, userTask: this.userTask } }
188
181
  this.send(res, this.totalOutputs - 1)
189
182
  }
190
183
  },
191
- collapsed (newVal) {
184
+ collapsed(newVal) {
192
185
  if (!newVal && this.hasUserTask) {
193
186
  nextTick(() => {
194
187
  this.focusFirstFormField()
195
188
  })
196
189
  }
197
190
  },
198
- userTask (newVal) {
191
+ userTask(newVal) {
199
192
  if (newVal && !this.collapsed) {
200
193
  nextTick(() => {
201
194
  this.focusFirstFormField()
@@ -205,7 +198,7 @@ export default {
205
198
  deep: true
206
199
  }
207
200
  },
208
- created () {
201
+ created() {
209
202
  const currentPath = window.location.pathname
210
203
  const lastPart = currentPath.substring(currentPath.lastIndexOf('/'))
211
204
 
@@ -225,7 +218,7 @@ export default {
225
218
  }
226
219
  }
227
220
  },
228
- mounted () {
221
+ mounted() {
229
222
  const elements = document.querySelectorAll('.formkit-input')
230
223
 
231
224
  elements.forEach((element) => {
@@ -242,13 +235,13 @@ export default {
242
235
  // tell Node-RED that we're loading a new instance of this widget
243
236
  this.$socket.emit('widget-load', this.id)
244
237
  },
245
- unmounted () {
238
+ unmounted() {
246
239
  /* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */
247
240
  this.$socket?.off('widget-load' + this.id)
248
241
  this.$socket?.off('msg-input:' + this.id)
249
242
  },
250
243
  methods: {
251
- createComponent (field) {
244
+ createComponent(field) {
252
245
  const customForm = field.customForm ? JSON.parse(field.customForm) : {}
253
246
  const hint = customForm.hint
254
247
  const placeholder = customForm.placeholder
@@ -262,521 +255,521 @@ export default {
262
255
  ? 'true'
263
256
  : undefined
264
257
  switch (field.type) {
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'
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
+ }
284
278
  }
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'
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
+ }
306
300
  }
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'
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
+ }
326
320
  }
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'
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
+ }
351
345
  }
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'
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
+ }
377
371
  }
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'
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
+ }
398
392
  }
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'
393
+ case 'confirm':
394
+ return {
395
+ type: 'h3',
396
+ innerText: field.label
423
397
  }
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'
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
+ }
447
417
  }
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'
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
+ }
472
441
  }
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'
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
+ }
489
466
  }
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'
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
+ }
509
483
  }
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'
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
+ }
530
503
  }
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]
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
+ }
550
524
  }
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'
525
+ case 'header':
526
+ let typeToUse = 'h1'
527
+ if (field.customForm && JSON.parse(field.customForm).style === 'heading_2') {
528
+ typeToUse = 'h2'
570
529
  }
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'
530
+ if (field.customForm && JSON.parse(field.customForm).style === 'heading_3') {
531
+ typeToUse = 'h3'
596
532
  }
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'
533
+ return {
534
+ type: typeToUse,
535
+ innerText: this.formData[field.id]
621
536
  }
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'
537
+ case 'hidden':
538
+ return {
539
+ type: 'input',
540
+ props: {
541
+ type: 'hidden',
542
+ value: this.formData[field.id]
543
+ }
646
544
  }
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'
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
+ }
667
564
  }
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'
565
+ case 'paragraph':
566
+ return {
567
+ type: 'p',
568
+ innerText: this.formData[field.id]
690
569
  }
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'
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
+ }
711
590
  }
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'
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
+ }
732
615
  }
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'
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
+ }
753
640
  }
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'
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
+ }
661
+ }
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
+ }
684
+ }
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
+ }
705
+ }
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
+ }
726
+ }
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
+ }
747
+ }
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
+ }
772
766
  }
773
- }
774
767
  }
775
768
  },
776
- toggleCollapse () {
769
+ toggleCollapse() {
777
770
  this.collapsed = !this.collapsed
778
771
  },
779
- getRowWidthStyling (field, index) {
772
+ getRowWidthStyling(field, index) {
780
773
  let style = ''
781
774
  if (index === 0) {
782
775
  style += 'margin-top: 12px;'
@@ -788,7 +781,7 @@ export default {
788
781
  }
789
782
  return style
790
783
  },
791
- fields () {
784
+ fields() {
792
785
  const aFields = this.userTask.userTaskConfig?.formFields ?? []
793
786
  const fieldMap = aFields.map((field) => ({
794
787
  ...field,
@@ -801,12 +794,12 @@ export default {
801
794
  widget-action just sends a msg to Node-RED, it does not store the msg state server-side
802
795
  alternatively, you can use widget-change, which will also store the msg in the Node's datastore
803
796
  */
804
- send (msg, index) {
797
+ send(msg, index) {
805
798
  const msgArr = []
806
799
  msgArr[index] = msg
807
800
  this.$socket.emit('widget-action', this.id, msgArr)
808
801
  },
809
- init (msg) {
802
+ init(msg) {
810
803
  this.msg = msg
811
804
  if (!msg) {
812
805
  return
@@ -879,7 +872,7 @@ export default {
879
872
  this.focusFirstFormField()
880
873
  })
881
874
  },
882
- actionFn (action) {
875
+ actionFn(action) {
883
876
  if (action.label === 'Speichern' || action.label === 'Speichern und nächster') {
884
877
  const formkitInputs = this.$refs.form.$el.querySelectorAll('.formkit-outer')
885
878
  let allComplete = true
@@ -915,7 +908,7 @@ export default {
915
908
  this.showError(action.errorMessage)
916
909
  }
917
910
  },
918
- checkCondition (condition) {
911
+ checkCondition(condition) {
919
912
  if (condition === '') return true
920
913
  try {
921
914
  // eslint-disable-next-line no-new-func
@@ -927,10 +920,10 @@ export default {
927
920
  return false
928
921
  }
929
922
  },
930
- showError (errMsg) {
923
+ showError(errMsg) {
931
924
  this.errorMsg = errMsg
932
925
  },
933
- focusFirstFormField () {
926
+ focusFirstFormField() {
934
927
  if (this.collapsed || !this.hasUserTask) {
935
928
  return
936
929
  }
@@ -958,7 +951,7 @@ export default {
958
951
  }
959
952
  }
960
953
 
961
- function mapItems (type, field) {
954
+ function mapItems(type, field) {
962
955
  if (type === 'enum') {
963
956
  return field.enumValues.map((enumValue) => ({
964
957
  title: enumValue.name,