@@ -8,19 +8,18 @@ import { useRouter } from 'vue-router'
8
8
import debounce from ' lodash/debounce'
9
9
10
10
import Item from ' @core/entities/item'
11
- import Collection , { CollectionColumn } from ' @core/entities/collection'
11
+ import Collection from ' @core/entities/collection'
12
12
import { ViewTable } from ' @core/entities/view'
13
13
14
- import { toCssMeasurement , useNonReactive } from ' @/composables/utils'
14
+ import { useNonReactive } from ' @/composables/utils'
15
+ import { filter } from ' @/modules/collection/composables/filter'
16
+ import { createBindings } from ' @/composables/binding'
15
17
import { useStore } from ' @/modules/collection/store'
16
18
17
- import { Filter , filter } from ' @/modules/collection/composables/filter'
18
-
19
19
import Draggable from ' vuedraggable'
20
20
import CColumn from ' ./CColumn.vue'
21
- import CFilter from ' ./CFilter .vue'
21
+ import CDrawerFilter from ' ./CDrawerFilter .vue'
22
22
import IValue from ' @/modules/item/components/IValue.vue'
23
- import { createBindings } from ' @/composables/binding'
24
23
25
24
const props = defineProps ({
26
25
width: {
@@ -75,22 +74,6 @@ watch(() => props.collectionId, setCollection, {
75
74
immediate: true ,
76
75
})
77
76
78
- // set items
79
- const items = ref <Item []>([])
80
-
81
- async function setItems() {
82
- if (! collection .value ) {
83
- items .value = []
84
- return
85
- }
86
- store .item
87
- .list ({ collectionId: props .collectionId })
88
- .then ((r ) => (items .value = r .data ))
89
- .catch (() => (items .value = []))
90
- }
91
-
92
- watch (collection , setItems )
93
-
94
77
// view
95
78
const view = ref <ViewTable & { loading: boolean }>({
96
79
loading: false ,
@@ -129,15 +112,13 @@ async function setView() {
129
112
130
113
collection .value .columns
131
114
.map ((c ) => useNonReactive (c ))
132
- .forEach ((c ) => {
133
- const saved = savedColumns .find ((s ) => s .id === c .id )
134
-
115
+ .forEach ((c ) =>
135
116
columns .push ({
136
- width: 200 ,
117
+ width: 5 ,
137
118
... c ,
138
- ... saved ,
119
+ ... savedColumns . find (( s ) => s . id === c . id ) ,
139
120
})
140
- } )
121
+ )
141
122
142
123
columns .push ({
143
124
id: ' _actions_right' ,
@@ -171,58 +152,48 @@ watch(collection, setView)
171
152
watch (() => view .value .columns , saveView , { deep: true })
172
153
watch (() => view .value .filters , saveView , { deep: true })
173
154
174
- // filters
155
+ // set items
156
+
175
157
const search = ref ({
176
158
input: ' ' ,
177
159
show: false ,
178
160
onInput: debounce ((v ) => (search .value .input = v ), 100 ),
179
161
})
180
162
181
- const filters = ref ({
182
- drawer: false ,
183
- payload: [] as Filter [],
184
- })
163
+ const items = ref <Item []>([])
164
+ const loadingItems = ref (false )
165
+
166
+ async function setItems() {
167
+ if (! collection .value ) {
168
+ items .value = []
169
+ return
170
+ }
185
171
186
- const filteredItems = computed (() =>
187
- items .value .filter ((i ) => {
172
+ if (loadingItems .value ) return
173
+
174
+ loadingItems .value = true
175
+
176
+ const raw = await store .item
177
+ .list ({ collectionId: props .collectionId })
178
+ .then ((r ) => (items .value = r .data ))
179
+ .catch (() => (items .value = []))
180
+
181
+ items .value = raw .filter ((i ) => {
188
182
let valid = !! JSON .stringify (i ).toLowerCase ().includes (search .value .input .toLowerCase ())
189
183
190
184
valid = view .value .filters .reduce ((r , f ) => r && filter (i , f ), valid )
191
185
192
186
return valid
193
187
})
194
- )
195
-
196
- function addFilter(column : CollectionColumn ) {
197
- filters .value .payload .push ({
198
- columnId: column .id ,
199
- field: column .field ,
200
- type: column .type ,
201
- config: {},
202
- value: ' ' ,
203
- })
204
- }
205
188
206
- function applyFilters() {
207
- view .value .filters = useNonReactive (filters .value .payload )
208
-
209
- filters .value .drawer = false
189
+ setTimeout (() => (loadingItems .value = false ), 800 )
210
190
}
211
191
212
- function cancelFilters() {
213
- filters .value .payload = useNonReactive (view .value .filters )
192
+ watch (collection , setItems )
214
193
215
- filters .value .drawer = false
216
- }
194
+ watch (() => view .value .filters , debounce (setItems , 500 ), { deep: true })
217
195
218
- watch (
219
- () => view .value .loading ,
220
- (v ) => {
221
- if (v ) return
222
-
223
- filters .value .payload = useNonReactive (view .value .filters )
224
- }
225
- )
196
+ watch (() => search .value .input , debounce (setItems , 1000 ))
226
197
227
198
// bindings
228
199
const attrs = useAttrs ()
@@ -265,74 +236,21 @@ const bindings = computed(() => createBindings(attrs, ['table', 'head']))
265
236
<is-icon name =" search" />
266
237
</v-btn >
267
238
268
- <is-drawer v-model =" filters.drawer" >
269
- <template #activator =" { attrs } " >
270
- <v-btn text size =" sm" v-bind =" attrs" >
271
- <is-icon name =" filter" />
272
- </v-btn >
273
- </template >
274
-
275
- <form @submit.prevent =" applyFilters" >
276
- <v-card-head class =" px-4" >
277
- <v-card-title class =" text-t-secondary mr-auto" >
278
- {{ $t('filter', 2) }}
279
- </v-card-title >
280
-
281
- <v-btn class =" mr-4" color =" danger" @click =" cancelFilters" >
282
- {{ $t('cancel') }}
283
- </v-btn >
284
-
285
- <v-btn class =" mr-4" type =" submit" >
286
- {{ $t('apply') }}
287
- </v-btn >
288
-
289
- <v-btn @click =" filters.drawer = false" >
290
- <is-icon name =" times" />
291
- </v-btn >
292
- </v-card-head >
293
-
294
- <c-filter
295
- v-for =" (f, index) in filters.payload"
296
- :key =" index"
297
- :model-value =" f"
298
- :columns =" collection ? collection.columns : []"
299
- @update:model-value =" (v) => (filters[index] = v)"
300
- @destroy =" filters.payload.splice(index, 1)"
301
- />
302
-
303
- <v-card-content class =" flex-wrap" >
304
- <div
305
- v-if =" !filters.payload.length"
306
- class =" w-full mb-3 text-t-secondary"
307
- >
308
- {{ $t('noEntity', [$t('filter', 2)]) }}
309
- </div >
310
-
311
- <is-menu offset-y close-on-content-click >
312
- <template #activator =" { on } " >
313
- <v-btn v-bind =" on" class =" mr-4" color =" info" >
314
- {{ $t('addEntity', [$t('filter')]) }}
315
- </v-btn >
316
- </template >
239
+ <v-btn text size =" sm" @click =" setItems" >
240
+ <is-icon name =" rotate" />
241
+ </v-btn >
317
242
318
- <v-card color =" b-secondary" >
319
- <is-list-item
320
- v-for =" c in collection ? collection.columns : []"
321
- :key =" c.id"
322
- @click =" addFilter(c)"
323
- >
324
- {{ c.label }}
325
- </is-list-item >
326
- </v-card >
327
- </is-menu >
328
- </v-card-content >
329
- </form >
330
- </is-drawer >
243
+ <c-drawer-filter v-model =" view.filters" :columns =" collection?.columns" />
331
244
</div >
332
245
</v-card-head >
333
246
334
247
<div class =" overflow-auto w-full h-[calc(100%_-_53px)]" >
335
- <v-table :items =" filteredItems" :columns =" view.columns" v-bind =" bindings.table" >
248
+ <v-table
249
+ :items =" items"
250
+ :columns =" view.columns"
251
+ v-bind =" bindings.table"
252
+ :loading =" loadingItems"
253
+ >
336
254
<template #column >
337
255
<Draggable v-model =" view.columns" handle =" .drag" item-key =" id" tag =" v-tr" >
338
256
<template #item =" { element: c } " >
@@ -369,7 +287,6 @@ const bindings = computed(() => createBindings(attrs, ['table', 'head']))
369
287
v-for =" c in view.columns"
370
288
:key =" c.id"
371
289
no-padding
372
- :width =" c.width"
373
290
:class =" c.id[0] === '_' ? '!border-x-0' : ''"
374
291
>
375
292
<is-menu v-if =" c.id === '_actions_left'" offset-y >
0 commit comments