@mixd-id/web-scaffold 0.1.230406247 → 0.1.230406248
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 +1 -1
- package/src/components/Chart.vue +2 -1
- package/src/components/DGridItem.vue +76 -9
- package/src/components/List.vue +131 -91
- package/src/components/ListItem.vue +0 -2
- package/src/components/ObjectTree.vue +1 -1
- package/src/components/PresetSelectorFilterItem.vue +85 -0
- package/src/components/TextWithTag.vue +3 -3
- package/src/index.js +27 -35
- package/src/utils/preset-selector.js +384 -116
- package/src/widgets/PresetSelector.vue +101 -108
package/package.json
CHANGED
package/src/components/Chart.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div v-if="readyState === 1" :class="$style.comp">
|
|
3
3
|
|
|
4
4
|
<div class="p-3 flex flex-col items-start leading-tight">
|
|
5
|
-
<small class="text-text-400">
|
|
5
|
+
<small class="text-text-400">{{ title ?? 'Untitled' }}</small>
|
|
6
6
|
<h5 class="inline align-top cursor-pointer hover:text-primary group" @click="$refs.presetSelector.open()">
|
|
7
7
|
{{ preset.name ?? 'Preset Name' }}
|
|
8
8
|
<span v-if="badgeCount > 0" class="mx-1 min-w-[19px] px-2 h-[19px] relative top-[-2px] rounded-full bg-primary text-white inline-flex items-center justify-center">
|
|
@@ -52,6 +52,7 @@ export default{
|
|
|
52
52
|
|
|
53
53
|
presetKey: undefined,
|
|
54
54
|
src: undefined,
|
|
55
|
+
title: String,
|
|
55
56
|
subscribeKey: String,
|
|
56
57
|
},
|
|
57
58
|
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
@click="editMode = true"
|
|
16
16
|
@mousedown="(e) => onMouseDown(e, 'bottom')"></div>
|
|
17
17
|
|
|
18
|
+
<div ref="drag" :class="`${$style.drag} ${editMode ? $style.editMode : ''}`">
|
|
19
|
+
<svg width="48" height="48" class="fill-primary" 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="M512 255.1c0 6.755-2.844 13.09-7.844 17.62l-88 80.05C411.5 357.8 405.8 359.9 400 359.9c-13.27 0-24-10.76-24-24c0-6.534 2.647-13.04 7.844-17.78l42.07-38.28H280v146l38.25-42.1c4.715-5.2 11.21-7.849 17.74-7.849c13.23 0 24.01 10.71 24.01 24.03c0 5.765-2.061 11.55-6.25 16.15l-80 88.06C269.2 509.2 262.8 512 256 512s-13.22-2.846-17.75-7.849l-80-88.06c-4.189-4.603-6.25-10.39-6.25-16.15c0-13.38 10.83-24.03 23.1-24.03c6.526 0 13.02 2.649 17.75 7.849L232 425.9V279.8H86.09l42.07 38.28c5.196 4.735 7.844 11.24 7.844 17.78c0 13.22-10.71 24-24 24c-5.781 0-11.53-2.064-16.16-6.254l-88-80.05C2.844 269.1 0 262.7 0 255.1c0-6.755 2.844-13.37 7.844-17.9l88-80.05C100.5 153.8 106.2 151.8 112 151.8c13.26 0 23.99 10.74 23.99 23.99c0 6.534-2.647 13.04-7.844 17.78L86.09 231.8H232V85.8L193.8 127.9C189 133.1 182.5 135.7 175.1 135.7c-13.16 0-23.1-10.66-23.1-24.03c0-5.765 2.061-11.55 6.25-16.15l80-88.06C242.8 2.502 249.4 0 256 0s13.22 2.502 17.75 7.505l80 88.06c4.189 4.603 6.25 10.39 6.25 16.15c0 13.35-10.81 24.03-24 24.03c-6.531 0-13.03-2.658-17.75-7.849L280 85.8v146h145.9l-42.07-38.28c-5.196-4.735-7.844-11.24-7.844-17.78c0-13.25 10.74-23.99 23.98-23.99c5.759 0 11.55 2.061 16.18 6.242l88 80.05C509.2 242.6 512 249.2 512 255.1z"/></svg>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
18
22
|
<button type="button" :class="`${$style.removeBtn} ${editMode ? $style.editMode : ''}`" @click="$emit('remove')">
|
|
19
23
|
<svg width="11" height="11" class="fill-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M378.4 440.6c8.531 10.16 7.203 25.28-2.938 33.81C370.9 478.2 365.5 480 360 480c-6.844 0-13.64-2.906-18.39-8.562L192 293.3l-149.6 178.1C37.63 477.1 30.83 480 23.98 480c-5.453 0-10.92-1.844-15.42-5.625c-10.14-8.531-11.47-23.66-2.938-33.81L160.7 256L5.625 71.44C-2.906 61.28-1.578 46.16 8.563 37.63C18.69 29.08 33.84 30.39 42.38 40.56L192 218.7l149.6-178.1c8.547-10.17 23.67-11.47 33.81-2.938s11.47 23.66 2.938 33.81L223.3 256L378.4 440.6z"/></svg>
|
|
20
24
|
</button>
|
|
@@ -26,7 +30,7 @@
|
|
|
26
30
|
|
|
27
31
|
export default{
|
|
28
32
|
|
|
29
|
-
emits: [ 'class-change', 'remove' ],
|
|
33
|
+
emits: [ 'class-change', 'remove', 'reorder' ],
|
|
30
34
|
|
|
31
35
|
props: {
|
|
32
36
|
|
|
@@ -53,6 +57,7 @@ export default{
|
|
|
53
57
|
return {
|
|
54
58
|
drag: null,
|
|
55
59
|
editMode: false,
|
|
60
|
+
oEl: null,
|
|
56
61
|
}
|
|
57
62
|
},
|
|
58
63
|
|
|
@@ -82,16 +87,12 @@ export default{
|
|
|
82
87
|
|
|
83
88
|
if(Math.abs(distanceX) > 35){
|
|
84
89
|
const match = this.class.match(/col-span-(\d+)/)
|
|
85
|
-
console.log(match)
|
|
86
90
|
const colSpan = match ? parseInt(match[1]) : 1
|
|
87
91
|
const nextColSpan = distanceX > 0 ? colSpan + 1 <= 12 ? colSpan + 1 : 12 :
|
|
88
92
|
colSpan - 1 >= 1 ? colSpan - 1 : 1
|
|
89
|
-
console.log(colSpan, nextColSpan)
|
|
90
93
|
|
|
91
|
-
console.log(2, this.class)
|
|
92
94
|
const nextClass = match ? this.class.replace(`col-span-${colSpan}`, `col-span-${nextColSpan}`) :
|
|
93
95
|
`${this.class} col-span-${nextColSpan}`
|
|
94
|
-
console.log(2, nextClass)
|
|
95
96
|
|
|
96
97
|
this.drag.x = e.clientX
|
|
97
98
|
this.$emit('class-change', nextClass)
|
|
@@ -100,17 +101,17 @@ export default{
|
|
|
100
101
|
|
|
101
102
|
case 'bottom':
|
|
102
103
|
const distanceY = e.clientY - this.drag.y
|
|
103
|
-
if(Math.abs(distanceY) >
|
|
104
|
+
if(Math.abs(distanceY) > 70){
|
|
104
105
|
const match = this.class.match(/row-span-(\d+)/)
|
|
105
106
|
const rowSpan = match ? parseInt(match[1]) : 1
|
|
106
107
|
const nextRowSpan = distanceY > 0 ? rowSpan + 1 <= 12 ? rowSpan + 1 : 12 :
|
|
107
108
|
rowSpan - 1 >= 1 ? rowSpan - 1 : 1
|
|
108
109
|
|
|
109
|
-
match ? this.class.replace(`row-span-${rowSpan}`, `row-span-${nextRowSpan}`) :
|
|
110
|
-
this.class
|
|
110
|
+
const nextClass = match ? this.class.replace(`row-span-${rowSpan}`, `row-span-${nextRowSpan}`) :
|
|
111
|
+
`${this.class} row-span-${nextRowSpan}`
|
|
111
112
|
|
|
112
113
|
this.drag.y = e.clientY
|
|
113
|
-
this.$emit('class-change',
|
|
114
|
+
this.$emit('class-change', nextClass)
|
|
114
115
|
}
|
|
115
116
|
break
|
|
116
117
|
}
|
|
@@ -131,6 +132,47 @@ export default{
|
|
|
131
132
|
|
|
132
133
|
},
|
|
133
134
|
|
|
135
|
+
onDragOver(e){
|
|
136
|
+
e.preventDefault();
|
|
137
|
+
const oEl = e.target.closest(`.${this.$style.comp}`)
|
|
138
|
+
|
|
139
|
+
if(this.oEl !== oEl){
|
|
140
|
+
this.oEl ? this.oEl.style.opacity = '' : '';
|
|
141
|
+
|
|
142
|
+
if(oEl){
|
|
143
|
+
this.oEl = oEl
|
|
144
|
+
this.oEl.style.opacity = '.5'
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
onDragStart(e){
|
|
150
|
+
window.addEventListener('dragover', this.onDragOver)
|
|
151
|
+
window.addEventListener('dragend', this.onDragEnd)
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
onDragEnd(e){
|
|
155
|
+
|
|
156
|
+
e.preventDefault()
|
|
157
|
+
|
|
158
|
+
const childNodes = Array.from(this.$el.parentNode.children)
|
|
159
|
+
const fromIdx = childNodes.indexOf(this.$el)
|
|
160
|
+
const toIdx = childNodes.indexOf(this.oEl)
|
|
161
|
+
|
|
162
|
+
this.oEl ? this.oEl.style.opacity = '' : '';
|
|
163
|
+
|
|
164
|
+
this.$el.setAttribute('draggable', false)
|
|
165
|
+
window.removeEventListener('dragover', this.onDragOver)
|
|
166
|
+
window.removeEventListener('dragend', this.onDragEnd)
|
|
167
|
+
|
|
168
|
+
this.$emit('reorder', fromIdx, toIdx)
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
onDrag(e){
|
|
172
|
+
this.$el.addEventListener('dragstart', this.onDragStart)
|
|
173
|
+
this.$el.setAttribute('draggable', true)
|
|
174
|
+
}
|
|
175
|
+
|
|
134
176
|
},
|
|
135
177
|
|
|
136
178
|
watch: {
|
|
@@ -138,6 +180,9 @@ export default{
|
|
|
138
180
|
editMode(to){
|
|
139
181
|
to ? window.addEventListener('click', this.checkEditMode) :
|
|
140
182
|
window.removeEventListener('click', this.checkEditMode)
|
|
183
|
+
|
|
184
|
+
to ? this.$refs.drag.addEventListener('mousedown', this.onDrag) :
|
|
185
|
+
this.$refs.drag.removeEventListener('mousedown', this.onDrag)
|
|
141
186
|
}
|
|
142
187
|
|
|
143
188
|
}
|
|
@@ -151,6 +196,19 @@ export default{
|
|
|
151
196
|
.comp{
|
|
152
197
|
@apply relative flex;
|
|
153
198
|
}
|
|
199
|
+
.comp[class~='row-span-2']>*:first-child,
|
|
200
|
+
.comp[class~='row-span-3']>*:first-child,
|
|
201
|
+
.comp[class~='row-span-4']>*:first-child,
|
|
202
|
+
.comp[class~='row-span-5']>*:first-child,
|
|
203
|
+
.comp[class~='row-span-6']>*:first-child,
|
|
204
|
+
.comp[class~='row-span-7']>*:first-child,
|
|
205
|
+
.comp[class~='row-span-8']>*:first-child,
|
|
206
|
+
.comp[class~='row-span-9']>*:first-child,
|
|
207
|
+
.comp[class~='row-span-10']>*:first-child,
|
|
208
|
+
.comp[class~='row-span-11']>*:first-child
|
|
209
|
+
.comp[class~='row-span-12']>*:first-child{
|
|
210
|
+
@apply !absolute !top-0 !left-0 !right-0 !bottom-0 !h-auto;
|
|
211
|
+
}
|
|
154
212
|
|
|
155
213
|
.top{
|
|
156
214
|
@apply h-[3px];
|
|
@@ -193,4 +251,13 @@ export default{
|
|
|
193
251
|
@apply flex;
|
|
194
252
|
}
|
|
195
253
|
|
|
254
|
+
.drag{
|
|
255
|
+
@apply absolute top-0 left-0 right-0 bottom-0;
|
|
256
|
+
@apply rounded-full hidden;
|
|
257
|
+
}
|
|
258
|
+
.drag.editMode{
|
|
259
|
+
@apply flex items-center justify-center flex items-center justify-center;
|
|
260
|
+
@apply cursor-move;
|
|
261
|
+
}
|
|
262
|
+
|
|
196
263
|
</style>
|
package/src/components/List.vue
CHANGED
|
@@ -1,91 +1,105 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@clear="delete preset.search; load()"
|
|
24
|
-
@keyup.enter="load">
|
|
25
|
-
<template #start>
|
|
26
|
-
<div class="p-2 pr-0">
|
|
27
|
-
<svg width="16" height="16" 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="M504.1 471l-134-134C399.1 301.5 415.1 256.8 415.1 208c0-114.9-93.13-208-208-208S-.0002 93.13-.0002 208S93.12 416 207.1 416c48.79 0 93.55-16.91 129-45.04l134 134C475.7 509.7 481.9 512 488 512s12.28-2.344 16.97-7.031C514.3 495.6 514.3 480.4 504.1 471zM48 208c0-88.22 71.78-160 160-160s160 71.78 160 160s-71.78 160-160 160S48 296.2 48 208z"/></svg>
|
|
28
|
-
</div>
|
|
29
|
-
</template>
|
|
30
|
-
</Textbox>
|
|
31
|
-
|
|
32
|
-
<div class="grid grid-cols-2 gap-[1px]">
|
|
33
|
-
<Radio v-model="preset.view"
|
|
34
|
-
name="view"
|
|
35
|
-
value="table"
|
|
36
|
-
:custom="true"
|
|
37
|
-
class="p-3 rounded-lg rounded-r-none"
|
|
38
|
-
:class="preset.view === 'table' ? 'bg-primary-500' : 'bg-base-500'">
|
|
39
|
-
<svg width="14" height="14" :class="preset.view === 'table' ? 'fill-white' : 'fill-text'" 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="M448 32H64.05C28.7 32 .0492 60.65 .0492 96v320c0 35.35 28.65 64 64 64h383.1c35.35 0 64-28.65 64-64V96C512 60.65 483.4 32 448 32zM224 416H64v-96h160V416zM224 256H64V160h160V256zM448 416h-160v-96h160V416zM448 256h-160V160h160V256z"/></svg>
|
|
40
|
-
</Radio>
|
|
41
|
-
<Radio v-model="preset.view"
|
|
42
|
-
name="view"
|
|
43
|
-
value="grid"
|
|
44
|
-
:custom="true"
|
|
45
|
-
class="p-3 bg-base-500 rounded-lg rounded-l-none"
|
|
46
|
-
:class="preset.view === 'grid' ? 'bg-primary-500' : 'bg-base-500'">
|
|
47
|
-
<svg width="14" height="14" :class="preset.view === 'grid' ? 'fill-white' : 'fill-text'" 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="M144 288h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96C176 302.3 161.7 288 144 288zM368 288h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96C400 302.3 385.7 288 368 288zM592 288h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96C624 302.3 609.7 288 592 288zM144 64h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V96C176 78.33 161.7 64 144 64zM368 64h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V96C400 78.33 385.7 64 368 64zM592 64h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V96C624 78.33 609.7 64 592 64z"/></svg>
|
|
48
|
-
</Radio>
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
2
|
+
<div class="flex flex-col">
|
|
3
|
+
<div v-if="readyState === 1"
|
|
4
|
+
class="flex-1 flex flex-col gap-3">
|
|
5
|
+
|
|
6
|
+
<slot name="head"
|
|
7
|
+
:preset="preset"
|
|
8
|
+
:badge-count="badgeCount"
|
|
9
|
+
:presetSelector="$refs.presetSelector"
|
|
10
|
+
:compPrefix="compPrefix">
|
|
11
|
+
<div class="flex flex-row gap-3 items-center overflow-hidden leading-tight pl-3">
|
|
12
|
+
<div class="flex flex-col whitespace-nowrap text-ellipsis overflow-hidden">
|
|
13
|
+
<small class="text-text-400">{{ title ?? 'Untitled' }}</small>
|
|
14
|
+
<h3 class="cursor-pointer whitespace-nowrap text-ellipsis overflow-hidden hover:text-primary group"
|
|
15
|
+
@click="$refs.presetSelector.open()">
|
|
16
|
+
{{ preset.name ?? 'Preset Name' }}
|
|
17
|
+
<span v-if="badgeCount > 0" class="inline mx-1 min-w-[19px] px-2 h-[19px] relative top-[-2px] rounded-full bg-primary text-white inline-flex items-center justify-center">
|
|
18
|
+
{{ badgeCount }}
|
|
19
|
+
</span>
|
|
20
|
+
<svg width="13" height="13" class="inline fill-text pointer-events-none group-hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"/></svg>
|
|
21
|
+
</h3>
|
|
22
|
+
</div>
|
|
52
23
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
24
|
+
<div class="flex-1"></div>
|
|
25
|
+
|
|
26
|
+
<slot name="toolbar"></slot>
|
|
27
|
+
|
|
28
|
+
<div class="flex flex-row gap-2 gap-1">
|
|
29
|
+
<Textbox class="bg-base-500 w-[240px]" placeholder="Search..." clearable="1"
|
|
30
|
+
v-model="preset.search"
|
|
31
|
+
@clear="delete preset.search; load()"
|
|
32
|
+
@keyup.enter="load">
|
|
33
|
+
<template #start>
|
|
34
|
+
<div class="p-2 pr-0">
|
|
35
|
+
<svg width="16" height="16" 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="M504.1 471l-134-134C399.1 301.5 415.1 256.8 415.1 208c0-114.9-93.13-208-208-208S-.0002 93.13-.0002 208S93.12 416 207.1 416c48.79 0 93.55-16.91 129-45.04l134 134C475.7 509.7 481.9 512 488 512s12.28-2.344 16.97-7.031C514.3 495.6 514.3 480.4 504.1 471zM48 208c0-88.22 71.78-160 160-160s160 71.78 160 160s-71.78 160-160 160S48 296.2 48 208z"/></svg>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
</Textbox>
|
|
39
|
+
|
|
40
|
+
<div v-if="$slots.gridItem" class="grid grid-cols-2 gap-[1px]">
|
|
41
|
+
<Radio v-model="preset.view"
|
|
42
|
+
name="view"
|
|
43
|
+
value="table"
|
|
44
|
+
:custom="true"
|
|
45
|
+
class="p-3 rounded-lg rounded-r-none"
|
|
46
|
+
:class="preset.view === 'table' ? 'bg-primary-500' : 'bg-base-500'">
|
|
47
|
+
<svg width="16" height="16" :class="preset.view === 'table' ? 'fill-white' : 'fill-text'" 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="M448 32H64.05C28.7 32 .0492 60.65 .0492 96v320c0 35.35 28.65 64 64 64h383.1c35.35 0 64-28.65 64-64V96C512 60.65 483.4 32 448 32zM224 416H64v-96h160V416zM224 256H64V160h160V256zM448 416h-160v-96h160V416zM448 256h-160V160h160V256z"/></svg>
|
|
48
|
+
</Radio>
|
|
49
|
+
<Radio v-model="preset.view"
|
|
50
|
+
name="view"
|
|
51
|
+
value="grid"
|
|
52
|
+
:custom="true"
|
|
53
|
+
class="p-3 bg-base-500 rounded-lg rounded-l-none"
|
|
54
|
+
:class="preset.view === 'grid' ? 'bg-primary-500' : 'bg-base-500'">
|
|
55
|
+
<svg width="16" height="16" :class="preset.view === 'grid' ? 'fill-white' : 'fill-text'" 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="M144 288h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96C176 302.3 161.7 288 144 288zM368 288h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96C400 302.3 385.7 288 368 288zM592 288h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-96C624 302.3 609.7 288 592 288zM144 64h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V96C176 78.33 161.7 64 144 64zM368 64h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V96C400 78.33 385.7 64 368 64zM592 64h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32V96C624 78.33 609.7 64 592 64z"/></svg>
|
|
56
|
+
</Radio>
|
|
80
57
|
</div>
|
|
81
58
|
</div>
|
|
82
|
-
</slot>
|
|
83
|
-
</template>
|
|
84
|
-
</VirtualGrid>
|
|
85
59
|
|
|
86
|
-
|
|
60
|
+
<slot name="toolbar2"></slot>
|
|
61
|
+
|
|
62
|
+
</div>
|
|
63
|
+
</slot>
|
|
64
|
+
|
|
65
|
+
<VirtualTable v-if="presetView === 'table'"
|
|
66
|
+
:columns="columns"
|
|
67
|
+
class="flex-1"
|
|
68
|
+
:items="users.items"
|
|
69
|
+
@scroll-end="loadNext">
|
|
70
|
+
|
|
71
|
+
<template v-for="(_, slot) in contentSlots" #[slot]="{ item, index }">
|
|
72
|
+
<slot :name="slot" :item="item" :index="index"></slot>
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
</VirtualTable>
|
|
76
|
+
|
|
77
|
+
<VirtualGrid v-else-if="presetView === 'grid'"
|
|
78
|
+
:items="users.items"
|
|
79
|
+
:column="computedGridColumn"
|
|
80
|
+
class="flex-1"
|
|
81
|
+
@scroll-end="loadNext"
|
|
82
|
+
container-class="gap-5"
|
|
83
|
+
:config="config">
|
|
84
|
+
<template #item="{ item }">
|
|
85
|
+
<slot name="gridItem" :item="item">
|
|
86
|
+
<div class="flex flex-row bg-base-400 rounded-lg overflow-hidden">
|
|
87
|
+
<div>
|
|
88
|
+
<Image :src="item.imageUrl" class="bg-text-50 w-[64px] h-[64px]" />
|
|
89
|
+
</div>
|
|
90
|
+
<div class="flex-1 p-3">
|
|
91
|
+
<strong>{{ item.name }}</strong>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</slot>
|
|
95
|
+
</template>
|
|
96
|
+
</VirtualGrid>
|
|
97
|
+
|
|
98
|
+
<PresetSelector ref="presetSelector" :config="config" @select="load" />
|
|
87
99
|
|
|
100
|
+
</div>
|
|
88
101
|
</div>
|
|
102
|
+
|
|
89
103
|
</template>
|
|
90
104
|
|
|
91
105
|
<script>
|
|
@@ -95,20 +109,18 @@ import throttle from "lodash/throttle";
|
|
|
95
109
|
import PresetSelector from "../widgets/PresetSelector.vue";
|
|
96
110
|
|
|
97
111
|
export default{
|
|
98
|
-
components: {PresetSelector, VirtualTable},
|
|
99
|
-
|
|
100
|
-
inject: [ 'socket', 'toast' ],
|
|
101
112
|
|
|
102
113
|
props: {
|
|
103
|
-
|
|
104
114
|
config: {
|
|
105
115
|
type: Object,
|
|
106
116
|
default: {}
|
|
107
117
|
},
|
|
108
|
-
|
|
109
118
|
presetKey: String,
|
|
110
119
|
subscribeKey: String,
|
|
111
120
|
src: undefined,
|
|
121
|
+
title: String,
|
|
122
|
+
view: String,
|
|
123
|
+
gridColumn: [ Number, String ],
|
|
112
124
|
},
|
|
113
125
|
|
|
114
126
|
methods: {
|
|
@@ -153,6 +165,14 @@ export default{
|
|
|
153
165
|
return new Promise(resolve => resolve())
|
|
154
166
|
},
|
|
155
167
|
|
|
168
|
+
selectPreset(idx){
|
|
169
|
+
if(this.config.presets[idx]){
|
|
170
|
+
this.config.presetIdx = idx
|
|
171
|
+
this.load()
|
|
172
|
+
this.$refs.presetSelector.close()
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
|
|
156
176
|
savePreset: throttle(function() {
|
|
157
177
|
if(this.presetKey) {
|
|
158
178
|
this.socket.send('user.preset',
|
|
@@ -160,6 +180,10 @@ export default{
|
|
|
160
180
|
}
|
|
161
181
|
}, 1000, { leading:true }),
|
|
162
182
|
|
|
183
|
+
openPresetSelector(){
|
|
184
|
+
this.$refs.presetSelector.open()
|
|
185
|
+
},
|
|
186
|
+
|
|
163
187
|
onSignal(event, items){
|
|
164
188
|
|
|
165
189
|
switch(event){
|
|
@@ -172,14 +196,21 @@ export default{
|
|
|
172
196
|
this.socket.send(this.src, {
|
|
173
197
|
id: items.map(item => item.id)
|
|
174
198
|
})
|
|
175
|
-
|
|
199
|
+
.then(({ items }) => items.forEach(item => this.$util.push(this.users.items, item)))
|
|
176
200
|
|
|
177
201
|
}
|
|
178
202
|
},
|
|
179
203
|
|
|
180
204
|
},
|
|
181
205
|
|
|
206
|
+
|
|
207
|
+
components: {PresetSelector, VirtualTable},
|
|
208
|
+
|
|
209
|
+
inject: [ 'socket', 'toast' ],
|
|
210
|
+
|
|
182
211
|
mounted() {
|
|
212
|
+
this.$addResizeListener(this.$el, () => this.compPrefix = this.$util.calculateMediaPrefix(this.$el.clientWidth))
|
|
213
|
+
|
|
183
214
|
this.loadPreset()
|
|
184
215
|
.then(() => {
|
|
185
216
|
|
|
@@ -206,6 +237,8 @@ export default{
|
|
|
206
237
|
},
|
|
207
238
|
|
|
208
239
|
unmounted() {
|
|
240
|
+
this.$removeResizeListener(this.$el)
|
|
241
|
+
|
|
209
242
|
if(this.subscribeKey) {
|
|
210
243
|
this.socket.send('user.unsubscribe', {name: this.subscribeKey})
|
|
211
244
|
this.socket.off(this.subscribeKey, this.onSignal)
|
|
@@ -215,7 +248,7 @@ export default{
|
|
|
215
248
|
computed: {
|
|
216
249
|
|
|
217
250
|
columns(){
|
|
218
|
-
return this.config.columns
|
|
251
|
+
return this.preset.columns ?? this.config.columns
|
|
219
252
|
},
|
|
220
253
|
|
|
221
254
|
contentSlots(){
|
|
@@ -227,10 +260,18 @@ export default{
|
|
|
227
260
|
return slots
|
|
228
261
|
},
|
|
229
262
|
|
|
263
|
+
computedGridColumn(){
|
|
264
|
+
return this.gridColumn ?? 3
|
|
265
|
+
},
|
|
266
|
+
|
|
230
267
|
preset(){
|
|
231
268
|
return ((this.config ?? {}).presets ?? [])[(this.config ?? {}).presetIdx ?? 0] ?? {}
|
|
232
269
|
},
|
|
233
270
|
|
|
271
|
+
presetView(){
|
|
272
|
+
return this.view ?? this.preset.view
|
|
273
|
+
},
|
|
274
|
+
|
|
234
275
|
},
|
|
235
276
|
|
|
236
277
|
data(){
|
|
@@ -240,6 +281,8 @@ export default{
|
|
|
240
281
|
users: {
|
|
241
282
|
itemsPerPage: 15,
|
|
242
283
|
},
|
|
284
|
+
observer: null,
|
|
285
|
+
compPrefix: '',
|
|
243
286
|
}
|
|
244
287
|
},
|
|
245
288
|
|
|
@@ -260,8 +303,5 @@ export default{
|
|
|
260
303
|
|
|
261
304
|
<style module>
|
|
262
305
|
|
|
263
|
-
.comp{
|
|
264
|
-
|
|
265
|
-
}
|
|
266
306
|
|
|
267
307
|
</style>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="type === 'date'" class="flex flex-row gap-2">
|
|
3
|
+
<div class="flex-1 flex flex-row gap-2">
|
|
4
|
+
<Dropdown v-model="value.operator"
|
|
5
|
+
:class="value.operator !== 'between' && (value.operator ?? '').length >= 5 ? 'w-[200px]' : 'w-[100px]'">
|
|
6
|
+
<option value="=">=</option>
|
|
7
|
+
<option value=">">></option>
|
|
8
|
+
<option value=">=">>=</option>
|
|
9
|
+
<option value="<"><</option>
|
|
10
|
+
<option value="<="><=</option>
|
|
11
|
+
<option value="between">Between</option>
|
|
12
|
+
<option value="yesterday">Yesterday</option>
|
|
13
|
+
<option value="today">Today</option>
|
|
14
|
+
<option value="thisWeek">This Week</option>
|
|
15
|
+
<option value="thisMonth">This Month</option>
|
|
16
|
+
<option value="thisYear">This Year</option>
|
|
17
|
+
</Dropdown>
|
|
18
|
+
<Datepicker class="w-[150px]" mode="popup" v-model="value.value" />
|
|
19
|
+
<Datepicker v-if="value.operator === 'between'" class="w-[150px]" mode="popup" v-model="value.value2" />
|
|
20
|
+
<button v-if="index >= 1" type="button" class="p-1" @click="$emit('remove')">
|
|
21
|
+
<svg width="14" height="14" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z"/></svg>
|
|
22
|
+
</button>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div v-else-if="type === 'number'" class="flex flex-row gap-2">
|
|
27
|
+
<Dropdown v-model="value.operator" class="w-[100px]">
|
|
28
|
+
<option value="=">=</option>
|
|
29
|
+
<option value=">">></option>
|
|
30
|
+
<option value=">=">>=</option>
|
|
31
|
+
<option value="<"><</option>
|
|
32
|
+
<option value="<="><=</option>
|
|
33
|
+
<option value="in">Multiple with comma</option>
|
|
34
|
+
<option value="notIn">Except with comma</option>
|
|
35
|
+
</Dropdown>
|
|
36
|
+
<Textbox v-model="value.value" />
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div v-else-if="type === 'boolean'" class="flex flex-row gap-2">
|
|
40
|
+
<Radio :name="value.key" :value="true" v-model="value.value">True</Radio>
|
|
41
|
+
<Radio :name="value.key" :value="false" v-model="value.value">False</Radio>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div v-else class="flex flex-row gap-2">
|
|
45
|
+
<Dropdown v-model="value.operator" class="w-[100px]">
|
|
46
|
+
<option value="eq">Equal</option>
|
|
47
|
+
<option value="not">Not Equal</option>
|
|
48
|
+
<option value="startsWith">Starts With</option>
|
|
49
|
+
<option value="endsWith">Ends With</option>
|
|
50
|
+
<option value="contains">Contains</option>
|
|
51
|
+
<option value="notContains">Not Contains</option>
|
|
52
|
+
<option value="in">Multiple with comma</option>
|
|
53
|
+
<option value="notIn">Except with comma</option>
|
|
54
|
+
<option value="regex">Regex</option>
|
|
55
|
+
</Dropdown>
|
|
56
|
+
<Textbox v-model="value.value" />
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<script>
|
|
62
|
+
|
|
63
|
+
export default{
|
|
64
|
+
|
|
65
|
+
emits: [ 'remove' ],
|
|
66
|
+
|
|
67
|
+
props: {
|
|
68
|
+
|
|
69
|
+
index: Number,
|
|
70
|
+
type: String,
|
|
71
|
+
value: Object,
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<style module>
|
|
80
|
+
|
|
81
|
+
.comp{
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
</style>
|
|
@@ -189,13 +189,13 @@ export default{
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
.comp .tag{
|
|
192
|
-
@apply bg-
|
|
193
|
-
@apply font-mono text-
|
|
192
|
+
@apply bg-text-100 p-1 rounded-lg whitespace-nowrap relative top-[-1px];
|
|
193
|
+
@apply font-mono text-sm;
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
.tag2{
|
|
197
197
|
@apply bg-text-50 p-1 rounded-lg px-2 cursor-pointer;
|
|
198
|
-
@apply hover:bg-
|
|
198
|
+
@apply hover:bg-text-100 hover:text-white;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
.noScrollbar::-webkit-scrollbar{
|