@5minds/node-red-dashboard-2-processcube-dynamic-form 1.0.13 → 1.0.15-feature-ca6857-lzbajzx1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/nodes/dynamic-form.html +83 -47
- package/nodes/dynamic-form.js +40 -40
- package/package.json +81 -81
- package/resources/ui-dynamic-form.umd.js +2 -0
- package/ui/components/DynamicForm.vue +201 -194
- package/ui/stylesheets/dynamic-form.css +19 -19
- package/resources/dynamic-form.umd.js +0 -2
package/nodes/dynamic-form.html
CHANGED
|
@@ -1,53 +1,59 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
-
RED.nodes.registerType('dynamic-form', {
|
|
2
|
+
RED.nodes.registerType('ui-dynamic-form', {
|
|
3
3
|
category: 'ProcessCube UI',
|
|
4
4
|
color: '#00aed7',
|
|
5
5
|
defaults: {
|
|
6
|
-
name: { value:
|
|
6
|
+
name: { value: '' },
|
|
7
7
|
group: { type: 'ui-group', required: true },
|
|
8
8
|
order: { value: 0 },
|
|
9
9
|
options: {
|
|
10
|
-
value: [{ label: ''}],
|
|
10
|
+
value: [{ label: '' }],
|
|
11
11
|
validate: function (v) {
|
|
12
|
-
const unique = new Set(
|
|
12
|
+
const unique = new Set(
|
|
13
|
+
v.map(function (o) {
|
|
14
|
+
return o.label;
|
|
15
|
+
})
|
|
16
|
+
);
|
|
13
17
|
return v.length === unique.size;
|
|
14
|
-
}
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
waiting_title: { value: 'Waiting for Warten auf den Usertask...' },
|
|
21
|
+
waiting_info: {
|
|
22
|
+
value: 'Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist.',
|
|
15
23
|
},
|
|
16
|
-
waiting_title: { value: "Waiting for Warten auf den Usertask..." },
|
|
17
|
-
waiting_info: { value: "Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist." },
|
|
18
24
|
width: {
|
|
19
25
|
value: 0,
|
|
20
26
|
validate: function (v) {
|
|
21
|
-
const width = v || 0
|
|
22
|
-
const currentGroup = $('#node-input-group').val() || this.group
|
|
23
|
-
const groupNode = RED.nodes.node(currentGroup)
|
|
24
|
-
const valid = !groupNode || +width <= +groupNode.width
|
|
25
|
-
$('#node-input-size').toggleClass('input-error', !valid)
|
|
26
|
-
return valid
|
|
27
|
-
}
|
|
27
|
+
const width = v || 0;
|
|
28
|
+
const currentGroup = $('#node-input-group').val() || this.group;
|
|
29
|
+
const groupNode = RED.nodes.node(currentGroup);
|
|
30
|
+
const valid = !groupNode || +width <= +groupNode.width;
|
|
31
|
+
$('#node-input-size').toggleClass('input-error', !valid);
|
|
32
|
+
return valid;
|
|
33
|
+
},
|
|
28
34
|
},
|
|
29
35
|
height: { value: 0 },
|
|
30
|
-
outputs: { value: 1}
|
|
36
|
+
outputs: { value: 1 },
|
|
31
37
|
},
|
|
32
38
|
inputs: 1,
|
|
33
39
|
outputs: 1,
|
|
34
|
-
outputLabels: function(index) {
|
|
35
|
-
|
|
40
|
+
outputLabels: function (index) {
|
|
41
|
+
return this.options[index].label;
|
|
36
42
|
},
|
|
37
|
-
icon:
|
|
38
|
-
label: function() {
|
|
39
|
-
return this.name ||
|
|
43
|
+
icon: 'file.svg',
|
|
44
|
+
label: function () {
|
|
45
|
+
return this.name || 'dynamic-form';
|
|
40
46
|
},
|
|
41
47
|
oneditprepare: function () {
|
|
42
48
|
$('#node-input-size').elementSizer({
|
|
43
49
|
width: '#node-input-width',
|
|
44
50
|
height: '#node-input-height',
|
|
45
|
-
group: '#node-input-group'
|
|
51
|
+
group: '#node-input-group',
|
|
46
52
|
});
|
|
47
53
|
|
|
48
54
|
function generateOption(i, option) {
|
|
49
55
|
const container = $('<li/>', {
|
|
50
|
-
style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;'
|
|
56
|
+
style: 'background: var(--red-ui-secondary-background, #fff); margin:0; padding:8px 0px 0px;',
|
|
51
57
|
});
|
|
52
58
|
|
|
53
59
|
// Create input fields for value and label
|
|
@@ -55,30 +61,57 @@
|
|
|
55
61
|
$('<input/>', {
|
|
56
62
|
class: 'node-input-option-label',
|
|
57
63
|
type: 'text',
|
|
58
|
-
style: 'margin-left:7px; width:calc(
|
|
64
|
+
style: 'margin-left:7px; width:calc(29%);',
|
|
59
65
|
placeholder: 'Label',
|
|
60
|
-
value: option.label
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
value: option.label,
|
|
67
|
+
})
|
|
68
|
+
.appendTo(row)
|
|
69
|
+
.typedInput({
|
|
70
|
+
type: 'str',
|
|
71
|
+
types: ['str'],
|
|
72
|
+
});
|
|
64
73
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
$('<input/>', {
|
|
75
|
+
class: 'node-input-option-condition',
|
|
76
|
+
type: 'text',
|
|
77
|
+
style: 'margin-left:7px; width:calc(29%);',
|
|
78
|
+
placeholder: 'Condition',
|
|
79
|
+
value: option.condition,
|
|
80
|
+
})
|
|
81
|
+
.appendTo(row)
|
|
82
|
+
.typedInput({
|
|
83
|
+
type: 'str',
|
|
84
|
+
types: ['str'],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
$('<input/>', {
|
|
88
|
+
class: 'node-input-option-error',
|
|
89
|
+
type: 'text',
|
|
90
|
+
style: 'margin-left:7px; width:calc(29%);',
|
|
91
|
+
placeholder: 'Error message',
|
|
92
|
+
value: option.errorMessage,
|
|
93
|
+
})
|
|
94
|
+
.appendTo(row)
|
|
95
|
+
.typedInput({
|
|
96
|
+
type: 'str',
|
|
97
|
+
types: ['str'],
|
|
98
|
+
});
|
|
74
99
|
|
|
75
100
|
// Create delete button for the option
|
|
76
|
-
const finalSpan = $('<span/>', {
|
|
77
|
-
|
|
101
|
+
const finalSpan = $('<span/>', {
|
|
102
|
+
style: 'float:right; margin-right:8px;',
|
|
103
|
+
}).appendTo(row);
|
|
104
|
+
const deleteButton = $('<a/>', {
|
|
105
|
+
href: '#',
|
|
106
|
+
class: 'editor-button editor-button-small',
|
|
107
|
+
style: 'margin-top:7px; margin-left:5px;',
|
|
108
|
+
}).appendTo(finalSpan);
|
|
78
109
|
$('<i/>', { class: 'fa fa-remove' }).appendTo(deleteButton);
|
|
79
110
|
|
|
80
111
|
deleteButton.click(function () {
|
|
81
|
-
container.css({
|
|
112
|
+
container.css({
|
|
113
|
+
background: 'var(--red-ui-secondary-background-inactive, #fee)',
|
|
114
|
+
});
|
|
82
115
|
container.fadeOut(300, function () {
|
|
83
116
|
$(this).remove();
|
|
84
117
|
});
|
|
@@ -89,7 +122,9 @@
|
|
|
89
122
|
|
|
90
123
|
$('#node-input-add-option').click(function () {
|
|
91
124
|
generateOption($('#node-input-option-container').children().length + 1, {});
|
|
92
|
-
$('#node-input-option-container-div').scrollTop(
|
|
125
|
+
$('#node-input-option-container-div').scrollTop(
|
|
126
|
+
$('#node-input-option-container-div').get(0).scrollHeight
|
|
127
|
+
);
|
|
93
128
|
});
|
|
94
129
|
|
|
95
130
|
for (let i = 0; i < this.options.length; i++) {
|
|
@@ -100,7 +135,7 @@
|
|
|
100
135
|
$('#node-input-option-container').sortable({
|
|
101
136
|
axis: 'y',
|
|
102
137
|
handle: '.node-input-option-handle',
|
|
103
|
-
cursor: 'move'
|
|
138
|
+
cursor: 'move',
|
|
104
139
|
});
|
|
105
140
|
},
|
|
106
141
|
oneditsave: function () {
|
|
@@ -111,18 +146,19 @@
|
|
|
111
146
|
const option = $(this);
|
|
112
147
|
const o = {
|
|
113
148
|
label: option.find('.node-input-option-label').val(),
|
|
114
|
-
|
|
149
|
+
condition: option.find('.node-input-option-condition').val(),
|
|
150
|
+
errorMessage: option.find('.node-input-option-error').val(),
|
|
115
151
|
};
|
|
116
152
|
|
|
117
153
|
node.options.push(o);
|
|
118
154
|
});
|
|
119
155
|
|
|
120
|
-
this.outputs = node.options.length || 1
|
|
156
|
+
this.outputs = node.options.length || 1;
|
|
121
157
|
},
|
|
122
158
|
});
|
|
123
159
|
</script>
|
|
124
160
|
|
|
125
|
-
<script type="text/html" data-template-name="dynamic-form">
|
|
161
|
+
<script type="text/html" data-template-name="ui-dynamic-form">
|
|
126
162
|
<div class="form-row">
|
|
127
163
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
128
164
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
@@ -132,7 +168,7 @@
|
|
|
132
168
|
<input type="text" id="node-input-group">
|
|
133
169
|
</div>
|
|
134
170
|
<div class="form-row">
|
|
135
|
-
<label><i class="fa fa-object-group"></i> <span data-i18n="dynamic-form.label.size"></label>
|
|
171
|
+
<label><i class="fa fa-object-group"></i> <span data-i18n="ui-dynamic-form.label.size"></label>
|
|
136
172
|
<input type="hidden" id="node-input-width">
|
|
137
173
|
<input type="hidden" id="node-input-height">
|
|
138
174
|
<button class="editor-button" id="node-input-size"></button>
|
|
@@ -144,13 +180,13 @@
|
|
|
144
180
|
<span id="valWarning" style="color: var(--red-ui-text-color-error, #910000)"><b>All Values must be unique.</b></span>
|
|
145
181
|
<ol id="node-input-option-container" style="list-style-type:none; margin:0;"></ol>
|
|
146
182
|
</div>
|
|
147
|
-
<a
|
|
183
|
+
<!-- <a
|
|
148
184
|
data-html="true"
|
|
149
185
|
title="Dynamic Property: Send 'msg.options' in order to override this property."
|
|
150
186
|
class="red-ui-button ui-node-popover-title"
|
|
151
187
|
style="margin-left: 4px; cursor: help; font-size: 0.625rem; border-radius: 50%; width: 24px; height: 24px; display: inline-flex; justify-content: center; align-items: center;">
|
|
152
188
|
<i style="font-family: ui-serif;">fx</i>
|
|
153
|
-
</a>
|
|
189
|
+
</a> -->
|
|
154
190
|
</div>
|
|
155
191
|
<!-- Add Option Button -->
|
|
156
192
|
<div class="form-row">
|
package/nodes/dynamic-form.js
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
module.exports = function (RED) {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
function DynamicFormNode(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const node = this;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// which group are we rendering this widget
|
|
8
|
+
const group = RED.nodes.getNode(config.group);
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const base = group.getBase();
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
12
|
+
// server-side event handlers
|
|
13
|
+
const evts = {
|
|
14
|
+
onAction: true,
|
|
15
|
+
onInput: function (msg, send, done) {
|
|
16
|
+
// store the latest value in our Node-RED datastore
|
|
17
|
+
base.stores.data.save(base, node, msg);
|
|
18
|
+
},
|
|
19
|
+
onSocket: {
|
|
20
|
+
"my-custom-event": function (conn, id, msg) {
|
|
21
|
+
console.info('"my-custom-event" received:', conn.id, id, msg);
|
|
22
|
+
console.info("conn.id:", conn.id);
|
|
23
|
+
console.info("id:", id);
|
|
24
|
+
console.info("msg:", msg);
|
|
25
|
+
console.info("node.id:", node.id);
|
|
26
|
+
// emit a msg in Node-RED from this node
|
|
27
|
+
node.send(msg);
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
32
|
+
// inform the dashboard UI that we are adding this node
|
|
33
|
+
if (group) {
|
|
34
|
+
group.register(node, config, evts);
|
|
35
|
+
} else {
|
|
36
|
+
node.error("No group configured");
|
|
38
37
|
}
|
|
38
|
+
}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
40
|
+
RED.nodes.registerType("ui-dynamic-form", DynamicFormNode, {
|
|
41
|
+
defaults: {
|
|
42
|
+
outputs: { value: 1 },
|
|
43
|
+
},
|
|
44
|
+
outputs: function (config) {
|
|
45
|
+
return config.outputs || 1;
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
};
|
package/package.json
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
"name": "@5minds/node-red-dashboard-2-processcube-dynamic-form",
|
|
3
|
+
"version": "1.0.15-feature-ca6857-lzbajzx1",
|
|
4
|
+
"description": "The ui component for the ProcessCube dynamic-form",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"processcube",
|
|
7
|
+
"dynamic-form",
|
|
8
|
+
"node-red",
|
|
9
|
+
"node-red-dashboard-2"
|
|
10
|
+
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/5minds/.gitnode-red-dashboard-2-processcube-dynamic-form"
|
|
14
|
+
},
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"author": {
|
|
17
|
+
"name": "Martin Moellenbeck",
|
|
18
|
+
"url": "https://github.com/moellenbeck"
|
|
19
|
+
},
|
|
20
|
+
"contributors": [
|
|
21
|
+
{
|
|
22
|
+
"name": "Robin Lenz",
|
|
23
|
+
"url": "https://github.com/roblen45"
|
|
14
24
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
"dynamic-form": "nodes/dynamic-form.js"
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
"node-red-dashboard-2": {
|
|
77
|
-
"version": "1.0.0",
|
|
78
|
-
"widgets": {
|
|
79
|
-
"dynamic-form": {
|
|
80
|
-
"output": "dynamic-form.umd.js",
|
|
81
|
-
"component": "DynamicForm"
|
|
82
|
-
}
|
|
83
|
-
}
|
|
25
|
+
{
|
|
26
|
+
"name": "Luis Thieme",
|
|
27
|
+
"url": "https://github.com/luisthieme"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"exports": {
|
|
31
|
+
"import": "./resources/dynamic-form.esm.js",
|
|
32
|
+
"require": "./resources/dynamic-form.umd.js"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist/*",
|
|
36
|
+
"nodes/*",
|
|
37
|
+
"ui/*",
|
|
38
|
+
"resources/*"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "vite build",
|
|
42
|
+
"build:dev": "NODE_ENV=development vite build",
|
|
43
|
+
"dev": "NODE_ENV=development vite build --watch",
|
|
44
|
+
"dev:prod": "vite build --watch",
|
|
45
|
+
"lint": "npm run lint:js && npm run lint:package",
|
|
46
|
+
"lint:fix": "npm run lint:js:fix && npm run lint:package:fix",
|
|
47
|
+
"lint:js": "eslint --ext .js,.vue,.cjs,.mjs .",
|
|
48
|
+
"lint:js:fix": "yarn lint:js --fix",
|
|
49
|
+
"lint:package": "sort-package-json --check 'package.json'",
|
|
50
|
+
"lint:package:fix": "sort-package-json 'package.json'"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"to-title-case": "^1.0.0",
|
|
54
|
+
"vue": "^3.3.8",
|
|
55
|
+
"vuex": "^4.1.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@vitejs/plugin-vue": "^4.5.0",
|
|
59
|
+
"eslint": "^8.53.0",
|
|
60
|
+
"eslint-config-standard": "^17.1.0",
|
|
61
|
+
"eslint-plugin-import": "^2.29.0",
|
|
62
|
+
"eslint-plugin-n": "^16.3.1",
|
|
63
|
+
"eslint-plugin-vue": "^9.18.1",
|
|
64
|
+
"vite": "^5.0.13",
|
|
65
|
+
"vite-plugin-css-injected-by-js": "^3.3.0"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=14"
|
|
69
|
+
},
|
|
70
|
+
"node-red": {
|
|
71
|
+
"version": ">=3.0.0",
|
|
72
|
+
"nodes": {
|
|
73
|
+
"ui-dynamic-form": "nodes/dynamic-form.js"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"node-red-dashboard-2": {
|
|
77
|
+
"version": "1.0.0",
|
|
78
|
+
"widgets": {
|
|
79
|
+
"ui-dynamic-form": {
|
|
80
|
+
"output": "ui-dynamic-form.umd.js",
|
|
81
|
+
"component": "DynamicForm"
|
|
82
|
+
}
|
|
84
83
|
}
|
|
84
|
+
}
|
|
85
85
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".dynamic-form-wrapper[data-v-0d226515]{padding:10px;margin:10px;border:1px solid black}.dynamic-form-class[data-v-0d226515]{color:green;font-weight:700}h1[data-v-0d226515]{margin-bottom:10px}h2[data-v-0d226515]{margin-top:1.5rem;margin-bottom:.75rem}h3[data-v-0d226515]{margin-top:1rem}p[data-v-0d226515]{margin-bottom:5px}ul li[data-v-0d226515]{list-style-type:circle;list-style-position:inside;margin-left:15px}pre[data-v-0d226515]{padding:12px;margin:12px;background-color:#eee}code[data-v-0d226515]{font-size:.825rem;color:#ae0000}")),document.head.appendChild(e)}}catch(a){console.error("vite-plugin-css-injected-by-js",a)}})();
|
|
2
|
+
(function(n,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("vuex")):typeof define=="function"&&define.amd?define(["exports","vue","vuex"],e):(n=typeof globalThis<"u"?globalThis:n||self,e(n["ui-dynamic-form"]={},n.Vue,n.vuex))})(this,function(n,e,h){"use strict";const f=(t,r)=>{const s=t.__vccOpts||t;for(const[d,i]of r)s[d]=i;return s},u={name:"DynamicForm",inject:["$socket"],props:{id:{type:String,required:!0},props:{type:Object,default:()=>({})},state:{type:Object,default:()=>({enabled:!1,visible:!1})}},setup(t){console.info("DynamicForm setup with:",t),console.debug("Vue function loaded correctly",e.markRaw)},data(){return{actions:[],form:{},formData:{},error:!1,errorMsg:""}},computed:{...h.mapState("data",["messages"]),waiting_title(){return this.props.waiting_title||"Warten auf den Usertask..."},waiting_info(){return this.props.waiting_info||"Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist."}},mounted(){this.$socket.on("widget-load:"+this.id,t=>{this.init(),this.$store.commit("data/bind",{widgetId:this.id,msg:t})}),this.$socket.on("msg-input:"+this.id,t=>{this.init(),t.payload&&t.payload.userTask&&t.payload.userTask.startToken&&(this.formData={...t.payload.userTask.startToken},console.info(this.formData)),this.$store.commit("data/bind",{widgetId:this.id,msg:t})}),this.$socket.emit("widget-load",this.id)},unmounted(){var t,r;(t=this.$socket)==null||t.off("widget-load"+this.id),(r=this.$socket)==null||r.off("msg-input:"+this.id)},methods:{hasUserTask(){return this.messages&&this.messages[this.id]&&this.messages[this.id].payload.userTask},userTask(){return this.hasUserTask()?this.messages[this.id].payload.userTask:{}},fields(){return(this.hasUserTask()?this.userTask().userTaskConfig.formFields:[]).map(s=>({...s,component:_(s.type),items:k(s.type,s)}))},hasFields(){return this.messages&&this.messages[this.id]&&this.messages[this.id].payload.userTask!==void 0},send(t,r){const s=[];s[r]=t,console.info(s),this.$socket.emit("widget-action",this.id,s)},init(){console.info(this.props.options),this.actions=this.props.options},actionFn(t){this.checkCondition(t.condition)?(this.showError(!1,""),this.send({payload:{formData:this.formData,userTask:this.userTask()}},this.actions.findIndex(r=>r.label===t.label))):this.showError(!0,t.errorMessage)},checkCondition(t){try{return!!Function("fields",'"use strict"; return ('+t+")")(this.formData)}catch(r){return console.error("Error while evaluating condition: "+r),!1}},showError(t,r){this.error=t,this.errorMsg=r}}};function k(t,r){return t==="enum"?r.enumValues.map(s=>({title:s.name,value:s.id})):null}function _(t){switch(t){case"string":return"v-text-field";case"long":case"date":return"v-text-field";case"enum":return"v-select";case"boolean":return"v-checkbox";case"text":return"v-text-field";case"select":return"v-select";case"checkbox":return"v-checkbox";case"radio":return"v-radio";case"switch":return"v-switch";case"slider":return"v-slider";case"time":return"v-time-picker";case"datetime":return"v-datetime-picker";case"color":return"v-color-picker";case"file":return"v-file-input";case"textarea":return"v-textarea";case"password":return"v-text-field";case"number":return"v-text-field";case"email":return"v-text-field";case"tel":return"v-text-field";case"url":return"v-text-field";default:return"v-text-field"}}const y={className:"dynamic-form-wrapper"},g={key:0},x={key:1};function w(t,r,s,d,i,a){const b=e.resolveComponent("v-col"),l=e.resolveComponent("v-row"),m=e.resolveComponent("v-alert"),B=e.resolveComponent("v-btn"),C=e.resolveComponent("v-form");return e.openBlock(),e.createElementBlock("div",y,[a.hasFields()?(e.openBlock(),e.createElementBlock("p",g,[e.createVNode(C,{ref:"form",modelValue:i.form,"onUpdate:modelValue":r[0]||(r[0]=o=>i.form=o)},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(a.fields(),(o,c)=>(e.openBlock(),e.createBlock(l,{key:c},{default:e.withCtx(()=>[e.createVNode(b,{cols:"12"},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(o.component),{id:o.id,modelValue:i.formData[o.id],"onUpdate:modelValue":p=>i.formData[o.id]=p,required:o.required,items:o.items,label:o.label},null,8,["id","modelValue","onUpdate:modelValue","required","items","label"]))]),_:2},1024)]),_:2},1024))),128)),e.createVNode(l,{style:{padding:"12px"}},{default:e.withCtx(()=>[i.error?(e.openBlock(),e.createBlock(m,{key:0,type:"error"},{default:e.withCtx(()=>[e.createTextVNode("Error: "+e.toDisplayString(i.errorMsg),1)]),_:1})):e.createCommentVNode("",!0)]),_:1}),e.createVNode(l,{style:{display:"flex",gap:"8px",padding:"12px"}},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(i.actions,(o,c)=>(e.openBlock(),e.createElementBlock("div",{key:c,style:{"flex-grow":"1"}},[(e.openBlock(),e.createBlock(B,{key:c,style:{width:"100%"},onClick:p=>a.actionFn(o)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(o.label),1)]),_:2},1032,["onClick"]))]))),128))]),_:1})]),_:1},8,["modelValue"])])):(e.openBlock(),e.createElementBlock("p",x,[e.createVNode(m,{text:a.waiting_info,title:a.waiting_title},null,8,["text","title"])]))])}const T=f(u,[["render",w],["__scopeId","data-v-0d226515"]]);n.DynamicForm=T,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -1,226 +1,233 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</v-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<v-alert :text="waiting_info" :title="waiting_title" />
|
|
35
|
-
</p>
|
|
36
|
-
</div>
|
|
2
|
+
<!-- Component must be wrapped in a block so props such as className and style can be passed in from parent -->
|
|
3
|
+
<div className="dynamic-form-wrapper">
|
|
4
|
+
<p v-if="hasFields()">
|
|
5
|
+
<v-form ref="form" v-model="form">
|
|
6
|
+
<v-row v-for="(field, index) in fields()" :key="index">
|
|
7
|
+
<v-col cols="12">
|
|
8
|
+
<component
|
|
9
|
+
:is="field.component"
|
|
10
|
+
:id="field.id"
|
|
11
|
+
v-model="formData[field.id]"
|
|
12
|
+
:required="field.required"
|
|
13
|
+
:items="field.items"
|
|
14
|
+
:label="field.label"
|
|
15
|
+
/>
|
|
16
|
+
</v-col>
|
|
17
|
+
</v-row>
|
|
18
|
+
<v-row style="padding: 12px">
|
|
19
|
+
<v-alert v-if="error" type="error">Error: {{ errorMsg }}</v-alert>
|
|
20
|
+
</v-row>
|
|
21
|
+
<v-row style="display: flex; gap: 8px; padding: 12px">
|
|
22
|
+
<div v-for="(action, index) in actions" :key="index" style="flex-grow: 1">
|
|
23
|
+
<v-btn :key="index" style="width: 100%" @click="actionFn(action)">
|
|
24
|
+
{{ action.label }}
|
|
25
|
+
</v-btn>
|
|
26
|
+
</div>
|
|
27
|
+
</v-row>
|
|
28
|
+
</v-form>
|
|
29
|
+
</p>
|
|
30
|
+
<p v-else>
|
|
31
|
+
<v-alert :text="waiting_info" :title="waiting_title" />
|
|
32
|
+
</p>
|
|
33
|
+
</div>
|
|
37
34
|
</template>
|
|
38
35
|
|
|
39
36
|
<script>
|
|
40
|
-
import { markRaw } from
|
|
41
|
-
import { mapState } from
|
|
37
|
+
import { markRaw } from 'vue';
|
|
38
|
+
import { mapState } from 'vuex';
|
|
42
39
|
|
|
43
40
|
export default {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
name: 'DynamicForm',
|
|
42
|
+
inject: ['$socket'],
|
|
43
|
+
props: {
|
|
44
|
+
/* do not remove entries from this - Dashboard's Layout Manager's will pass this data to your component */
|
|
45
|
+
id: { type: String, required: true },
|
|
46
|
+
props: { type: Object, default: () => ({}) },
|
|
47
|
+
state: {
|
|
48
|
+
type: Object,
|
|
49
|
+
default: () => ({ enabled: false, visible: false }),
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
setup(props) {
|
|
53
|
+
console.info('DynamicForm setup with:', props);
|
|
54
|
+
console.debug('Vue function loaded correctly', markRaw);
|
|
53
55
|
},
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
form: {},
|
|
63
|
-
formData: {},
|
|
64
|
-
};
|
|
65
|
-
},
|
|
66
|
-
computed: {
|
|
67
|
-
...mapState("data", ["messages"]),
|
|
68
|
-
waiting_title() {
|
|
69
|
-
return this.props.waiting_title || "Warten auf den Usertask..."
|
|
56
|
+
data() {
|
|
57
|
+
return {
|
|
58
|
+
actions: [],
|
|
59
|
+
form: {},
|
|
60
|
+
formData: {},
|
|
61
|
+
error: false,
|
|
62
|
+
errorMsg: '',
|
|
63
|
+
};
|
|
70
64
|
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
computed: {
|
|
66
|
+
...mapState('data', ['messages']),
|
|
67
|
+
waiting_title() {
|
|
68
|
+
return this.props.waiting_title || 'Warten auf den Usertask...';
|
|
69
|
+
},
|
|
70
|
+
waiting_info() {
|
|
71
|
+
return (
|
|
72
|
+
this.props.waiting_info ||
|
|
73
|
+
'Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist.'
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
76
|
},
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
this.init()
|
|
77
|
+
mounted() {
|
|
78
|
+
this.$socket.on('widget-load:' + this.id, (msg) => {
|
|
79
|
+
this.init();
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
81
|
+
this.$store.commit('data/bind', {
|
|
82
|
+
widgetId: this.id,
|
|
83
|
+
msg,
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
this.$socket.on('msg-input:' + this.id, (msg) => {
|
|
87
|
+
// store the latest message in our client-side vuex store when we receive a new message
|
|
88
|
+
this.init();
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
if (msg.payload && msg.payload.userTask && msg.payload.userTask.startToken) {
|
|
91
|
+
//this.formData = { ...msg.payload.userTask.startToken.formData };
|
|
92
|
+
this.formData = { ...msg.payload.userTask.startToken };
|
|
93
|
+
console.info(this.formData);
|
|
94
|
+
}
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
105
|
-
unmounted() {
|
|
106
|
-
/* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */
|
|
107
|
-
this.$socket?.off("widget-load" + this.id);
|
|
108
|
-
this.$socket?.off("msg-input:" + this.id);
|
|
109
|
-
},
|
|
110
|
-
methods: {
|
|
111
|
-
hasUserTask() {
|
|
112
|
-
return (
|
|
113
|
-
this.messages &&
|
|
114
|
-
this.messages[this.id] &&
|
|
115
|
-
this.messages[this.id].payload.userTask
|
|
116
|
-
);
|
|
96
|
+
this.$store.commit('data/bind', {
|
|
97
|
+
widgetId: this.id,
|
|
98
|
+
msg,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
// tell Node-RED that we're loading a new instance of this widget
|
|
102
|
+
this.$socket.emit('widget-load', this.id);
|
|
117
103
|
},
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
unmounted() {
|
|
105
|
+
/* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */
|
|
106
|
+
this.$socket?.off('widget-load' + this.id);
|
|
107
|
+
this.$socket?.off('msg-input:' + this.id);
|
|
120
108
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
109
|
+
methods: {
|
|
110
|
+
hasUserTask() {
|
|
111
|
+
return this.messages && this.messages[this.id] && this.messages[this.id].payload.userTask;
|
|
112
|
+
},
|
|
113
|
+
userTask() {
|
|
114
|
+
return this.hasUserTask() ? this.messages[this.id].payload.userTask : {};
|
|
115
|
+
},
|
|
116
|
+
fields() {
|
|
117
|
+
const aFields = this.hasUserTask() ? this.userTask().userTaskConfig.formFields : [];
|
|
125
118
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
119
|
+
const fieldMap = aFields.map((field) => ({
|
|
120
|
+
...field,
|
|
121
|
+
component: mapFieldTypes(field.type),
|
|
122
|
+
items: mapItems(field.type, field),
|
|
123
|
+
}));
|
|
131
124
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
this.messages[this.id].payload.userTask !== undefined
|
|
139
|
-
);
|
|
140
|
-
},
|
|
141
|
-
/*
|
|
125
|
+
return fieldMap;
|
|
126
|
+
},
|
|
127
|
+
hasFields() {
|
|
128
|
+
return this.messages && this.messages[this.id] && this.messages[this.id].payload.userTask !== undefined;
|
|
129
|
+
},
|
|
130
|
+
/*
|
|
142
131
|
widget-action just sends a msg to Node-RED, it does not store the msg state server-side
|
|
143
132
|
alternatively, you can use widget-change, which will also store the msg in the Node's datastore
|
|
144
133
|
*/
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
134
|
+
send(msg, index) {
|
|
135
|
+
const msgArr = [];
|
|
136
|
+
msgArr[index] = msg;
|
|
137
|
+
this.$socket.emit('widget-action', this.id, msgArr);
|
|
138
|
+
},
|
|
139
|
+
init() {
|
|
140
|
+
this.actions = this.props.options;
|
|
141
|
+
},
|
|
142
|
+
actionFn(action) {
|
|
143
|
+
if (this.checkCondition(action.condition)) {
|
|
144
|
+
this.showError(false, '');
|
|
145
|
+
this.send(
|
|
146
|
+
{ payload: { formData: this.formData, userTask: this.userTask() } },
|
|
147
|
+
this.actions.findIndex((element) => element.label === action.label)
|
|
148
|
+
);
|
|
149
|
+
} else {
|
|
150
|
+
this.showError(true, action.errorMessage);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
checkCondition(condition) {
|
|
154
|
+
try {
|
|
155
|
+
const func = Function('fields', '"use strict"; return (' + condition + ')');
|
|
156
|
+
const result = func(this.formData);
|
|
157
|
+
return Boolean(result);
|
|
158
|
+
} catch (err) {
|
|
159
|
+
console.error('Error while evaluating condition: ' + err);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
showError(bool, errMsg) {
|
|
164
|
+
this.error = bool;
|
|
165
|
+
this.errorMsg = errMsg;
|
|
166
|
+
},
|
|
159
167
|
},
|
|
160
|
-
},
|
|
161
168
|
};
|
|
162
169
|
|
|
163
170
|
function mapItems(type, field) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
if (type === 'enum') {
|
|
172
|
+
return field.enumValues.map((enumValue) => ({
|
|
173
|
+
title: enumValue.name,
|
|
174
|
+
value: enumValue.id,
|
|
175
|
+
}));
|
|
176
|
+
} else {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
172
179
|
}
|
|
173
180
|
|
|
174
181
|
function mapFieldTypes(fieldType) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
182
|
+
switch (fieldType) {
|
|
183
|
+
case 'string':
|
|
184
|
+
return 'v-text-field';
|
|
185
|
+
case 'long':
|
|
186
|
+
case 'date':
|
|
187
|
+
return 'v-text-field';
|
|
188
|
+
case 'enum':
|
|
189
|
+
return 'v-select';
|
|
190
|
+
case 'boolean':
|
|
191
|
+
return 'v-checkbox';
|
|
192
|
+
case 'text':
|
|
193
|
+
return 'v-text-field';
|
|
194
|
+
case 'select':
|
|
195
|
+
return 'v-select';
|
|
196
|
+
case 'checkbox':
|
|
197
|
+
return 'v-checkbox';
|
|
198
|
+
case 'radio':
|
|
199
|
+
return 'v-radio';
|
|
200
|
+
case 'switch':
|
|
201
|
+
return 'v-switch';
|
|
202
|
+
case 'slider':
|
|
203
|
+
return 'v-slider';
|
|
204
|
+
case 'time':
|
|
205
|
+
return 'v-time-picker';
|
|
206
|
+
case 'datetime':
|
|
207
|
+
return 'v-datetime-picker';
|
|
208
|
+
case 'color':
|
|
209
|
+
return 'v-color-picker';
|
|
210
|
+
case 'file':
|
|
211
|
+
return 'v-file-input';
|
|
212
|
+
case 'textarea':
|
|
213
|
+
return 'v-textarea';
|
|
214
|
+
case 'password':
|
|
215
|
+
return 'v-text-field';
|
|
216
|
+
case 'number':
|
|
217
|
+
return 'v-text-field';
|
|
218
|
+
case 'email':
|
|
219
|
+
return 'v-text-field';
|
|
220
|
+
case 'tel':
|
|
221
|
+
return 'v-text-field';
|
|
222
|
+
case 'url':
|
|
223
|
+
return 'v-text-field';
|
|
224
|
+
default:
|
|
225
|
+
return 'v-text-field';
|
|
226
|
+
}
|
|
220
227
|
}
|
|
221
228
|
</script>
|
|
222
229
|
|
|
223
230
|
<style scoped>
|
|
224
231
|
/* CSS is auto scoped, but using named classes is still recommended */
|
|
225
|
-
@import
|
|
232
|
+
@import '../stylesheets/dynamic-form.css';
|
|
226
233
|
</style>
|
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
.dynamic-form-wrapper {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
padding: 10px;
|
|
3
|
+
margin: 10px;
|
|
4
|
+
border: 1px solid black;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
.dynamic-form-class {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
color: green;
|
|
9
|
+
font-weight: bold;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
h1 {
|
|
13
|
-
|
|
13
|
+
margin-bottom: 10px;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
h2 {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
margin-top: 1.5rem;
|
|
18
|
+
margin-bottom: 0.75rem;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
h3 {
|
|
22
|
-
|
|
22
|
+
margin-top: 1rem;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
p {
|
|
26
|
-
|
|
26
|
+
margin-bottom: 5px;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
ul li {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
list-style-type: circle;
|
|
31
|
+
list-style-position: inside;
|
|
32
|
+
margin-left: 15px;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
pre {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
padding: 12px;
|
|
37
|
+
margin: 12px;
|
|
38
|
+
background-color: #eee;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
code {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
42
|
+
font-size: 0.825rem;
|
|
43
|
+
color: #ae0000;
|
|
44
|
+
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".dynamic-form-wrapper[data-v-37f46fd0]{padding:10px;margin:10px;border:1px solid black}.dynamic-form-class[data-v-37f46fd0]{color:green;font-weight:700}h1[data-v-37f46fd0]{margin-bottom:10px}h2[data-v-37f46fd0]{margin-top:1.5rem;margin-bottom:.75rem}h3[data-v-37f46fd0]{margin-top:1rem}p[data-v-37f46fd0]{margin-bottom:5px}ul li[data-v-37f46fd0]{list-style-type:circle;list-style-position:inside;margin-left:15px}pre[data-v-37f46fd0]{padding:12px;margin:12px;background-color:#eee}code[data-v-37f46fd0]{font-size:.825rem;color:#ae0000}")),document.head.appendChild(e)}}catch(a){console.error("vite-plugin-css-injected-by-js",a)}})();
|
|
2
|
-
(function(n,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("vuex")):typeof define=="function"&&define.amd?define(["exports","vue","vuex"],e):(n=typeof globalThis<"u"?globalThis:n||self,e(n["dynamic-form"]={},n.Vue,n.vuex))})(this,function(n,e,p){"use strict";const u=(t,o)=>{const s=t.__vccOpts||t;for(const[l,r]of o)s[l]=r;return s},f={name:"DynamicForm",inject:["$socket"],props:{id:{type:String,required:!0},props:{type:Object,default:()=>({})},state:{type:Object,default:()=>({enabled:!1,visible:!1})}},setup(t){console.info("DynamicForm setup with:",t),console.debug("Vue function loaded correctly",e.markRaw)},data(){return{actions:[],form:{},formData:{}}},computed:{...p.mapState("data",["messages"]),waiting_title(){return this.props.waiting_title||"Warten auf den Usertask..."},waiting_info(){return this.props.waiting_info||"Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist."}},mounted(){this.$socket.on("widget-load:"+this.id,t=>{this.init(),this.$store.commit("data/bind",{widgetId:this.id,msg:t})}),this.$socket.on("msg-input:"+this.id,t=>{this.init(),t.payload&&t.payload.userTask&&t.payload.userTask.startToken&&(this.formData={...t.payload.userTask.startToken},console.info(this.formData)),this.$store.commit("data/bind",{widgetId:this.id,msg:t})}),this.$socket.emit("widget-load",this.id)},unmounted(){var t,o;(t=this.$socket)==null||t.off("widget-load"+this.id),(o=this.$socket)==null||o.off("msg-input:"+this.id)},methods:{hasUserTask(){return this.messages&&this.messages[this.id]&&this.messages[this.id].payload.userTask},userTask(){return this.hasUserTask()?this.messages[this.id].payload.userTask:{}},fields(){return(this.hasUserTask()?this.userTask().userTaskConfig.formFields:[]).map(s=>({...s,component:k(s.type),items:h(s.type,s)}))},hasFields(){return this.messages&&this.messages[this.id]&&this.messages[this.id].payload.userTask!==void 0},send(t,o){const s=[];s[o]=t,console.info(s),this.$socket.emit("widget-action",this.id,s)},init(){this.actions=this.props.options},actionFn(t){this.send({payload:{formData:this.formData,userTask:this.userTask()}},this.actions.findIndex(o=>o.label===t))}}};function h(t,o){return t==="enum"?o.enumValues.map(s=>({title:s.name,value:s.id})):null}function k(t){switch(t){case"string":return"v-text-field";case"long":case"date":return"v-text-field";case"enum":return"v-select";case"boolean":return"v-checkbox";case"text":return"v-text-field";case"select":return"v-select";case"checkbox":return"v-checkbox";case"radio":return"v-radio";case"switch":return"v-switch";case"slider":return"v-slider";case"time":return"v-time-picker";case"datetime":return"v-datetime-picker";case"color":return"v-color-picker";case"file":return"v-file-input";case"textarea":return"v-textarea";case"password":return"v-text-field";case"number":return"v-text-field";case"email":return"v-text-field";case"tel":return"v-text-field";case"url":return"v-text-field";default:return"v-text-field"}}const _={className:"dynamic-form-wrapper"},y={key:0},x={key:1};function g(t,o,s,l,r,a){const T=e.resolveComponent("v-col"),d=e.resolveComponent("v-row"),b=e.resolveComponent("v-btn"),B=e.resolveComponent("v-form"),C=e.resolveComponent("v-alert");return e.openBlock(),e.createElementBlock("div",_,[a.hasFields()?(e.openBlock(),e.createElementBlock("p",y,[e.createVNode(B,{ref:"form",modelValue:r.form,"onUpdate:modelValue":o[0]||(o[0]=i=>r.form=i)},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(a.fields(),(i,c)=>(e.openBlock(),e.createBlock(d,{key:c},{default:e.withCtx(()=>[e.createVNode(T,{cols:"12"},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(i.component),{id:i.id,modelValue:r.formData[i.id],"onUpdate:modelValue":m=>r.formData[i.id]=m,required:i.required,items:i.items,label:i.label},null,8,["id","modelValue","onUpdate:modelValue","required","items","label"]))]),_:2},1024)]),_:2},1024))),128)),e.createVNode(d,{style:{display:"flex",gap:"8px",padding:"12px"}},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.actions,(i,c)=>(e.openBlock(),e.createElementBlock("div",{key:c,style:{"flex-grow":"1"}},[(e.openBlock(),e.createBlock(b,{key:c,style:{width:"100%"},onClick:m=>a.actionFn(i.label)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(i.label),1)]),_:2},1032,["onClick"]))]))),128))]),_:1})]),_:1},8,["modelValue"])])):(e.openBlock(),e.createElementBlock("p",x,[e.createVNode(C,{text:a.waiting_info,title:a.waiting_title},null,8,["text","title"])]))])}const w=u(f,[["render",g],["__scopeId","data-v-37f46fd0"]]);n.DynamicForm=w,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});
|