@5minds/node-red-dashboard-2-processcube-dynamic-form 1.1.2-develop-231918-m7na5yab → 1.1.2-develop-3a05ff-madmm9tj

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,71 +1,99 @@
1
1
  <template>
2
- <!-- Component must be wrapped in a block so props such as className and style can be passed in from parent -->
3
- <div className="ui-dynamic-form-wrapper">
4
- <p v-if="hasFields()">
5
- <v-form ref="form" v-model="form" :class="dynamicClass">
6
- <h3 style="padding: 16px">{{ props.name }}</h3>
7
- <div style="padding: 16px; max-height: 550px; overflow-y: auto">
8
- <FormKit id="form" type="group">
9
- <v-row v-for="(field, index) in fields()" :key="field">
10
- <v-col cols="12">
11
- <component
12
- :is="createComponent(field).type"
13
- v-if="createComponent(field).innerText"
14
- v-bind="createComponent(field).props"
15
- v-model="formData[field.id]"
16
- >
17
- {{ createComponent(field).innerText }}
18
- </component>
19
- <div v-else-if="createComponent(field).type == 'v-slider'">
20
- <p class="formkit-label">{{ field.label }}</p>
21
- <component
22
- :is="createComponent(field).type"
23
- v-bind="createComponent(field).props"
24
- v-model="field.defaultValue"
25
- />
26
- <p class="formkit-help">
27
- {{ field.customForm ? JSON.parse(field.customForm).hint : undefined }}
28
- </p>
29
- </div>
30
- <component
31
- :is="createComponent(field).type"
32
- v-else
33
- v-bind="createComponent(field).props"
34
- v-model="formData[field.id]"
35
- />
36
- </v-col>
37
- </v-row>
38
- </FormKit>
39
- </div>
40
- <v-row :class="dynamicFooterClass">
41
- <v-row v-if="error" style="padding: 12px">
42
- <v-alert v-if="error" type="error">Error: {{ errorMsg }}</v-alert>
43
- </v-row>
44
- <div style="display: flex; gap: 8px">
45
- <div v-for="(action, index) in actions" :key="index" style="flex-grow: 1">
46
- <v-btn :key="index" style="width: 100% !important; min-height: 36px" @click="actionFn(action)">
47
- {{ action.label }}
48
- </v-btn>
2
+ <div className="ui-dynamic-form-external-sizing-wrapper" :style="props.card_size_styling">
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"
6
+ :style="props.title_style"
7
+ :title="props.title_text"
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
+ />
14
+ <div className="ui-dynamic-form-wrapper">
15
+ <p v-if="hasUserTask" style="margin-bottom: 0px;">
16
+ <v-form ref="form" v-model="form" :class="dynamicClass">
17
+ <UIDynamicFormTitleText
18
+ v-if="props.title_style != 'outside'"
19
+ :style="props.title_style"
20
+ :title="props.title_text"
21
+ :customStyles="props.title_custom_text_styling"
22
+ :titleIcon="props.title_icon"
23
+ :collapsible="props.collapsible || (props.collapse_when_finished && formIsFinished)"
24
+ :collapsed="collapsed"
25
+ :toggleCollapse="toggleCollapse"
26
+ />
27
+ <Transition name="cardCollapse">
28
+ <div v-if="!collapsed">
29
+ <div className="ui-dynamic-form-formfield-positioner">
30
+ <FormKit id="form" type="group">
31
+ <v-row v-for="(field, index) in fields()" :key="field" :style="getRowWidthStyling(field, index)">
32
+ <v-col cols="12">
33
+ <component
34
+ :is="createComponent(field).type"
35
+ v-if="createComponent(field).innerText"
36
+ v-bind="createComponent(field).props"
37
+ v-model="formData[field.id]"
38
+ >
39
+ {{ createComponent(field).innerText }}
40
+ </component>
41
+ <div v-else-if="createComponent(field).type == 'v-slider'">
42
+ <p class="formkit-label">{{ field.label }}</p>
43
+ <component
44
+ :is="createComponent(field).type"
45
+ v-bind="createComponent(field).props"
46
+ v-model="field.defaultValue"
47
+ />
48
+ <p class="formkit-help">
49
+ {{ field.customForm ? JSON.parse(field.customForm).hint : undefined }}
50
+ </p>
51
+ </div>
52
+ <component
53
+ :is="createComponent(field).type"
54
+ v-else
55
+ v-bind="createComponent(field).props"
56
+ v-model="formData[field.id]"
57
+ />
58
+ </v-col>
59
+ </v-row>
60
+ </FormKit>
61
+ </div>
62
+ <v-row :class="dynamicFooterClass">
63
+ <v-row v-if="errorMsg.length > 0" style="padding: 12px">
64
+ <v-alert type="error">Error: {{ errorMsg }}</v-alert>
65
+ </v-row>
66
+ <UIDynamicFormFooterAction v-if="props.actions_inside_card && actions.length > 0" :actions="actions" :actionCallback="actionFn" :formIsFinished="formIsFinished" style="padding: 16px; padding-top: 0px;" />
67
+ </v-row>
49
68
  </div>
