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
825aac59
Commit
825aac59
authored
Jun 01, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
skeletons for search results
parent
4b7cec98
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
122 additions
and
53 deletions
+122
-53
search-results.tsx
pages/search-results.tsx
+3
-1
search.ts
stubs/search.ts
+24
-0
SearchResults.tsx
ui/pages/SearchResults.tsx
+36
-26
Token.tsx
ui/pages/Token.tsx
+9
-1
SearchResultListItem.tsx
ui/searchResults/SearchResultListItem.tsx
+18
-7
SearchResultTableItem.tsx
ui/searchResults/SearchResultTableItem.tsx
+17
-10
AddressHeadingInfo.tsx
ui/shared/AddressHeadingInfo.tsx
+1
-1
LinkInternal.tsx
ui/shared/LinkInternal.tsx
+4
-4
PageTitle.tsx
ui/shared/Page/PageTitle.tsx
+2
-2
useSearchQuery.tsx
ui/snippets/searchBar/useSearchQuery.tsx
+8
-1
No files found.
pages/search-results.tsx
View file @
825aac59
import
type
{
NextPage
}
from
'
next
'
;
import
dynamic
from
'
next/dynamic
'
;
import
Head
from
'
next/head
'
;
import
React
from
'
react
'
;
import
getNetworkTitle
from
'
lib/networks/getNetworkTitle
'
;
import
SearchResults
from
'
ui/pages/SearchResults
'
;
const
SearchResults
=
dynamic
(()
=>
import
(
'
ui/pages/SearchResults
'
),
{
ssr
:
false
});
const
SearchResultsPage
:
NextPage
=
()
=>
{
const
title
=
getNetworkTitle
();
...
...
stubs/search.ts
0 → 100644
View file @
825aac59
import
type
{
SearchResult
,
SearchResultItem
}
from
'
types/api/search
'
;
import
{
ADDRESS_HASH
}
from
'
./addressParams
'
;
export
const
SEARCH_RESULT_ITEM
:
SearchResultItem
=
{
address
:
ADDRESS_HASH
,
address_url
:
'
/address/0x3714A8C7824B22271550894f7555f0a672f97809
'
,
name
:
'
USDC
'
,
symbol
:
'
USDC
'
,
token_url
:
'
/token/0x3714A8C7824B22271550894f7555f0a672f97809
'
,
type
:
'
token
'
,
};
export
const
SEARCH_RESULT_NEXT_PAGE_PARAMS
:
SearchResult
[
'
next_page_params
'
]
=
{
address_hash
:
ADDRESS_HASH
,
block_hash
:
null
,
holder_count
:
11
,
inserted_at
:
'
2023-05-19T17:21:19.203681Z
'
,
item_type
:
'
token
'
,
items_count
:
50
,
name
:
'
USDCTest
'
,
q
:
'
usd
'
,
tx_hash
:
null
,
};
ui/pages/SearchResults.tsx
View file @
825aac59
...
...
@@ -6,13 +6,12 @@ import React from 'react';
import
SearchResultListItem
from
'
ui/searchResults/SearchResultListItem
'
;
import
SearchResultTableItem
from
'
ui/searchResults/SearchResultTableItem
'
;
import
ActionBar
from
'
ui/shared/ActionBar
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
Page
from
'
ui/shared/Page/Page
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
Pagination
from
'
ui/shared/Pagination
'
;
import
SkeletonList
from
'
ui/shared/skeletons/SkeletonList
'
;
import
SkeletonTable
from
'
ui/shared/skeletons/SkeletonTable
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
Thead
from
'
ui/shared/TheadSticky
'
;
import
Header
from
'
ui/snippets/header/Header
'
;
import
SearchBarInput
from
'
ui/snippets/searchBar/SearchBarInput
'
;
import
useSearchQuery
from
'
ui/snippets/searchBar/useSearchQuery
'
;
...
...
@@ -20,7 +19,8 @@ import useSearchQuery from 'ui/snippets/searchBar/useSearchQuery';
const
SearchResultsPageContent
=
()
=>
{
const
router
=
useRouter
();
const
{
query
,
redirectCheckQuery
,
searchTerm
,
debouncedSearchTerm
,
handleSearchTermChange
}
=
useSearchQuery
(
true
);
const
{
data
,
isError
,
isLoading
,
pagination
,
isPaginationVisible
}
=
query
;
const
{
data
,
isError
,
isPlaceholderData
,
pagination
,
isPaginationVisible
}
=
query
;
const
[
showContent
,
setShowContent
]
=
React
.
useState
(
false
);
React
.
useEffect
(()
=>
{
if
(
redirectCheckQuery
.
data
?.
redirect
&&
redirectCheckQuery
.
data
.
parameter
)
{
...
...
@@ -39,7 +39,9 @@ const SearchResultsPageContent = () => {
}
}
}
},
[
redirectCheckQuery
.
data
,
router
]);
!
redirectCheckQuery
.
isLoading
&&
setShowContent
(
true
);
},
[
redirectCheckQuery
,
router
]);
const
handleSubmit
=
React
.
useCallback
((
event
:
FormEvent
<
HTMLFormElement
>
)
=>
{
event
.
preventDefault
();
...
...
@@ -50,23 +52,21 @@ const SearchResultsPageContent = () => {
return
<
DataFetchAlert
/>;
}
if
(
isLoading
||
redirectCheckQuery
.
isLoading
)
{
return
(
<
Box
>
<
SkeletonList
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
/>
<
SkeletonTable
display=
{
{
base
:
'
none
'
,
lg
:
'
block
'
}
}
columns=
{
[
'
50%
'
,
'
50%
'
,
'
150px
'
]
}
/>
</
Box
>
);
}
if
(
data
.
items
.
length
===
0
)
{
if
(
!
data
?.
items
.
length
)
{
return
null
;
}
return
(
<>
<
Show
below=
"lg"
ssr=
{
false
}
>
{
data
.
items
.
map
((
item
,
index
)
=>
<
SearchResultListItem
key=
{
index
}
data=
{
item
}
searchTerm=
{
debouncedSearchTerm
}
/>)
}
{
data
.
items
.
map
((
item
,
index
)
=>
(
<
SearchResultListItem
key=
{
(
isPlaceholderData
?
'
placeholder_
'
:
'
actual_
'
)
+
index
}
data=
{
item
}
searchTerm=
{
debouncedSearchTerm
}
isLoading=
{
isPlaceholderData
}
/>
))
}
</
Show
>
<
Hide
below=
"lg"
ssr=
{
false
}
>
<
Table
variant=
"simple"
size=
"md"
fontWeight=
{
500
}
>
...
...
@@ -78,7 +78,14 @@ const SearchResultsPageContent = () => {
</
Tr
>
</
Thead
>
<
Tbody
>
{
data
.
items
.
map
((
item
,
index
)
=>
<
SearchResultTableItem
key=
{
index
}
data=
{
item
}
searchTerm=
{
debouncedSearchTerm
}
/>)
}
{
data
.
items
.
map
((
item
,
index
)
=>
(
<
SearchResultTableItem
key=
{
(
isPlaceholderData
?
'
placeholder_
'
:
'
actual_
'
)
+
index
}
data=
{
item
}
searchTerm=
{
debouncedSearchTerm
}
isLoading=
{
isPlaceholderData
}
/>
))
}
</
Tbody
>
</
Table
>
</
Hide
>
...
...
@@ -91,16 +98,16 @@ const SearchResultsPageContent = () => {
return
null
;
}
const
text
=
is
Loading
||
redirectCheckQuery
.
isLoading
?
(
const
text
=
is
PlaceholderData
&&
pagination
.
page
===
1
?
(
<
Skeleton
h=
{
6
}
w=
"280px"
borderRadius=
"full"
mb=
{
isPaginationVisible
?
0
:
6
}
/>
)
:
(
(
<
Box
mb=
{
isPaginationVisible
?
0
:
6
}
lineHeight=
"32px"
>
<
span
>
Found
</
span
>
<
chakra
.
span
fontWeight=
{
700
}
>
{
pagination
.
page
>
1
?
50
:
data
.
items
.
length
}{
data
.
next_page_params
||
pagination
.
page
>
1
?
'
+
'
:
''
}
{
pagination
.
page
>
1
?
50
:
data
?.
items
.
length
}{
data
?
.
next_page_params
||
pagination
.
page
>
1
?
'
+
'
:
''
}
</
chakra
.
span
>
<
span
>
matching result
{
data
.
items
.
length
>
1
||
pagination
.
page
>
1
?
'
s
'
:
''
}
for
</
span
>
<
span
>
matching result
{
(
data
?.
items
&&
data
.
items
.
length
>
1
)
||
pagination
.
page
>
1
?
'
s
'
:
''
}
for
</
span
>
“
<
chakra
.
span
fontWeight=
{
700
}
>
{
debouncedSearchTerm
}
</
chakra
.
span
>
”
</
Box
>
)
...
...
@@ -148,14 +155,17 @@ const SearchResultsPageContent = () => {
return
<
Header
renderSearchBar=
{
renderSearchBar
}
/>;
},
[
renderSearchBar
]);
return
(
<
Page
renderHeader=
{
renderHeader
}
>
{
isLoading
||
redirectCheckQuery
.
isLoading
?
<
Skeleton
h=
{
10
}
mb=
{
6
}
w=
"100%"
maxW=
"222px"
/>
:
const
pageContent
=
!
showContent
?
<
ContentLoader
/>
:
(
<>
<
PageTitle
title=
"Search results"
/>
}
{
bar
}
{
content
}
</>
);
return
(
<
Page
renderHeader=
{
renderHeader
}
>
{
pageContent
}
</
Page
>
);
};
...
...
ui/pages/Token.tsx
View file @
825aac59
...
...
@@ -251,7 +251,15 @@ const TokenPageContent = () => {
isLoading={ tokenQuery.isPlaceholderData }
backLink={ backLink }
beforeTitle={ (
<TokenLogo data={ tokenQuery.data } boxSize={ 6 } isLoading={ tokenQuery.isPlaceholderData } display="inline-block" mr={ 2 }/>
<TokenLogo
data={ tokenQuery.data }
boxSize={ 6 }
isLoading={ tokenQuery.isPlaceholderData }
display="inline-block"
mr={ 2 }
my={{ base: 'auto', lg: tokenQuery.isPlaceholderData ? 2 : 'auto' }}
verticalAlign={{ base: undefined, lg: tokenQuery.isPlaceholderData ? 'text-bottom' : undefined }}
/>
) }
afterTitle={
verifiedInfoQuery.data?.tokenAddress ?
...
...
ui/searchResults/SearchResultListItem.tsx
View file @
825aac59
import
{
Text
,
Flex
,
Icon
,
Box
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Icon
,
Box
,
chakra
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
React
from
'
react
'
;
...
...
@@ -19,9 +19,10 @@ import TokenLogo from 'ui/shared/TokenLogo';
interface
Props
{
data
:
SearchResultItem
;
searchTerm
:
string
;
isLoading
?:
boolean
;
}
const
SearchResultListItem
=
({
data
,
searchTerm
}:
Props
)
=>
{
const
SearchResultListItem
=
({
data
,
searchTerm
,
isLoading
}:
Props
)
=>
{
const
firstRow
=
(()
=>
{
switch
(
data
.
type
)
{
...
...
@@ -30,9 +31,15 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => {
return
(
<
Flex
alignItems=
"flex-start"
>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
flexShrink=
{
0
}
/>
<
LinkInternal
ml=
{
2
}
href=
{
route
({
pathname
:
'
/token/[hash]
'
,
query
:
{
hash
:
data
.
address
}
})
}
fontWeight=
{
700
}
wordBreak=
"break-all"
>
<
chakra
.
span
dangerouslySetInnerHTML=
{
{
__html
:
highlightText
(
name
,
searchTerm
)
}
}
/>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
flexShrink=
{
0
}
isLoading=
{
isLoading
}
/>
<
LinkInternal
ml=
{
2
}
href=
{
route
({
pathname
:
'
/token/[hash]
'
,
query
:
{
hash
:
data
.
address
}
})
}
fontWeight=
{
700
}
wordBreak=
"break-all"
isLoading=
{
isLoading
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
dangerouslySetInnerHTML=
{
{
__html
:
highlightText
(
name
,
searchTerm
)
}
}
/>
</
LinkInternal
>
</
Flex
>
);
...
...
@@ -80,7 +87,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => {
switch
(
data
.
type
)
{
case
'
token
'
:
{
return
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
HashStringShortenDynamic
hash=
{
data
.
address
}
/>
</
Skeleton
>
);
}
case
'
block
'
:
{
...
...
@@ -106,7 +115,9 @@ const SearchResultListItem = ({ data, searchTerm }: Props) => {
<
ListItemMobile
py=
{
3
}
fontSize=
"sm"
rowGap=
{
2
}
>
<
Flex
justifyContent=
"space-between"
w=
"100%"
overflow=
"hidden"
lineHeight=
{
6
}
>
{
firstRow
}
<
Text
variant=
"secondary"
ml=
{
8
}
textTransform=
"capitalize"
>
{
data
.
type
}
</
Text
>
<
Skeleton
isLoaded=
{
!
isLoading
}
color=
"text_secondary"
ml=
{
8
}
textTransform=
"capitalize"
>
<
span
>
{
data
.
type
}
</
span
>
</
Skeleton
>
</
Flex
>
{
secondRow
}
</
ListItemMobile
>
...
...
ui/searchResults/SearchResultTableItem.tsx
View file @
825aac59
import
{
Tr
,
Td
,
Text
,
Flex
,
Icon
,
Box
}
from
'
@chakra-ui/react
'
;
import
{
Tr
,
Td
,
Flex
,
Icon
,
Box
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
React
from
'
react
'
;
...
...
@@ -18,9 +18,10 @@ import TokenLogo from 'ui/shared/TokenLogo';
interface
Props
{
data
:
SearchResultItem
;
searchTerm
:
string
;
isLoading
?:
boolean
;
}
const
SearchResultTableItem
=
({
data
,
searchTerm
}:
Props
)
=>
{
const
SearchResultTableItem
=
({
data
,
searchTerm
,
isLoading
}:
Props
)
=>
{
const
content
=
(()
=>
{
switch
(
data
.
type
)
{
...
...
@@ -30,16 +31,22 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<>
<
Td
fontSize=
"sm"
>
<
Flex
alignItems=
"center"
>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
flexShrink=
{
0
}
/>
<
LinkInternal
ml=
{
2
}
href=
{
route
({
pathname
:
'
/token/[hash]
'
,
query
:
{
hash
:
data
.
address
}
})
}
fontWeight=
{
700
}
wordBreak=
"break-all"
>
<
span
dangerouslySetInnerHTML=
{
{
__html
:
highlightText
(
name
,
searchTerm
)
}
}
/>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
flexShrink=
{
0
}
isLoading=
{
isLoading
}
/>
<
LinkInternal
ml=
{
2
}
href=
{
route
({
pathname
:
'
/token/[hash]
'
,
query
:
{
hash
:
data
.
address
}
})
}
fontWeight=
{
700
}
wordBreak=
"break-all"
isLoading=
{
isLoading
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
dangerouslySetInnerHTML=
{
{
__html
:
highlightText
(
name
,
searchTerm
)
}
}
/>
</
LinkInternal
>
</
Flex
>
</
Td
>
<
Td
fontSize=
"sm"
verticalAlign=
"middle"
>
<
Box
whiteSpace=
"nowrap"
overflow=
"hidden"
>
<
Skeleton
isLoaded=
{
!
isLoading
}
whiteSpace=
"nowrap"
overflow=
"hidden"
>
<
HashStringShortenDynamic
hash=
{
data
.
address
}
/>
</
Box
>
</
Skeleton
>
</
Td
>
</>
);
...
...
@@ -126,9 +133,9 @@ const SearchResultTableItem = ({ data, searchTerm }: Props) => {
<
Tr
>
{
content
}
<
Td
fontSize=
"sm"
textTransform=
"capitalize"
verticalAlign=
"middle"
>
<
Text
variant=
"secondary
"
>
{
data
.
type
}
</
Text
>
<
Skeleton
isLoaded=
{
!
isLoading
}
color=
"text_secondary"
display=
"inline-block
"
>
<
span
>
{
data
.
type
}
</
span
>
</
Skeleton
>
</
Td
>
</
Tr
>
);
...
...
ui/shared/AddressHeadingInfo.tsx
View file @
825aac59
...
...
@@ -39,7 +39,7 @@ const AddressHeadingInfo = ({ address, token, isLinkDisabled, isLoading }: Props
{
!
isLoading
&&
!
address
.
is_contract
&&
appConfig
.
isAccountSupported
&&
(
<
AddressFavoriteButton
hash=
{
address
.
hash
}
watchListId=
{
address
.
watchlist_address_id
}
ml=
{
3
}
/>
)
}
<
AddressQrCode
hash=
{
address
.
hash
}
ml=
{
2
}
isLoading=
{
isLoading
}
/>
<
AddressQrCode
hash=
{
address
.
hash
}
ml=
{
2
}
isLoading=
{
isLoading
}
flexShrink=
{
0
}
/>
{
appConfig
.
isAccountSupported
&&
<
AddressActionsMenu
isLoading=
{
isLoading
}
/>
}
</
Flex
>
);
...
...
ui/shared/LinkInternal.tsx
View file @
825aac59
import
type
{
LinkProps
}
from
'
@chakra-ui/react
'
;
import
type
{
LinkProps
,
FlexProps
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Link
}
from
'
@chakra-ui/react
'
;
import
type
{
LinkProps
as
NextLinkProps
}
from
'
next/link
'
;
import
NextLink
from
'
next/link
'
;
...
...
@@ -6,9 +6,9 @@ import type { LegacyRef } from 'react';
import
React
from
'
react
'
;
// NOTE! use this component only for links to pages that are completely implemented in new UI
const
LinkInternal
=
(
props
:
LinkProps
&
{
isLoading
?:
boolean
},
ref
:
LegacyRef
<
HTMLAnchorElement
>
)
=>
{
if
(
props
.
isLoading
)
{
return
<
Flex
alignItems=
"center"
>
{
props
.
children
}
</
Flex
>;
const
LinkInternal
=
(
{
isLoading
,
...
props
}
:
LinkProps
&
{
isLoading
?:
boolean
},
ref
:
LegacyRef
<
HTMLAnchorElement
>
)
=>
{
if
(
isLoading
)
{
return
<
Flex
alignItems=
"center"
{
...
props
as
FlexProps
}
>
{
props
.
children
}
</
Flex
>;
}
if
(
!
props
.
href
)
{
...
...
ui/shared/Page/PageTitle.tsx
View file @
825aac59
...
...
@@ -59,12 +59,12 @@ const PageTitle = ({ title, contentAfter, withTextAd, backLink, className, isLoa
columnGap=
{
3
}
alignItems=
"center"
>
<
Box
>
<
Box
h=
{
{
base
:
'
auto
'
,
lg
:
isLoading
?
10
:
'
auto
'
}
}
>
{
backLink
&&
<
BackLink
{
...
backLink
}
isLoading=
{
isLoading
}
/>
}
{
beforeTitle
}
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
{
isLoading
?
'
inline-block
'
:
'
inline
'
}
display=
{
{
base
:
'
inline
'
,
lg
:
isLoading
?
'
inline-block
'
:
'
inline
'
}
}
verticalAlign=
{
isLoading
?
'
super
'
:
undefined
}
>
<
Heading
...
...
ui/snippets/searchBar/useSearchQuery.tsx
View file @
825aac59
...
...
@@ -6,6 +6,8 @@ import useDebounce from 'lib/hooks/useDebounce';
import
useQueryWithPages
from
'
lib/hooks/useQueryWithPages
'
;
import
useUpdateValueEffect
from
'
lib/hooks/useUpdateValueEffect
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
SEARCH_RESULT_ITEM
,
SEARCH_RESULT_NEXT_PAGE_PARAMS
}
from
'
stubs/search
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
export
default
function
useSearchQuery
(
isSearchPage
=
false
)
{
const
router
=
useRouter
();
...
...
@@ -20,7 +22,12 @@ export default function useSearchQuery(isSearchPage = false) {
const
query
=
useQueryWithPages
({
resourceName
:
'
search
'
,
filters
:
{
q
:
debouncedSearchTerm
},
options
:
{
enabled
:
debouncedSearchTerm
.
trim
().
length
>
0
},
options
:
{
enabled
:
debouncedSearchTerm
.
trim
().
length
>
0
,
placeholderData
:
isSearchPage
?
generateListStub
<
'
search
'
>
(
SEARCH_RESULT_ITEM
,
50
,
{
next_page_params
:
SEARCH_RESULT_NEXT_PAGE_PARAMS
})
:
undefined
,
},
});
const
redirectCheckQuery
=
useApiQuery
(
'
search_check_redirect
'
,
{
...
...
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