1
- import { ref , computed } from 'vue' ;
2
- import { router } from '@inertiajs/vue3' ;
1
+ import { ref , computed , onMounted } from 'vue' ;
2
+ import { router , usePage } from '@inertiajs/vue3' ;
3
+
4
+ export function useLazyDataTable (
5
+ defaultFilters = { } ,
6
+ only = [ 'request' ] ,
7
+ rows = 20
8
+ ) {
9
+ const page = usePage ( ) ;
3
10
4
- export function useDataTable ( defaultFilters = { } , only = [ 'urlParams' ] ) {
5
11
const dataTableDefaults = {
6
12
filters : defaultFilters ,
7
13
sortField : '' ,
8
14
sortOrder : 1 ,
9
15
currentPage : 1 ,
10
- rowsPerPage : 20 ,
16
+ rowsPerPage : rows ,
11
17
} ;
12
18
13
19
const filters = ref ( dataTableDefaults . filters ) ;
@@ -19,11 +25,21 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
19
25
const firstDatasetIndex = computed ( ( ) => {
20
26
return ( currentPage . value - 1 ) * rowsPerPage . value ;
21
27
} ) ;
28
+ const hasFilteringApplied = computed ( ( ) => {
29
+ const filters = page . props ?. request ?. urlParams ?. filters || { } ;
30
+ const sortField = page . props ?. request ?. urlParams ?. sortField || null ;
31
+ const isFiltering = Object . values ( filters ) . some (
32
+ ( filter ) => filter . value !== null && filter . value !== ''
33
+ ) ;
34
+ const isSorting = sortField !== null && sortField !== '' ;
35
+
36
+ return isFiltering || isSorting ;
37
+ } ) ;
22
38
23
39
function fetchData ( ) {
24
40
return new Promise ( ( resolve , reject ) => {
25
41
router . reload ( {
26
- only,
42
+ only : [ 'request' , ... new Set ( only ) ] ,
27
43
data : {
28
44
filters : filters . value ,
29
45
sortField : sortField . value ,
@@ -42,12 +58,18 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
42
58
} ) ;
43
59
}
44
60
45
- function onPage ( event ) {
46
- currentPage . value = event . page + 1 ;
47
- rowsPerPage . value = event . rows ;
48
- fetchData ( ) . then ( ( ) => {
49
- scrollToTop ( ) ;
61
+ function onFilter ( event ) {
62
+ // TODO: debounce "contains" searches
63
+ currentPage . value = 1 ;
64
+ filters . value = event . filters ;
65
+ // empty arrays cause filtering issues, set to null instead
66
+ Object . keys ( filters . value ) . forEach ( ( key ) => {
67
+ const filter = filters . value [ key ] ;
68
+ if ( Array . isArray ( filter . value ) && filter . value . length === 0 ) {
69
+ filters . value [ key ] . value = null ;
70
+ }
50
71
} ) ;
72
+ fetchData ( ) ;
51
73
}
52
74
53
75
function onSort ( event ) {
@@ -56,10 +78,12 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
56
78
fetchData ( ) ;
57
79
}
58
80
59
- function onFilter ( event ) {
60
- currentPage . value = 1 ;
61
- filters . value = event . filters ;
62
- fetchData ( ) ;
81
+ function onPage ( event ) {
82
+ currentPage . value = event . page + 1 ;
83
+ rowsPerPage . value = event . rows ;
84
+ fetchData ( ) . then ( ( ) => {
85
+ scrollToTop ( ) ;
86
+ } ) ;
63
87
}
64
88
65
89
function scrollToTop ( ) {
@@ -69,7 +93,7 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
69
93
} ) ;
70
94
}
71
95
72
- function reset ( ) {
96
+ function resetFilters ( ) {
73
97
filters . value = dataTableDefaults . filters ;
74
98
sortField . value = dataTableDefaults . sortField ;
75
99
sortOrder . value = dataTableDefaults . sortOrder ;
@@ -80,6 +104,27 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
80
104
81
105
function parseUrlParams ( urlParams ) {
82
106
filters . value = urlParams ?. filters || dataTableDefaults . filters ;
107
+ // Cast strings to Numbers for v-model
108
+ Object . keys ( filters . value ) . forEach ( ( key ) => {
109
+ const filter = filters . value [ key ] ;
110
+ if ( ! filter . value ) {
111
+ return ;
112
+ }
113
+ if ( typeof filter . value === 'string' && ! isNaN ( filter . value ) ) {
114
+ filters . value [ key ] . value = Number ( filter . value ) ;
115
+ }
116
+ if ( Array . isArray ( filter . value ) ) {
117
+ // TODO: find out why there are duplicate array values in multi-select filters
118
+ // "Fixed" with reassigning to unique array
119
+ const unique = [ ...new Set ( filter . value ) ] ;
120
+ filter . value = unique ;
121
+ filter . value . forEach ( ( value , index ) => {
122
+ if ( typeof value === 'string' && ! isNaN ( value ) ) {
123
+ filter . value [ index ] = Number ( value ) ;
124
+ }
125
+ } ) ;
126
+ }
127
+ } ) ;
83
128
sortField . value = urlParams ?. sortField || dataTableDefaults . sortField ;
84
129
sortOrder . value =
85
130
parseInt ( urlParams ?. sortOrder ) || dataTableDefaults . sortOrder ;
@@ -89,17 +134,22 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
89
134
parseInt ( urlParams ?. rows ) || dataTableDefaults . rowsPerPage ;
90
135
}
91
136
137
+ onMounted ( ( ) => {
138
+ parseUrlParams ( page . props . request . urlParams ) ;
139
+ } ) ;
140
+
92
141
return {
93
142
filters,
94
143
sortField,
95
144
sortOrder,
96
145
currentPage,
97
146
rowsPerPage,
98
147
firstDatasetIndex,
99
- onPage,
100
- onSort,
148
+ hasFilteringApplied,
101
149
onFilter,
102
- reset,
150
+ onSort,
151
+ onPage,
152
+ resetFilters,
103
153
fetchData,
104
154
parseUrlParams,
105
155
} ;
0 commit comments