50
- </div>
51
- </v-row>
52
- </v-form>
53
- </p>
54
- <p v-else>
55
- <v-alert :text="waiting_info" :title="waiting_title" />
56
- </p>
69
+ </Transition>
70
+ </v-form>
71
+ </p>
72
+ <p v-else>
73
+ <v-alert v-if="props.waiting_info.length > 0 || props.waiting_title.length > 0" :text="props.waiting_info" :title="props.waiting_title" />
74
+ </p>
75
+ </div>
76
+ <div v-if="!props.actions_inside_card && actions.length > 0 && hasUserTask" style="padding-top: 32px;">
77
+ <UIDynamicFormFooterAction :actions="actions" :actionCallback="actionFn" />
78
+ </div>
57
79
  </div>
58
80
  </template>
59
81
 
82
+ <!-- eslint-disable no-case-declarations -->
60
83
  <script>
61
84
  import { FormKit, defaultConfig, plugin } from '@formkit/vue'
62
- import { getCurrentInstance, h, markRaw } from 'vue'
63
- import { mapState } from 'vuex'
85
+ import { getCurrentInstance, markRaw } from 'vue'
86
+
87
+ // eslint-disable-next-line import/no-unresolved
64
88
  import '@formkit/themes/genesis'
65
- import { getNode } from '@formkit/core'
89
+ import UIDynamicFormFooterAction from './FooterActions.vue'
90
+ import UIDynamicFormTitleText from './TitleText.vue'
66
91
 
