1
1
import { ref , computed , onMounted , toRaw } from 'vue' ;
2
- import { router } from '@inertiajs/vue3' ;
2
+ import { router , usePage } from '@inertiajs/vue3' ;
3
3
import type { Page , PageProps } from '@inertiajs/core' ;
4
4
import { FilterMatchMode } from '@primevue/core/api' ;
5
5
import { PageState , DataTablePageEvent } from 'primevue' ;
6
6
import debounce from 'lodash-es/debounce' ;
7
- import qs from 'qs' ;
8
- import type { PrimeVueDataFilters , InertiaRouterFetchCallbacks } from '@/types' ;
7
+ import type { AppPageProps , PrimeVueDataFilters , InertiaRouterFetchCallbacks } from '@/types' ;
9
8
10
- interface PaginatedFilteredSortedQueryParams {
9
+ interface QueryParams {
11
10
filters ?: PrimeVueDataFilters ;
12
11
page ?: string ;
13
12
rows ?: string ;
14
13
sortField ?: string ;
15
14
sortOrder ?: string ;
15
+ [ key : string ] : any ;
16
16
}
17
17
interface PaginationState {
18
18
page : number ;
@@ -22,13 +22,16 @@ interface SortState {
22
22
field : string ;
23
23
order : number ;
24
24
}
25
+ type InertiaPageProps = PageProps & Omit < AppPageProps , 'queryParams' > & {
26
+ queryParams : QueryParams
27
+ }
25
28
26
29
export function usePaginatedData (
27
30
propDataToFetch : string | string [ ] ,
28
31
initialFilters : PrimeVueDataFilters = { } ,
29
32
initialRows : number = 20
30
33
) {
31
- const urlParams = ref < PaginatedFilteredSortedQueryParams > ( { } ) ;
34
+ const page = usePage < InertiaPageProps > ( ) ;
32
35
const processing = ref < boolean > ( false ) ;
33
36
const filters = ref < PrimeVueDataFilters > ( structuredClone ( toRaw ( initialFilters ) ) ) ;
34
37
const sorting = ref < SortState > ( {
@@ -43,9 +46,10 @@ export function usePaginatedData(
43
46
const firstDatasetIndex = computed ( ( ) => {
44
47
return ( pagination . value . page - 1 ) * pagination . value . rows ;
45
48
} ) ;
49
+
46
50
const filteredOrSorted = computed ( ( ) => {
47
- const paramsFilters = urlParams . value ?. filters || { } ;
48
- const sortField = urlParams . value ?. sortField || null ;
51
+ const paramsFilters = page . props . queryParams ?. filters || { } ;
52
+ const sortField = page . props . queryParams ?. sortField || null ;
49
53
const isFiltering = Object . values ( paramsFilters ) . some (
50
54
( filter ) => filter . value !== null && filter . value !== ''
51
55
) ;
@@ -58,21 +62,6 @@ export function usePaginatedData(
58
62
filterCallback ( ) ;
59
63
} , 300 ) ;
60
64
61
- function setUrlParams ( ) : void {
62
- const queryString = window . location . search ;
63
- const params = qs . parse ( queryString , {
64
- ignoreQueryPrefix : true ,
65
- strictNullHandling : true ,
66
- decoder : function ( str , defaultDecoder ) {
67
- // set empty string values to null to match Laravel backend behavior
68
- const value = defaultDecoder ( str ) ;
69
- return value === '' ? null : value ;
70
- } ,
71
- } ) as PaginatedFilteredSortedQueryParams ;
72
-
73
- urlParams . value = { ...params } ;
74
- }
75
-
76
65
function scrollToTop ( ) : void {
77
66
window . scrollTo ( {
78
67
top : 0 ,
@@ -85,7 +74,6 @@ export function usePaginatedData(
85
74
86
75
return new Promise ( ( resolve , reject ) => {
87
76
processing . value = true ;
88
-
89
77
router . visit ( window . location . pathname , {
90
78
method : 'get' ,
91
79
data : {
@@ -98,7 +86,9 @@ export function usePaginatedData(
98
86
preserveUrl : false ,
99
87
showProgress : true ,
100
88
replace : true ,
101
- only : Array . isArray ( propDataToFetch ) ? propDataToFetch : [ propDataToFetch ] ,
89
+ only : Array . isArray ( propDataToFetch )
90
+ ? [ ...propDataToFetch , 'queryParams' ]
91
+ : [ propDataToFetch , 'queryParams' ] ,
102
92
onSuccess : ( page ) => {
103
93
onSuccess ?.( page ) ;
104
94
resolve ( page ) ;
@@ -108,7 +98,6 @@ export function usePaginatedData(
108
98
reject ( errors ) ;
109
99
} ,
110
100
onFinish : ( ) => {
111
- setUrlParams ( ) ;
112
101
processing . value = false ;
113
102
onFinish ?.( ) ;
114
103
} ,
@@ -122,7 +111,6 @@ export function usePaginatedData(
122
111
} else {
123
112
pagination . value . page = event . page + 1 ;
124
113
}
125
-
126
114
pagination . value . rows = event . rows ;
127
115
128
116
return fetchData ( {
@@ -134,8 +122,8 @@ export function usePaginatedData(
134
122
135
123
function filter ( options : InertiaRouterFetchCallbacks = { } ) : Promise < Page < PageProps > > {
136
124
const { onFinish : onFinishCallback , onSuccess, onError } = options ;
137
-
138
125
pagination . value . page = 1 ;
126
+
139
127
return fetchData ( {
140
128
onSuccess,
141
129
onError,
@@ -162,22 +150,23 @@ export function usePaginatedData(
162
150
163
151
return new Promise ( ( resolve , reject ) => {
164
152
processing . value = true ;
165
-
166
153
router . visit ( window . location . pathname , {
167
154
method : 'get' ,
168
155
preserveUrl : false ,
169
156
showProgress : true ,
170
157
replace : true ,
171
- only : Array . isArray ( propDataToFetch ) ? propDataToFetch : [ propDataToFetch ] ,
172
- onSuccess ( page ) {
158
+ only : Array . isArray ( propDataToFetch )
159
+ ? [ ...propDataToFetch , 'queryParams' ]
160
+ : [ propDataToFetch , 'queryParams' ] ,
161
+ onSuccess : ( page ) => {
173
162
onSuccess ?.( page ) ;
174
163
resolve ( page ) ;
175
164
} ,
176
- onError ( errors ) {
165
+ onError : ( errors ) => {
177
166
onError ?.( errors ) ;
178
167
reject ( errors ) ;
179
168
} ,
180
- onFinish ( ) {
169
+ onFinish : ( ) => {
181
170
processing . value = false ;
182
171
onFinish ?.( ) ;
183
172
} ,
@@ -188,19 +177,17 @@ export function usePaginatedData(
188
177
function parseUrlFilterValues ( ) : void {
189
178
Object . keys ( filters . value ) . forEach ( ( key ) => {
190
179
const filter = filters . value [ key ] ;
191
-
192
180
if ( ! filter ?. value || ! filter ?. matchMode ) {
193
181
return ;
194
182
}
195
-
196
- if (
197
- filter . matchMode == FilterMatchMode . DATE_IS ||
198
- filter . matchMode == FilterMatchMode . DATE_IS_NOT ||
199
- filter . matchMode == FilterMatchMode . DATE_BEFORE ||
200
- filter . matchMode == FilterMatchMode . DATE_AFTER
201
- ) {
183
+ if ( [
184
+ FilterMatchMode . DATE_IS ,
185
+ FilterMatchMode . DATE_IS_NOT ,
186
+ FilterMatchMode . DATE_BEFORE ,
187
+ FilterMatchMode . DATE_AFTER ,
188
+ ] . includes ( filter . matchMode ) ) {
202
189
filters . value [ key ] . value = new Date ( filter . value as string ) ;
203
- } else if ( filter . matchMode == FilterMatchMode . BETWEEN ) {
190
+ } else if ( filter . matchMode === FilterMatchMode . BETWEEN ) {
204
191
filter . value . forEach ( ( value : any , index : number ) => {
205
192
if ( typeof value === 'string' ) {
206
193
filter . value [ index ] = new Date ( value ) ;
@@ -214,15 +201,14 @@ export function usePaginatedData(
214
201
filters . value [ key ] . value = Number ( filter . value ) ;
215
202
} else if (
216
203
Array . isArray ( filter . value ) ||
217
- filter . matchMode == FilterMatchMode . IN
204
+ filter . matchMode === FilterMatchMode . IN
218
205
) {
219
206
if ( filter . value . length === 0 ) {
220
207
// empty arrays cause filtering issues, set to null instead
221
208
filters . value [ key ] . value = null ;
222
209
} else {
223
210
// Unique array values
224
211
const unique = [ ...new Set ( filter . value ) ] ;
225
-
226
212
filter . value = unique ;
227
213
filter . value . forEach ( ( value : any , index : number ) => {
228
214
if ( typeof value === 'string' && ! isNaN ( Number ( value ) ) ) {
@@ -234,34 +220,29 @@ export function usePaginatedData(
234
220
} ) ;
235
221
}
236
222
237
- function parseUrlParams ( urlParamsObj : PaginatedFilteredSortedQueryParams ) : void {
223
+ function parseUrlParams ( ) : void {
224
+ const queryParams = page . props . queryParams || { } ;
238
225
filters . value = {
239
226
...structuredClone ( toRaw ( initialFilters ) ) ,
240
- ...urlParamsObj ? .filters ,
227
+ ...queryParams . filters ,
241
228
} ;
242
-
243
229
parseUrlFilterValues ( ) ;
244
-
245
- if ( urlParamsObj ?. sortField ) {
246
- sorting . value . field = urlParamsObj . sortField ;
230
+ if ( queryParams . sortField ) {
231
+ sorting . value . field = queryParams . sortField ;
247
232
}
248
-
249
- if ( urlParamsObj ?. sortOrder ) {
250
- sorting . value . order = parseInt ( urlParamsObj . sortOrder ) ;
233
+ if ( queryParams . sortOrder ) {
234
+ sorting . value . order = parseInt ( queryParams . sortOrder ) ;
251
235
}
252
-
253
- if ( urlParamsObj ?. page ) {
254
- pagination . value . page = parseInt ( urlParamsObj . page ) ;
236
+ if ( queryParams . page ) {
237
+ pagination . value . page = parseInt ( queryParams . page ) ;
255
238
}
256
-
257
- if ( urlParamsObj ?. rows ) {
258
- pagination . value . rows = parseInt ( urlParamsObj . rows ) ;
239
+ if ( queryParams . rows ) {
240
+ pagination . value . rows = parseInt ( queryParams . rows ) ;
259
241
}
260
242
}
261
243
262
244
onMounted ( ( ) => {
263
- setUrlParams ( ) ;
264
- parseUrlParams ( urlParams . value ) ;
245
+ parseUrlParams ( ) ;
265
246
} ) ;
266
247
267
248
return {
0 commit comments