@mixd-id/web-scaffold 0.1.230406060 → 0.1.230406061
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 +3 -2
- package/src/components/ColorPicker.vue +84 -0
- package/src/components/ImagePreview.vue +1 -1
- package/src/components/ListView.vue +43 -19
- package/src/components/Modal.vue +3 -2
- package/src/components/VirtualScroll.vue +3 -5
- package/src/index.js +1 -0
- package/src/utils/listview.js +1507 -0
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.
|
|
4
|
+
"version": "0.1.230406061",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite serve",
|
|
7
7
|
"build": "vite build",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"import": "./src/utils/helpers.mjs"
|
|
17
17
|
},
|
|
18
18
|
"./importer": "./src/utils/importer.js",
|
|
19
|
-
"./listpage1": "./src/utils/listpage1.js"
|
|
19
|
+
"./listpage1": "./src/utils/listpage1.js",
|
|
20
|
+
"./listview": "./src/utils/listview.js"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
23
|
"@faker-js/faker": "^7.3.0",
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="$style.comp">
|
|
3
|
+
<div :class="$style.circle" @click="$refs.contextMenu.open($refs.btn)"
|
|
4
|
+
ref="btn" :style="{ backgroundColor:this.modelValue }"></div>
|
|
5
|
+
<input type="color" :class="$style.inputColor" ref="inputColor"
|
|
6
|
+
@change="select($refs.inputColor.value)"/>
|
|
7
|
+
|
|
8
|
+
<ContextMenu ref="contextMenu" :dismiss="false">
|
|
9
|
+
<div class="p-4 flex flex-col gap-4">
|
|
10
|
+
<div class="grid grid-cols-6 gap-4">
|
|
11
|
+
<div v-for="color in colors">
|
|
12
|
+
<div :class="$style.circle" :style="{ backgroundColor:color }"
|
|
13
|
+
@click="select(color)"></div>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
<button type="button" v-if="Boolean(customColor)"
|
|
17
|
+
class="w-full p-1 border-text-100 border-[1px] rounded-lg"
|
|
18
|
+
@click="$refs.inputColor.click()">Custom</button>
|
|
19
|
+
</div>
|
|
20
|
+
</ContextMenu>
|
|
21
|
+
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
|
|
27
|
+
export default{
|
|
28
|
+
|
|
29
|
+
props: {
|
|
30
|
+
|
|
31
|
+
colors: Array,
|
|
32
|
+
|
|
33
|
+
customColor: undefined,
|
|
34
|
+
|
|
35
|
+
modelValue: String
|
|
36
|
+
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
methods: {
|
|
40
|
+
|
|
41
|
+
select(color){
|
|
42
|
+
this.$emit('update:modelValue', color)
|
|
43
|
+
this.$refs.contextMenu.close()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
computed:{
|
|
49
|
+
|
|
50
|
+
customColorCount(){
|
|
51
|
+
const count = parseInt(this.customColor)
|
|
52
|
+
return isNaN(count) ? 0 : count
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
data(){
|
|
58
|
+
return {
|
|
59
|
+
customColors: []
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<style module>
|
|
68
|
+
|
|
69
|
+
.comp{
|
|
70
|
+
@apply p-[2px] border-[1px] border-text-200 rounded-full relative;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.circle{
|
|
74
|
+
@apply w-[19px] h-[19px] rounded-full cursor-pointer;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.inputColor{
|
|
78
|
+
@apply absolute top-0 left-0;
|
|
79
|
+
width: 0;
|
|
80
|
+
height: 0;
|
|
81
|
+
opacity: 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="$style.comp"
|
|
2
|
+
<div :class="$style.comp">
|
|
3
3
|
|
|
4
4
|
<slot v-if="$slots.head" name="head"></slot>
|
|
5
5
|
<div v-else class="flex flex-row items-center gap-4 px-6 md:px-0 py-4 md:py-0 bg-base-400 dark:bg-base-300 md:bg-transparent">
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
class="flex-1 md:flex-none flex flex-row gap-1 items-center text-left md:ml-2"
|
|
9
9
|
@click="$refs.presetSelector.toggle($refs.presetSelectorBtn)">
|
|
10
10
|
<h2 class="overflow-hidden whitespace-nowrap text-ellipsis">{{ preset.name }}</h2>
|
|
11
|
-
<svg width="
|
|
11
|
+
<svg width="13" height="13" class="ml-1 relative top-[2px] fill-text 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>
|
|
12
12
|
</button>
|
|
13
13
|
|
|
14
14
|
<ContextMenu ref="presetSelector">
|
|
@@ -53,8 +53,9 @@
|
|
|
53
53
|
|
|
54
54
|
<slot name="headerOpt"></slot>
|
|
55
55
|
|
|
56
|
-
<Textbox :placeholder="$t('Search...')" :clearable="true"
|
|
57
|
-
@
|
|
56
|
+
<Textbox v-if="mediaPrefix && mediaPrefix !== 'sm'" :placeholder="$t('Search...')" :clearable="true"
|
|
57
|
+
@clear="clearSearch" v-model="preset.search"
|
|
58
|
+
@keyup.enter="load" :class="$style.searchBox">
|
|
58
59
|
<template #start>
|
|
59
60
|
<div class="pl-2">
|
|
60
61
|
<svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208 32s176 78.7 176 176-78.7 176-176 176z"/></svg>
|
|
@@ -63,9 +64,9 @@
|
|
|
63
64
|
</Textbox>
|
|
64
65
|
</div>
|
|
65
66
|
|
|
66
|
-
<div v-if="mediaPrefix === 'sm'" class="px-6 pb-4 border-b-[1px] border-text-50 bg-base-400 dark:bg-base-300">
|
|
67
|
+
<div v-if="mediaPrefix && mediaPrefix === 'sm'" class="px-6 pb-4 border-b-[1px] border-text-50 bg-base-400 dark:bg-base-300">
|
|
67
68
|
<Textbox :placeholder="$t('Search...')" :clearable="true" @clear="clearSearch" v-model="preset.search"
|
|
68
|
-
@keyup.enter="load" :class="$style.
|
|
69
|
+
@keyup.enter="load" :class="$style.searchBox2">
|
|
69
70
|
<template #start>
|
|
70
71
|
<div class="pl-2">
|
|
71
72
|
<svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208 32s176 78.7 176 176-78.7 176-176 176z"/></svg>
|
|
@@ -74,8 +75,24 @@
|
|
|
74
75
|
</Textbox>
|
|
75
76
|
</div>
|
|
76
77
|
|
|
78
|
+
<div class="grid grid-cols-4 gap-4 hidden">
|
|
79
|
+
<div v-for="i in 4">
|
|
80
|
+
<div class="p-3 rounded-lg bg-base-400 border-[1px] border-text-50">
|
|
81
|
+
<label>Value</label>
|
|
82
|
+
<h2>23,000</h2>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
77
87
|
<div class="flex-1 flex" v-if="mediaPrefix">
|
|
78
|
-
<
|
|
88
|
+
<VirtualScroll v-if="mediaPrefix === 'sm'" :items="items" ref="table2"
|
|
89
|
+
class="flex-1 bg-base-400 dark:bg-base-300" @scroll-end="loadNext">
|
|
90
|
+
<template #item="{ item }">
|
|
91
|
+
<slot name="mobileItem" :item="item"></slot>
|
|
92
|
+
</template>
|
|
93
|
+
</VirtualScroll>
|
|
94
|
+
|
|
95
|
+
<VirtualTable v-else ref="table1" :columns="presetColumns" :items="items"
|
|
79
96
|
class="flex-1 bg-base-400"
|
|
80
97
|
@scroll-end="loadNext">
|
|
81
98
|
<template v-for="column in presetColumns" #[colOf(column.key)]="{}">
|
|
@@ -110,11 +127,6 @@
|
|
|
110
127
|
<slot :name="slot" :item="item" :index="index"></slot>
|
|
111
128
|
</template>
|
|
112
129
|
</VirtualTable>
|
|
113
|
-
<VirtualScroll v-else :items="items" ref="table2" class="flex-1 bg-base-400 dark:bg-base-300" @scroll-end="loadNext">
|
|
114
|
-
<template #item="{ item }">
|
|
115
|
-
<slot name="mobileItem" :item="item"></slot>
|
|
116
|
-
</template>
|
|
117
|
-
</VirtualScroll>
|
|
118
130
|
</div>
|
|
119
131
|
|
|
120
132
|
<ContextMenu ref="columnMenu" :dismiss="false">
|
|
@@ -214,7 +226,7 @@ export default{
|
|
|
214
226
|
this.presetFilterSelector = null
|
|
215
227
|
},
|
|
216
228
|
|
|
217
|
-
calcMediaPrefix
|
|
229
|
+
calcMediaPrefix() {
|
|
218
230
|
if(!this.$el) return
|
|
219
231
|
|
|
220
232
|
const w = this.$el.clientWidth
|
|
@@ -238,7 +250,7 @@ export default{
|
|
|
238
250
|
}
|
|
239
251
|
|
|
240
252
|
this.mediaPrefix = prefix
|
|
241
|
-
},
|
|
253
|
+
},
|
|
242
254
|
|
|
243
255
|
clearSearch(){
|
|
244
256
|
this.preset.search = ''
|
|
@@ -268,10 +280,16 @@ export default{
|
|
|
268
280
|
load(){
|
|
269
281
|
if(!this.src) return
|
|
270
282
|
|
|
283
|
+
this.$refs.table1 ? this.$refs.table1.setState(2) : this.$refs.table2.setState(3)
|
|
271
284
|
this.socketEmit2(this.src, { preset: this.preset })
|
|
272
285
|
.then((res) => {
|
|
273
286
|
Object.assign(this.$data, res)
|
|
274
287
|
})
|
|
288
|
+
.finally(() => {
|
|
289
|
+
this.$refs.table1 ? this.$refs.table1.setState(1) : this.$refs.table2.setState(1)
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
this.loadSummary()
|
|
275
293
|
},
|
|
276
294
|
|
|
277
295
|
loadNext(){
|
|
@@ -293,6 +311,7 @@ export default{
|
|
|
293
311
|
},
|
|
294
312
|
|
|
295
313
|
async loadConfig(){
|
|
314
|
+
|
|
296
315
|
if(!this.configStoreObj || 'reset' in ((this.$route ?? {}).query ?? {})){
|
|
297
316
|
this.configLoaded = true
|
|
298
317
|
return
|
|
@@ -308,7 +327,6 @@ export default{
|
|
|
308
327
|
}
|
|
309
328
|
|
|
310
329
|
this.configLoaded = true
|
|
311
|
-
this.$nextTick(() => this.calcMediaPrefix())
|
|
312
330
|
})
|
|
313
331
|
}
|
|
314
332
|
},
|
|
@@ -531,20 +549,22 @@ export default{
|
|
|
531
549
|
configLoaded: false,
|
|
532
550
|
selectedColumn: null,
|
|
533
551
|
copiedConfig: null,
|
|
534
|
-
mediaPrefix:
|
|
552
|
+
mediaPrefix: null
|
|
535
553
|
}
|
|
536
554
|
},
|
|
537
555
|
|
|
538
556
|
|
|
539
557
|
mounted() {
|
|
540
|
-
window.addEventListener('resize', () => this.calcMediaPrefix())
|
|
558
|
+
window.addEventListener('resize', throttle(() => this.calcMediaPrefix(), 100, { leading:true }))
|
|
541
559
|
this.calcMediaPrefix()
|
|
560
|
+
|
|
542
561
|
this.socket.onAny(this.onHooks)
|
|
543
562
|
|
|
544
563
|
window.setTimeout(() => {
|
|
545
564
|
this.loadConfig().then(() => {
|
|
546
|
-
|
|
547
|
-
|
|
565
|
+
window.setTimeout(() => {})
|
|
566
|
+
this.load()
|
|
567
|
+
}, 1000)
|
|
548
568
|
}, 201)
|
|
549
569
|
|
|
550
570
|
this.subscribe()
|
|
@@ -579,6 +599,10 @@ export default{
|
|
|
579
599
|
@apply !bg-base-400 md:w-[300px];
|
|
580
600
|
}
|
|
581
601
|
|
|
602
|
+
.searchBox2{
|
|
603
|
+
@apply bg-text-50;
|
|
604
|
+
}
|
|
605
|
+
|
|
582
606
|
.header{
|
|
583
607
|
@apply p-2 cursor-pointer border-b-[2px] border-transparent overflow-hidden;
|
|
584
608
|
}
|
package/src/components/Modal.vue
CHANGED
|
@@ -205,7 +205,8 @@ export default{
|
|
|
205
205
|
|
|
206
206
|
.modal{
|
|
207
207
|
@apply fixed;
|
|
208
|
-
@apply bg-base-
|
|
208
|
+
@apply bg-base-300;
|
|
209
|
+
@apply border-[1px] border-text-50 z-20 flex max-h-[90vh];
|
|
209
210
|
@apply rounded-xl overflow-hidden;
|
|
210
211
|
transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
|
|
211
212
|
}
|
|
@@ -215,7 +216,7 @@ export default{
|
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
.modalBody{
|
|
218
|
-
@apply flex-1 min-h-0 overflow-y-auto flex;
|
|
219
|
+
@apply flex-1 min-h-0 overflow-y-auto flex bg-base-400 dark:bg-base-300;
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
.overlay{
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="$style.comp">
|
|
3
|
-
<div v-if="state ===
|
|
4
|
-
<
|
|
5
|
-
<svg class="animate-spin aspect-square w-[16px] h-[16px] text-primary" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
|
|
6
|
-
</div>
|
|
3
|
+
<div v-if="state === 3" ref="spinner" class="flex-1 flex items-center justify-center p-8">
|
|
4
|
+
<svg class="animate-spin aspect-square w-[32px] h-[32px] text-primary" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
|
|
7
5
|
</div>
|
|
8
|
-
<div ref="scroller" :class="$style.scroller" :style="scrollerStyle">
|
|
6
|
+
<div v-else ref="scroller" :class="$style.scroller" :style="scrollerStyle">
|
|
9
7
|
<div v-if="visibleItems && visibleItems.length > 0" :class="$style.spacer" ref="spacer" :style="spacerStyle">
|
|
10
8
|
<div v-for="(item, index) in visibleItems" :key="item" :data-id="item.id"
|
|
11
9
|
@click="select(item, index)"
|
package/src/index.js
CHANGED
|
@@ -225,6 +225,7 @@ export default{
|
|
|
225
225
|
app.component('Alert', defineAsyncComponent(() => import("./components/Alert.vue")))
|
|
226
226
|
app.component('Button', defineAsyncComponent(() => import("./components/Button.vue")))
|
|
227
227
|
app.component('Box', defineAsyncComponent(() => import("./components/Box.vue")))
|
|
228
|
+
app.component('ColorPicker', defineAsyncComponent(() => import("./components/ColorPicker.vue")))
|
|
228
229
|
app.component('SearchButton', defineAsyncComponent(() => import("./components/SearchButton.vue")))
|
|
229
230
|
app.component('ButtonGroup', defineAsyncComponent(() => import("./components/ButtonGroup.vue")))
|
|
230
231
|
app.component('ChatTyping', defineAsyncComponent(() => import("./components/ChatTyping.vue")))
|