@mixd-id/web-scaffold 0.2.240701 → 0.2.240703

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.
Files changed (92) hide show
  1. package/docs/schema/user-action.json +266 -0
  2. package/package.json +6 -2
  3. package/public/assets/dashboard/bar.png +0 -0
  4. package/public/assets/dashboard/doughnut.png +0 -0
  5. package/public/assets/dashboard/metric.png +0 -0
  6. package/public/assets/dashboard/pie.png +0 -0
  7. package/public/assets/dashboard/polar-area.png +0 -0
  8. package/public/assets/dashboard/virtual-table.png +0 -0
  9. package/public/static/dashboard/bar.png +0 -0
  10. package/public/static/dashboard/doughnut.png +0 -0
  11. package/public/static/dashboard/metric.png +0 -0
  12. package/public/static/dashboard/pie.png +0 -0
  13. package/public/static/dashboard/polar-area.png +0 -0
  14. package/public/static/dashboard/virtual-table.png +0 -0
  15. package/src/components/Button.vue +179 -160
  16. package/src/components/Checkbox.vue +0 -1
  17. package/src/components/Datepicker.vue +8 -6
  18. package/src/components/GHeatMaps.vue +317 -0
  19. package/src/components/GmapsDirection.vue +191 -0
  20. package/src/components/Grid.vue +2 -0
  21. package/src/components/HTMLEditor.vue +2 -2
  22. package/src/components/List.vue +384 -308
  23. package/src/components/Modal.vue +2 -3
  24. package/src/components/PresetSelectorFilterItem.vue +15 -2
  25. package/src/components/Switch.vue +3 -0
  26. package/src/components/Tabs.vue +1 -1
  27. package/src/components/TextWithTag.vue +67 -25
  28. package/src/components/Textbox.vue +5 -0
  29. package/src/components/VirtualGrid.vue +224 -228
  30. package/src/components/VirtualTable.vue +46 -28
  31. package/src/configs/dashboard/bar.js +10 -0
  32. package/src/configs/dashboard/collection-1.js +5 -0
  33. package/src/configs/dashboard/doughnut.js +7 -0
  34. package/src/configs/dashboard/gheatmaps.js +9 -0
  35. package/src/configs/dashboard/grid-2.js +34 -0
  36. package/src/configs/dashboard/grid-3.js +34 -0
  37. package/src/configs/dashboard/grid-4.js +34 -0
  38. package/src/configs/dashboard/grid.js +15 -0
  39. package/src/configs/dashboard/metric.js +10 -0
  40. package/src/configs/dashboard/pie.js +7 -0
  41. package/src/configs/dashboard/polar-area.js +7 -0
  42. package/src/configs/dashboard/virtual-table.js +9 -0
  43. package/src/defs/dashboard-preset.js +22 -0
  44. package/src/index.js +35 -23
  45. package/src/mixin/ready-state.js +37 -0
  46. package/src/stores/datasource.js +11 -0
  47. package/src/themes/default/index.js +1 -1
  48. package/src/utils/dashboard.js +1080 -0
  49. package/src/utils/event-bus.js +8 -0
  50. package/src/utils/helpers.js +56 -10
  51. package/src/utils/helpers.mjs +35 -1
  52. package/src/utils/preset-selector.js +5 -2
  53. package/src/utils/preset-selector.mjs +23 -13
  54. package/src/widgets/Dashboard/BarChart.vue +330 -0
  55. package/src/widgets/Dashboard/BarChartSetting.vue +317 -0
  56. package/src/widgets/Dashboard/DatasourceFilterSharing.vue +93 -0
  57. package/src/widgets/Dashboard/DatasourcePreview.vue +93 -0
  58. package/src/widgets/Dashboard/DatasourceSelector.vue +122 -0
  59. package/src/widgets/Dashboard/Doughnut.vue +157 -0
  60. package/src/widgets/Dashboard/DoughnutSetting.vue +196 -0
  61. package/src/widgets/Dashboard/GHeatMapsSetting.vue +108 -0
  62. package/src/widgets/Dashboard/InteractionEdit.vue +228 -0
  63. package/src/widgets/Dashboard/Metric.vue +76 -0
  64. package/src/widgets/Dashboard/MetricSetting.vue +174 -0
  65. package/src/widgets/Dashboard/Pie.vue +139 -0
  66. package/src/widgets/Dashboard/PieSetting.vue +247 -0
  67. package/src/widgets/Dashboard/PolarArea.vue +159 -0
  68. package/src/widgets/Dashboard/PolarAreaSetting.vue +195 -0
  69. package/src/widgets/Dashboard/SharingModal.vue +116 -0
  70. package/src/widgets/Dashboard/ViewSelector.vue +183 -0
  71. package/src/widgets/Dashboard/VirtualColumnEdit.vue +97 -0
  72. package/src/widgets/Dashboard/VirtualTableSetting.vue +234 -0
  73. package/src/widgets/Dashboard.vue +1773 -0
  74. package/src/widgets/PresetBar.vue +136 -175
  75. package/src/widgets/PresetBarPivot.vue +186 -0
  76. package/src/widgets/UserActionBuilder/UserActionCondition.vue +97 -0
  77. package/src/widgets/UserActionBuilder/UserActionConsole.vue +77 -0
  78. package/src/widgets/UserActionBuilder/UserActionItem.vue +163 -58
  79. package/src/widgets/UserActionBuilder/UserActionOutput.vue +35 -9
  80. package/src/widgets/UserActionBuilder/UserActionOutputDelay.vue +27 -0
  81. package/src/widgets/UserActionBuilder/UserActionOutputLog.vue +28 -0
  82. package/src/widgets/UserActionBuilder/UserActionOutputReply.vue +135 -0
  83. package/src/widgets/UserActionBuilder/UserActionProps.vue +211 -0
  84. package/src/widgets/UserActionBuilder.vue +68 -199
  85. package/src/widgets/WebPageBuilder4/GridSetting.vue +123 -73
  86. package/src/widgets/WebPageBuilder4/HeightSetting.vue +14 -11
  87. package/src/widgets/WebPageBuilder4/MarginSetting.vue +4 -1
  88. package/src/widgets/WebPageBuilder4/MultiValueSetting.vue +12 -4
  89. package/src/widgets/WebPageBuilder4/PaddingSetting.vue +4 -0
  90. package/src/widgets/WebPageBuilder4/TreeView.vue +6 -3
  91. package/src/widgets/WebPageBuilder4/TreeViewItem.vue +32 -58
  92. package/tailwind.config.js +2 -2