67
92
  export default {
68
93
  name: 'UIDynamicForm',
94
+ components: {
95
+ FormKit, UIDynamicFormFooterAction, UIDynamicFormTitleText
96
+ },
69
97
  inject: ['$socket'],
70
98
  props: {
71
99
  /* do not remove entries from this - Dashboard's Layout Manager's will pass this data to your component */
@@ -89,12 +117,35 @@ export default {
89
117
  data () {
90
118
  return {
91
119
  actions: [],
92
- form: {},
93
120
  formData: {},
94
- taskInput: {},
121
+ userTask: null,
95
122
  theme: '',
96
- error: false,
97
- errorMsg: ''
123
+ errorMsg: '',
124
+ formIsFinished: false,
125
+ msg: null,
126
+ collapsed: false
127
+ }
128
+ },
129
+ computed: {
130
+ dynamicClass () {
131
+ return `ui-dynamic-form-${this.theme} ui-dynamic-form-common`
132
+ },
133
+ dynamicFooterClass () {
134
+ return `ui-dynamic-form-footer-${this.theme} ui-dynamic-form-footer-common`
135
+ },
136
+ hasUserTask () {
137
+ return !!this.userTask
138
+ }
139
+ },
140
+ watch: {
141
+ formData: {
142
+ handler (newData, oldData) {
143
+ if (this.props.trigger_on_change) {
144
+ const res = { payload: { formData: newData, userTask: this.userTask } }
145
+ this.send(res, this.actions.length)
146
+ }
147
+ },
148
+ deep: true
98
149
  }
99
150
  },
100
151
  created () {
@@ -117,26 +168,6 @@ export default {
117
168
  }
118
169
  }
119
170
  },
120
- computed: {
121
- ...mapState('data', ['messages']),
122
- waiting_title () {
123
- return this.props.waiting_title || 'Warten auf den Usertask...'
124
- },
125
- waiting_info () {
126
- return (
127
- this.props.waiting_info ||
128
- 'Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist.'
129
- )
130
- },
131
-
132
- dynamicClass () {
133
- return `ui-dynamic-form-${this.theme}`
134
- },
135
-
136
- dynamicFooterClass () {
137
- return `ui-dynamic-form-footer-${this.theme}`
138
- }
139
- },
140
171
  mounted () {
141
172
  const elements = document.querySelectorAll('.formkit-input')
142
173
 
@@ -145,61 +176,32 @@ export default {
145
176
  })
146
177
 
147
178
  this.$socket.on('widget-load:' + this.id, (msg) => {
148
- this.init()
149
- this.$store.commit('data/bind', {
150
- widgetId: this.id,
151
- msg
152
- })
179
+ this.init(msg)
153
180
  })
154
181
  this.$socket.on('msg-input:' + this.id, (msg) => {
155
182
  // store the latest message in our client-side vuex store when we receive a new message
156
- this.init()
157
-
158
- this.messages[this.id] = msg
159
-
160
- const hasTask = msg.payload && msg.payload.userTask
161
- const defaultValues = msg.payload.userTask.userTaskConfig.formFields
162
- const initialValues = msg.payload.userTask.startToken
163
-
164
- if (hasTask) {
165
- this.taskInput = msg.payload.userTask
166
- }
167
-
168
- if (hasTask && defaultValues) {
169
- defaultValues.forEach((field) => {
170
- this.formData[field.id] = field.defaultValue
171
- })
172
- }
173
-
174
- if (hasTask && initialValues) {
175
- Object.keys(initialValues).forEach((key) => {
176
- this.formData[key] = initialValues[key]
177
- })
178
- }
179
-
180
- this.$store.commit('data/bind', {
181
- widgetId: this.id,
182
- msg
183
- })
183
+ this.init(msg)
184
184
  })
185
185
  // tell Node-RED that we're loading a new instance of this widget
186
186
  this.$socket.emit('widget-load', this.id)
187
187
  },
188
188
  unmounted () {
189
- /* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */
189
+ /* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */
190
190
  this.$socket?.off('widget-load' + this.id)
191
191
  this.$socket?.off('msg-input:' + this.id)
192
192
  },
193
- components: {
194
- FormKit
195
- },
196
193
  methods: {
197
194
  createComponent (field) {
198
- const hint = field.customForm ? JSON.parse(field.customForm).hint : undefined
199
- const placeholder = field.customForm ? JSON.parse(field.customForm).placeholder : undefined
200
- const validation = field.customForm ? JSON.parse(field.customForm).validation : undefined
195
+ const customForm = field.customForm ? JSON.parse(field.customForm) : {}
196
+ const hint = customForm.hint
197
+ const placeholder = customForm.placeholder
198
+ const validation = customForm.validation
201
199
  const name = field.id
202
-
200
+ const customProperties = customForm.customProperties ?? []
201
+ const isReadOnly = (
202
+ this.props.readonly || this.formIsFinished || customProperties.find(entry => ['readOnly', 'readonly'].includes(entry.name) && entry.value === 'true'))
203
+ ? 'true'
204
+ : undefined
203
205
  switch (field.type) {
204
206
  case 'long':
205
207
  return {
@@ -210,12 +212,14 @@ export default {
210
212
  name,
211
213
  label: field.label,
212
214
  required: field.required,
213
- value: field.defaultValue,
215
+ value: this.formData[field.id],
214
216
  number: 'integer',
215
217
  help: hint,
216
218
  wrapperClass: '$remove:formkit-wrapper',
219
+ labelClass: 'ui-dynamic-form-input-label',
217
220
  inputClass: `input-${this.theme}`,
218
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
221
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
222
+ readonly: isReadOnly,
219
223
  validation,
220
224
  validationVisibility: 'live'
221
225
  }
@@ -230,12 +234,14 @@ export default {
230
234
  name,
231
235
  label: field.label,
232
236
  required: field.required,
233
- value: field.defaultValue,
237
+ value: this.formData[field.id],
234
238
  step,
235
239
  help: hint,
236
240
  wrapperClass: '$remove:formkit-wrapper',
241
+ labelClass: 'ui-dynamic-form-input-label',
237
242
  inputClass: `input-${this.theme}`,
238
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
243
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
244
+ readonly: isReadOnly,
239
245
  validation,
240
246
  validationVisibility: 'live'
241
247
  }
@@ -249,11 +255,13 @@ export default {
249
255
  name,
250
256
  label: field.label,
251
257
  required: field.required,
252
- value: field.defaultValue,
258
+ value: this.formData[field.id],
253
259
  help: hint,
254
260
  wrapperClass: '$remove:formkit-wrapper',
261
+ labelClass: 'ui-dynamic-form-input-label',
255
262
  inputClass: `input-${this.theme}`,
256
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
263
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
264
+ readonly: isReadOnly,
257
265
  validation,
258
266
  validationVisibility: 'live'
259
267
  }
@@ -270,12 +278,15 @@ export default {
270
278
  name,
271
279
  label: field.label,
272
280
  required: field.required,
273
- value: field.defaultValue,
281
+ value: this.formData[field.id],
274
282
  options: enums,
275
283
  help: hint,
276
284
  wrapperClass: '$remove:formkit-wrapper',
285
+ labelClass: 'ui-dynamic-form-input-label',
277
286
  inputClass: `input-${this.theme}`,
278
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
287
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
288
+ readonly: isReadOnly,
289
+ disabled: isReadOnly,
279
290
  validation,
280
291
  validationVisibility: 'live'
281
292
  }
@@ -292,13 +303,16 @@ export default {
292
303
  name,
293
304
  label: field.label,
294
305
  required: field.required,
295
- value: field.defaultValue,
306
+ value: this.formData[field.id],
296
307
  options: selections,
297
308
  placeholder,
298
309
  help: hint,
299
310
  wrapperClass: '$remove:formkit-wrapper',
311
+ labelClass: 'ui-dynamic-form-input-label',
300
312
  inputClass: `input-${this.theme}`,
301
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
313
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
314
+ readonly: isReadOnly,
315
+ disabled: isReadOnly,
302
316
  validation,
303
317
  validationVisibility: 'live'
304
318
  }
@@ -312,12 +326,14 @@ export default {
312
326
  name,
313
327
  label: field.label,
314
328
  required: field.required,
315
- value: field.defaultValue,
329
+ value: this.formData[field.id],
316
330
  help: hint,
317
331
  placeholder,
318
332
  wrapperClass: '$remove:formkit-wrapper',
333
+ labelClass: 'ui-dynamic-form-input-label',
319
334
  inputClass: `input-${this.theme}`,
320
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
335
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
336
+ readonly: isReadOnly,
321
337
  validation,
322
338
  validationVisibility: 'live'
323
339
  }
@@ -331,10 +347,13 @@ export default {
331
347
  name,
332
348
  label: field.label,
333
349
  required: field.required,
334
- value: field.defaultValue,
350
+ value: this.formData[field.id],
335
351
  help: hint,
352
+ labelClass: 'ui-dynamic-form-input-label',
336
353
  inputClass: `input-${this.theme}`,
337
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
354
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
355
+ readonly: isReadOnly,
356
+ disabled: isReadOnly,
338
357
  validation,
339
358
  validationVisibility: 'live'
340
359
  }
@@ -348,12 +367,15 @@ export default {
348
367
  name,
349
368
  label: field.label,
350
369
  required: field.required,
351
- value: field.defaultValue,
370
+ value: this.formData[field.id],
352
371
  help: hint,
353
372
  innerClass: 'reset-background',
354
373
  wrapperClass: '$remove:formkit-wrapper',
374
+ labelClass: 'ui-dynamic-form-input-label',
355
375
  inputClass: `input-${this.theme}`,
356
- // innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
376
+ // innerClass: ui-dynamic-form-input-outlines `${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
377
+ readonly: isReadOnly,
378
+ disabled: isReadOnly,
357
379
  validation,
358
380
  validationVisibility: 'live'
359
381
  }
@@ -370,12 +392,15 @@ export default {
370
392
  name,
371
393
  label: field.label,
372
394
  required: field.required,
373
- value: field.defaultValue,
395
+ value: this.formData[field.id],
374
396
  options,
375
397
  help: hint,
376
398
  fieldsetClass: 'custom-fieldset',
399
+ labelClass: 'ui-dynamic-form-input-label',
377
400
  inputClass: `input-${this.theme}`,
378
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
401
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
402
+ readonly: isReadOnly,
403
+ disabled: isReadOnly,
379
404
  validation,
380
405
  validationVisibility: 'live'
381
406
  }
@@ -389,8 +414,10 @@ export default {
389
414
  name,
390
415
  label: field.label,
391
416
  required: field.required,
392
- value: field.defaultValue,
417
+ value: this.formData[field.id],
393
418
  help: hint,
419
+ readonly: isReadOnly,
420
+ disabled: isReadOnly,
394
421
  validation,
395
422
  validationVisibility: 'live'
396
423
  }
@@ -404,11 +431,13 @@ export default {
404
431
  name,
405
432
  label: field.label,
406
433
  required: field.required,
407
- value: field.defaultValue,
434
+ value: this.formData[field.id],
408
435
  help: hint,
409
436
  wrapperClass: '$remove:formkit-wrapper',
437
+ labelClass: 'ui-dynamic-form-input-label',
410
438
  inputClass: `input-${this.theme}`,
411
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
439
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
440
+ readonly: isReadOnly,
412
441
  validation,
413
442
  validationVisibility: 'live'
414
443
  }
@@ -422,36 +451,36 @@ export default {
422
451
  name,
423
452
  label: field.label,
424
453
  required: field.required,
425
- value: field.defaultValue,
454
+ value: this.formData[field.id],
426
455
  help: hint,
427
- validation: 'email',
428
- validationVisibility: 'live',
429
456
  placeholder,
430
457
  wrapperClass: '$remove:formkit-wrapper',
458
+ labelClass: 'ui-dynamic-form-input-label',
431
459
  inputClass: `input-${this.theme}`,
432
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
460
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
461
+ readonly: isReadOnly,
433
462
  validation,
434
463
  validationVisibility: 'live'
435
464
  }
436
465
  }
437
466
  case 'header':
438
467
  let typeToUse = 'h1'
439
- if (field.customForm && JSON.parse(field.customForm).style == 'heading_2') {
468
+ if (field.customForm && JSON.parse(field.customForm).style === 'heading_2') {
440
469
  typeToUse = 'h2'
441
470
  }
442
- if (field.customForm && JSON.parse(field.customForm).style == 'heading_3') {
471
+ if (field.customForm && JSON.parse(field.customForm).style === 'heading_3') {
443
472
  typeToUse = 'h3'
444
473
  }
445
474
  return {
446
475
  type: typeToUse,
447
- innerText: field.defaultValue
476
+ innerText: this.formData[field.id]
448
477
  }
449
478
  case 'hidden':
450
479
  return {
451
480
  type: 'input',
452
481
  props: {
453
482
  type: 'hidden',
454
- value: field.defaultValue
483
+ value: this.formData[field.id]
455
484
  }
456
485
  }
457
486
  case 'month':
@@ -463,11 +492,13 @@ export default {
463
492
  name,
464
493
  label: field.label,
465
494
  required: field.required,
466
- value: field.defaultValue,
495
+ value: this.formData[field.id],
467
496
  help: hint,
468
497
  wrapperClass: '$remove:formkit-wrapper',
498
+ labelClass: 'ui-dynamic-form-input-label',
469
499
  inputClass: `input-${this.theme}`,
470
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
500
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
501
+ readonly: isReadOnly,
471
502
  validation,
472
503
  validationVisibility: 'live'
473
504
  }
@@ -475,7 +506,7 @@ export default {
475
506
  case 'paragraph':
476
507
  return {
477
508
  type: 'p',
478
- innerText: field.defaultValue
509
+ innerText: this.formData[field.id]
479
510
  }
480
511
  case 'password':
481
512
  return {
@@ -486,12 +517,14 @@ export default {
486
517
  name,
487
518
  label: field.label,
488
519
  required: field.required,
489
- value: field.defaultValue,
520
+ value: this.formData[field.id],
490
521
  help: hint,
491
522
  placeholder,
492
523
  wrapperClass: '$remove:formkit-wrapper',
524
+ labelClass: 'ui-dynamic-form-input-label',
493
525
  inputClass: `input-${this.theme}`,
494
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
526
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
527
+ readonly: isReadOnly,
495
528
  validation,
496
529
  validationVisibility: 'live'
497
530
  }
@@ -508,12 +541,15 @@ export default {
508
541
  name,
509
542
  label: field.label,
510
543
  required: field.required,
511
- value: field.defaultValue,
544
+ value: this.formData[field.id],
512
545
  options: radioOptions,
513
546
  help: hint,
514
547
  fieldsetClass: 'custom-fieldset',
548
+ labelClass: 'ui-dynamic-form-input-label',
515
549
  inputClass: `input-${this.theme}`,
516
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
550
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
551
+ readonly: isReadOnly,
552
+ disabled: isReadOnly,
517
553
  validation,
518
554
  validationVisibility: 'live'
519
555
  }
@@ -527,15 +563,18 @@ export default {
527
563
  name,
528
564
  // label: field.label,
529
565
  required: field.required,
530
- // value: field.defaultValue,
566
+ // value: this.formData[field.id],
531
567
  // help: hint,
532
568
  min: customForm.min,
533
569
  max: customForm.max,
534
570
  step: customForm.step,
535
571
  thumbLabel: true,
536
572
  // wrapperClass: '$remove:formkit-wrapper',
573
+ labelClass: 'ui-dynamic-form-input-label',
537
574
  // inputClass: `input-${this.theme}`,
538
- // innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
575
+ // innerClass: ui-dynamic-form-input-outlines `${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
576
+ readonly: isReadOnly,
577
+ disabled: isReadOnly,
539
578
  validation,
540
579
  validationVisibility: 'live'
541
580
  }
@@ -549,12 +588,14 @@ export default {
549
588
  name,
550
589
  label: field.label,
551
590
  required: field.required,
552
- value: field.defaultValue,
591
+ value: this.formData[field.id],
553
592
  help: hint,
554
593
  placeholder,
555
594
  wrapperClass: '$remove:formkit-wrapper',
595
+ labelClass: 'ui-dynamic-form-input-label',
556
596
  inputClass: `input-${this.theme}`,
557
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
597
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
598
+ readonly: isReadOnly,
558
599
  validation,
559
600
  validationVisibility: 'live'
560
601
  }
@@ -569,13 +610,15 @@ export default {
569
610
  name,
570
611
  label: field.label,
571
612
  required: field.required,
572
- value: field.defaultValue,
613
+ value: this.formData[field.id],
573
614
  rows,
574
615
  help: hint,
575
616
  placeholder,
576
617
  wrapperClass: '$remove:formkit-wrapper',
618
+ labelClass: 'ui-dynamic-form-input-label',
577
619
  inputClass: `input-${this.theme}`,
578
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
620
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
621
+ readonly: isReadOnly,
579
622
  validation,
580
623
  validationVisibility: 'live'
581
624
  }
@@ -589,12 +632,14 @@ export default {
589
632
  name,
590
633
  label: field.label,
591
634
  required: field.required,
592
- value: field.defaultValue,
635
+ value: this.formData[field.id],
593
636
  help: hint,
594
637
  placeholder,
595
638
  wrapperClass: '$remove:formkit-wrapper',
639
+ labelClass: 'ui-dynamic-form-input-label',
596
640
  inputClass: `input-${this.theme}`,
597
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
641
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
642
+ readonly: isReadOnly,
598
643
  validation,
599
644
  validationVisibility: 'live'
600
645
  }
@@ -608,14 +653,14 @@ export default {
608
653
  name,
609
654
  label: field.label,
610
655
  required: field.required,
611
- value: field.defaultValue,
656
+ value: this.formData[field.id],
612
657
  help: hint,
613
658
  placeholder,
614
- validation: 'url',
615
- validationVisibility: 'live',
616
659
  wrapperClass: '$remove:formkit-wrapper',
660
+ labelClass: 'ui-dynamic-form-input-label',
617
661
  inputClass: `input-${this.theme}`,
618
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
662
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
663
+ readonly: isReadOnly,
619
664
  validation,
620
665
  validationVisibility: 'live'
621
666
  }
@@ -629,12 +674,14 @@ export default {
629
674
  name,
630
675
  label: field.label,
631
676
  required: field.required,
632
- value: field.defaultValue,
677
+ value: this.formData[field.id],
633
678
  help: hint,
634
679
  placeholder,
635
680
  wrapperClass: '$remove:formkit-wrapper',
681
+ labelClass: 'ui-dynamic-form-input-label',
636
682
  inputClass: `input-${this.theme}`,
637
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
683
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
684
+ readonly: isReadOnly,
638
685
  validation,
639
686
  validationVisibility: 'live'
640
687
  }
@@ -648,35 +695,35 @@ export default {
648
695
  name,
649
696
  label: field.label,
650
697
  required: field.required,
651
- value: field.defaultValue,
698
+ value: this.formData[field.id],
652
699
  help: hint,
700
+ labelClass: 'ui-dynamic-form-input-label',
653
701
  inputClass: `input-${this.theme}`,
654
- innerClass: `${this.theme == 'dark' ? '$remove:formkit-inner' : ''}`,
702
+ innerClass: `ui-dynamic-form-input-outlines ${this.theme === 'dark' ? '$remove:formkit-inner' : ''}`,
703
+ readonly: isReadOnly,
655
704
  validation,
656
705
  validationVisibility: 'live'
657
706
  }
658
707
  }
659
708
  }
660
709
  },
661
- checkFormState (state) {
662
- // const field = this.$formkit.get('field_01');
663
- // console.info(field.context.state.valid);
664
-
665
- return true
666
-
667
- // loop over fields then this.$formkit.get(this.id) -> check error state if all ok return true else return false
668
- // ?? wie unterscheiden wir welche actions dieser validierungsfehler betrifft ??
669
- // ?? wie machen wir formkit validierung auch im Studio available ??
670
- // \_ vllt macht es sinn das schema von formkit zu übernehmen oder alternativ nur unsere validierung zu nutzen.
671
- },
672
- hasUserTask () {
673
- return this.messages && this.messages[this.id] && this.messages[this.id].payload.userTask
710
+ toggleCollapse () {
711
+ this.collapsed = !this.collapsed
674
712
  },
675
- userTask () {
676
- return this.hasUserTask() ? this.messages[this.id].payload.userTask : {}
713
+ getRowWidthStyling (field, index) {
714
+ let style = ''
715
+ if (index === 0) {
716
+ style += 'margin-top: 12px;'
717
+ }
718
+ if (field.type === 'header') {
719
+ style += 'flex-basis: 100%;'
720
+ } else {
721
+ style += `flex-basis: ${1 / this.props.form_columns * 100}%;`
722
+ }
723
+ return style
677
724
  },
678
725
  fields () {
679
- const aFields = this.hasUserTask() ? this.userTask().userTaskConfig.formFields : []
726
+ const aFields = this.userTask.userTaskConfig?.formFields ?? []
680
727
  const fieldMap = aFields.map((field) => ({
681
728
  ...field,
682
729
  items: mapItems(field.type, field)
@@ -684,9 +731,6 @@ export default {
684
731
 
685
732
  return fieldMap
686
733
  },
687
- hasFields () {
688
- return this.messages && this.messages[this.id] && this.messages[this.id].payload.userTask !== undefined
689
- },
690
734
  /*
691
735
  widget-action just sends a msg to Node-RED, it does not store the msg state server-side
692
736
  alternatively, you can use widget-change, which will also store the msg in the Node's datastore
@@ -696,12 +740,52 @@ export default {
696
740
  msgArr[index] = msg
697
741
  this.$socket.emit('widget-action', this.id, msgArr)
698
742
  },
699
- init () {
743
+ init (msg) {
744
+ this.msg = msg
745
+ if (!msg) {
746
+ return
747
+ }
748
+
700
749
  this.actions = this.props.options
750
+
751
+ const hasTask = msg.payload && msg.payload.userTask
752
+
753
+ if (hasTask) {
754
+ this.userTask = msg.payload.userTask
755
+ } else {
756
+ this.userTask = null
757
+ this.formData = {}
758
+ return
759
+ }
760
+
761
+ const formFields = this.userTask.userTaskConfig.formFields
762
+ const formFieldIds = formFields.map(ff => ff.id)
763
+ const initialValues = this.userTask.startToken
764
+ const finishedFormData = msg.payload.formData
765
+ this.formIsFinished = !!msg.payload.formData
766
+ if (this.formIsFinished) {
767
+ this.collapsed = this.props.collapse_when_finished
768
+ }
769
+
770
+ if (formFields) {
771
+ formFields.forEach((field) => {
772
+ this.formData[field.id] = field.defaultValue
773
+ })
774
+ }
775
+
776
+ if (initialValues) {
777
+ Object.keys(initialValues).filter(key => formFieldIds.includes(key)).forEach((key) => {
778
+ this.formData[key] = initialValues[key]
779
+ })
780
+ }
781
+
782
+ if (this.formIsFinished) {
783
+ Object.keys(finishedFormData).filter(key => formFieldIds.includes(key)).forEach(key => {
784
+ this.formData[key] = finishedFormData[key]
785
+ })
786
+ }
701
787
  },
702
788
  actionFn (action) {
703
- // this.checkFormState();
704
-
705
789
  if (action.label === 'Speichern' || action.label === 'Speichern und nächster') {
706
790
  const formkitInputs = this.$refs.form.$el.querySelectorAll('.formkit-outer')
707
791
  let allComplete = true
@@ -719,37 +803,36 @@ export default {
719
803
  }
720
804
 
721
805
  if (this.checkCondition(action.condition)) {
722
- this.showError(false, '')
806
+ this.showError('')
723
807
  // TODO: MM - begin
724
808
  // this.send(
725
- // { payload: { formData: this.formData, userTask: this.userTask() } },
809
+ // { payload: { formData: this.formData, userTask: this.userTask } },
726
810
  // this.actions.findIndex((element) => element.label === action.label)
727
811
  // );
728
- const msg = this.messages[this.id] || {}
729
- msg.payload = { formData: this.formData, userTask: this.userTask() }
812
+ const msg = this.msg ?? {}
813
+ msg.payload = { formData: this.formData, userTask: this.userTask }
730
814
  this.send(
731
815
  msg,
732
816
  this.actions.findIndex((element) => element.label === action.label)
733
817
  )
734
818
  // TODO: mm - end
735
819
  } else {
736
- this.showError(true, action.errorMessage)
820
+ this.showError(action.errorMessage)
737
821
  }
738
822
  },
739
823
  checkCondition (condition) {
740
- if (condition == '') return true
824
+ if (condition === '') return true
741
825
  try {
826
+ // eslint-disable-next-line no-new-func
742
827
  const func = Function('fields', 'userTask', 'msg', '"use strict"; return (' + condition + ')')
743
- const result = func(this.formData, this.taskInput, this.messages[this.id])
744
- console.log(this.formData, result)
828
+ const result = func(this.formData, this.userTask, this.msg)
745
829
  return Boolean(result)
746
830
  } catch (err) {
747
831
  console.error('Error while evaluating condition: ' + err)
748
832
  return false
749
833
  }
750
834
  },
751
- showError (bool, errMsg) {
752
- this.error = bool
835
+ showError (errMsg) {
753
836
  this.errorMsg = errMsg
754
837
  }
755
838
  }