@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.
- package/nodes/ui-dynamic-form.html +238 -30
- package/package.json +1 -1
- package/resources/ui-dynamic-form.umd.js +2 -2
- package/ui/components/FooterActions.vue +55 -0
- package/ui/components/TitleText.vue +56 -0
- package/ui/components/UIDynamicForm.vue +289 -206
- package/ui/stylesheets/ui-dynamic-form.css +137 -41
|
@@ -1,71 +1,99 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
</
|
|
51
|
-
</v-
|
|
52
|
-
</
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
</
|
|
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,
|
|
63
|
-
|
|
85
|
+
import { getCurrentInstance, markRaw } from 'vue'
|
|
86
|
+
|
|
87
|
+
// eslint-disable-next-line import/no-unresolved
|
|
64
88
|
import '@formkit/themes/genesis'
|
|
65
|
-
import
|
|
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
|
-
|
|
121
|
+
userTask: null,
|
|
95
122
|
theme: '',
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
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
|
|
199
|
-
const
|
|
200
|
-
const
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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
|
|
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.
|
|
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:
|
|
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.
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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:
|
|
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.
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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
|
-
|
|
662
|
-
|
|
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
|
-
|
|
676
|
-
|
|
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.
|
|
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(
|
|
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.
|
|
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(
|
|
820
|
+
this.showError(action.errorMessage)
|
|
737
821
|
}
|
|
738
822
|
},
|
|
739
823
|
checkCondition (condition) {
|
|
740
|
-
if (condition
|
|
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.
|
|
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 (
|
|
752
|
-
this.error = bool
|
|
835
|
+
showError (errMsg) {
|
|
753
836
|
this.errorMsg = errMsg
|
|
754
837
|
}
|
|
755
838
|
}
|