11import { ref , computed , onMounted , toRaw } from 'vue' ;
2- import { router } from '@inertiajs/vue3' ;
2+ import { router , usePage } from '@inertiajs/vue3' ;
33import type { Page , PageProps } from '@inertiajs/core' ;
44import { FilterMatchMode } from '@primevue/core/api' ;
55import { PageState , DataTablePageEvent } from 'primevue' ;
66import 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' ;
98
10- interface PaginatedFilteredSortedQueryParams {
9+ interface QueryParams {
1110 filters ?: PrimeVueDataFilters ;
1211 page ?: string ;
1312 rows ?: string ;
1413 sortField ?: string ;
1514 sortOrder ?: string ;
15+ [ key : string ] : any ;
1616}
1717interface PaginationState {
1818 page : number ;
@@ -22,13 +22,16 @@ interface SortState {
2222 field : string ;
2323 order : number ;
2424}
25+ type InertiaPageProps = PageProps & Omit < AppPageProps , 'queryParams' > & {
26+ queryParams : QueryParams
27+ }
2528
2629export function usePaginatedData (
2730 propDataToFetch : string | string [ ] ,
2831 initialFilters : PrimeVueDataFilters = { } ,
2932 initialRows : number = 20
3033) {
31- const urlParams = ref < PaginatedFilteredSortedQueryParams > ( { } ) ;
34+ const page = usePage < InertiaPageProps > ( ) ;
3235 const processing = ref < boolean > ( false ) ;
3336 const filters = ref < PrimeVueDataFilters > ( structuredClone ( toRaw ( initialFilters ) ) ) ;
3437 const sorting = ref < SortState > ( {
@@ -43,9 +46,10 @@ export function usePaginatedData(
4346 const firstDatasetIndex = computed ( ( ) => {
4447 return ( pagination . value . page - 1 ) * pagination . value . rows ;
4548 } ) ;
49+
4650 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 ;
4953 const isFiltering = Object . values ( paramsFilters ) . some (
5054 ( filter ) => filter . value !== null && filter . value !== ''
5155 ) ;
@@ -58,21 +62,6 @@ export function usePaginatedData(
5862 filterCallback ( ) ;
5963 } , 300 ) ;
6064
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-
7665 function scrollToTop ( ) : void {
7766 window . scrollTo ( {
7867 top : 0 ,
@@ -85,7 +74,6 @@ export function usePaginatedData(
8574
8675 return new Promise ( ( resolve , reject ) => {
8776 processing . value = true ;
88-
8977 router . visit ( window . location . pathname , {
9078 method : 'get' ,
9179 data : {
@@ -98,7 +86,9 @@ export function usePaginatedData(
9886 preserveUrl : false ,
9987 showProgress : true ,
10088 replace : true ,
101- only : Array . isArray ( propDataToFetch ) ? propDataToFetch : [ propDataToFetch ] ,
89+ only : Array . isArray ( propDataToFetch )
90+ ? [ ...propDataToFetch , 'queryParams' ]
91+ : [ propDataToFetch , 'queryParams' ] ,
10292 onSuccess : ( page ) => {
10393 onSuccess ?.( page ) ;
10494 resolve ( page ) ;
@@ -108,7 +98,6 @@ export function usePaginatedData(
10898 reject ( errors ) ;
10999 } ,
110100 onFinish : ( ) => {
111- setUrlParams ( ) ;
112101 processing . value = false ;
113102 onFinish ?.( ) ;
114103 } ,
@@ -122,7 +111,6 @@ export function usePaginatedData(
122111 } else {
123112 pagination . value . page = event . page + 1 ;
124113 }
125-
126114 pagination . value . rows = event . rows ;
127115
128116 return fetchData ( {
@@ -134,8 +122,8 @@ export function usePaginatedData(
134122
135123 function filter ( options : InertiaRouterFetchCallbacks = { } ) : Promise < Page < PageProps > > {
136124 const { onFinish : onFinishCallback , onSuccess, onError } = options ;
137-
138125 pagination . value . page = 1 ;
126+
139127 return fetchData ( {
140128 onSuccess,
141129 onError,
@@ -162,22 +150,23 @@ export function usePaginatedData(
162150
163151 return new Promise ( ( resolve , reject ) => {
164152 processing . value = true ;
165-
166153 router . visit ( window . location . pathname , {
167154 method : 'get' ,
168155 preserveUrl : false ,
169156 showProgress : true ,
170157 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 ) => {
173162 onSuccess ?.( page ) ;
174163 resolve ( page ) ;
175164 } ,
176- onError ( errors ) {
165+ onError : ( errors ) => {
177166 onError ?.( errors ) ;
178167 reject ( errors ) ;
179168 } ,
180- onFinish ( ) {
169+ onFinish : ( ) => {
181170 processing . value = false ;
182171 onFinish ?.( ) ;
183172 } ,
@@ -188,19 +177,17 @@ export function usePaginatedData(
188177 function parseUrlFilterValues ( ) : void {
189178 Object . keys ( filters . value ) . forEach ( ( key ) => {
190179 const filter = filters . value [ key ] ;
191-
192180 if ( ! filter ?. value || ! filter ?. matchMode ) {
193181 return ;
194182 }
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 ) ) {
202189 filters . value [ key ] . value = new Date ( filter . value as string ) ;
203- } else if ( filter . matchMode == FilterMatchMode . BETWEEN ) {
190+ } else if ( filter . matchMode === FilterMatchMode . BETWEEN ) {
204191 filter . value . forEach ( ( value : any , index : number ) => {
205192 if ( typeof value === 'string' ) {
206193 filter . value [ index ] = new Date ( value ) ;
@@ -214,15 +201,14 @@ export function usePaginatedData(
214201 filters . value [ key ] . value = Number ( filter . value ) ;
215202 } else if (
216203 Array . isArray ( filter . value ) ||
217- filter . matchMode == FilterMatchMode . IN
204+ filter . matchMode === FilterMatchMode . IN
218205 ) {
219206 if ( filter . value . length === 0 ) {
220207 // empty arrays cause filtering issues, set to null instead
221208 filters . value [ key ] . value = null ;
222209 } else {
223210 // Unique array values
224211 const unique = [ ...new Set ( filter . value ) ] ;
225-
226212 filter . value = unique ;
227213 filter . value . forEach ( ( value : any , index : number ) => {
228214 if ( typeof value === 'string' && ! isNaN ( Number ( value ) ) ) {
@@ -234,34 +220,29 @@ export function usePaginatedData(
234220 } ) ;
235221 }
236222
237- function parseUrlParams ( urlParamsObj : PaginatedFilteredSortedQueryParams ) : void {
223+ function parseUrlParams ( ) : void {
224+ const queryParams = page . props . queryParams || { } ;
238225 filters . value = {
239226 ...structuredClone ( toRaw ( initialFilters ) ) ,
240- ...urlParamsObj ? .filters ,
227+ ...queryParams . filters ,
241228 } ;
242-
243229 parseUrlFilterValues ( ) ;
244-
245- if ( urlParamsObj ?. sortField ) {
246- sorting . value . field = urlParamsObj . sortField ;
230+ if ( queryParams . sortField ) {
231+ sorting . value . field = queryParams . sortField ;
247232 }
248-
249- if ( urlParamsObj ?. sortOrder ) {
250- sorting . value . order = parseInt ( urlParamsObj . sortOrder ) ;
233+ if ( queryParams . sortOrder ) {
234+ sorting . value . order = parseInt ( queryParams . sortOrder ) ;
251235 }
252-
253- if ( urlParamsObj ?. page ) {
254- pagination . value . page = parseInt ( urlParamsObj . page ) ;
236+ if ( queryParams . page ) {
237+ pagination . value . page = parseInt ( queryParams . page ) ;
255238 }
256-
257- if ( urlParamsObj ?. rows ) {
258- pagination . value . rows = parseInt ( urlParamsObj . rows ) ;
239+ if ( queryParams . rows ) {
240+ pagination . value . rows = parseInt ( queryParams . rows ) ;
259241 }
260242 }
261243
262244 onMounted ( ( ) => {
263- setUrlParams ( ) ;
264- parseUrlParams ( urlParams . value ) ;
245+ parseUrlParams ( ) ;
265246 } ) ;
266247
267248 return {
0 commit comments