@5minds/node-red-dashboard-2-processcube-dynamic-form 1.1.2-feature-544b78-m738mhwq → 1.1.2-feature-997de4-m7nhlmql

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