@@ -112,9 +112,10 @@ export default{
112
112
  this.context = context
113
113
 
114
114
  if(this.hash){
115
+ const hash = context.hash ?? this.hash
115
116
  this.$router.push({
116
117
  ...this.$route,
117
- hash: this.$route.hash.replace(this.hash, '') + this.hash
118
+ hash: this.$route.hash.replace(hash, '') + hash
118
119
  })
119
120
  }
120
121
  else{
@@ -331,10 +332,8 @@ export default{
331
332
  @apply panel-400;
332
333
  @apply border-[1px] border-text-50 z-20 flex max-h-[90vh];
333
334
  @apply rounded-xl overflow-hidden transition-all;
334
- background-color: rgba(255, 255, 255, .6)
335
335
  }
336
336
  html[data-theme='dark'] .modal{
337
- background-color: rgba(0, 0, 0, .6)
338
337
  }
339
338
 
340
339
  .modal.v-show{
@@ -5,6 +5,7 @@
5
5
  <div v-if="type === 'date'" class="flex-1 flex flex-row gap-2">
6
6
  <div class="flex-1 flex flex-row gap-2">
7
7
  <Dropdown v-model="value.operator"
8
+ :readonly="readonly"
8
9
  :class="![ 'yesterday', 'today', 'thisWeek', 'thisMonth', 'lastMonth', 'thisYear' ].includes(value.operator) ? 'w-[100px]' : 'w-full'"
9
10
  @change="apply">
10
11
  <option value="=">=</option>
@@ -24,10 +25,12 @@
24
25
  class="flex-1 flex flex-row gap-2">
25
26
  <Datepicker class="flex-1"
26
27
  mode="popup"
28
+ :readonly="readonly"
27
29
  v-model="value.value"
28
30
  @change="apply" />
29
31
  <Datepicker v-if="value.operator === 'between'"
30
32
  class="flex-1"
33
+ :readonly="readonly"
31
34
  mode="popup"
32
35
  v-model="value.value2"
33
36
  @change="apply" />
@@ -38,6 +41,7 @@
38
41
  <div v-else-if="type === 'number'" class="flex flex-row gap-2">
39
42
  <Dropdown v-model="value.operator"
40
43
  class="w-[100px]"
44
+ :readonly="readonly"
41
45
  @change="apply">
42
46
  <option value="=">=</option>
43
47
  <option value=">">&gt;</option>
@@ -49,13 +53,16 @@
49
53
  </Dropdown>
50
54
  <Textbox v-model="value.value"
51
55
  class="flex-1"
56
+ :readonly="readonly"
52
57
  @keyup.enter="apply"
53
58
  @blur="apply" />
54
59
  </div>
55
60
 
56
61
  <div v-else-if="type === 'boolean'" class="flex flex-row gap-2">
57
- <Radio :name="value.key" :value="true" v-model="value.value" @change="apply">True</Radio>
58
- <Radio :name="value.key" :value="false" v-model="value.value" @change="apply">False</Radio>
62
+ <Radio :name="value.key"
63
+ :readonly="readonly" :value="true" v-model="value.value" @change="apply">True</Radio>
64
+ <Radio :name="value.key"
65
+ :readonly="readonly" :value="false" v-model="value.value" @change="apply">False</Radio>
59
66
  </div>
60
67
 
61
68
  <div v-else-if="type === 'enum' && Array.isArray(cTypeParams) && cTypeParams.length > 0"
@@ -64,6 +71,7 @@
64
71
  <Checkbox v-for="param in cTypeParams"
65
72
  v-model="cValue.value"
66
73
  class="flex-1"
74
+ :readonly="readonly"
67
75
  :value="param.value"
68
76
  @change="apply">
69
77
  {{ param.text }}
@@ -74,11 +82,13 @@
74
82
  <div v-else-if="type === 'component'">
75
83
  <component :is="column.component"
76
84
  :value="value"
85
+ :readonly="readonly"
77
86
  @change="apply" />
78
87
  </div>
79
88
 
80
89
  <div v-else class="flex flex-row gap-2">
81
90
  <Dropdown v-model="value.operator" class="w-[100px]"
91
+ :readonly="readonly"
82
92
  @change="apply">
83
93
  <option value="eq">Equal</option>
84
94
  <option value="not">Not Equal</option>
@@ -91,6 +101,7 @@
91
101
  <option value="regex">Regex</option>
92
102
  </Dropdown>
93
103
  <Textbox v-model="value.value"
104
+ :readonly="readonly"
94
105
  class="flex-1"
95
106
  @keyup.enter="apply"
96
107
  @blur="apply" />
@@ -120,6 +131,8 @@ export default{
120
131
 
121
132
  value: Object,
122
133
 
134
+ readonly: [ Boolean, Number ],
135
+
123
136
  enumCache: Object,
124
137
 
125
138
  },
@@ -91,6 +91,9 @@ export default{
91
91
  .switch>input:checked + label>span{
92
92
  @apply ml-[1.3rem] border-base bg-white
93
93
  }
94
+ .switch>input:checked:disabled + label{
95
+ @apply bg-text-50;
96
+ }
94
97
 
95
98
  .switch>input:checked + label + *,
96
99
  .switch>input:not(:checked) + label + * + *{
@@ -2,7 +2,7 @@
2
2
  <div :class="computedClass">
3
3
  <button v-for="(item, index) in filteredItems" :class="tabClass(item)"
4
4
  class="whitespace-nowrap"
5
- @click="onClick(item)" type="button" >
5
+ @click="item.disabled !== true ? onClick(item) : ''" type="button" >
6
6
  <slot name="default" :="{ item, index }">
7
7
  <label class="px-1">
8
8
  {{ item.text }}
@@ -2,18 +2,20 @@
2
2
  <div :class="$style.comp">
3
3
 
4
4
  <div class="flex flex-row items-start">
5
- <p contenteditable="true" spellcheck="false" class="flex-1 whitespace-pre-line"
5
+ <span contenteditable="true" spellcheck="false"
6
6
  ref="html"
7
7
  v-html="html"
8
- :class="itemClass"
9
- @input="onInput"></p>
8
+ :class="`${$style.content}${itemClass ? ' ' + itemClass : ''}`"
9
+ @blur="saveSelection($refs.html)"
10
+ @paste="onPaste"
11
+ @input="onInput"></span>
10
12
 
11
13
  <button v-if="variant === 'minimal'" type="button" class="p-3" @click="$refs.modal.open()">
12
14
  <svg width="14" height="14" class="fill-text-300 hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg>
13
15
  </button>
14
16
  </div>
15
17
 
16
- <div v-if="variant !== 'minimal'" class="flex flex-row bg-base-300">
18
+ <div v-if="variant !== 'minimal'" class="flex flex-row bg-base-300" @dblclick.alt="log(JSON.stringify(modelValue))">
17
19
  <div class="flex-1 flex flex-row gap-2 overflow-x-auto p-1" :class="$style.noScrollbar">
18
20
  <button type="button" v-for="item in viewedItems" :class="$style.tag2" class="text-xs" @click="add(item)">{{ item.text ?? item.value }}</button>
19
21
  </div>
@@ -59,7 +61,8 @@
59
61
  </template>
60
62
 
61
63
  <script>
62
- import groupBy from "lodash/groupBy";
64
+
65
+ import {restoreSelection, saveSelection} from "../utils/selection";
63
66
 
64
67
  export default{
65
68
 
@@ -69,6 +72,8 @@ export default{
69
72
 
70
73
  addFn: Function,
71
74
 
75
+ itemFn: Function,
76
+
72
77
  modelValue: String,
73
78
 
74
79
  items: Array,
@@ -82,7 +87,12 @@ export default{
82
87
  computed:{
83
88
 
84
89
  groupedItems(){
85
- return groupBy(this.items ?? [], 'group')
90
+ return this.items.reduce((acc, item) => {
91
+ const key = item.group ?? ''
92
+ if(!acc[key]) acc[key] = []
93
+ acc[key].push(item)
94
+ return acc
95
+ }, {})
86
96
  },
87
97
 
88
98
  viewedItems(){
@@ -99,6 +109,8 @@ export default{
99
109
  },
100
110
 
101
111
  methods: {
112
+ restoreSelection,
113
+ saveSelection,
102
114
 
103
115
  insertElement(newNode){
104
116
  let selection = window.getSelection();
@@ -123,12 +135,8 @@ export default{
123
135
  selection.addRange(range);
124
136
  },
125
137
 
126
- add(item){
127
- this.$refs.modal.close()
128
-
129
- if(typeof this.addFn === 'function'){
130
- item = this.addFn(item)
131
- }
138
+ addItem(item){
139
+ this.restoreSelection()
132
140
 
133
141
  const el = document.createElement('span')
134
142
  el.setAttribute('contenteditable', 'false')
@@ -140,22 +148,47 @@ export default{
140
148
  this.onInput()
141
149
  },
142
150
 
151
+ add(item){
152
+ this.$refs.modal.close()
153
+
154
+ if(typeof this.addFn === 'function'){
155
+
156
+ if(this.addFn.constructor.name === 'AsyncFunction'){
157
+ this.addFn(item).then(newItem => {
158
+ if(newItem === false) return
159
+ item = newItem ? newItem : item
160
+ this.addItem(item)
161
+ })
162
+ return
163
+ }
164
+
165
+ const newItem = this.addFn(item)
166
+ if(newItem === false) return
167
+ item = newItem ? newItem : item
168
+ }
169
+
170
+ this.addItem(item)
171
+ },
172
+
143
173
  remove(e){
144
174
  e.target.parentNode.removeChild(e.target)
145
175
  },
146
176
 
177
+ onPaste(e){
178
+ e.preventDefault()
179
+ const text = e.clipboardData.getData('text/plain')
180
+ document.execCommand('insertText', false, text)
181
+ },
182
+
147
183
  onInput(){
148
184
 
149
185
  const arr = []
150
186
  for(let i = 0 ; i < this.$refs.html.childNodes.length ; i++){
151
- if(this.$refs.html.childNodes[i].nodeType === 1 && this.$refs.html.childNodes[i].classList.contains(this.$style.tag)){
152
- arr.push(this.$refs.html.childNodes[i].getAttribute('data-value'))
153
- }
154
- else if(this.$refs.html.childNodes[i].nodeType === 3){
155
- arr.push(this.$refs.html.childNodes[i].textContent)
187
+ if(this.$refs.html.childNodes[i].nodeType === 3){
188
+ arr.push(this.$refs.html.childNodes[i].nodeValue)
156
189
  }
157
- else{
158
- arr.push((arr.length > 0 ? "\n\n" : '') + this.$refs.html.childNodes[i].innerText)
190
+ else if(this.$refs.html.childNodes[i].nodeType === 1 && this.$refs.html.childNodes[i].classList.contains(this.$style.tag)){
191
+ arr.push(this.$refs.html.childNodes[i].getAttribute('data-value'))
159
192
  }
160
193
  }
161
194
 
@@ -179,10 +212,19 @@ export default{
179
212
  }
180
213
 
181
214
  let html = val ?? ''
182
- if(Array.isArray(this.items)){
183
- for(let item of this.items){
184
- html = html.replaceAll(item.value, `<span class="${this.$style.tag}" contenteditable="false" @click="remove" data-value="${item.value}">${item.text ?? item.value}</span>`, 'gi')
185
- }
215
+
216
+ let customItems = []
217
+ if(typeof this.itemFn === 'function'){
218
+ customItems = this.itemFn(html)
219
+ }
220
+
221
+ const items = [
222
+ ...Array.isArray(this.items) ? this.items : [],
223
+ ...customItems
224
+ ]
225
+
226
+ for(let item of items){
227
+ html = html.replaceAll(item.value, `<span title="${item.value.replaceAll('"', '')}" class="${this.$style.tag}" contenteditable="false" data-value="${item.value}">${item.text ?? item.value}</span>`, 'gi')
186
228
  }
187
229
 
188
230
  this.html = html
@@ -204,8 +246,8 @@ export default{
204
246
  @apply divide-y divide-text-100;
205
247
  }
206
248
 
207
- .comp p{
208
- @apply outline-none p-2 align-baseline;
249
+ .content{
250
+ @apply flex-1 whitespace-pre-line outline-none p-2;
209
251
  }
210
252
 
211
253
  .comp .tag{
@@ -72,6 +72,7 @@ export default{
72
72
  computedClass(){
73
73
  return [
74
74
  this.$style.textbox,
75
+ this.$style['variant-' + this.variant],
75
76
  this.$style['state-' + this.computedState],
76
77
  this.readonly ? this.$style.readonly : '',
77
78
  this.isActive && !this.readonly ? this.$style.active : '',
@@ -218,4 +219,8 @@ export default{
218
219
  @apply text-right
219
220
  }
220
221
 
222
+ .textbox.variant-minimal{
223
+ @apply border-transparent;
224
+ }
225
+
221
226
  </style>