@5minds/node-red-dashboard-2-processcube-dynamic-form 1.1.1-feature-735e79-m734z5f9 → 1.1.1-feature-77a9de-m79111vs

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