@mixd-id/web-scaffold 0.1.230406041 → 0.1.230406043
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/Alert.vue +5 -6
- package/src/components/Box.vue +25 -0
- package/src/components/Datepicker.vue +2 -5
- package/src/components/ListView.vue +459 -0
- package/src/components/ListViewSettings.vue +598 -0
- package/src/components/PageBuilder.vue +449 -0
- package/src/components/VirtualScroll.vue +5 -1
- package/src/index.js +5 -1
- package/src/utils/helpers.mjs +8 -1
package/package.json
CHANGED
package/src/components/Alert.vue
CHANGED
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
<path d="M13 16C13 16.5523 12.5523 17 12 17C11.4477 17 11 16.5523 11 16C11 15.4477 11.4477 15 12 15C12.5523 15 13 15.4477 13 16Z"/>
|
|
16
16
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 20.5C16.6944 20.5 20.5 16.6944 20.5 12C20.5 7.30558 16.6944 3.5 12 3.5C7.30558 3.5 3.5 7.30558 3.5 12C3.5 16.6944 7.30558 20.5 12 20.5ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"/>
|
|
17
17
|
</svg>
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
<div :class="$style.cont2">
|
|
20
20
|
<h5 :class="$style.title">{{ title }}</h5>
|
|
21
21
|
<p :class="$style.description">{{ description }}</p>
|
|
22
22
|
</div>
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
<div class="mt-4" v-if="mode === 'alert'">
|
|
25
25
|
<Button @click="$emit('dismiss')" class="min-w-[88px]">
|
|
26
26
|
<strong class="px-4">
|
|
@@ -104,9 +104,8 @@ export default{
|
|
|
104
104
|
else if(this.state.title.message){
|
|
105
105
|
description = this.state.title.message
|
|
106
106
|
}
|
|
107
|
-
else if(this.state.title.reason && this.state.title.reason.message
|
|
108
|
-
|
|
109
|
-
description = this.state.title.reason.message.message
|
|
107
|
+
else if(this.state.title.reason && this.state.title.reason.message){
|
|
108
|
+
description = this.state.title.reason.message
|
|
110
109
|
}
|
|
111
110
|
}
|
|
112
111
|
else{
|
|
@@ -197,4 +196,4 @@ export default{
|
|
|
197
196
|
opacity: 0;
|
|
198
197
|
}
|
|
199
198
|
|
|
200
|
-
</style>
|
|
199
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="$style.comp">
|
|
3
|
+
<h1>{{ title }}</h1>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
|
|
9
|
+
export default{
|
|
10
|
+
|
|
11
|
+
props: {
|
|
12
|
+
title: String
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<style module>
|
|
20
|
+
|
|
21
|
+
.comp{
|
|
22
|
+
@apply flex-1 bg-base-300 flex items-center justify-center;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
</style>
|
|
@@ -133,10 +133,7 @@ export default{
|
|
|
133
133
|
default: ''
|
|
134
134
|
},
|
|
135
135
|
|
|
136
|
-
modelValue:
|
|
137
|
-
type: String,
|
|
138
|
-
default: currentDate
|
|
139
|
-
}
|
|
136
|
+
modelValue:String
|
|
140
137
|
|
|
141
138
|
},
|
|
142
139
|
|
|
@@ -309,4 +306,4 @@ export default{
|
|
|
309
306
|
@apply bg-primary;
|
|
310
307
|
}
|
|
311
308
|
|
|
312
|
-
</style>
|
|
309
|
+
</style>
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="$style.comp" v-if="true || configLoaded">
|
|
3
|
+
|
|
4
|
+
<slot v-if="$slots.head" name="head"></slot>
|
|
5
|
+
<div v-else class="flex flex-row items-center gap-4">
|
|
6
|
+
<div class="flex flex-row gap-1">
|
|
7
|
+
<button type="button" class="flex flex-row gap-1 items-center">
|
|
8
|
+
<h3>{{ title }}</h3>
|
|
9
|
+
<svg width="16" height="16" class="fill-text-300 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>
|
|
10
|
+
</button>
|
|
11
|
+
<button type="button" @click="$refs.setting.open()">
|
|
12
|
+
<svg width="16" height="16" class="fill-text-300 hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M452.515 237l31.843-18.382c9.426-5.441 13.996-16.542 11.177-27.054-11.404-42.531-33.842-80.547-64.058-110.797-7.68-7.688-19.575-9.246-28.985-3.811l-31.785 18.358a196.276 196.276 0 0 0-32.899-19.02V39.541a24.016 24.016 0 0 0-17.842-23.206c-41.761-11.107-86.117-11.121-127.93-.001-10.519 2.798-17.844 12.321-17.844 23.206v36.753a196.276 196.276 0 0 0-32.899 19.02l-31.785-18.358c-9.41-5.435-21.305-3.877-28.985 3.811-30.216 30.25-52.654 68.265-64.058 110.797-2.819 10.512 1.751 21.613 11.177 27.054L59.485 237a197.715 197.715 0 0 0 0 37.999l-31.843 18.382c-9.426 5.441-13.996 16.542-11.177 27.054 11.404 42.531 33.842 80.547 64.058 110.797 7.68 7.688 19.575 9.246 28.985 3.811l31.785-18.358a196.202 196.202 0 0 0 32.899 19.019v36.753a24.016 24.016 0 0 0 17.842 23.206c41.761 11.107 86.117 11.122 127.93.001 10.519-2.798 17.844-12.321 17.844-23.206v-36.753a196.34 196.34 0 0 0 32.899-19.019l31.785 18.358c9.41 5.435 21.305 3.877 28.985-3.811 30.216-30.25 52.654-68.266 64.058-110.797 2.819-10.512-1.751-21.613-11.177-27.054L452.515 275c1.22-12.65 1.22-25.35 0-38zm-52.679 63.019l43.819 25.289a200.138 200.138 0 0 1-33.849 58.528l-43.829-25.309c-31.984 27.397-36.659 30.077-76.168 44.029v50.599a200.917 200.917 0 0 1-67.618 0v-50.599c-39.504-13.95-44.196-16.642-76.168-44.029l-43.829 25.309a200.15 200.15 0 0 1-33.849-58.528l43.819-25.289c-7.63-41.299-7.634-46.719 0-88.038l-43.819-25.289c7.85-21.229 19.31-41.049 33.849-58.529l43.829 25.309c31.984-27.397 36.66-30.078 76.168-44.029V58.845a200.917 200.917 0 0 1 67.618 0v50.599c39.504 13.95 44.196 16.642 76.168 44.029l43.829-25.309a200.143 200.143 0 0 1 33.849 58.529l-43.819 25.289c7.631 41.3 7.634 46.718 0 88.037zM256 160c-52.935 0-96 43.065-96 96s43.065 96 96 96 96-43.065 96-96-43.065-96-96-96zm0 144c-26.468 0-48-21.532-48-48 0-26.467 21.532-48 48-48s48 21.533 48 48c0 26.468-21.532 48-48 48z"/></svg>
|
|
13
|
+
</button>
|
|
14
|
+
|
|
15
|
+
<Modal ref="setting" width="680" height="560">
|
|
16
|
+
<template #head>
|
|
17
|
+
<div class="relative">
|
|
18
|
+
<div class="absolute top-0 right-0 p-2">
|
|
19
|
+
<button type="button" class="p-2" @click="$refs.setting.close()">
|
|
20
|
+
<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">
|
|
21
|
+
<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"/>
|
|
22
|
+
</svg>
|
|
23
|
+
</button>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
<ListViewSettings class="flex-1"
|
|
28
|
+
:config="config"
|
|
29
|
+
@change="load" />
|
|
30
|
+
</Modal>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="flex-1">
|
|
34
|
+
<slot name="headerOpt"></slot>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<Textbox :placeholder="$t('Search...')" :clearable="true" @clear="clearSearch" v-model="preset.search"
|
|
38
|
+
@keyup.enter="load" :class="$style.searchBox">
|
|
39
|
+
<template #start>
|
|
40
|
+
<div class="pl-2">
|
|
41
|
+
<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>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
</Textbox>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<VirtualTable ref="table1" :columns="presetColumns" :items="items" class="flex-1"
|
|
48
|
+
@scroll-end="loadNext">
|
|
49
|
+
<template v-for="column in presetColumns" #[colOf(column.key)]="{}">
|
|
50
|
+
<div :class="getHeader(column)" @click="openColumnOptions(column.key, $event.target.closest('.' + $style.header))">
|
|
51
|
+
<div>
|
|
52
|
+
{{ column.label ?? column.key }}
|
|
53
|
+
</div>
|
|
54
|
+
<div class="absolute top-0 right-0 p-2 bg-base-500" v-if="false">
|
|
55
|
+
<svg width="19" height="19" viewBox="0 0 24 24" class="fill-text-400" xmlns="http://www.w3.org/2000/svg">
|
|
56
|
+
<path d="M6.75 5C6.75 4.58579 6.41421 4.25 6 4.25C5.58579 4.25 5.25 4.58579 5.25 5V17.6893L3.53033 15.9697C3.23744 15.6768 2.76256 15.6768 2.46967 15.9697C2.17678 16.2626 2.17678 16.7374 2.46967 17.0303L4.76256 19.3232C5.44598 20.0066 6.55402 20.0066 7.23744 19.3232L9.53033 17.0303C9.82322 16.7374 9.82322 16.2626 9.53033 15.9697C9.23744 15.6768 8.76256 15.6768 8.46967 15.9697L6.75 17.6893V5Z"/>
|
|
57
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 17C12.25 17.4142 12.5858 17.75 13 17.75H21C21.4142 17.75 21.75 17.4142 21.75 17C21.75 16.5858 21.4142 16.25 21 16.25H13C12.5858 16.25 12.25 16.5858 12.25 17Z"/>
|
|
58
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 12C12.25 11.5858 12.5858 11.25 13 11.25H18C18.4142 11.25 18.75 11.5858 18.75 12C18.75 12.4142 18.4142 12.75 18 12.75H13C12.5858 12.75 12.25 12.4142 12.25 12Z"/>
|
|
59
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 7C12.25 6.58579 12.5858 6.25 13 6.25H15C15.4142 6.25 15.75 6.58579 15.75 7C15.75 7.41421 15.4142 7.75 15 7.75H13C12.5858 7.75 12.25 7.41421 12.25 7Z"/>
|
|
60
|
+
</svg>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="absolute top-0 right-0 p-2 bg-base-500" v-else-if="false">
|
|
63
|
+
<svg width="19" height="19" viewBox="0 0 24 24" class="fill-text-400" xmlns="http://www.w3.org/2000/svg">
|
|
64
|
+
<path d="M6.75 5C6.75 4.58579 6.41421 4.25 6 4.25C5.58579 4.25 5.25 4.58579 5.25 5V17.6893L3.53033 15.9697C3.23744 15.6768 2.76256 15.6768 2.46967 15.9697C2.17678 16.2626 2.17678 16.7374 2.46967 17.0303L4.76256 19.3232C5.44598 20.0066 6.55402 20.0066 7.23744 19.3232L9.53033 17.0303C9.82322 16.7374 9.82322 16.2626 9.53033 15.9697C9.23744 15.6768 8.76256 15.6768 8.46967 15.9697L6.75 17.6893V5Z"/>
|
|
65
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 7C12.25 6.58579 12.5858 6.25 13 6.25H21C21.4142 6.25 21.75 6.58579 21.75 7C21.75 7.41421 21.4142 7.75 21 7.75H13C12.5858 7.75 12.25 7.41421 12.25 7Z"/>
|
|
66
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 12C12.25 12.4142 12.5858 12.75 13 12.75H18C18.4142 12.75 18.75 12.4142 18.75 12C18.75 11.5858 18.4142 11.25 18 11.25H13C12.5858 11.25 12.25 11.5858 12.25 12Z"/>
|
|
67
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.25 17C12.25 17.4142 12.5858 17.75 13 17.75H15C15.4142 17.75 15.75 17.4142 15.75 17C15.75 16.5858 15.4142 16.25 15 16.25H13C12.5858 16.25 12.25 16.5858 12.25 17Z"/>
|
|
68
|
+
</svg>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</template>
|
|
72
|
+
<template v-for="(_, slot) in headerSlots" #[slot]="{ item, index }">
|
|
73
|
+
<div :class="getHeader(slot.replace('col-', ''))">
|
|
74
|
+
<slot :name="slot" :item="item" :index="index"></slot>
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
77
|
+
<template v-for="(_, slot) in contentSlots" #[slot]="{ item, index }">
|
|
78
|
+
<slot :name="slot" :item="item" :index="index"></slot>
|
|
79
|
+
</template>
|
|
80
|
+
</VirtualTable>
|
|
81
|
+
|
|
82
|
+
<ContextMenu ref="columnMenu" :dismiss="false">
|
|
83
|
+
<div class="flex-1 flex flex-col w-[270px] p-3">
|
|
84
|
+
<div class="flex flex-col">
|
|
85
|
+
<div class="flex flex-row gap-2 items-center">
|
|
86
|
+
<div class="p-2 text-text-300 flex-1">Sort By</div>
|
|
87
|
+
<div class="text-primary cursor-pointer text-sm" @click="openPreset('sort');$refs.columnMenu.close()">Sort Options</div>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="p-2 cursor-pointer" :class="$style.hoverable" @click="setSortCurrent(1)">Sort Ascending</div>
|
|
90
|
+
<div class="p-2 cursor-pointer" :class="$style.hoverable" @click="setSortCurrent(2)">Sort Descending</div>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="h-[1px] bg-text-50 my-2"></div>
|
|
93
|
+
<div class="flex flex-col">
|
|
94
|
+
<div class="p-2 cursor-pointer" :class="$style.hoverable" @click="hide">Hide</div>
|
|
95
|
+
<div class="p-2 cursor-pointer" :class="$style.hoverable" @click="openPreset();$refs.columnMenu.close()">Column Options</div>
|
|
96
|
+
</div>
|
|
97
|
+
<div class="h-[1px] bg-text-50 my-2"></div>
|
|
98
|
+
<div class="flex flex-col">
|
|
99
|
+
<div class="flex flex-row gap-2 items-center">
|
|
100
|
+
<div class="p-2 text-text-300 flex-1">Filters</div>
|
|
101
|
+
<div class="text-primary cursor-pointer text-sm" @click="openPreset('filter');$refs.columnMenu.close()">Filter Options</div>
|
|
102
|
+
</div>
|
|
103
|
+
<div v-if="presetCurrentFilters.length > 0">
|
|
104
|
+
<ListPage1Filter v-if="preset.filters" v-for="filter in presetCurrentFilters"
|
|
105
|
+
:filter="filter" :column="config.columns[filter.key]"
|
|
106
|
+
@remove="removeFilter(filter)" @change="load" />
|
|
107
|
+
</div>
|
|
108
|
+
<div v-else>
|
|
109
|
+
<div class="p-2 cursor-pointer" :class="$style.hoverable" @click.stop="addCurrentFilter">Add Filter</div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</ContextMenu>
|
|
114
|
+
|
|
115
|
+
</div>
|
|
116
|
+
</template>
|
|
117
|
+
|
|
118
|
+
<script>
|
|
119
|
+
|
|
120
|
+
import throttle from "lodash/throttle";
|
|
121
|
+
import VirtualTable from "./VirtualTable.vue";
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
export default{
|
|
125
|
+
components: {VirtualTable},
|
|
126
|
+
|
|
127
|
+
emits: [ ],
|
|
128
|
+
|
|
129
|
+
props: {
|
|
130
|
+
|
|
131
|
+
src: String,
|
|
132
|
+
|
|
133
|
+
model: String,
|
|
134
|
+
name: String,
|
|
135
|
+
channel: String,
|
|
136
|
+
|
|
137
|
+
config: {
|
|
138
|
+
type: Object,
|
|
139
|
+
defaultValue: {}
|
|
140
|
+
},
|
|
141
|
+
configStore: String,
|
|
142
|
+
subscription: String,
|
|
143
|
+
|
|
144
|
+
title: String
|
|
145
|
+
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
methods: {
|
|
149
|
+
|
|
150
|
+
addCurrentFilter(){
|
|
151
|
+
this.addFilter(this.selectedColumn)
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
addFilter(key){
|
|
155
|
+
|
|
156
|
+
const column = this.config.columns[key]
|
|
157
|
+
|
|
158
|
+
if(!this.preset.filters){
|
|
159
|
+
this.preset.filters = []
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let filters = [{}]
|
|
163
|
+
switch(column.type){
|
|
164
|
+
case 'date':
|
|
165
|
+
case 'enum':
|
|
166
|
+
filters = [{ value:[] }]
|
|
167
|
+
break
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
this.preset.filters.push({
|
|
171
|
+
enabled: true,
|
|
172
|
+
key: column.key,
|
|
173
|
+
label: column.label,
|
|
174
|
+
type: column.type,
|
|
175
|
+
typeParams: column.typeParams,
|
|
176
|
+
filters
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
this.presetFilterSelector = null
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
clearSearch(){
|
|
183
|
+
this.preset.search = ''
|
|
184
|
+
this.load()
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
colOf(key){
|
|
188
|
+
return 'col-' + key
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
getHeader(column){
|
|
192
|
+
|
|
193
|
+
return [
|
|
194
|
+
this.$style.header,
|
|
195
|
+
(this.preset.filters ?? []).findIndex((_) => _.key === column.key && _.enabled) >= 0 ?
|
|
196
|
+
this.$style.headerSelected : ''
|
|
197
|
+
]
|
|
198
|
+
.join(' ')
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
hide(){
|
|
202
|
+
const idx = this.preset.columns.findIndex((_) => _.key === this.selectedColumn)
|
|
203
|
+
this.preset.columns[idx].visible = false
|
|
204
|
+
this.$refs.columnMenu.close()
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
load(){
|
|
208
|
+
if(!this.src) return
|
|
209
|
+
|
|
210
|
+
this.socketEmit2(this.src, { preset: this.preset })
|
|
211
|
+
.then((res) => {
|
|
212
|
+
Object.assign(this.$data, res)
|
|
213
|
+
})
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
loadNext(){
|
|
217
|
+
|
|
218
|
+
this.$refs.table1.setState(2)
|
|
219
|
+
this.socketEmit2(this.src, {
|
|
220
|
+
preset: this.preset,
|
|
221
|
+
afterItem: this.items[this.items.length - 1]
|
|
222
|
+
})
|
|
223
|
+
.then((res) => {
|
|
224
|
+
this.items.push(...res.items)
|
|
225
|
+
this.hasNext = res.hasNext
|
|
226
|
+
console.log('loadNext', this.$data)
|
|
227
|
+
})
|
|
228
|
+
.catch((err) => {
|
|
229
|
+
this.toast(err)
|
|
230
|
+
})
|
|
231
|
+
.finally(() => this.$refs.table1.setState(1))
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
async loadConfig(){
|
|
235
|
+
if(!this.configStoreObj) return
|
|
236
|
+
|
|
237
|
+
switch(this.configStoreObj.type){
|
|
238
|
+
case 'socket':
|
|
239
|
+
return this.socketEmit2(this.configStoreObj.src,
|
|
240
|
+
{ key:this.configStoreObj.name ?? 'ListView' })
|
|
241
|
+
.then((config) => {
|
|
242
|
+
Object.assign(this.config, config ?? {})
|
|
243
|
+
this.configLoaded = true
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
onHooks(model, event, items){
|
|
249
|
+
console.log('onHooks', model, event, items)
|
|
250
|
+
if(model === this.subscriptionObj.model){
|
|
251
|
+
switch(event){
|
|
252
|
+
|
|
253
|
+
case 'create':
|
|
254
|
+
case 'update':
|
|
255
|
+
items.forEach((item) => {
|
|
256
|
+
this.$util.unshift(this.items, item)
|
|
257
|
+
})
|
|
258
|
+
break
|
|
259
|
+
|
|
260
|
+
case 'remove':
|
|
261
|
+
case 'destroy':
|
|
262
|
+
items.forEach((item) => {
|
|
263
|
+
const idx = this.items.findIndex((_) => _.id === item.id)
|
|
264
|
+
if(idx >= 0){
|
|
265
|
+
this.items.splice(idx, 1)
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
break
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
openColumnOptions(key, target){
|
|
274
|
+
this.selectedColumn = key
|
|
275
|
+
this.$refs.columnMenu.open(target)
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
openPreset(tab){
|
|
279
|
+
this.$refs.setting.open()
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
removeFilter(filter){
|
|
283
|
+
this.preset.filters.splice(this.preset.filters.indexOf(filter), 1)
|
|
284
|
+
this.load()
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
setSortCurrent(sortType){
|
|
288
|
+
this.preset.sorts = [
|
|
289
|
+
{
|
|
290
|
+
key: this.selectedColumn,
|
|
291
|
+
label: this.config.columns[this.selectedColumn].label,
|
|
292
|
+
type: sortType === 2 ? 'desc' : 'asc'
|
|
293
|
+
}
|
|
294
|
+
]
|
|
295
|
+
this.load()
|
|
296
|
+
this.$refs.columnMenu.close()
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
saveConfig: throttle(function() {
|
|
300
|
+
if(!this.configLoaded || !this.configStoreObj) return
|
|
301
|
+
switch(this.configStoreObj.type){
|
|
302
|
+
case 'socket':
|
|
303
|
+
this.socketEmit2(this.configStoreObj.src,
|
|
304
|
+
{ key:this.configStoreObj.name ?? 'ListView', config:this.config })
|
|
305
|
+
break
|
|
306
|
+
}
|
|
307
|
+
}, 1000, { leading:true }),
|
|
308
|
+
|
|
309
|
+
subscribe(){
|
|
310
|
+
if(!this.subscriptionObj) return
|
|
311
|
+
|
|
312
|
+
const { type, method, model } = this.subscriptionObj
|
|
313
|
+
|
|
314
|
+
switch(type){
|
|
315
|
+
|
|
316
|
+
case 'socket':
|
|
317
|
+
this.socketEmit2(method, { name:model }).then()
|
|
318
|
+
break
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
inject: [ 'socket', 'socketEmit2', 'toast', 'alert' ],
|
|
326
|
+
|
|
327
|
+
computed: {
|
|
328
|
+
|
|
329
|
+
subscriptionObj(){
|
|
330
|
+
const splitted = ((this.subscription ?? '').toString()).split(':')
|
|
331
|
+
const splitted2 = (splitted[1] ?? '').split(',')
|
|
332
|
+
const obj = {
|
|
333
|
+
type: splitted[0],
|
|
334
|
+
method: splitted2[0],
|
|
335
|
+
model: splitted2[1],
|
|
336
|
+
}
|
|
337
|
+
return obj.type && obj.method && obj.model ? obj : null
|
|
338
|
+
},
|
|
339
|
+
|
|
340
|
+
configStoreObj(){
|
|
341
|
+
const splitted = ((this.configStore ?? '').toString()).split(':')
|
|
342
|
+
const splitted2 = (splitted[1] ?? '').split(',')
|
|
343
|
+
const obj = {
|
|
344
|
+
type: splitted[0],
|
|
345
|
+
src: splitted2[0],
|
|
346
|
+
name: splitted2[1]
|
|
347
|
+
}
|
|
348
|
+
return obj.type && obj.src ? obj : null
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
contentSlots(){
|
|
352
|
+
const slots = {}
|
|
353
|
+
for(let key in this.$slots){
|
|
354
|
+
if(!key.startsWith('col-'))
|
|
355
|
+
slots[key] = this.$slots[key]
|
|
356
|
+
}
|
|
357
|
+
return slots
|
|
358
|
+
},
|
|
359
|
+
|
|
360
|
+
headerSlots(){
|
|
361
|
+
const slots = {}
|
|
362
|
+
for(let key in this.$slots){
|
|
363
|
+
if(key.startsWith('col-'))
|
|
364
|
+
slots[key] = this.$slots[key]
|
|
365
|
+
}
|
|
366
|
+
return slots
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
preset(){
|
|
370
|
+
return ((this.config ?? {}).presets ?? [])[(this.config ?? {}).presetIdx]
|
|
371
|
+
},
|
|
372
|
+
|
|
373
|
+
presetColumns(){
|
|
374
|
+
if(!this.preset.columns) return
|
|
375
|
+
|
|
376
|
+
for(let i = 0 ; i < (this.preset.columns).length ; i++){
|
|
377
|
+
const presetColumn = this.preset.columns[i]
|
|
378
|
+
const column = this.config.columns[presetColumn.key] ?? {}
|
|
379
|
+
for(let key in column){
|
|
380
|
+
if(!presetColumn[key]){
|
|
381
|
+
this.preset.columns[i][key] = column[key]
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return this.preset.columns
|
|
387
|
+
},
|
|
388
|
+
|
|
389
|
+
presetCurrentFilters(){
|
|
390
|
+
if(!this.preset.filters) return []
|
|
391
|
+
return this.preset.filters.filter((_) => _.key === this.selectedColumn)
|
|
392
|
+
},
|
|
393
|
+
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
data(){
|
|
397
|
+
return {
|
|
398
|
+
items: [],
|
|
399
|
+
hasNext: false,
|
|
400
|
+
count: null,
|
|
401
|
+
configLoaded: false,
|
|
402
|
+
selectedColumn: null
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
mounted() {
|
|
408
|
+
this.socket.onAny(this.onHooks)
|
|
409
|
+
|
|
410
|
+
window.setTimeout(() => {
|
|
411
|
+
this.loadConfig().then(() => {
|
|
412
|
+
this.load()
|
|
413
|
+
})
|
|
414
|
+
}, 201)
|
|
415
|
+
|
|
416
|
+
this.subscribe()
|
|
417
|
+
},
|
|
418
|
+
|
|
419
|
+
unmounted() {
|
|
420
|
+
this.socket.offAny(this.onHooks)
|
|
421
|
+
},
|
|
422
|
+
|
|
423
|
+
watch: {
|
|
424
|
+
|
|
425
|
+
config: {
|
|
426
|
+
deep: true,
|
|
427
|
+
handler(to){
|
|
428
|
+
this.saveConfig()
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
</script>
|
|
437
|
+
|
|
438
|
+
<style module>
|
|
439
|
+
|
|
440
|
+
.comp{
|
|
441
|
+
@apply flex-1 flex flex-col gap-4;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.header{
|
|
445
|
+
@apply p-2 cursor-pointer border-b-[2px] border-transparent overflow-hidden;
|
|
446
|
+
}
|
|
447
|
+
.header>*:first-child{
|
|
448
|
+
@apply text-ellipsis whitespace-nowrap overflow-x-hidden;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.searchBox{
|
|
452
|
+
@apply w-[300px] max-w-[30%];
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.hoverable{
|
|
456
|
+
@apply hover:bg-primary hover:text-white;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
</style>
|