Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
dba0d25a
Commit
dba0d25a
authored
Oct 17, 2022
by
isstuev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
scroll and sorting preserve
parent
b1219d40
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
253 additions
and
226 deletions
+253
-226
BlockTxs.tsx
ui/block/BlockTxs.tsx
+13
-11
Transactions.tsx
ui/pages/Transactions.tsx
+3
-5
Pagination.tsx
ui/shared/Pagination.tsx
+4
-3
TxsContent.tsx
ui/txs/TxsContent.tsx
+53
-60
TxsPending.tsx
ui/txs/TxsPending.tsx
+0
-48
TxsSkeletonDesktop.tsx
ui/txs/TxsSkeletonDesktop.tsx
+4
-9
TxsSkeletonMobile.tsx
ui/txs/TxsSkeletonMobile.tsx
+26
-34
TxsTab.tsx
ui/txs/TxsTab.tsx
+21
-0
TxsTableItem.tsx
ui/txs/TxsTableItem.tsx
+6
-9
TxsValidated.tsx
ui/txs/TxsValidated.tsx
+0
-40
TxsWithSort.tsx
ui/txs/TxsWithSort.tsx
+78
-0
useQueryWithPages.ts
ui/txs/useQueryWithPages.ts
+45
-7
No files found.
ui/block/BlockTxs.tsx
View file @
dba0d25a
import
React
from
'
react
'
;
import
Txs
Content
from
'
ui/txs/TxsConten
t
'
;
import
Txs
WithSort
from
'
ui/txs/TxsWithSor
t
'
;
const
BlockTxs
=
()
=>
{
return
(
<
TxsContent
showDescription=
{
false
}
showSortButton=
{
false
}
txs=
{
[]
}
page=
{
1
}
// eslint-disable-next-line react/jsx-no-bind
onNextPageClick=
{
()
=>
{}
}
// eslint-disable-next-line react/jsx-no-bind
onPrevPageClick=
{
()
=>
{}
}
/>
// <TxsContent
// showDescription={ false }
// showSortButton={ false }
// txs={ [] }
// page={ 1 }
// // eslint-disable-next-line react/jsx-no-bind
// onNextPageClick={ () => {} }
// // eslint-disable-next-line react/jsx-no-bind
// onPrevPageClick={ () => {} }
// />
// eslint-disable-next-line react/jsx-no-bind
<
TxsWithSort
txs=
{
[]
}
setSorting=
{
()
=>
{}
}
/>
);
};
...
...
ui/pages/Transactions.tsx
View file @
dba0d25a
...
...
@@ -9,15 +9,13 @@ import appConfig from 'configs/app/config';
import
Page
from
'
ui/shared/Page/Page
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
RoutedTabs
from
'
ui/shared/RoutedTabs/RoutedTabs
'
;
import
TxsPending
from
'
ui/txs/TxsPending
'
;
import
TxsValidated
from
'
ui/txs/TxsValidated
'
;
import
TxsTab
from
'
ui/txs/TxsTab
'
;
const
Transactions
=
()
=>
{
const
verifiedTitle
=
appConfig
.
network
.
verificationType
===
'
validation
'
?
'
Validated
'
:
'
Mined
'
;
const
TABS
:
Array
<
RoutedTab
>
=
[
{
id
:
'
validated
'
,
title
:
verifiedTitle
,
component
:
<
Txs
Validated
/>
},
{
id
:
'
pending
'
,
title
:
'
Pending
'
,
component
:
<
Txs
Pending
/>
},
{
id
:
'
validated
'
,
title
:
verifiedTitle
,
component
:
<
Txs
Tab
tab=
"validated"
/>
},
{
id
:
'
pending
'
,
title
:
'
Pending
'
,
component
:
<
Txs
Tab
tab=
"pending"
/>
},
];
return
(
...
...
ui/shared/Pagination.tsx
View file @
dba0d25a
import
{
Button
,
Flex
,
I
nput
,
I
con
,
IconButton
}
from
'
@chakra-ui/react
'
;
import
{
Button
,
Flex
,
Icon
,
IconButton
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
arrowIcon
from
'
icons/arrows/east-mini.svg
'
;
...
...
@@ -70,9 +70,10 @@ const Pagination = ({ currentPage, maxPage, onNextPageClick, onPrevPageClick }:
ml=
{
8
}
/>
</
Flex
>
<
Flex
alignItems=
"center"
width=
"132px"
ml=
{
16
}
display=
{
{
base
:
'
none
'
,
lg
:
'
flex
'
}
}
>
{
/* not implemented yet */
}
{
/* <Flex alignItems="center" width="132px" ml={ 16 } display={{ base: 'none', lg: 'flex' }}>
Go to <Input w="84px" size="xs" ml={ 2 }/>
</
Flex
>
</Flex>
*/
}
</
Flex
>
);
...
...
ui/txs/TxsContent.tsx
View file @
dba0d25a
import
{
Box
,
HStack
,
Show
}
from
'
@chakra-ui/react
'
;
import
React
,
{
use
Callback
,
useEffect
,
use
State
}
from
'
react
'
;
import
{
Alert
,
Box
,
HStack
,
Show
,
Button
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useState
}
from
'
react
'
;
import
type
{
TransactionsResponse
}
from
'
types/api/transaction
'
;
import
type
{
Sort
}
from
'
types/client/txs-sort
'
;
import
compareBns
from
'
lib/bigint/compareBns
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
FilterButton
from
'
ui/shared/FilterButton
'
;
import
FilterInput
from
'
ui/shared/FilterInput
'
;
import
Pagination
from
'
ui/shared/Pagination
'
;
import
SortButton
from
'
ui/shared/SortButton
'
;
import
TxsListItem
from
'
./TxsListItem
'
;
import
TxsTable
from
'
./TxsTable
'
;
import
TxsSkeletonDesktop
from
'
./TxsSkeletonDesktop
'
;
import
TxsSkeletonMobile
from
'
./TxsSkeletonMobile
'
;
import
TxsWithSort
from
'
./TxsWithSort
'
;
import
useQueryWithPages
from
'
./useQueryWithPages
'
;
type
Props
=
{
txs
:
TransactionsResponse
[
'
items
'
]
;
queryName
:
string
;
showDescription
?:
boolean
;
showSortButton
?:
boolean
;
onNextPageClick
:
()
=>
void
;
onPrevPageClick
:
()
=>
void
;
page
:
number
;
stateFilter
:
'
validated
'
|
'
pending
'
;
}
const
TxsContent
=
({
showSortButton
=
true
,
showDescription
=
true
,
txs
,
page
,
onNextPageClick
,
onPrevPageClick
}:
Props
)
=>
{
const
TxsContent
=
({
showDescription
,
queryName
,
stateFilter
,
}:
Props
)
=>
{
const
[
sorting
,
setSorting
]
=
useState
<
Sort
>
();
const
[
sortedTxs
,
setSortedTxs
]
=
useState
(
txs
);
// sorting should be preserved with pagination!
const
sort
=
useCallback
((
field
:
'
val
'
|
'
fee
'
)
=>
()
=>
{
if
(
field
===
'
val
'
)
{
setSorting
((
prevVal
=>
{
if
(
prevVal
===
'
val-asc
'
)
{
return
undefined
;
}
if
(
prevVal
===
'
val-desc
'
)
{
return
'
val-asc
'
;
}
return
'
val-desc
'
;
}));
}
if
(
field
===
'
fee
'
)
{
setSorting
((
prevVal
=>
{
if
(
prevVal
===
'
fee-asc
'
)
{
return
undefined
;
}
if
(
prevVal
===
'
fee-desc
'
)
{
return
'
fee-asc
'
;
}
return
'
fee-desc
'
;
}));
}
},
[]);
const
{
data
,
isLoading
,
isError
,
page
,
onPrevPageClick
,
onNextPageClick
,
hasPagination
,
resetPage
,
}
=
useQueryWithPages
(
queryName
,
stateFilter
);
const
isMobile
=
useIsMobile
(
false
);
if
(
isError
)
{
return
<
DataFetchAlert
/>;
}
const
txs
=
data
?.
items
;
useEffect
(()
=>
{
switch
(
sorting
)
{
case
'
val-desc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx1
.
value
,
tx2
.
value
)));
break
;
case
'
val-asc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx2
.
value
,
tx1
.
value
)));
break
;
case
'
fee-desc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx1
.
fee
.
value
,
tx2
.
fee
.
value
)));
break
;
case
'
fee-asc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx2
.
fee
.
value
,
tx1
.
fee
.
value
)));
break
;
default
:
setSortedTxs
(
txs
);
}
},
[
sorting
,
txs
]);
if
(
!
isLoading
&&
!
txs
)
{
return
<
Alert
>
There are no transactions.
</
Alert
>;
}
let
content
=
(
<>
<
Show
below=
"lg"
ssr=
{
false
}
><
TxsSkeletonMobile
/></
Show
>
<
Show
above=
"lg"
ssr=
{
false
}
><
TxsSkeletonDesktop
/></
Show
>
</>
);
if
(
!
isLoading
&&
txs
)
{
content
=
<
TxsWithSort
txs=
{
txs
}
sorting=
{
sorting
}
setSorting=
{
setSorting
}
/>;
}
return
(
<>
...
...
@@ -82,7 +73,7 @@ const TxsContent = ({ showSortButton = true, showDescription = true, txs, page,
onClick=
{
()
=>
{}
}
appliedFiltersNum=
{
0
}
/>
{
showSortButton
&&
(
{
isMobile
&&
(
<
SortButton
// eslint-disable-next-line react/jsx-no-bind
handleSort=
{
()
=>
{}
}
...
...
@@ -98,10 +89,12 @@ const TxsContent = ({ showSortButton = true, showDescription = true, txs, page,
placeholder=
"Search by addresses, hash, method..."
/>
</
HStack
>
<
Show
below=
"lg"
ssr=
{
false
}
><
Box
>
{
sortedTxs
.
map
(
tx
=>
<
TxsListItem
tx=
{
tx
}
key=
{
tx
.
hash
}
/>)
}
</
Box
></
Show
>
<
Show
above=
"lg"
ssr=
{
false
}
><
TxsTable
txs=
{
sortedTxs
}
sort=
{
sort
}
sorting=
{
sorting
}
/></
Show
>
{
content
}
<
Box
mx=
{
{
base
:
0
,
lg
:
6
}
}
my=
{
{
base
:
6
,
lg
:
3
}
}
>
<
Pagination
currentPage=
{
page
}
onNextPageClick=
{
onNextPageClick
}
onPrevPageClick=
{
onPrevPageClick
}
/>
{
hasPagination
?
<
Pagination
currentPage=
{
page
}
onNextPageClick=
{
onNextPageClick
}
onPrevPageClick=
{
onPrevPageClick
}
/>
:
<
Button
onClick=
{
resetPage
}
>
Reset
</
Button
>
}
</
Box
>
</>
);
...
...
ui/txs/TxsPending.tsx
deleted
100644 → 0
View file @
b1219d40
import
{
Show
,
Alert
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TransactionsResponse
}
from
'
types/api/transaction
'
;
import
{
QueryKeys
}
from
'
types/client/queries
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
TxsContent
from
'
./TxsContent
'
;
import
TxsSkeletonDesktop
from
'
./TxsSkeletonDesktop
'
;
import
TxsSkeletonMobile
from
'
./TxsSkeletonMobile
'
;
import
useQueryWithPages
from
'
./useQueryWithPages
'
;
const
TxsValidated
=
()
=>
{
const
fetch
=
useFetch
();
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
TransactionsResponse
>
([
QueryKeys
.
transactionsPending
],
async
()
=>
fetch
(
'
/api/transactions/?filter=pending
'
));
if
(
isError
)
{
return
<
DataFetchAlert
/>;
}
if
(
isLoading
)
{
return
(
<>
<
Show
below=
"lg"
><
TxsSkeletonMobile
isPending
/></
Show
>
<
Show
above=
"lg"
><
TxsSkeletonDesktop
isPending
/></
Show
>
</>
);
}
if
(
!
data
||
!
data
.
items
)
{
return
<
Alert
>
There are no transactions.
</
Alert
>;
}
return
(
<
TxsContent
txs=
{
data
.
items
}
showDescription=
{
false
}
page=
{
page
}
onPrevPageClick=
{
onPrevPageClick
}
onNextPageClick=
{
onNextPageClick
}
/>
);
};
export
default
TxsValidated
;
ui/txs/TxsSkeletonDesktop.tsx
View file @
dba0d25a
import
{
Skeleton
,
Fle
x
}
from
'
@chakra-ui/react
'
;
import
{
Bo
x
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
SkeletonTable
from
'
ui/shared/SkeletonTable
'
;
const
TxsInternalsSkeletonDesktop
=
(
{
isPending
}:
{
isPending
?:
boolean
}
)
=>
{
const
TxsInternalsSkeletonDesktop
=
()
=>
{
return
(
<>
{
!
isPending
&&
<
Skeleton
h=
{
6
}
w=
"100%"
mb=
{
12
}
/>
}
<
Flex
columnGap=
{
3
}
h=
{
8
}
mb=
{
6
}
>
<
Skeleton
w=
"78px"
/>
<
Skeleton
w=
"360px"
/>
</
Flex
>
<
Box
mb=
{
8
}
>
<
SkeletonTable
columns=
{
[
'
32px
'
,
'
20%
'
,
'
18%
'
,
'
15%
'
,
'
11%
'
,
'
292px
'
,
'
18%
'
,
'
18%
'
]
}
/>
</>
</
Box
>
);
};
...
...
ui/txs/TxsSkeletonMobile.tsx
View file @
dba0d25a
import
{
Skeleton
,
Flex
,
Box
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
const
TxInternalsSkeletonMobile
=
(
{
isPending
}:
{
isPending
?:
boolean
}
)
=>
{
const
TxInternalsSkeletonMobile
=
()
=>
{
const
borderColor
=
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
);
return
(
<>
{
!
isPending
&&
<
Skeleton
h=
{
6
}
w=
"100%"
mb=
{
12
}
/>
}
<
Flex
columnGap=
{
3
}
h=
{
8
}
mb=
{
6
}
>
<
Skeleton
w=
"36px"
flexShrink=
{
0
}
/>
<
Skeleton
w=
"36px"
flexShrink=
{
0
}
/>
<
Skeleton
w=
"100%"
/>
</
Flex
>
<
Box
>
{
Array
.
from
(
Array
(
2
)).
map
((
item
,
index
)
=>
(
<
Flex
key=
{
index
}
flexDirection=
"column"
paddingBottom=
{
3
}
paddingTop=
{
4
}
borderTopWidth=
"1px"
borderColor=
{
borderColor
}
_last=
{
{
borderBottomWidth
:
'
1px
'
,
}
}
>
<
Flex
h=
{
6
}
>
<
Skeleton
w=
"100px"
mr=
{
2
}
h=
{
6
}
/>
<
Skeleton
w=
"100px"
h=
{
6
}
/>
</
Flex
>
<
Skeleton
w=
"100%"
h=
"30px"
mt=
{
3
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
3
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
2
}
/>
<
Skeleton
w=
"100%"
h=
{
6
}
mt=
{
6
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
2
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
2
}
/>
<
Box
>
{
Array
.
from
(
Array
(
2
)).
map
((
item
,
index
)
=>
(
<
Flex
key=
{
index
}
flexDirection=
"column"
paddingBottom=
{
3
}
paddingTop=
{
4
}
borderTopWidth=
"1px"
borderColor=
{
borderColor
}
_last=
{
{
borderBottomWidth
:
'
1px
'
,
}
}
>
<
Flex
h=
{
6
}
>
<
Skeleton
w=
"100px"
mr=
{
2
}
h=
{
6
}
/>
<
Skeleton
w=
"100px"
h=
{
6
}
/>
</
Flex
>
))
}
</
Box
>
</>
<
Skeleton
w=
"100%"
h=
"30px"
mt=
{
3
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
3
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
2
}
/>
<
Skeleton
w=
"100%"
h=
{
6
}
mt=
{
6
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
2
}
/>
<
Skeleton
w=
"50%"
h=
{
6
}
mt=
{
2
}
/>
</
Flex
>
))
}
</
Box
>
);
};
...
...
ui/txs/TxsTab.tsx
0 → 100644
View file @
dba0d25a
import
React
from
'
react
'
;
import
{
QueryKeys
}
from
'
types/client/queries
'
;
import
TxsContent
from
'
./TxsContent
'
;
type
Props
=
{
tab
:
'
validated
'
|
'
pending
'
;
}
const
TxsTab
=
({
tab
}:
Props
)
=>
{
return
(
<
TxsContent
queryName=
{
tab
===
'
validated
'
?
QueryKeys
.
transactionsValidated
:
QueryKeys
.
transactionsPending
}
showDescription=
{
tab
===
'
validated
'
}
stateFilter=
{
tab
}
/>
);
};
export
default
TxsTab
;
ui/txs/TxsTableItem.tsx
View file @
dba0d25a
...
...
@@ -12,7 +12,6 @@ import {
PopoverTrigger
,
PopoverContent
,
PopoverBody
,
Portal
,
useColorModeValue
,
Show
,
}
from
'
@chakra-ui/react
'
;
...
...
@@ -57,19 +56,17 @@ const TxsTableItem = ({ tx }: {tx: Transaction}) => {
return
(
<
Tr
>
<
Td
pl=
{
4
}
>
<
Popover
placement=
"right-start"
openDelay=
{
300
}
>
<
Popover
placement=
"right-start"
openDelay=
{
300
}
isLazy
>
{
({
isOpen
})
=>
(
<>
<
PopoverTrigger
>
<
TxAdditionalInfoButton
isOpen=
{
isOpen
}
/>
</
PopoverTrigger
>
<
Portal
>
<
PopoverContent
border=
"1px solid"
borderColor=
{
infoBorderColor
}
>
<
PopoverBody
>
<
TxAdditionalInfo
tx=
{
tx
}
/>
</
PopoverBody
>
</
PopoverContent
>
</
Portal
>
<
PopoverContent
border=
"1px solid"
borderColor=
{
infoBorderColor
}
>
<
PopoverBody
>
<
TxAdditionalInfo
tx=
{
tx
}
/>
</
PopoverBody
>
</
PopoverContent
>
</>
)
}
</
Popover
>
...
...
ui/txs/TxsValidated.tsx
deleted
100644 → 0
View file @
b1219d40
import
{
Show
,
Alert
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TransactionsResponse
}
from
'
types/api/transaction
'
;
import
{
QueryKeys
}
from
'
types/client/queries
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
TxsContent
from
'
./TxsContent
'
;
import
TxsSkeletonDesktop
from
'
./TxsSkeletonDesktop
'
;
import
TxsSkeletonMobile
from
'
./TxsSkeletonMobile
'
;
import
useQueryWithPages
from
'
./useQueryWithPages
'
;
const
TxsValidated
=
()
=>
{
const
fetch
=
useFetch
();
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
TransactionsResponse
>
([
QueryKeys
.
transactionsValidated
],
async
()
=>
fetch
(
'
/api/transactions/?filter=validated
'
));
if
(
isError
)
{
return
<
DataFetchAlert
/>;
}
if
(
isLoading
)
{
return
(
<>
<
Show
below=
"lg"
><
TxsSkeletonMobile
/></
Show
>
<
Show
above=
"lg"
><
TxsSkeletonDesktop
/></
Show
>
</>
);
}
if
(
!
data
||
!
data
.
items
)
{
return
<
Alert
>
There are no transactions.
</
Alert
>;
}
return
<
TxsContent
txs=
{
data
.
items
}
page=
{
page
}
onNextPageClick=
{
onNextPageClick
}
onPrevPageClick=
{
onPrevPageClick
}
/>;
};
export
default
TxsValidated
;
ui/txs/TxsWithSort.tsx
0 → 100644
View file @
dba0d25a
import
{
Box
,
Show
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
,
useEffect
,
useState
}
from
'
react
'
;
import
type
{
TransactionsResponse
}
from
'
types/api/transaction
'
;
import
type
{
Sort
}
from
'
types/client/txs-sort
'
;
import
compareBns
from
'
lib/bigint/compareBns
'
;
import
TxsListItem
from
'
./TxsListItem
'
;
import
TxsTable
from
'
./TxsTable
'
;
type
Props
=
{
txs
:
TransactionsResponse
[
'
items
'
];
sorting
?:
Sort
;
setSorting
:
(
sorting
:
Sort
|
((
val
:
Sort
)
=>
Sort
))
=>
void
;
}
const
TxsContent
=
({
txs
,
sorting
,
setSorting
,
}:
Props
)
=>
{
const
[
sortedTxs
,
setSortedTxs
]
=
useState
(
txs
);
const
sort
=
useCallback
((
field
:
'
val
'
|
'
fee
'
)
=>
()
=>
{
if
(
field
===
'
val
'
)
{
setSorting
((
prevVal
=>
{
if
(
prevVal
===
'
val-asc
'
)
{
return
undefined
;
}
if
(
prevVal
===
'
val-desc
'
)
{
return
'
val-asc
'
;
}
return
'
val-desc
'
;
}));
}
if
(
field
===
'
fee
'
)
{
setSorting
((
prevVal
=>
{
if
(
prevVal
===
'
fee-asc
'
)
{
return
undefined
;
}
if
(
prevVal
===
'
fee-desc
'
)
{
return
'
fee-asc
'
;
}
return
'
fee-desc
'
;
}));
}
},
[
setSorting
]);
useEffect
(()
=>
{
switch
(
sorting
)
{
case
'
val-desc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx1
.
value
,
tx2
.
value
)));
break
;
case
'
val-asc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx2
.
value
,
tx1
.
value
)));
break
;
case
'
fee-desc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx1
.
fee
.
value
,
tx2
.
fee
.
value
)));
break
;
case
'
fee-asc
'
:
setSortedTxs
([
...
txs
].
sort
((
tx1
,
tx2
)
=>
compareBns
(
tx2
.
fee
.
value
,
tx1
.
fee
.
value
)));
break
;
default
:
setSortedTxs
(
txs
);
}
},
[
sorting
,
txs
]);
return
(
<>
<
Show
below=
"lg"
ssr=
{
false
}
><
Box
>
{
sortedTxs
.
map
(
tx
=>
<
TxsListItem
tx=
{
tx
}
key=
{
tx
.
hash
}
/>)
}
</
Box
></
Show
>
<
Show
above=
"lg"
ssr=
{
false
}
><
TxsTable
txs=
{
sortedTxs
}
sort=
{
sort
}
sorting=
{
sorting
}
/></
Show
>
</>
);
};
export
default
TxsContent
;
ui/txs/useQueryWithPages.ts
View file @
dba0d25a
import
{
useQuery
}
from
'
@tanstack/react-query
'
;
import
{
pick
,
omit
}
from
'
lodash
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
{
animateScroll
}
from
'
react-scroll
'
;
import
type
{
TransactionsResponse
}
from
'
types/api/transaction
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
export
default
function
useQueryWithPages
(
queryName
:
string
)
{
const
PAGINATION_FIELDS
=
[
'
block_number
'
,
'
index
'
,
'
items_count
'
];
export
default
function
useQueryWithPages
(
queryName
:
string
,
filter
:
string
)
{
const
router
=
useRouter
();
const
[
page
,
setPage
]
=
React
.
useState
(
1
);
const
[
pageParams
,
setPageParams
]
=
React
.
useState
<
Array
<
Partial
<
TransactionsResponse
[
'
next_page_params
'
]
>>>
([
{}
]);
const
fetch
=
useFetch
();
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
TransactionsResponse
>
(
[
queryName
,
page
],
[
queryName
,
{
page
}
],
async
()
=>
{
const
params
:
Array
<
string
>
=
[];
Object
.
entries
(
pageParams
[
page
-
1
]).
forEach
(([
key
,
val
])
=>
params
.
push
(
`
${
key
}
=
${
val
}
`
));
return
fetch
(
`/api/transactions?filter=
validated
${
params
.
length
?
'
&
'
+
params
.
join
(
'
&
'
)
:
''
}
`
);
return
fetch
(
`/api/transactions?filter=
${
filter
}
${
params
.
length
?
'
&
'
+
params
.
join
(
'
&
'
)
:
''
}
`
);
},
{
staleTime
:
Infinity
},
);
const
onNextPageClick
=
useCallback
(()
=>
{
if
(
page
>=
pageParams
.
length
&&
data
?.
next_page_params
)
{
setPageParams
(
prev
=>
[
...
prev
,
data
?.
next_page_params
]);
// api adds filters into next-page-params now
// later filters will be removed from response
const
nextPageParams
=
pick
(
data
?.
next_page_params
,
PAGINATION_FIELDS
);
setPageParams
(
prev
=>
[
...
prev
,
nextPageParams
]);
const
nextPageQuery
=
{
...
router
.
query
};
Object
.
entries
(
nextPageParams
).
forEach
(([
key
,
val
])
=>
nextPageQuery
[
key
]
=
val
.
toString
());
router
.
query
=
nextPageQuery
;
router
.
push
(
router
);
}
animateScroll
.
scrollToTop
({
duration
:
0
});
setPage
(
prev
=>
prev
+
1
);
},
[
data
,
page
,
pageParams
]);
},
[
data
,
page
,
pageParams
,
router
]);
const
onPrevPageClick
=
useCallback
(()
=>
{
// returning for the first page
// we dont have pagination params for the first page
if
(
page
===
2
)
{
router
.
query
=
omit
(
router
.
query
,
PAGINATION_FIELDS
);
}
else
{
const
nextPageParams
=
{
...
pageParams
[
page
-
1
]
};
const
nextPageQuery
=
{
...
router
.
query
};
Object
.
entries
(
nextPageParams
).
forEach
(([
key
,
val
])
=>
nextPageQuery
[
key
]
=
val
.
toString
());
router
.
query
=
nextPageQuery
;
}
router
.
push
(
router
);
animateScroll
.
scrollToTop
({
duration
:
0
});
setPage
(
prev
=>
prev
-
1
);
},
[]);
},
[
router
,
page
,
pageParams
]);
const
resetPage
=
useCallback
(()
=>
{
router
.
query
=
omit
(
router
.
query
,
PAGINATION_FIELDS
);
router
.
push
(
router
);
animateScroll
.
scrollToTop
({
duration
:
0
});
setPageParams
([
{}
]);
setPage
(
1
);
},
[
router
]);
// if there are pagination params on the initial page, we shouldn't show pagination
const
hasPagination
=
!
(
page
===
1
&&
Object
.
keys
(
pick
(
router
.
query
,
PAGINATION_FIELDS
)).
length
>
0
);
return
{
data
,
isError
,
isLoading
,
page
,
onNextPageClick
,
onPrevPageClick
};
return
{
data
,
isError
,
isLoading
,
page
,
onNextPageClick
,
onPrevPageClick
,
hasPagination
,
resetPage
};
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment