@mixd-id/web-scaffold 0.1.230406365 → 0.1.230406367

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.230406365",
4
+ "version": "0.1.230406367",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -169,21 +169,14 @@ export default{
169
169
 
170
170
  .button-primary {
171
171
  @apply bg-primary-500 text-white rounded-lg;
172
+ @apply hover:bg-primary-600 focus:border-primary-300;
172
173
  box-shadow: 0 2px 1px rgba(0, 0, 0, .05);
173
174
  border: solid 1px rgb(var(--primary-500));
174
175
  }
175
176
 
176
- .button-primary:focus {
177
- border-color: rgb(var(--primary-600));
178
- }
179
-
180
- .button-primary:hover {
181
- @apply bg-primary-600;
182
- }
183
-
184
177
  .button-primary-disabled,
185
178
  .button-primary-disabled:hover {
186
- @apply bg-primary-300 top-0 left-0 cursor-not-allowed text-opacity-50;
179
+ @apply bg-primary-300 border-primary-300 top-0 left-0 cursor-not-allowed text-opacity-50;
187
180
  @apply top-0 left-0;
188
181
  }
189
182
 
@@ -0,0 +1,9 @@
1
+ export const component = {
2
+
3
+ type:"DataTable",
4
+
5
+ props:{
6
+ height:[ "h-[50vh]", "md:h-[50vh]", "", "" ]
7
+ }
8
+
9
+ }
package/src/index.js CHANGED
@@ -679,6 +679,7 @@ export default{
679
679
  app.component('PolarArea', defineAsyncComponent(() => import("./widgets/Dashboard/PolarArea.vue")))
680
680
  app.component('Metric', defineAsyncComponent(() => import("./widgets/Dashboard/Metric.vue")))
681
681
  app.component('BarChart', defineAsyncComponent(() => import("./widgets/Dashboard/BarChart.vue")))
682
+ app.component('DataTable', defineAsyncComponent(() => import("./widgets/Dashboard/DataTable.vue")))
682
683
 
683
684
  app.component('BotEditor', defineAsyncComponent(() => import("./widgets/BotEditor.vue")))
684
685
  }
@@ -85,6 +85,7 @@ const getDatasourceItems = async (datasource, opt) => {
85
85
  }
86
86
 
87
87
  const getSequelizeColumns = async (columns, opt) => {
88
+ if(!columns) columns = []
88
89
 
89
90
  const { DataTypes } = opt.Sequelize
90
91
 
package/src/utils/wss.js CHANGED
@@ -245,6 +245,12 @@ class WSS extends EventEmitter2{
245
245
 
246
246
  if(this._retryCount > 10){
247
247
  socket.close(1002, 'ping timeout')
248
+ if(subscriber){
249
+ subscriber.disconnect()
250
+ }
251
+ else{
252
+ console.log('CLOSE SOCKET#2', token.substring(0, 10) + '...')
253
+ }
248
254
  }
249
255
  }
250
256
  else{
@@ -112,6 +112,7 @@ export default{
112
112
  this.socket.send(`${this.controller}.open-action`, { uid })
113
113
  .then(_ => {
114
114
  this.action = _.item
115
+ this.config.selectedUid = this.action.uid
115
116
  this.initialAction = JSON.stringify(this.action)
116
117
  })
117
118
  },
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+
9
+ export default{
10
+
11
+ }
12
+
13
+ </script>
14
+
15
+ <style module>
16
+
17
+ .comp{
18
+ @apply p-6;
19
+ }
20
+
21
+ </style>
@@ -59,8 +59,7 @@
59
59
 
60
60
  <UserActionConsole class="flex-1"
61
61
  ref="console"
62
- @test-message="testMessage"
63
- @test-reset="testReset" />
62
+ :controller="controller" />
64
63
 
65
64
  </div>
66
65
 
@@ -85,6 +84,7 @@ import {capitalize} from "../utils/helpers.mjs";
85
84
  import BotEditorActions from "./BotEditor/BotEditorActions.vue";
86
85
  import VirtualGrid from "../components/VirtualGrid.vue";
87
86
  import UserActionConsole from "./UserActionBuilder/UserActionConsole.vue";
87
+ import BotEditorSettings from "./BotEditor/BotEditorSettings.vue";
88
88
 
89
89
 
90
90
  export default{
@@ -93,6 +93,7 @@ export default{
93
93
  UserActionConsole,
94
94
  VirtualGrid,
95
95
  BotEditorActions,
96
+ BotEditorSettings,
96
97
  },
97
98
 
98
99
  inject: [ 'alert', 'confirm', 'socket', 'toast' ],
@@ -140,12 +141,17 @@ export default{
140
141
  data(){
141
142
  return {
142
143
  actions: null,
144
+ user: null,
143
145
  page: '',
144
146
  }
145
147
  },
146
148
 
147
149
  methods: {
148
150
 
151
+ getUser(){
152
+ return this.user
153
+ },
154
+
149
155
  load(){
150
156
 
151
157
  },
@@ -157,6 +163,13 @@ export default{
157
163
  })
158
164
  },
159
165
 
166
+ open(id){
167
+ this.socket.send(`${this.controller}.open`, { id })
168
+ .then(res => {
169
+ this.user = res.user
170
+ })
171
+ },
172
+
160
173
  resize1(w) {
161
174
  if (this.sidebar.width + w >= 200 && this.sidebar.width + w <= 600) {
162
175
  this.sidebar.width += w
@@ -169,14 +182,6 @@ export default{
169
182
  }
170
183
  },
171
184
 
172
- testMessage(){
173
-
174
- },
175
-
176
- testReset(){
177
-
178
- },
179
-
180
185
  },
181
186
 
182
187
  props: {
@@ -186,6 +191,14 @@ export default{
186
191
 
187
192
  controller: String,
188
193
 
194
+ id: String,
195
+
196
+ },
197
+
198
+ provide(){
199
+ return {
200
+ getUser: this.getUser
201
+ }
189
202
  },
190
203
 
191
204
  watch: {
@@ -197,6 +210,13 @@ export default{
197
210
  }
198
211
  },
199
212
 
213
+ id: {
214
+ immediate: true,
215
+ handler(to){
216
+ this.open(to)
217
+ }
218
+ },
219
+
200
220
  page: {
201
221
  immediate: true,
202
222
  handler(to){
@@ -222,7 +242,7 @@ export default{
222
242
  }
223
243
 
224
244
  .resize2 {
225
- @apply h-[3px] cursor-n-resize absolute top-0 right-0 left-0 bg-red-500;
245
+ @apply h-[3px] cursor-n-resize absolute top-0 right-0 left-0 z-50;
226
246
  }
227
247
 
228
248
  </style>
@@ -74,7 +74,7 @@ import {Bar} from 'vue-chartjs'
74
74
  import Chart from 'chart.js/auto'
75
75
  import { color } from 'chart.js/helpers'
76
76
  import {strVars} from "../../utils/helpers.mjs";
77
- import {readyStateMixin} from "../../mixin/ready-state";
77
+ import {useEmitter} from "../../utils/event-bus";
78
78
 
79
79
  export default{
80
80
 
@@ -225,14 +225,43 @@ export default{
225
225
  ],
226
226
 
227
227
  height: '',
228
- datasets: null
228
+ datasets: null,
229
+ readyState: 1,
230
+ value: null
229
231
  }
230
232
  },
231
233
 
232
- inject: [ 'selectPreset' ],
234
+ inject: [ 'getSrc', 'getViewedPreset', 'getQueryFilters', 'selectPreset', 'socket' ],
233
235
 
234
236
  methods: {
235
237
 
238
+ load(){
239
+ const preset = this.getViewedPreset()
240
+ const {name, datasource} = preset
241
+
242
+ this.readyState = 2
243
+ this.socket.send(this.getSrc(), {
244
+ name,
245
+ views: [{
246
+ ...this.$props,
247
+ type: 'BarChart'
248
+ }],
249
+ datasource: datasource.map(_datasource => {
250
+ return {
251
+ ..._datasource,
252
+ filters: [
253
+ ...(_datasource.filters ?? []),
254
+ ...(this.getQueryFilters()[_datasource.uid] ?? [])
255
+ ]
256
+ }
257
+ })
258
+ })
259
+ .then(_ => {
260
+ this.value = _[this.uid]
261
+ })
262
+ .finally(_ => this.readyState = 1)
263
+ },
264
+
236
265
  onClick(e, segments){
237
266
 
238
267
  const clickInteractions = (this.interactions ?? []).filter(_ => _.event === 'click')
@@ -276,9 +305,17 @@ export default{
276
305
 
277
306
  mounted() {
278
307
  this.height = this.$el.clientHeight + 'px'
279
- },
280
308
 
281
- mixins: [ readyStateMixin ],
309
+ this.load()
310
+
311
+ this.emitter = useEmitter()
312
+ this.emitter.on(`${this.uid}.load`, () => {
313
+ this.load()
314
+ })
315
+ this.emitter.on(`dashboard.load`, () => {
316
+ this.load()
317
+ })
318
+ },
282
319
 
283
320
  props: {
284
321
 
@@ -309,8 +346,6 @@ export default{
309
346
 
310
347
  yAxeOnClick: Array,
311
348
 
312
- value: Object,
313
-
314
349
  interactions: Array,
315
350
 
316
351
  uid: String
@@ -0,0 +1,125 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <VirtualTable class="flex-1"
4
+ :columns="datasourceColumns"
5
+ @scroll-end="loadNext"
6
+ :items="items">
7
+
8
+ </VirtualTable>
9
+ </div>
10
+ </template>
11
+
12
+ <script>
13
+ import {useEmitter} from "../../utils/event-bus";
14
+ import VirtualTable from "../../components/VirtualTable.vue";
15
+
16
+ export default{
17
+ components: {VirtualTable},
18
+
19
+ data(){
20
+ return {
21
+ value: null,
22
+ readyState: 1,
23
+ items: null,
24
+ hasNext: false
25
+ }
26
+ },
27
+
28
+ inject: [ 'getSrc', 'getViewedPreset', 'getQueryFilters', 'socket' ],
29
+
30
+ methods: {
31
+
32
+ load(){
33
+ const preset = this.getViewedPreset()
34
+ const {name, datasource} = preset
35
+
36
+ this.readyState = 2
37
+ this.socket.send(this.getSrc(), {
38
+ name,
39
+ views: [{
40
+ ...this.$props,
41
+ type: 'DataTable'
42
+ }],
43
+ datasource: datasource.map(_datasource => {
44
+ return {
45
+ ..._datasource,
46
+ filters: [
47
+ ...(_datasource.filters ?? []),
48
+ ...(this.getQueryFilters()[_datasource.uid] ?? [])
49
+ ]
50
+ }
51
+ })
52
+ })
53
+ .then(_ => {
54
+ const { items, hasNext } = _[this.uid] ?? {}
55
+ this.items = items
56
+ this.hasNext = hasNext
57
+ })
58
+ .finally(_ => this.readyState = 1)
59
+ },
60
+
61
+ loadNext(){
62
+ if(!this.hasNext) return
63
+
64
+ const preset = this.getViewedPreset()
65
+ const {name, datasource} = preset
66
+ const afterItem = this.items[this.items.length - 1]
67
+
68
+ this.socket.send(this.getSrc(), {
69
+ name,
70
+ views: [{
71
+ ...this.$props,
72
+ type: 'DataTable',
73
+ afterItem
74
+ }],
75
+ datasource: datasource.map(_datasource => {
76
+ return {
77
+ ..._datasource,
78
+ filters: [
79
+ ...(_datasource.filters ?? []),
80
+ ...(this.getQueryFilters()[_datasource.uid] ?? [])
81
+ ]
82
+ }
83
+ })
84
+ })
85
+ .then(_ => {
86
+ const { items, hasNext } = _[this.uid] ?? {}
87
+ this.items.push(...items)
88
+ this.hasNext = hasNext
89
+ })
90
+ }
91
+
92
+ },
93
+
94
+ mounted() {
95
+ this.load()
96
+
97
+ this.emitter = useEmitter()
98
+ this.emitter.on(`${this.uid}.load`, () => {
99
+ this.load()
100
+ })
101
+ this.emitter.on(`dashboard.load`, () => {
102
+ this.load()
103
+ })
104
+ },
105
+
106
+ props: {
107
+
108
+ datasourceColumns: Array,
109
+ datasourceUid: String,
110
+ label: String,
111
+ uid: String,
112
+
113
+ }
114
+
115
+ }
116
+
117
+ </script>
118
+
119
+ <style module>
120
+
121
+ .comp{
122
+ @apply min-h-[50vh] flex flex-col;
123
+ }
124
+
125
+ </style>
@@ -0,0 +1,239 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ <div class="flex justify-center border-b-[1px] border-text-50" v-if="tabItems.length > 1">
5
+ <Tabs :items="tabItems" v-model="value.tabIndex" />
6
+ </div>
7
+
8
+ <div class="flex-1 overflow-y-auto flex flex-col">
9
+ <div v-if="value.tabIndex === 1" class="flex-1 flex flex-col gap-5 p-6">
10
+
11
+ <div class="flex flex-row items-center ">
12
+ <label class="flex-1">Active</label>
13
+ <Switch v-model="value.props.enabled" :readonly="readonly" />
14
+ </div>
15
+
16
+ <div class="flex flex-col gap-1">
17
+ <label class="text-text-400">Label</label>
18
+ <Textbox v-model="value.props.label" maxlength="50" placeholder="Label" :readonly="readonly" />
19
+ </div>
20
+
21
+ <div class="flex flex-row items-center">
22
+ <label class="flex-1">Datasource</label>
23
+ <div>
24
+ <Dropdown class="min-w-[150px]"
25
+ :readonly="readonly"
26
+ v-model="value.props.datasourceUid">
27
+ <option v-for="_datasource in datasource"
28
+ :value="_datasource.uid">
29
+ {{ _datasource.name }}
30
+ </option>
31
+ </Dropdown>
32
+ </div>
33
+ </div>
34
+
35
+ </div>
36
+
37
+ <div v-else-if="value.tabIndex === 2" class="flex-1 flex flex-col gap-5 p-6">
38
+
39
+ <div>
40
+ <Textbox placeholder="Search..." v-model="search">
41
+ <template #start>
42
+ <div class="pl-3">
43
+ <svg width="14" height="14" class="fill-text-300" 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="M500.3 443.7l-119.7-119.7c27.22-40.41 40.65-90.9 33.46-144.7C401.8 87.79 326.8 13.32 235.2 1.723C99.01-15.51-15.51 99.01 1.724 235.2c11.6 91.64 86.08 166.7 177.6 178.9c53.8 7.189 104.3-6.236 144.7-33.46l119.7 119.7c15.62 15.62 40.95 15.62 56.57 0C515.9 484.7 515.9 459.3 500.3 443.7zM79.1 208c0-70.58 57.42-128 128-128s128 57.42 128 128c0 70.58-57.42 128-128 128S79.1 278.6 79.1 208z"/></svg>
44
+ </div>
45
+ </template>
46
+ </Textbox>
47
+ </div>
48
+
49
+ <VirtualGrid class="flex-1 border-[1px] border-text-50 rounded-xl"
50
+ container-class="divide-y divide-text-50"
51
+ :items="columns">
52
+ <template #item="{ item }">
53
+ <div class="flex-1 flex flex-row gap-2 items-center p-1 px-3 group">
54
+ <div>
55
+ <Checkbox v-model="item.visible"
56
+ default="true"
57
+ :disabled="readonly"
58
+ @change="$emit('change')" />
59
+ </div>
60
+ <Textbox v-model="item.label2" :placeholder="item.label" :readonly="readonly"
61
+ class="flex-1 border-none bg-transparent" :class="$style.columnTextbox"
62
+ item-class="p-1 px-0" />
63
+ <div class="hidden flex-col justify-center group-hover:flex">
64
+ <button type="button" @click="moveUp(item)">
65
+ <svg width="11" height="11" class="fill-text-300 hover:fill-primary" 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="M9.39 265.4l127.1-128C143.6 131.1 151.8 128 160 128s16.38 3.125 22.63 9.375l127.1 128c9.156 9.156 11.9 22.91 6.943 34.88S300.9 320 287.1 320H32.01c-12.94 0-24.62-7.781-29.58-19.75S.2333 274.5 9.39 265.4z"/></svg>
66
+ </button>
67
+ <button type="button" @click="moveDown(item)">
68
+ <svg width="11" height="11" class="fill-text-300 hover:fill-primary" 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 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"/></svg>
69
+ </button>
70
+ </div>
71
+ </div>
72
+ </template>
73
+ </VirtualGrid>
74
+
75
+ </div>
76
+ </div>
77
+
78
+ </div>
79
+ </template>
80
+
81
+ <script>
82
+
83
+ import WebPagePropertySelector from "../WebPageBuilder4/WebPagePropertySelector.vue";
84
+ import {defineAsyncComponent} from "vue";
85
+ import InteractionEdit from "./InteractionEdit.vue";
86
+
87
+ export default{
88
+ components: {
89
+ InteractionEdit,
90
+ HeightSetting: defineAsyncComponent(() => import('../WebPageBuilder4/HeightSetting.vue')),
91
+ WebPagePropertySelector
92
+ },
93
+
94
+ computed: {
95
+
96
+ interactions(){
97
+ if(!Array.isArray(this.value.props.interactions))
98
+ this.value.props.interactions = []
99
+ return this.value.props.interactions
100
+ },
101
+
102
+ selectedDatasource(){
103
+ return this.datasource.find(d => d.uid === this.value.props.datasourceUid)
104
+ },
105
+
106
+ definedProperties(){
107
+ const settings = []
108
+
109
+ for(let key in this.properties){
110
+ if(key in this.value.props){
111
+ settings.push(this.properties[key])
112
+ }
113
+ }
114
+
115
+ return settings
116
+ },
117
+
118
+ tabItems(){
119
+ return [
120
+ { text:'General', value:1 },
121
+ this.value.props.datasourceUid ? { text:'Columns', value:2 } : null,
122
+ ]
123
+ .filter(_ => _)
124
+ },
125
+
126
+ columns(){
127
+ const searches = this.search.toLowerCase().split(' ').filter(_ => _.length > 2)
128
+ return (this.value.props.datasourceColumns ?? []).filter(_ => {
129
+ return !_.key.startsWith('_') &&
130
+ (searches.length < 1 || searches.every(search => _.label.toLowerCase().includes(search)))
131
+ })
132
+ },
133
+
134
+ },
135
+
136
+ data(){
137
+ return {
138
+ properties: {
139
+ 'height': { component:"HeightSetting", text:'Height', group:'Layout' }
140
+ },
141
+ search: ''
142
+ }
143
+ },
144
+
145
+ emits: [ 'change' ],
146
+
147
+ inject: [ 'uploadImage', 'viewTypes' ],
148
+
149
+ props: {
150
+
151
+ datasource: Object,
152
+
153
+ index: Number,
154
+
155
+ readonly: [ Boolean, Number ],
156
+
157
+ value: {
158
+ type: Object,
159
+ required: true
160
+ },
161
+
162
+ viewType: String,
163
+
164
+ },
165
+
166
+ methods: {
167
+
168
+ addInteraction(obj){
169
+ this.$util.push(this.interactions, obj)
170
+ },
171
+
172
+ applyDefault(){
173
+ if(!this.value.props.datasourceUid && this.datasource?.length === 1){
174
+ this.value.props.datasourceUid = this.datasource[0].uid
175
+ }
176
+
177
+ if(!this.value.tabIndex)
178
+ this.value.tabIndex = 1
179
+ },
180
+
181
+ generateColumns(){
182
+ this.value.props.datasourceColumns = (this.selectedDatasource.pivot?.enabled ?
183
+ this.selectedDatasource.pivot.columns :
184
+ this.selectedDatasource.columns)
185
+ .map((_, __) => ({
186
+ ..._,
187
+ visible: __ < 10
188
+ }))
189
+ },
190
+
191
+ moveDown(item){
192
+ const index = this.value.props.datasourceColumns.indexOf(item)
193
+ if(index + 1 < this.value.props.datasourceColumns.length){
194
+ this.value.props.datasourceColumns.splice(index + 1, 0, this.value.props.datasourceColumns.splice(index, 1)[0])
195
+ this.$emit('change')
196
+ }
197
+ },
198
+
199
+ moveUp(item){
200
+ const index = this.value.props.datasourceColumns.indexOf(item)
201
+ if(index - 1 >= 0){
202
+ this.value.props.datasourceColumns.splice(index - 1, 0, this.value.props.datasourceColumns.splice(index, 1)[0])
203
+ this.$emit('change')
204
+ }
205
+ },
206
+
207
+
208
+ },
209
+
210
+ mounted() {
211
+ this.applyDefault()
212
+ },
213
+
214
+ watch: {
215
+
216
+ 'value.props.datasourceUid'(to){
217
+ if(to){
218
+ this.generateColumns()
219
+ this.$emit('change')
220
+ }
221
+ }
222
+
223
+ }
224
+
225
+ }
226
+
227
+ </script>
228
+
229
+ <style module>
230
+
231
+ .comp{
232
+ @apply flex-1 flex flex-col;
233
+ }
234
+
235
+ .columnTextbox input::placeholder{
236
+ @apply text-text;
237
+ }
238
+
239
+ </style>