@mixd-id/web-scaffold 0.1.230406359 → 0.1.230406361

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,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.230406359",
4
+ "version": "0.1.230406361",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <Modal ref="modal"
3
+ width="380"
4
+ height="420">
5
+ <template v-slot:head>
6
+ <div class="relative p-6">
7
+ <h3>Condition</h3>
8
+ <div class="absolute top-0 right-0 p-2">
9
+ <button type="button" class="p-2" @click="close">
10
+ <svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
11
+ <path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
12
+ </svg>
13
+ </button>
14
+ </div>
15
+ </div>
16
+ </template>
17
+ <template v-slot:foot>
18
+ <div class="p-6">
19
+ <Button class="w-[90px]" @click="apply">OK</Button>
20
+ </div>
21
+ </template>
22
+ <div class="flex-1 p-6">
23
+
24
+ <div class="flex flex-col gap-6">
25
+
26
+ <div>
27
+ <label>Key</label>
28
+ <Dropdown v-model="instance.key" class="mt-1">
29
+ <option value="text">Text</option>
30
+ </Dropdown>
31
+ </div>
32
+
33
+ <div>
34
+ <label>Operator</label>
35
+ <Dropdown v-model="instance.op" class="mt-1">
36
+ <option value="=">Equal</option>
37
+ <option value="intent">Intent</option>
38
+ <option value="extractVariables">Extract Information</option>
39
+ </Dropdown>
40
+ </div>
41
+
42
+ <div>
43
+ <label>Value</label>
44
+ <Textarea v-model="instance.value" rows="3" class="mt-1"/>
45
+ </div>
46
+
47
+ </div>
48
+
49
+ </div>
50
+ </Modal>
51
+ </template>
52
+
53
+ <script>
54
+
55
+ export default{
56
+
57
+ inject: [ 'socketEmit2' ],
58
+
59
+ data(){
60
+ return {
61
+ callback: null,
62
+ instance: null,
63
+ }
64
+ },
65
+
66
+ methods: {
67
+
68
+ apply(){
69
+ if(typeof this.callback === 'function')
70
+ this.callback(this.instance)
71
+ this.close()
72
+ },
73
+
74
+ open(instance, callback){
75
+ this.instance = instance
76
+ this.callback = callback
77
+ this.$refs.modal.open()
78
+ },
79
+
80
+ close(){
81
+ this.$refs.modal.close()
82
+ },
83
+
84
+ }
85
+
86
+ }
87
+
88
+ </script>
89
+
90
+ <style module>
91
+
92
+ .comp{
93
+
94
+ }
95
+
96
+ </style>
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <div class="h-[200px] panel-400 border-[1px] border-text-50 flex flex-col relative">
3
+
4
+ <div class="flex-1 overflow-y-auto flex flex-col-reverse px-3 gap-2">
5
+ <div v-for="_message in reversedMessages"
6
+ class="p-1 bg-text-50 self-start"
7
+ :class="_message.direction === 2 ? 'ml-5' : ''">
8
+ {{ _message.body }}
9
+ </div>
10
+ </div>
11
+
12
+ <div class="absolute top-0 right-0 p-3">
13
+ <button type="button" class="text-primary" @click="clear">Clear</button>
14
+ </div>
15
+
16
+ <div class="p-2 flex flex-row gap-2">
17
+ <Textbox v-model="message.body" class="flex-1" />
18
+ <Button class="px-4" @click="send">Send</Button>
19
+ <Button class="px-3" variant="secondary" @click="reset">Reset</Button>
20
+ </div>
21
+ </div>
22
+ </template>
23
+
24
+ <script>
25
+
26
+ export default{
27
+
28
+ emits: [ 'test-message', 'test-reset' ],
29
+
30
+ computed: {
31
+
32
+ reversedMessages(){
33
+ return this.messages.slice().reverse()
34
+ }
35
+
36
+ },
37
+
38
+ data(){
39
+ return {
40
+ message: {},
41
+ messages: []
42
+ }
43
+ },
44
+
45
+ methods: {
46
+
47
+ addMessage(message){
48
+ this.messages.push(message)
49
+ },
50
+
51
+ clear(){
52
+ this.messages = []
53
+ },
54
+
55
+ reset(){
56
+ this.$emit('test-reset')
57
+ },
58
+
59
+ send(){
60
+ this.$emit('test-message', this.message)
61
+ this.messages.push(this.message)
62
+ this.message = {}
63
+ },
64
+
65
+ }
66
+
67
+ }
68
+
69
+ </script>
70
+
71
+ <style module>
72
+
73
+ .comp{
74
+
75
+ }
76
+
77
+ </style>
@@ -0,0 +1,270 @@
1
+ <template>
2
+ <div v-if="item"
3
+ class="flex flex-row items-start relative">
4
+
5
+ <div ref="outer" class="flex-1 flex flex-row items-start">
6
+ <div class="flex flex-col self-stretch" :class="debug ? '' : ''">
7
+
8
+ <div class="flex flex-row items-center">
9
+ <div class="bg-primary-300 h-[1px]" :style="{ width:`${size[2]}px` }"></div>
10
+
11
+ <div :style="{ width:`${size[0]}px` }"
12
+ ref="item"
13
+ @mousedown="mouseDown"
14
+ @mouseover="hoverMouseOver">
15
+ <div class="rounded-xl p-3 border-[1px] flex relative overflow-hidden"
16
+ :class="isSelected ? 'border-primary bg-base-500' : 'border-primary-300 bg-base-400'"
17
+ @click="$emit('select', item)" :style="{ }">
18
+ <div class="flex-1 flex flex-row">
19
+ <div class="flex-1 cursor-default whitespace-nowrap overflow-hidden text-ellipsis">
20
+ {{ item.name }}
21
+ </div>
22
+ <button v-if="isSelected && removable" class="text-primary" type="button" @click="$emit('remove')">
23
+ <svg width="16" height="16" class="fill-text-200 hover:fill-red-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256C397.4 512 512 397.4 512 256S397.4 0 256 0zM336.1 303c9.375 9.375 9.375 24.56 0 33.94c-9.381 9.381-24.56 9.373-33.94 0L256 289.9l-47.03 47.03c-9.381 9.381-24.56 9.373-33.94 0c-9.375-9.375-9.375-24.56 0-33.94l47.03-47.03L175 208.1c-9.375-9.375-9.375-24.56 0-33.94s24.56-9.375 33.94 0L256 222.1l47.03-47.03c9.375-9.375 24.56-9.375 33.94 0s9.375 24.56 0 33.94l-47.03 47.03L336.1 303z"/></svg>
24
+ </button>
25
+ </div>
26
+
27
+ <div v-if="item.isFallback" :class="$style.isFallback"></div>
28
+ </div>
29
+ </div>
30
+
31
+ <div v-if="hasChildren && (item.items ?? []).length < 1 && !item.isFallback"
32
+ class="flex flex-row items-center"
33
+ :style="{ width:`${size[2] * 1.2}px` }">
34
+ <div class="flex-1 bg-primary-300 h-[1px]"></div>
35
+ <button type="button"
36
+ @click="addItem(item)">
37
+ <svg width="16" height="16" class="fill-primary-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256C397.4 512 512 397.4 512 256S397.4 0 256 0zM352 280H280V352c0 13.2-10.8 24-23.1 24C242.8 376 232 365.2 232 352V280H160C146.8 280 136 269.2 136 256c0-13.2 10.8-24 24-24H232V160c0-13.2 10.8-24 24-24C269.2 136 280 146.8 280 160v72h72C365.2 232 376 242.8 376 256C376 269.2 365.2 280 352 280z"/></svg>
38
+ </button>
39
+ </div>
40
+ <div v-else-if="hasChildren && !item.isFallback" class="flex flex-row items-center" :style="{ width:`${size[2]}px` }">
41
+ <div class="flex-1 bg-primary-300 h-[1px]"></div>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="flex-1 flex flex-row items-start">
46
+ <div :style="{ width:`${size[2]}px` }"></div>
47
+
48
+ <div v-if="useAdd" class="self-stretch flex flex-col items-center" :style="{ width:`${size[0]}px`, height:`${size[2] * 1.2}px` }">
49
+ <div class="flex-1 w-[1px] bg-primary-300"></div>
50
+ <button type="button" v-if="useAdd" @click="$emit('add')">
51
+ <svg width="16" height="16" class="fill-primary-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256C397.4 512 512 397.4 512 256S397.4 0 256 0zM352 280H280V352c0 13.2-10.8 24-23.1 24C242.8 376 232 365.2 232 352V280H160C146.8 280 136 269.2 136 256c0-13.2 10.8-24 24-24H232V160c0-13.2 10.8-24 24-24C269.2 136 280 146.8 280 160v72h72C365.2 232 376 242.8 376 256C376 269.2 365.2 280 352 280z"/></svg>
52
+ </button>
53
+ <div class="flex-1"></div>
54
+ </div>
55
+ <div v-else class="flex flex-col items-center" :style="{ width:`${size[0]}px`, height:`${size[2]}px` }">
56
+
57
+ </div>
58
+
59
+ <div :style="{ width:`${size[2]}px` }"></div>
60
+ </div>
61
+
62
+ </div>
63
+
64
+ <div v-if="hasChildren" class="flex flex-col relative" :class="debug ? '' : ''">
65
+
66
+ <UserActionItem v-for="(subItem, idx) in item.items"
67
+ :config="config"
68
+ :item="subItem"
69
+ :level="level + 1"
70
+ :index="idx"
71
+ :parent="item.items"
72
+ :isLast="idx === item.items.length - 1"
73
+ @select="(item) => $emit('select', item)"
74
+ @remove="item.items.splice(idx, 1)"
75
+ :useAdd="idx === (item.items ?? []).length - 1"
76
+ @add="addItem(item)" />
77
+ </div>
78
+ </div>
79
+
80
+ <div v-if="level > 0 && index > 0" class="absolute w-[1px] bg-primary-300" :style="vBorder0"></div>
81
+ <div v-if="level > 0 && !isLast" class="absolute w-[1px] bg-primary-300" :style="vBorder"></div>
82
+
83
+ </div>
84
+ </template>
85
+
86
+ <script>
87
+
88
+ import md5 from "md5";
89
+
90
+ let dragged = null
91
+ let guide1 = null
92
+
93
+ export default{
94
+
95
+ computed: {
96
+
97
+ debug(){
98
+ return this.item.name === 'Tea'
99
+ },
100
+
101
+ isSelected(){
102
+ return this.config.selectedUid === this.item.uid
103
+ },
104
+
105
+ vBorder(){
106
+ let bottom = `${(this.size[2] * 1.2) + (this.size[1] * .5)}px`
107
+
108
+ return {
109
+ top:'20px',
110
+ bottom: 0
111
+ }
112
+ },
113
+
114
+ vBorder0(){
115
+ return {
116
+ top: 0,
117
+ height: '20px'
118
+ }
119
+ }
120
+
121
+ },
122
+
123
+ emits: [ 'add', 'remove', 'select' ],
124
+
125
+ methods: {
126
+
127
+ addItem(item){
128
+ if(!Array.isArray(item.items))
129
+ item.items = []
130
+
131
+ const uid = md5(Date.now())
132
+
133
+ item.items.push({
134
+ name: 'Untitled',
135
+ parentId: item.id,
136
+ uid,
137
+ enabled: true
138
+ })
139
+
140
+ this.config.selectedUid = uid
141
+ },
142
+
143
+ hoverMouseOver(e){
144
+ if(!dragged) return
145
+
146
+ const from = this.parent.indexOf(dragged.item)
147
+ const to = this.parent.indexOf(this.item)
148
+ this.parent.splice(to, 0, this.parent.splice(from, 1)[0]);
149
+ },
150
+
151
+ mouseDown(e){
152
+ if(!this.$el || this.$el.nodeType !== 1) return
153
+
154
+ e.preventDefault()
155
+
156
+ const startY = e.clientY
157
+
158
+ dragged = {
159
+ item: this.item,
160
+ parent: this.parent,
161
+ startY: e.clientY,
162
+ index: this.parent?.indexOf(this.item)
163
+ }
164
+
165
+ const mouseMove = (e) => {
166
+ const distanceY = e.clientY - startY
167
+
168
+ if(!dragged.cloned && Math.abs(distanceY) > 10){
169
+ const cloned = this.$refs.outer.cloneNode(true)
170
+ cloned.style.position = 'fixed'
171
+ cloned.style.width = this.$refs.item.clientWidth + "px"
172
+ cloned.style.pointerEvents = 'none'
173
+ cloned.style.opacity = '0.5'
174
+ document.body.appendChild(cloned)
175
+
176
+ dragged.cloned = cloned
177
+ }
178
+
179
+ if(dragged.cloned){
180
+ dragged.cloned.style.left = (e.clientX + 3) + "px"
181
+ dragged.cloned.style.top = (e.clientY + 3) + "px"
182
+ }
183
+
184
+ dragged.clientY = e.clientY
185
+ }
186
+
187
+ const mouseUp = (e) => {
188
+ if(dragged?.cloned){
189
+ document.body.removeChild(dragged.cloned)
190
+ }
191
+
192
+ window.removeEventListener('mousemove', mouseMove)
193
+ window.removeEventListener('mouseup', mouseUp)
194
+
195
+ if(guide1 && guide1.parentNode){
196
+ guide1.parentNode.removeChild(guide1)
197
+ }
198
+
199
+ dragged = null
200
+ }
201
+
202
+ const keyUp = (e) => {
203
+ if(e.keyCode === 27){
204
+ if(dragged && this.parent){
205
+ const from = this.parent.indexOf(this.item)
206
+ const to = this.parent.indexOf(dragged.item)
207
+ this.parent.splice(to, 0, this.parent.splice(from, 1)[0]);
208
+ }
209
+
210
+ mouseUp(e)
211
+ }
212
+ }
213
+
214
+ window.addEventListener('mousemove', mouseMove)
215
+ window.addEventListener('mouseup', mouseUp)
216
+ window.addEventListener('keyup', keyUp)
217
+ },
218
+
219
+ },
220
+
221
+ props: {
222
+
223
+ config: Object,
224
+
225
+ index: {
226
+ type: Number,
227
+ default: 0
228
+ },
229
+
230
+ isLast: Boolean,
231
+
232
+ item: Object,
233
+
234
+ level: {
235
+ type: Number,
236
+ default: 0
237
+ },
238
+
239
+ useAdd: undefined,
240
+
241
+ parent: Array,
242
+
243
+ removable: {
244
+ type: Boolean,
245
+ default: true
246
+ },
247
+
248
+ size: {
249
+ type: Array,
250
+ default: [ 160, 60, 24 ]
251
+ },
252
+
253
+ hasChildren: {
254
+ type: Boolean,
255
+ default: true
256
+ }
257
+
258
+ }
259
+
260
+ }
261
+
262
+ </script>
263
+
264
+ <style module>
265
+
266
+ .isFallback{
267
+ @apply absolute bottom-0 left-0 right-0 h-[4px] bg-primary;
268
+ }
269
+
270
+ </style>
@@ -0,0 +1,152 @@
1
+ <template>
2
+ <Modal :state="state"
3
+ :hash="hash"
4
+ ref="modal"
5
+ :width="width"
6
+ :height="height">
7
+
8
+ <template v-slot:head>
9
+ <div class="relative p-6">
10
+ <h3 v-if="!instance.type">{{ $t('Select Type') }}</h3>
11
+ <h3 v-else>{{ $t(instance.text) }}</h3>
12
+ <div class="absolute top-0 right-0 p-2">
13
+ <button type="button" class="p-2" @click="close">
14
+ <svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
15
+ <path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
16
+ </svg>
17
+ </button>
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <template v-slot:foot>
23
+ <div v-if="instance.type" class="p-6 flex flex-row gap-4 items-end">
24
+ <div class="flex-1">
25
+ <Button class="w-[100px]" :state="canApply ? 1 : -1" @click="apply">
26
+ {{ $t('OK') }}
27
+ </Button>
28
+ </div>
29
+ <div class="flex flex-row gap-2 items-center">
30
+ <Switch v-model="instance.params.passthrough" />
31
+ <label>Passthrough</label>
32
+ </div>
33
+ </div>
34
+ </template>
35
+
36
+ <div class="flex-1">
37
+
38
+ <div v-if="!instance.type" class="flex-1">
39
+
40
+ <div class="flex flex-col divide-text-50 border-t-[1px] border-b-[1px] border-text-50">
41
+ <button v-for="output in outputs"
42
+ type="button"
43
+ class="p-3 px-6 text-left"
44
+ @click="Object.assign(instance, output)">
45
+ {{ output.text }}
46
+ </button>
47
+ </div>
48
+
49
+ </div>
50
+
51
+ <div v-else>
52
+ <component :is="componentName" :output="instance"></component>
53
+ </div>
54
+
55
+ </div>
56
+
57
+ </Modal>
58
+ </template>
59
+
60
+ <script>
61
+
62
+ import Modal from "../../components/Modal.vue"
63
+ import {capitalize} from "../../utils/helpers.mjs";
64
+ import {defineAsyncComponent} from "vue";
65
+
66
+ export default{
67
+
68
+ components: {
69
+ Modal,
70
+ UserActionOutputReply: defineAsyncComponent(() => import('./UserActionOutputReply.vue')),
71
+ },
72
+
73
+ computed: {
74
+
75
+ canApply(){
76
+ return this.instance?.type
77
+ },
78
+
79
+ componentName(){
80
+ return this.instance._component?.name ?
81
+ this.instance._component?.name :
82
+ `UserActionOutput${capitalize(this.instance?.type)}`
83
+ },
84
+
85
+ height(){
86
+ return this.instance?.type ? 480 : 300
87
+ },
88
+
89
+ width(){
90
+ return this.instance?.type ? 420 : 300
91
+ },
92
+
93
+ },
94
+
95
+ emits: [ 'apply' ],
96
+
97
+ inject: [ 'socketEmit2' ],
98
+
99
+ props: {
100
+ state: Boolean,
101
+ hash: String,
102
+
103
+ outputs: Array
104
+ },
105
+
106
+ data(){
107
+ return {
108
+ id: null,
109
+ instance: null,
110
+ }
111
+ },
112
+
113
+ methods: {
114
+
115
+ apply(){
116
+ this.close()
117
+ this.$emit('apply', this.instance, this.id)
118
+ },
119
+
120
+ create(){
121
+ this.instance = {
122
+ params: {
123
+ passthrough: true
124
+ }
125
+ }
126
+ this.id = null
127
+ this.$refs.modal.open()
128
+ },
129
+
130
+ open(instance, id){
131
+ this.instance = instance
132
+ this.id = id
133
+ this.$refs.modal.open()
134
+ },
135
+
136
+ close(){
137
+ this.$refs.modal.close()
138
+ }
139
+
140
+ }
141
+
142
+ }
143
+
144
+ </script>
145
+
146
+ <style module>
147
+
148
+ .comp{
149
+
150
+ }
151
+
152
+ </style>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <div class="p-5">
3
+ <label>Delay</label>
4
+ <div class="flex flex-row gap-2 mt-2">
5
+ <Textbox v-model.number="output.params.value" maxlength="4" />
6
+ <Dropdown v-model="output.params.unit">
7
+ <option value="second">Seconds</option>
8
+ <option value="minute">Minutes</option>
9
+ <option value="hour">Hour</option>
10
+ </Dropdown>
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+
17
+ export default{
18
+
19
+ props: {
20
+
21
+ output: Object
22
+
23
+ }
24
+
25
+ }
26
+
27
+ </script>
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <div class="p-5">
3
+ <label>Text</label>
4
+ <TextWithTag v-model="output.params.text" :items="tagItems" />
5
+ </div>
6
+ </template>
7
+
8
+ <script>
9
+
10
+ export default{
11
+
12
+ props: {
13
+
14
+ output: Object,
15
+
16
+ tagItems: {
17
+ type: Array,
18
+ default: () => ([
19
+ { text:'Name', value:'{message.inbox.name}' },
20
+ { text:'Text', value:'{message.body}' }
21
+ ])
22
+ }
23
+
24
+ }
25
+
26
+ }
27
+
28
+ </script>
@@ -0,0 +1,112 @@
1
+ <template>
2
+ <div class="p-6 pt-0 flex flex-col gap-5">
3
+
4
+ <div class="flex justify-center">
5
+ <Tabs :items="tabItems" v-model="output.params.type" />
6
+ </div>
7
+
8
+ <div v-if="output.params.type === 1">
9
+ <div>
10
+ <label class="text-text-400">Image</label>
11
+ <Image :src="output.params.imageUrl"
12
+ :editable="true"
13
+ @change="(base64, file) => output.params.imageUrl = file"
14
+ ref="image"
15
+ class="w-full min-h-[100px] border-[1px] border-text-200 bg-base-500 rounded-lg flex">
16
+ <template #empty>
17
+ <div class="flex-1 flex items-center justify-center">
18
+ <button type="button" @click="$refs.image.edit()">
19
+ <svg width="24" height="24" class="fill-text-300 hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M630.8 469.1l-55.95-43.85C575.3 422.2 575.1 419.2 575.1 416l.0034-320c0-35.35-28.65-64-64-64H127.1C113.6 32 100.4 36.98 89.78 45.06L38.81 5.113C28.34-3.058 13.31-1.246 5.109 9.192C-3.063 19.63-1.235 34.72 9.187 42.89L601.2 506.9C605.6 510.3 610.8 512 615.1 512c7.125 0 14.17-3.156 18.91-9.188C643.1 492.4 641.2 477.3 630.8 469.1zM223.1 149.6l-64.29-50.39C164.2 97.15 169.9 96 175.1 96c26.51 0 48 21.49 48 48C223.1 145.9 223.4 147.7 223.1 149.6zM331.2 234.3l23.45-35.18C357.7 194.7 362.7 192 368 192s10.35 2.672 13.31 7.125l103.9 155.9L331.2 234.3zM145.1 416c-6.021 0-11.53-3.379-14.26-8.75c-2.73-5.367-2.215-11.81 1.334-16.68l70-96C206.1 290.4 210.9 288 216 288s9.916 2.441 12.93 6.574l32.46 44.51l16.43-24.65L63.99 146.8L63.99 416c0 35.35 28.65 64 64 64h361.1l-81.66-64H145.1z"/></svg>
20
+ </button>
21
+ </div>
22
+ </template>
23
+ </Image>
24
+ </div>
25
+
26
+ <div>
27
+ <label class="text-text-400">Text</label>
28
+ <TextWithTag rows="5" v-model="output.params.text" :items="replyTextItems" />
29
+ </div>
30
+
31
+ <div>
32
+ <label class="text-text-400">Footer</label>
33
+ <Textbox v-model="output.params.footer" maxlength="50" />
34
+ </div>
35
+
36
+ <div>
37
+ <div class="flex flex-row gap-2 items-center">
38
+ <label class="flex-1 text-text-400">Buttons</label>
39
+ <button type="button" class="text-primary" @click="$array(output.params, 'buttons').push({})">
40
+ {{ $t('Add Button') }}
41
+ </button>
42
+ </div>
43
+ <ListItem :items="output.params.buttons"
44
+ @reorder="(from, to) => { output.params.buttons.splice(to, 0, output.params.buttons.splice(from, 1)[0]); }">
45
+ <template v-slot="{ item, index }">
46
+ <div class="flex flex-row items-center gap-3">
47
+ <div data-reorder>
48
+ <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496 288H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-128H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z"/></svg>
49
+ </div>
50
+ <div class="flex-1 flex flex-row gap-2 items-center">
51
+ <Textbox class="w-[100px]" placeholder="Text" v-model="item.text" />
52
+ </div>
53
+ <div>
54
+ <button type="button" @click="output.params.buttons.splice(index, 1)">
55
+ <svg width="16" height="16" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
56
+ </button>
57
+ </div>
58
+ </div>
59
+ </template>
60
+ </ListItem>
61
+ </div>
62
+ </div>
63
+
64
+ <div v-else>
65
+
66
+ <div>
67
+ <label class="text-text-400">Template</label>
68
+ <Dropdown v-model="output.params.value">
69
+ <option value="hello_world">hello_world</option>
70
+ <option value="welcome1">welcome1</option>
71
+ <option value="select_beverages">select_beverages</option>
72
+ <option value="test7">test7</option>
73
+ </Dropdown>
74
+ </div>
75
+
76
+ </div>
77
+
78
+ </div>
79
+ </template>
80
+
81
+ <script>
82
+
83
+ export default{
84
+
85
+ computed: {
86
+
87
+ replyTextItems(){
88
+ return [
89
+ { text:"Mobile Number", value:"{mobileNumber}" },
90
+ { text:"Name", value:"{name}" },
91
+ { text:"Created At", value:"{createdAt}" },
92
+ ]
93
+ },
94
+
95
+ tabItems(){
96
+ return [
97
+ { text:"Text", value:1 },
98
+ { text:"Template", value:2 },
99
+ ]
100
+ }
101
+
102
+ },
103
+
104
+ props: {
105
+
106
+ output: Object
107
+
108
+ }
109
+
110
+ }
111
+
112
+ </script>
@@ -0,0 +1,211 @@
1
+ <template>
2
+ <div v-if="instance" class="p-6 flex flex-col gap-6" @dblclick="log(instance)">
3
+
4
+ <div class="flex flex-row gap-5">
5
+ <div class="flex-1">
6
+ <label>Name</label>
7
+ <Textbox v-model="instance.name" class="mt-2"/>
8
+ </div>
9
+ <div>
10
+ <label>Enabled</label>
11
+ <Switch v-model="instance.enabled" class="mt-2"/>
12
+ </div>
13
+ </div>
14
+
15
+ <div>
16
+ <label>Type</label>
17
+ <div class="flex flex-row gap-3 mt-2">
18
+ <Dropdown v-model.number="instance.type" class="w-full">
19
+ <option :value="1">Event</option>
20
+ <option :value="2">Time Based</option>
21
+ <option :value="3">Fallback</option>
22
+ </Dropdown>
23
+ </div>
24
+ </div>
25
+
26
+ <div>
27
+ <label>Event</label>
28
+ <div class="flex flex-row gap-3 mt-2">
29
+ <Dropdown v-model.number="instance.key" class="w-full">
30
+ <option value="onNewMessage">On New Message</option>
31
+ </Dropdown>
32
+ </div>
33
+ </div>
34
+
35
+ <div v-if="instance.type === 1" class="flex flex-col gap-6">
36
+
37
+ <div>
38
+ <div class="flex flex-row items-center gap-2">
39
+ <label class="flex-1">Condition</label>
40
+ <button type="button" class="text-primary"
41
+ @click="$refs.userActionCondition.open({}, addCondition)">
42
+ Add Condition
43
+ </button>
44
+ </div>
45
+ <ListItem :items="instance.conditions"
46
+ class="mt-2 bg-transparent"
47
+ container-class="flex flex-col gap-2"
48
+ @reorder="(from, to) => { instance.conditions.splice(to, 0, instance.conditions.splice(from, 1)[0]); }">
49
+ <template v-slot="{ item, index }">
50
+ <div class="flex flex-row items-center gap-2 px-3 bg-base-500 p-2">
51
+ <div data-reorder>
52
+ <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496 288H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-128H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z"/></svg>
53
+ </div>
54
+
55
+ <div class="flex-1 flex flex-row gap-2" @click="$refs.userActionCondition.open(item, _ => Object.assign(item, _))">
56
+ {{ item }}
57
+ </div>
58
+
59
+ <div>
60
+ <button type="button" @click="instance.conditions.splice(index, 1)">
61
+ <svg width="16" height="16" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
62
+ </button>
63
+ </div>
64
+ </div>
65
+ </template>
66
+
67
+ <template #empty>
68
+ <div class="flex justify-center p-2 bg-base-300 rounded-xl border-[1px] rounded-xl border-text-200">
69
+ <p class="text-text-400">{{ $t('All conditions') }}</p>
70
+ </div>
71
+ </template>
72
+ </ListItem>
73
+ </div>
74
+
75
+ </div>
76
+
77
+ <div>
78
+ <div class="flex flex-row items-center gap-2">
79
+ <label class="flex-1">Output</label>
80
+ <button type="button" class="text-primary" @click="$refs.userActionOutput.create()">Add Output</button>
81
+ </div>
82
+ <ListItem :items="instance.outputs"
83
+ class="mt-2 border-[1px] rounded-xl border-text-200"
84
+ container-class="divide-y divide-text-200"
85
+ @reorder="(from, to) => { instance.outputs.splice(to, 0, instance.outputs.splice(from, 1)[0]); }">
86
+ <template v-slot="{ item, index }">
87
+ <div class="flex flex-row items-center gap-3 px-3">
88
+ <div data-reorder>
89
+ <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496 288H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-128H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z"/></svg>
90
+ </div>
91
+ <div class="flex-1 p-2 flex flex-row items-center gap-2" @click="$refs.userActionOutput.open(item, index)">
92
+ <p>{{ item.text }}</p>
93
+ <p class="flex-1 text-text-300 text-ellipsis whitespace-nowrap overflow-hidden"></p>
94
+ </div>
95
+ <button type="button" @click="instance.outputs.splice(index, 1)">
96
+ <svg width="16" height="16" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
97
+ </button>
98
+ </div>
99
+ </template>
100
+
101
+ <template #empty>
102
+ <div class="flex justify-center p-2 bg-base-300 rounded-xl">
103
+ <p class="text-text-400">{{ $t('No actions') }}</p>
104
+ </div>
105
+ </template>
106
+ </ListItem>
107
+
108
+ <UserActionOutput ref="userActionOutput"
109
+ :outputs="outputs"
110
+ @apply="(instance, index) => addOutput(instance, index)" />
111
+
112
+ <UserActionCondition ref="userActionCondition" />
113
+ </div>
114
+
115
+ </div>
116
+ </template>
117
+
118
+ <script>
119
+
120
+ import UserActionOutput from "./UserActionOutput.vue";
121
+ import UserActionCondition from "./UserActionCondition.vue";
122
+
123
+ export default{
124
+
125
+ components: {UserActionCondition, UserActionOutput},
126
+
127
+ computed: {
128
+
129
+ conditions(){
130
+ return (this.eventOpt[this.instance.event]?.conditions ?? [])
131
+ .reduce((acc, cur) => {
132
+ acc[cur.key] = cur
133
+ return acc
134
+ }, {})
135
+ },
136
+
137
+ outputs(){
138
+ return [
139
+ { type: "log", text:"Log" },
140
+ { type: "reply", text:"Reply" },
141
+ { type: "delay", text:"Delay" },
142
+ { type: "reset", text:"Reset" },
143
+ { type: "endChat", text:"End Chat" },
144
+ { type: "startChat", text:"Start Chat" },
145
+ { type: "endConversation", text:"End Conversation" },
146
+ ]
147
+ return this.eventOpt[this.instance.key]?.outputs ?? []
148
+ },
149
+
150
+ },
151
+
152
+ data(){
153
+ return {
154
+ }
155
+ },
156
+
157
+ methods: {
158
+
159
+ addCondition(condition){
160
+ this.$util.push(this.instance.conditions, condition)
161
+ },
162
+
163
+ addOutput(output, idx){
164
+ if(!this.instance) return
165
+
166
+ if(!Array.isArray(this.instance.outputs))
167
+ this.instance.outputs = []
168
+
169
+ typeof idx === 'number' ?
170
+ Object.assign(this.instance.outputs[idx], output) :
171
+ this.instance.outputs.push(output)
172
+ },
173
+
174
+ },
175
+
176
+ props: {
177
+ instance: Object,
178
+
179
+ eventOpt: {
180
+ type: Object,
181
+ default: () => ({
182
+
183
+ 'onNewMessage': {
184
+ text: 'On message create',
185
+ conditions: [
186
+ { key:"{message.body}", text:"Text", type:"string", operators:[ [ 'contains', 'Contains' ], [ 'startsWith', 'Starts With' ] ] },
187
+ { key:"{message.direction}", text:"Direction", type:"enum", enum:[ [ 1, 'In' ], [ 2, 'Out' ] ] },
188
+ { key:"{message.channelId}", text:"Channel", type:"enum", enum:[ [ 1, 'Whatsapp' ] ] },
189
+ { key:"{message.inbox.mobileNumber}", text:"Mobile Number" }
190
+ ],
191
+ outputs: [
192
+ { type: "log", text:"Log" },
193
+ { type: "reply", text:"Reply" },
194
+ { type: "delay", text:"Delay" },
195
+ ]
196
+ }
197
+
198
+ })
199
+ },
200
+ }
201
+ }
202
+
203
+ </script>
204
+
205
+ <style module>
206
+
207
+ .comp{
208
+
209
+ }
210
+
211
+ </style>
@@ -0,0 +1,314 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ <div :class="$style.leftPane"
5
+ :style="leftStyle">
6
+ <div :class="$style.leftBoundary" @mousedown="(e) => $util.dragResize(e, resize1)"></div>
7
+
8
+ <div class="flex-1 flex flex-col gap-5 p-5">
9
+
10
+ <div class="flex flex-row items-center gap-2">
11
+ <div class="flex-1">
12
+ <h5>User</h5>
13
+ </div>
14
+ <button type="button" @click="create">
15
+ <svg width="21" height="21" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/></svg>
16
+ </button>
17
+ </div>
18
+
19
+ <div class="flex-1 flex flex-col">
20
+ <label class="text-text-300">Actions</label>
21
+ <VirtualGrid :items="items" class="flex-1 rounded-xl" container-class="divide-y divide-text-50">
22
+ <template #item="{ item }">
23
+ <div class="p-3 hover:bg-base-500 flex flex-row"
24
+ :class="item.uid === actionUid ? 'bg-base-500' : 'bg-base-400'"
25
+ @click="$emit('select', item.uid)">
26
+ <label class="flex-1 text-ellipsis overflow-hidden whitespace-nowrap">{{ item.name }}</label>
27
+ <button type="button" @click="$emit('remove', item )">
28
+ <svg width="14" height="14" class="fill-text-300 hover:fill-red-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg>
29
+ </button>
30
+ </div>
31
+ </template>
32
+ </VirtualGrid>
33
+ </div>
34
+ </div>
35
+
36
+ </div>
37
+
38
+ <div v-if="actionUid" class="flex-1 flex flex-col">
39
+
40
+ <div class="flex-1 flex flex-row">
41
+ <div class="flex-1 flex flex-col">
42
+
43
+ <div class="p-2 flex flex-row items-center panel-400 border-b-[1px] border-text-50">
44
+ <h5 class="pl-3">{{ item?.name }}</h5>
45
+ <div class="flex-1"></div>
46
+ <div>
47
+ <Button class="px-6 rounded-full" @click="save">Save</Button>
48
+ </div>
49
+ </div>
50
+
51
+ <div class="flex-1 overflow-auto">
52
+ <div class="p-12" v-if="item">
53
+ <UserActionItem :config="config"
54
+ :item="item"
55
+ :removable="false"
56
+ @select="select" />
57
+ </div>
58
+ </div>
59
+
60
+ <div class="p-5" v-if="item && item.type === 1 && item.key === 'onNewMessage'">
61
+ <UserActionConsole ref="console"
62
+ @test-message="testMessage"
63
+ @test-reset="$emit('test-reset')" />
64
+ </div>
65
+
66
+ </div>
67
+
68
+ <div :class="$style.rightPane" :style="rightStyle">
69
+ <div :class="$style.rightBoundary" @mousedown="(e) => $util.dragResize(e, resize2)"></div>
70
+
71
+ <UserActionProps ref="userActionProps" :instance="selectedItem" />
72
+
73
+ </div>
74
+ </div>
75
+
76
+ </div>
77
+
78
+ <div v-else class="flex-1 flex flex-col items-center justify-center">
79
+ <strong>No action selected</strong>
80
+ <p>Please select action from left panel</p>
81
+ </div>
82
+
83
+ </div>
84
+ </template>
85
+
86
+ <script>
87
+
88
+ import UserActionItem from './UserActionBuilder/UserActionItem.vue'
89
+ import UserActionOutput from './UserActionBuilder/UserActionOutput.vue'
90
+ import VirtualGrid from '../components/VirtualGrid.vue'
91
+ import UserActionConsole from "./UserActionBuilder/UserActionConsole.vue";
92
+ import UserActionProps from "./UserActionBuilder/UserActionProps.vue";
93
+
94
+ export default{
95
+
96
+ components: {
97
+ UserActionProps,
98
+ UserActionConsole,
99
+ UserActionOutput,
100
+ UserActionItem,
101
+ VirtualGrid
102
+ },
103
+
104
+ computed: {
105
+
106
+ canIsFallback(){
107
+ return true
108
+ },
109
+
110
+ cConfig(){
111
+ return this.config ?? this._config
112
+ },
113
+
114
+ leftBar() {
115
+ if (!this.cConfig.leftBar) {
116
+ this.cConfig.leftBar = {
117
+ width: 240
118
+ }
119
+ }
120
+
121
+ return this.cConfig.leftBar
122
+ },
123
+
124
+ leftStyle() {
125
+ return {
126
+ width: this.leftBar.width + 'px'
127
+ }
128
+ },
129
+
130
+ rightBar() {
131
+ if (!this.cConfig.rightBar) {
132
+ this.cConfig.rightBar = {
133
+ width: 240
134
+ }
135
+ }
136
+
137
+ return this.cConfig.rightBar
138
+ },
139
+
140
+ rightStyle() {
141
+ return {
142
+ width: this.rightBar.width + 'px'
143
+ }
144
+ },
145
+
146
+ selectedItem(){
147
+ if (!this.config.selectedUid) return
148
+ if (!this.item) return
149
+
150
+ const findComponents = (items, uid) => {
151
+ for (let item of items) {
152
+ if (item.uid === uid)
153
+ return item
154
+
155
+ if (item.items) {
156
+ const component = findComponents(item.items, uid)
157
+ if (component)
158
+ return component
159
+ }
160
+ }
161
+ }
162
+
163
+ if(this.item.uid === this.config.selectedUid)
164
+ return this.item
165
+ return findComponents(this.item.items ?? [], this.config.selectedUid)
166
+ },
167
+
168
+ },
169
+
170
+ data(){
171
+ return {
172
+ _config: {},
173
+ items: null,
174
+ item: null,
175
+ }
176
+ },
177
+
178
+ emits: [ 'remove', 'select', 'test-message', 'test-reset' ],
179
+
180
+ inject: [ 'alert', 'confirm', 'socket', 'toast' ],
181
+
182
+ methods: {
183
+
184
+ create(){
185
+ this.socket.send(`${this.src}.create`, {})
186
+ .then(_ => {
187
+ this.$emit('select', _.uid)
188
+ })
189
+ .catch(err => this.alert(err))
190
+ },
191
+
192
+ load(){
193
+ this.socket.send(`${this.src}.load`, { uid: this.uid })
194
+ .then(({ items }) => {
195
+ this.items = items
196
+ })
197
+ .catch(err => this.toast(err))
198
+ },
199
+
200
+ open(item){
201
+ this.socket.send(`${this.src}.open`, { uid: item.uid })
202
+ .then(({ item }) => {
203
+ this.item = item
204
+ })
205
+ .catch(err => this.toast(err))
206
+ },
207
+
208
+ addTestMessage(message){
209
+ this.$refs.console.addMessage(message)
210
+ },
211
+
212
+ testMessage(message){
213
+ this.$emit('test-message', {
214
+ message,
215
+ action: this.item
216
+ })
217
+ },
218
+
219
+ resize1(w) {
220
+ const nextWidth = this.leftBar.width + w
221
+ if (nextWidth >= 200 && nextWidth <= 480) {
222
+ this.leftBar.width += w
223
+ }
224
+ },
225
+
226
+ resize2(w) {
227
+ const nextWidth = this.rightBar.width - w
228
+ if (nextWidth >= 240 && nextWidth <= 480) {
229
+ this.rightBar.width -= w
230
+ }
231
+ },
232
+
233
+ save(){
234
+ this.socket.send(`${this.src}.save`, { userId:this.uid, item:this.item })
235
+ .then(_ => this.toast('Saved'))
236
+ .catch(err => this.alert(err))
237
+ },
238
+
239
+ select(item){
240
+ this.config.selectedUid = item.uid
241
+ }
242
+
243
+ },
244
+
245
+ mounted() {
246
+ this.load()
247
+ },
248
+
249
+ props: {
250
+
251
+ actionUid: String,
252
+
253
+ config: Object,
254
+
255
+ timeOpt: {
256
+ type: Object
257
+ },
258
+
259
+ src: [ String ],
260
+
261
+ uid: String,
262
+
263
+ },
264
+
265
+ watch: {
266
+
267
+ actionUid: {
268
+ immediate: true,
269
+ handler(to){
270
+ if(to){
271
+ this.open({ uid: to })
272
+ }
273
+ }
274
+ }
275
+
276
+ }
277
+
278
+ }
279
+
280
+ </script>
281
+
282
+ <style module>
283
+
284
+ .comp{
285
+ @apply flex flex-row;
286
+ }
287
+
288
+ .leftPane{
289
+ @apply relative overflow-y-auto;
290
+ @apply flex flex-col panel-400;
291
+ }
292
+
293
+ .leftBoundary {
294
+ @apply absolute top-0 right-0 bottom-0 w-[3px] border-r-[1px] border-text-50 cursor-e-resize;
295
+ }
296
+
297
+ .contentPane{
298
+ @apply flex-1 flex flex-row;
299
+ }
300
+
301
+ .treePane{
302
+ @apply flex-1;
303
+ }
304
+
305
+ .rightPane {
306
+ @apply relative overflow-y-auto panel-400;
307
+
308
+ }
309
+
310
+ .rightBoundary {
311
+ @apply absolute top-0 left-0 bottom-0 w-[3px] border-l-[1px] border-text-50 cursor-w-resize;
312
+ }
313
+
314
+ </style>