@@ -50,6 +50,56 @@ const FILTERS_GUTTER: RowProps['gutter'] = [16, 20]
5050const ASC = 'ASC'
5151const DESC = 'DESC'
5252
53+ const getSortQueryValue = ( sortState : FullTableState [ 'sortState' ] ) : string | undefined => {
54+ if ( ! sortState ?. length ) return undefined
55+
56+ const firstSort = sortState [ 0 ]
57+ const sortOrder = firstSort . desc ? DESC : ASC
58+ return `${ firstSort . id } _${ sortOrder } `
59+ }
60+
61+ const getFiltersWithGlobalSearch = ( filterState : FullTableState [ 'filterState' ] , globalFilter ?: string ) : FullTableState [ 'filterState' ] => {
62+ const nextFilters = { ...filterState }
63+
64+ if ( globalFilter && globalFilter . trim ( ) !== '' ) {
65+ nextFilters . search = globalFilter
66+ } else {
67+ delete nextFilters . search
68+ }
69+
70+ return nextFilters
71+ }
72+
73+ const setQueryParam = ( query : Record < string , string | string [ ] > , key : string , value : string | undefined ) : void => {
74+ if ( value ) {
75+ query [ key ] = value
76+ return
77+ }
78+
79+ delete query [ key ]
80+ }
81+
82+ const buildNextTableQuery = (
83+ currentQuery : Record < string , string | string [ ] > ,
84+ params : FullTableState
85+ ) : Record < string , string | string [ ] > => {
86+ const { startRow, filterState, sortState, rowSelectionState, globalFilter } = params
87+ const nextFilters = getFiltersWithGlobalSearch ( filterState , globalFilter )
88+ const nextQuery = { ...currentQuery }
89+
90+ const nextOffset = startRow > 0 ? String ( startRow ) : undefined
91+ const nextFiltersValue = Object . keys ( nextFilters ) . length > 0 ? JSON . stringify ( nextFilters ) : undefined
92+ const nextSortValue = getSortQueryValue ( sortState )
93+ const nextSelectedRows = rowSelectionState ?. length > 0 ? JSON . stringify ( rowSelectionState ) : undefined
94+
95+ setQueryParam ( nextQuery , 'offset' , nextOffset )
96+ setQueryParam ( nextQuery , 'filters' , nextFiltersValue )
97+ setQueryParam ( nextQuery , 'sort' , nextSortValue )
98+ setQueryParam ( nextQuery , 'selectedRows' , nextSelectedRows )
99+
100+ return nextQuery
101+ }
102+
53103export const ReceiptsTable : React . FC = ( ) => {
54104 const intl = useIntl ( )
55105 const SearchPlaceholder = intl . formatMessage ( { id : 'filters.FullSearch' } )
@@ -64,7 +114,7 @@ export const ReceiptsTable: React.FC = () => {
64114 const billingContext = billingContexts . length > 0 ? billingContexts [ 0 ] : null
65115 const currencyCode = get ( billingContext , [ 'integration' , 'currencyCode' ] , defaultCurrencyCode )
66116 const reportPeriod = get ( billingContexts . find ( ( { lastReport } ) => ! ! lastReport ) , [ 'lastReport' , 'period' ] , null )
67- const contextIdsKey = useMemo ( ( ) => billingContexts . map ( ( { id } ) => id ) . sort ( ) . join ( ',' ) , [ billingContexts ] )
117+ const contextIdsKey = useMemo ( ( ) => billingContexts . map ( ( { id } ) => id ) . sort ( ( left , right ) => left . localeCompare ( right ) ) . join ( ',' ) , [ billingContexts ] )
68118 const contextIds = useMemo ( ( ) => contextIdsKey ? contextIdsKey . split ( ',' ) : [ ] , [ contextIdsKey ] )
69119 const hasToPayDetails = get ( billingContext , [ 'integration' , 'dataFormat' , 'hasToPayDetails' ] , false )
70120 const hasServices = get ( billingContext , [ 'integration' , 'dataFormat' , 'hasServices' ] , false )
@@ -85,43 +135,15 @@ export const ReceiptsTable: React.FC = () => {
85135 const columnLabels = useTableTranslations ( )
86136 const initialTableState = useMemo ( ( ) => defaultParseUrlQuery ( router . query , DEFAULT_PAGE_SIZE ) , [ router . query ] )
87137 const updateUrlQuery = useCallback ( ( params : FullTableState ) => {
88- const { startRow, filterState, sortState, rowSelectionState, globalFilter } = params
89-
90- const nextFilters = { ...filterState }
91- if ( globalFilter && globalFilter . trim ( ) !== '' ) {
92- nextFilters . search = globalFilter
93- } else {
94- delete nextFilters . search
95- }
96-
97- const sort = sortState ?. length
98- ? `${ sortState [ 0 ] . id } _${ sortState [ 0 ] . desc ? DESC : ASC } `
99- : null
100-
101- const nextQuery : Record < string , string | string [ ] > = { ...router . query } as Record < string , string | string [ ] >
102- const nextOffset = startRow > 0 ? String ( startRow ) : undefined
103- const nextFiltersValue = Object . keys ( nextFilters ) . length > 0 ? JSON . stringify ( nextFilters ) : undefined
104- const nextSortValue = sort ?? undefined
105- const nextSelectedRows = rowSelectionState ?. length > 0 ? JSON . stringify ( rowSelectionState ) : undefined
106-
107- if ( nextOffset ) nextQuery . offset = nextOffset
108- else delete nextQuery . offset
109-
110- if ( nextFiltersValue ) nextQuery . filters = nextFiltersValue
111- else delete nextQuery . filters
112-
113- if ( nextSortValue ) nextQuery . sort = nextSortValue
114- else delete nextQuery . sort
115-
116- if ( nextSelectedRows ) nextQuery . selectedRows = nextSelectedRows
117- else delete nextQuery . selectedRows
118-
138+ const nextQuery = buildNextTableQuery ( router . query as Record < string , string | string [ ] > , params )
119139 if ( isEqual ( router . query , nextQuery ) ) return
120140
121- void router . replace ( {
141+ router . replace ( {
122142 pathname : router . pathname ,
123143 query : nextQuery ,
124- } , undefined , { shallow : true } )
144+ } , undefined , { shallow : true } ) . catch ( ( error ) => {
145+ console . error ( 'Failed to update billing receipts table query params' , error )
146+ } )
125147 } , [ router ] )
126148
127149 const { updateStepIfNotCompleted } = useTourContext ( )
@@ -154,7 +176,7 @@ export const ReceiptsTable: React.FC = () => {
154176 } , [ reportPeriod ] )
155177
156178 const onRowClick = useCallback ( ( record : BillingReceiptType ) => {
157- const hasSelectedText = typeof window !== 'undefined' && window . getSelection ?.( ) ?. toString ( ) . trim ( )
179+ const hasSelectedText = typeof globalThis . window !== 'undefined' && globalThis . window . getSelection ?.( ) ?. toString ( ) . trim ( )
158180 if ( hasSelectedText ) return
159181
160182 if ( hasServices ) {
@@ -202,6 +224,7 @@ export const ReceiptsTable: React.FC = () => {
202224 rowCount,
203225 }
204226 } catch ( error ) {
227+ console . error ( 'Failed to fetch billing receipts' , error )
205228 setLoadingError ( true )
206229 return {
207230 rowData : [ ] ,
@@ -273,7 +296,12 @@ export const ReceiptsTable: React.FC = () => {
273296 setSelectedRowIds ( initialTableState . rowSelectionState )
274297
275298 const tablePeriod = get ( nextTableRef . api . getFilterState ( ) , 'period' )
276- const nextPeriod = tablePeriod ? dayjs ( String ( tablePeriod ) , 'YYYY-MM-DD' ) : ( reportPeriod ? dayjs ( reportPeriod , 'YYYY-MM-DD' ) : null )
299+ let nextPeriod : Dayjs | null = null
300+ if ( tablePeriod ) {
301+ nextPeriod = dayjs ( String ( tablePeriod ) , 'YYYY-MM-DD' )
302+ } else if ( reportPeriod ) {
303+ nextPeriod = dayjs ( reportPeriod , 'YYYY-MM-DD' )
304+ }
277305 setPeriod ( nextPeriod )
278306 } , [ initialTableState . rowSelectionState , reportPeriod , setSearch ] )
279307
0 commit comments