@5minds/node-red-dashboard-2-processcube-dynamic-form 1.0.0 → 1.0.2
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/package.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".dynamic-form-wrapper[data-v-19b58e9c]{padding:10px;margin:10px;border:1px solid black}.dynamic-form-class[data-v-19b58e9c]{color:green;font-weight:700}h1[data-v-19b58e9c]{margin-bottom:10px}h2[data-v-19b58e9c]{margin-top:1.5rem;margin-bottom:.75rem}h3[data-v-19b58e9c]{margin-top:1rem}p[data-v-19b58e9c]{margin-bottom:5px}ul li[data-v-19b58e9c]{list-style-type:circle;list-style-position:inside;margin-left:15px}pre[data-v-19b58e9c]{padding:12px;margin:12px;background-color:#eee}code[data-v-19b58e9c]{font-size:.825rem;color:#ae0000}")),document.head.appendChild(e)}}catch(a){console.error("vite-plugin-css-injected-by-js",a)}})();
|
|
2
|
-
(function(
|
|
2
|
+
(function(i,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("vuex")):typeof define=="function"&&define.amd?define(["exports","vue","vuex"],e):(i=typeof globalThis<"u"?globalThis:i||self,e(i["dynamic-form"]={},i.Vue,i.vuex))})(this,function(i,e,f){"use strict";const p=(t,s)=>{const o=t.__vccOpts||t;for(const[n,c]of s)o[n]=c;return o},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{form:{},formData:{}}},computed:{...f.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."},submit_title(){return this.props.submit_title||"Submit your task"},cancel_title(){return this.props.cancel_title||"Cancel your task"}},mounted(){this.$socket.on("widget-load:"+this.id,t=>{this.$store.commit("data/bind",{widgetId:this.id,msg:t})}),this.$socket.on("msg-input:"+this.id,t=>{if(console.info(t),t.payload.formFields){const s=t.payload.formFields.reduce((o,n)=>(console.info("field:",n),console.info("field.id:",n.id),o[n.id]=n.value||"",o),{});console.info("formData: ",s),console.info("this.formData (1):",this.formData),this.formData=s,console.info("this.formData (2):",this.formData)}this.$store.commit("data/bind",{widgetId:this.id,msg:t})}),this.$socket.emit("widget-load",this.id)},unmounted(){var t,s;(t=this.$socket)==null||t.off("widget-load"+this.id),(s=this.$socket)==null||s.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(o=>({...o,component:h(o.type)}))},hasFields(){return this.hasUserTask&&this.userTask.userTaskConfig.formFields.length>0},send(t){this.$socket.emit("widget-action",this.id,t)},submit(){this.send({payload:{formData:this.formData,userTask:this.userTask(),action:"submit"}})},cancel(){this.send({payload:{formData:this.formData,userTask:this.userTask(),action:"cancal"}})}}};function h(t){switch(t){case"string":case"long":case"date":case"enum":case"boolean":return"v-text-field";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 k={className:"dynamic-form-wrapper"},_={key:0},y={key:1};function b(t,s,o,n,c,r){const l=e.resolveComponent("v-col"),d=e.resolveComponent("v-row"),m=e.resolveComponent("v-btn"),x=e.resolveComponent("v-form"),g=e.resolveComponent("v-alert");return e.openBlock(),e.createElementBlock(e.Fragment,null,[e.createCommentVNode(" Component must be wrapped in a block so props such as className and style can be passed in from parent "),e.createElementVNode("div",k,[r.hasFields?(e.openBlock(),e.createElementBlock("p",_,[e.createVNode(x,{ref:"form",modelValue:c.form,"onUpdate:modelValue":s[0]||(s[0]=a=>c.form=a)},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.fields(),(a,C)=>(e.openBlock(),e.createBlock(d,{key:C},{default:e.withCtx(()=>[e.createVNode(l,{cols:"12"},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(a.component),{id:a.id,modelValue:c.formData[a.id],"onUpdate:modelValue":D=>c.formData[a.id]=D,required:a.required,items:a.items,label:a.label},null,8,["id","modelValue","onUpdate:modelValue","required","items","label"]))]),_:2},1024)]),_:2},1024))),128)),e.createVNode(d,null,{default:e.withCtx(()=>[e.createVNode(l,{cols:"6"},{default:e.withCtx(()=>[e.createVNode(m,{variant:"outlined",block:"",onClick:r.cancel},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.cancel_title),1)]),_:1},8,["onClick"])]),_:1}),e.createVNode(l,{cols:"6"},{default:e.withCtx(()=>[e.createVNode(m,{block:"",onClick:r.submit},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(r.submit_title),1)]),_:1},8,["onClick"])]),_:1})]),_:1})]),_:1},8,["modelValue"])])):(e.openBlock(),e.createElementBlock("p",y,[e.createVNode(g,{text:r.waiting_info,title:r.waiting_title},null,8,["text","title"])]))])],2112)}const w=p(u,[["render",b],["__scopeId","data-v-19b58e9c"],["__file","/Users/moellenbeck/projects/5minds/reps/node-red-dashboard-2-processcube-dynamic-form/ui/components/DynamicForm.vue"]]);i.DynamicForm=w,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
|
|
3
3
|
//# sourceMappingURL=dynamic-form.umd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-form.umd.js","sources":["../ui/components/DynamicForm.vue"],"sourcesContent":["<template>\n <!-- Component must be wrapped in a block so props such as className and style can be passed in from parent -->\n <div className=\"dynamic-form-wrapper\">\n <p v-if=\"hasFields\">\n <v-form ref=\"form\" v-model=\"form\">\n <v-row v-for=\"(field, index) in fields\" :key=\"index\">\n <v-col cols=\"12\">\n <component\n :is=\"field.component\"\n :id=\"field.id\"\n v-model=\"formData[field.id]\"\n :required=\"field.required\"\n :items=\"field.items\"\n :label=\"field.label\"\n />\n </v-col>\n </v-row>\n\n <v-row>\n <v-col cols=\"6\">\n <v-btn variant=\"outlined\" block @click=\"cancel\">{{ cancel_title }}</v-btn>\n </v-col>\n <v-col cols=\"6\">\n <v-btn block @click=\"submit\">{{ submit_title }}</v-btn>\n </v-col>\n </v-row>\n </v-form>\n </p>\n <p v-else>\n <v-alert :text=\"waiting_info\" :title=\"waiting_title\" />\n </p>\n </div>\n</template>\n\n<script>\nimport { markRaw } from 'vue'\nimport { mapState } from 'vuex'\n\nexport default {\n name: 'DynamicForm',\n inject: ['$socket'],\n props: {\n /* do not remove entries from this - Dashboard's Layout Manager's will pass this data to your component */\n id: { type: String, required: true },\n props: { type: Object, default: () => ({}) },\n state: { type: Object, default: () => ({ enabled: false, visible: false }) }\n },\n setup (props) {\n console.info('DynamicForm setup with:', props)\n console.debug('Vue function loaded correctly', markRaw)\n },\n data () {\n return {\n form: {},\n formData: {}\n }\n },\n computed: {\n ...mapState('data', ['messages']),\n fields () {\n const aFields = this.messages && this.messages[this.id] ? this.messages[this.id].payload.formFields : []\n\n const fieldMap = aFields.map(field => ({\n ...field,\n component: field.type\n }))\n\n return fieldMap\n },\n hasFields () {\n return this.messages && this.messages[this.id] && this.messages[this.id].payload.formFields\n },\n waiting_title () {\n return this.props.waiting_title || 'Warten auf den Usertask...'\n },\n waiting_info () {\n return this.props.waiting_info || 'Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist.'\n },\n submit_title () {\n return this.props.submit_title || 'Submit your task'\n },\n cancel_title () {\n return this.props.cancel_title || 'Cancel your task'\n }\n },\n mounted () {\n this.$socket.on('widget-load:' + this.id, (msg) => {\n // load the latest message from the Node-RED datastore when this widget is loaded\n // storing it in our vuex store so that we have it saved as we navigate around\n this.$store.commit('data/bind', {\n widgetId: this.id,\n msg\n })\n })\n this.$socket.on('msg-input:' + this.id, (msg) => {\n // store the latest message in our client-side vuex store when we receive a new message\n\n console.info(msg)\n\n if (msg.payload.formFields) {\n const formData = msg.payload.formFields.reduce((acc, field) => {\n console.info('field:', field)\n console.info('field.id:', field.id)\n\n acc[field.id] = field.value || ''\n return acc\n }, {})\n\n console.info('formData: ', formData)\n console.info('this.formData (1):', this.formData)\n\n this.formData = formData\n console.info('this.formData (2):', this.formData)\n }\n\n this.$store.commit('data/bind', {\n widgetId: this.id,\n msg\n })\n })\n // tell Node-RED that we're loading a new instance of this widget\n this.$socket.emit('widget-load', this.id)\n },\n unmounted () {\n /* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */\n this.$socket?.off('widget-load' + this.id)\n this.$socket?.off('msg-input:' + this.id)\n },\n methods: {\n /*\n widget-action just sends a msg to Node-RED, it does not store the msg state server-side\n alternatively, you can use widget-change, which will also store the msg in the Node's datastore\n */\n send (msg) {\n this.$socket.emit('widget-action', this.id, msg)\n },\n submit () {\n this.send({ payload: this.formData })\n },\n cancel () {\n this.send({ payload: this.formData })\n }\n }\n}\n</script>\n\n<style scoped>\n/* CSS is auto scoped, but using named classes is still recommended */\n@import \"../stylesheets/dynamic-form.css\";\n</style>\n"],"names":["_sfc_main","props","markRaw","mapState","field","msg","formData","acc","_a","_b","_hoisted_1","_openBlock","_createElementBlock","_Fragment","_createCommentVNode","_createElementVNode","$options","_hoisted_2","_createVNode","_component_v_form","$data","_cache","$event","_withCtx","_renderList","index","_createBlock","_component_v_row","_component_v_col","_resolveDynamicComponent","_component_v_btn","_createTextVNode","_toDisplayString","_hoisted_3","_component_v_alert"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dynamic-form.umd.js","sources":["../ui/components/DynamicForm.vue"],"sourcesContent":["<template>\n <!-- Component must be wrapped in a block so props such as className and style can be passed in from parent -->\n <div className=\"dynamic-form-wrapper\">\n <p v-if=\"hasFields\">\n <v-form ref=\"form\" v-model=\"form\">\n <v-row v-for=\"(field, index) in fields()\" :key=\"index\">\n <v-col cols=\"12\">\n <component\n :is=\"field.component\"\n :id=\"field.id\"\n v-model=\"formData[field.id]\"\n :required=\"field.required\"\n :items=\"field.items\"\n :label=\"field.label\"\n />\n </v-col>\n </v-row>\n\n <v-row>\n <v-col cols=\"6\">\n <v-btn variant=\"outlined\" block @click=\"cancel\">{{ cancel_title }}</v-btn>\n </v-col>\n <v-col cols=\"6\">\n <v-btn block @click=\"submit\">{{ submit_title }}</v-btn>\n </v-col>\n </v-row>\n </v-form>\n </p>\n <p v-else>\n <v-alert :text=\"waiting_info\" :title=\"waiting_title\" />\n </p>\n </div>\n</template>\n\n<script>\nimport { markRaw } from 'vue'\nimport { mapState } from 'vuex'\n\nexport default {\n name: 'DynamicForm',\n inject: ['$socket'],\n props: {\n /* do not remove entries from this - Dashboard's Layout Manager's will pass this data to your component */\n id: { type: String, required: true },\n props: { type: Object, default: () => ({}) },\n state: { type: Object, default: () => ({ enabled: false, visible: false }) }\n },\n setup (props) {\n console.info('DynamicForm setup with:', props)\n console.debug('Vue function loaded correctly', markRaw)\n },\n data () {\n return {\n form: {},\n formData: {}\n }\n },\n computed: {\n ...mapState('data', ['messages']),\n waiting_title () {\n return this.props.waiting_title || 'Warten auf den Usertask...'\n },\n waiting_info () {\n return this.props.waiting_info || 'Der Usertask wird automatisch angezeigt, wenn ein entsprechender Task vorhanden ist.'\n },\n submit_title () {\n return this.props.submit_title || 'Submit your task'\n },\n cancel_title () {\n return this.props.cancel_title || 'Cancel your task'\n }\n },\n mounted () {\n this.$socket.on('widget-load:' + this.id, (msg) => {\n // load the latest message from the Node-RED datastore when this widget is loaded\n // storing it in our vuex store so that we have it saved as we navigate around\n this.$store.commit('data/bind', {\n widgetId: this.id,\n msg\n })\n })\n this.$socket.on('msg-input:' + this.id, (msg) => {\n // store the latest message in our client-side vuex store when we receive a new message\n\n console.info(msg)\n\n if (msg.payload.formFields) {\n const formData = msg.payload.formFields.reduce((acc, field) => {\n console.info('field:', field)\n console.info('field.id:', field.id)\n\n acc[field.id] = field.value || ''\n return acc\n }, {})\n\n console.info('formData: ', formData)\n console.info('this.formData (1):', this.formData)\n\n this.formData = formData\n console.info('this.formData (2):', this.formData)\n }\n\n this.$store.commit('data/bind', {\n widgetId: this.id,\n msg\n })\n })\n // tell Node-RED that we're loading a new instance of this widget\n this.$socket.emit('widget-load', this.id)\n },\n unmounted () {\n /* Make sure, any events you subscribe to on SocketIO are unsubscribed to here */\n this.$socket?.off('widget-load' + this.id)\n this.$socket?.off('msg-input:' + this.id)\n },\n methods: {\n hasUserTask () {\n return this.messages && this.messages[this.id] && this.messages[this.id].payload.userTask\n },\n userTask () {\n return this.hasUserTask() ? this.messages[this.id].payload.userTask : {}\n },\n fields () {\n const aFields = this.hasUserTask() ? this.userTask().userTaskConfig.formFields : []\n\n const fieldMap = aFields.map(field => ({\n ...field,\n component: mapFieldTypes(field.type)\n }))\n\n return fieldMap\n },\n hasFields () {\n return this.hasUserTask && this.userTask.userTaskConfig.formFields.length > 0\n },\n /*\n widget-action just sends a msg to Node-RED, it does not store the msg state server-side\n alternatively, you can use widget-change, which will also store the msg in the Node's datastore\n */\n send (msg) {\n this.$socket.emit('widget-action', this.id, msg)\n },\n submit () {\n this.send({ payload: { formData: this.formData, userTask: this.userTask(), action: 'submit' } })\n },\n cancel () {\n this.send({ payload: { formData: this.formData, userTask: this.userTask(), action: 'cancal' } })\n }\n }\n}\n\nfunction mapFieldTypes (fieldType) {\n switch (fieldType) {\n case 'string':\n case 'long':\n case 'date':\n case 'enum':\n case 'boolean':\n return 'v-text-field'\n case 'text':\n return 'v-text-field'\n case 'select':\n return 'v-select'\n case 'checkbox':\n return 'v-checkbox'\n case 'radio':\n return 'v-radio'\n case 'switch':\n return 'v-switch'\n case 'slider':\n return 'v-slider'\n case 'time':\n return 'v-time-picker'\n case 'datetime':\n return 'v-datetime-picker'\n case 'color':\n return 'v-color-picker'\n case 'file':\n return 'v-file-input'\n case 'textarea':\n return 'v-textarea'\n case 'password':\n return 'v-text-field'\n case 'number':\n return 'v-text-field'\n case 'email':\n return 'v-text-field'\n case 'tel':\n return 'v-text-field'\n case 'url':\n return 'v-text-field'\n default:\n return 'v-text-field'\n }\n}\n\n</script>\n\n<style scoped>\n/* CSS is auto scoped, but using named classes is still recommended */\n@import \"../stylesheets/dynamic-form.css\";\n</style>\n"],"names":["_sfc_main","props","markRaw","mapState","msg","formData","acc","field","_a","_b","mapFieldTypes","fieldType","_hoisted_1","_openBlock","_createElementBlock","_Fragment","_createCommentVNode","_createElementVNode","$options","_hoisted_2","_createVNode","_component_v_form","$data","_cache","$event","_withCtx","_renderList","index","_createBlock","_component_v_row","_component_v_col","_resolveDynamicComponent","_component_v_btn","_createTextVNode","_toDisplayString","_hoisted_3","_component_v_alert"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div className="dynamic-form-wrapper">
|
|
4
4
|
<p v-if="hasFields">
|
|
5
5
|
<v-form ref="form" v-model="form">
|
|
6
|
-
<v-row v-for="(field, index) in fields" :key="index">
|
|
6
|
+
<v-row v-for="(field, index) in fields()" :key="index">
|
|
7
7
|
<v-col cols="12">
|
|
8
8
|
<component
|
|
9
9
|
:is="field.component"
|
|
@@ -57,19 +57,6 @@ export default {
|
|
|
57
57
|
},
|
|
58
58
|
computed: {
|
|
59
59
|
...mapState('data', ['messages']),
|
|
60
|
-
fields () {
|
|
61
|
-
const aFields = this.messages && this.messages[this.id] ? this.messages[this.id].payload.formFields : []
|
|
62
|
-
|
|
63
|
-
const fieldMap = aFields.map(field => ({
|
|
64
|
-
...field,
|
|
65
|
-
component: field.type
|
|
66
|
-
}))
|
|
67
|
-
|
|
68
|
-
return fieldMap
|
|
69
|
-
},
|
|
70
|
-
hasFields () {
|
|
71
|
-
return this.messages && this.messages[this.id] && this.messages[this.id].payload.formFields
|
|
72
|
-
},
|
|
73
60
|
waiting_title () {
|
|
74
61
|
return this.props.waiting_title || 'Warten auf den Usertask...'
|
|
75
62
|
},
|
|
@@ -127,6 +114,25 @@ export default {
|
|
|
127
114
|
this.$socket?.off('msg-input:' + this.id)
|
|
128
115
|
},
|
|
129
116
|
methods: {
|
|
117
|
+
hasUserTask () {
|
|
118
|
+
return this.messages && this.messages[this.id] && this.messages[this.id].payload.userTask
|
|
119
|
+
},
|
|
120
|
+
userTask () {
|
|
121
|
+
return this.hasUserTask() ? this.messages[this.id].payload.userTask : {}
|
|
122
|
+
},
|
|
123
|
+
fields () {
|
|
124
|
+
const aFields = this.hasUserTask() ? this.userTask().userTaskConfig.formFields : []
|
|
125
|
+
|
|
126
|
+
const fieldMap = aFields.map(field => ({
|
|
127
|
+
...field,
|
|
128
|
+
component: mapFieldTypes(field.type)
|
|
129
|
+
}))
|
|
130
|
+
|
|
131
|
+
return fieldMap
|
|
132
|
+
},
|
|
133
|
+
hasFields () {
|
|
134
|
+
return this.hasUserTask && this.userTask.userTaskConfig.formFields.length > 0
|
|
135
|
+
},
|
|
130
136
|
/*
|
|
131
137
|
widget-action just sends a msg to Node-RED, it does not store the msg state server-side
|
|
132
138
|
alternatively, you can use widget-change, which will also store the msg in the Node's datastore
|
|
@@ -135,13 +141,59 @@ export default {
|
|
|
135
141
|
this.$socket.emit('widget-action', this.id, msg)
|
|
136
142
|
},
|
|
137
143
|
submit () {
|
|
138
|
-
this.send({ payload: this.formData })
|
|
144
|
+
this.send({ payload: { formData: this.formData, userTask: this.userTask(), action: 'submit' } })
|
|
139
145
|
},
|
|
140
146
|
cancel () {
|
|
141
|
-
this.send({ payload: this.formData })
|
|
147
|
+
this.send({ payload: { formData: this.formData, userTask: this.userTask(), action: 'cancal' } })
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
150
|
}
|
|
151
|
+
|
|
152
|
+
function mapFieldTypes (fieldType) {
|
|
153
|
+
switch (fieldType) {
|
|
154
|
+
case 'string':
|
|
155
|
+
case 'long':
|
|
156
|
+
case 'date':
|
|
157
|
+
case 'enum':
|
|
158
|
+
case 'boolean':
|
|
159
|
+
return 'v-text-field'
|
|
160
|
+
case 'text':
|
|
161
|
+
return 'v-text-field'
|
|
162
|
+
case 'select':
|
|
163
|
+
return 'v-select'
|
|
164
|
+
case 'checkbox':
|
|
165
|
+
return 'v-checkbox'
|
|
166
|
+
case 'radio':
|
|
167
|
+
return 'v-radio'
|
|
168
|
+
case 'switch':
|
|
169
|
+
return 'v-switch'
|
|
170
|
+
case 'slider':
|
|
171
|
+
return 'v-slider'
|
|
172
|
+
case 'time':
|
|
173
|
+
return 'v-time-picker'
|
|
174
|
+
case 'datetime':
|
|
175
|
+
return 'v-datetime-picker'
|
|
176
|
+
case 'color':
|
|
177
|
+
return 'v-color-picker'
|
|
178
|
+
case 'file':
|
|
179
|
+
return 'v-file-input'
|
|
180
|
+
case 'textarea':
|
|
181
|
+
return 'v-textarea'
|
|
182
|
+
case 'password':
|
|
183
|
+
return 'v-text-field'
|
|
184
|
+
case 'number':
|
|
185
|
+
return 'v-text-field'
|
|
186
|
+
case 'email':
|
|
187
|
+
return 'v-text-field'
|
|
188
|
+
case 'tel':
|
|
189
|
+
return 'v-text-field'
|
|
190
|
+
case 'url':
|
|
191
|
+
return 'v-text-field'
|
|
192
|
+
default:
|
|
193
|
+
return 'v-text-field'
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
145
197
|
</script>
|
|
146
198
|
|
|
147
199
|
<style scoped>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
{
|
|
2
|
+
"userTask": {
|
|
3
|
+
"flowNodeInstanceId": "3b3102c5-102d-4e52-ab27-40602cc5fd86",
|
|
4
|
+
"flowNodeId": "Activity_0ljiko7",
|
|
5
|
+
"flowNodeName": "Hello world",
|
|
6
|
+
"flowNodeLane": "Lane",
|
|
7
|
+
"flowNodeType": "bpmn:UserTask",
|
|
8
|
+
"previousFlowNodeInstanceId": "2ebcb278-d90c-4b2b-98ee-c9847dcaf461",
|
|
9
|
+
"parentProcessInstanceId": null,
|
|
10
|
+
"processDefinitionId": "SampleUserTask_Definition",
|
|
11
|
+
"processModelId": "SampleUserTask_Process",
|
|
12
|
+
"processInstanceId": "8a8ab5a7-fbef-4bf0-9905-1937defb8cd8",
|
|
13
|
+
"correlationId": "61845380-2bd3-4bc9-b3bf-60933d05121b",
|
|
14
|
+
"state": "suspended",
|
|
15
|
+
"tokens": [],
|
|
16
|
+
"startToken": {},
|
|
17
|
+
"endToken": {},
|
|
18
|
+
"ownerId": "dummy_token",
|
|
19
|
+
"startedAt": "2024-06-16T19:18:38.580Z",
|
|
20
|
+
"assignedUserIds": null,
|
|
21
|
+
"actualOwnerId": null,
|
|
22
|
+
"finishedByUserId": null,
|
|
23
|
+
"userTaskConfig": {
|
|
24
|
+
"formFields": [
|
|
25
|
+
{
|
|
26
|
+
"id": "text_id",
|
|
27
|
+
"label": "Text Label",
|
|
28
|
+
"type": "string"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "number_id",
|
|
32
|
+
"label": "Number Label",
|
|
33
|
+
"type": "long",
|
|
34
|
+
"defaultValue": "undefined",
|
|
35
|
+
"customForm": "{\"hint\":\"Sample\"}"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "date_id",
|
|
39
|
+
"label": "Date Label",
|
|
40
|
+
"type": "date"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "select_id",
|
|
44
|
+
"label": "Select Label",
|
|
45
|
+
"type": "enum",
|
|
46
|
+
"enumValues": [
|
|
47
|
+
{
|
|
48
|
+
"id": "value_01",
|
|
49
|
+
"name": "Value 01"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"id": "value_02",
|
|
53
|
+
"name": "Value 02"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "boolean_id",
|
|
59
|
+
"label": "Boolean Label",
|
|
60
|
+
"type": "boolean"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "customer_01",
|
|
64
|
+
"label": "Custom_01",
|
|
65
|
+
"type": "v-text-field"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
"userTaskConfigModel": {
|
|
70
|
+
"formFields": [
|
|
71
|
+
{
|
|
72
|
+
"id": "text_id",
|
|
73
|
+
"label": "Text Label",
|
|
74
|
+
"type": "string"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "number_id",
|
|
78
|
+
"label": "Number Label",
|
|
79
|
+
"type": "long",
|
|
80
|
+
"defaultValue": "${token.current.sample}",
|
|
81
|
+
"customForm": "{\"hint\":\"Sample\"}"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "date_id",
|
|
85
|
+
"label": "Date Label",
|
|
86
|
+
"type": "date"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "select_id",
|
|
90
|
+
"label": "Select Label",
|
|
91
|
+
"type": "enum",
|
|
92
|
+
"enumValues": [
|
|
93
|
+
{
|
|
94
|
+
"id": "value_01",
|
|
95
|
+
"name": "Value 01"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "value_02",
|
|
99
|
+
"name": "Value 02"
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "boolean_id",
|
|
105
|
+
"label": "Boolean Label",
|
|
106
|
+
"type": "boolean"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": "customer_01",
|
|
110
|
+
"label": "Custom_01",
|
|
111
|
+
"type": "v-text-field"
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|