Skip to content

Commit

Permalink
feat(xudt): add filter to filter tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Daryl-L committed Jun 24, 2024
1 parent 41e5f09 commit c33e859
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 26 deletions.
3 changes: 3 additions & 0 deletions src/assets/not-selected-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/assets/partial-selected-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/selected-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions src/components/MultiFilterButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Link } from 'react-router-dom'
import { Popover } from 'antd'
import { ReactComponent as FilterIcon } from '../../assets/filter_icon.svg'
import { ReactComponent as SelectedIcon } from '../../assets/selected-icon.svg'
import { ReactComponent as NotSelectedIcon } from '../../assets/not-selected-icon.svg'
import { ReactComponent as PartialSelectedIcon } from '../../assets/partial-selected-icon.svg'
import { useSearchParams } from '../../hooks'
import styles from './styles.module.scss'

export function MultiFilterButton({
filteredList,
isMobile,
filterName,
}: {
filterName: string
filteredList: { key: string; value: string; to: string; title: string | JSX.Element }[]
isMobile?: boolean
}) {
const params = useSearchParams('tags')
const types = params.tags?.split(',').filter(t => t !== '') ?? []

return (
<Popover
className={styles.container}
placement="bottomRight"
trigger={isMobile ? 'click' : 'hover'}
overlayClassName={styles.antPopover}
content={
<div className={styles.filterItems}>
<div className={styles.selectTitle}>
<h2>Select</h2>
{types.length > 0 ? (
<>{types.length === filteredList.length ? <SelectedIcon /> : <PartialSelectedIcon />}</>
) : (
<NotSelectedIcon />
)}
</div>
{filteredList.map(f => (
<Link
key={f.key}
to={() => {
let subTypes = types.map(t => t)
if (subTypes.includes(f.value)) {
subTypes = subTypes.filter(t => t !== f.value)
} else {
subTypes.push(f.value)
}
return `${f.to}?${filterName}=${subTypes.slice().join(',')}`
}}
data-is-active={types.includes(f.value)}
>
{f.title}
{types.includes(f.value) ? <SelectedIcon /> : <NotSelectedIcon />}
</Link>
))}
</div>
}
>
<FilterIcon className={styles.filter} />
</Popover>
)
}

MultiFilterButton.displayName = 'MultiFilterButton'

export default MultiFilterButton
71 changes: 71 additions & 0 deletions src/components/MultiFilterButton/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
.container {
appearance: none;
border: none;
outline: none;
background: none;
display: inline-flex;
vertical-align: text-top;
margin-left: 8px;
cursor: pointer;
}

.antPopover {
:global {
/* stylelint-disable-next-line selector-class-pattern */
.ant-popover-inner {
border-radius: 8px;
box-shadow: 0 2px 10px 0 #eee;
}

/* stylelint-disable-next-line selector-class-pattern */
.ant-popover-inner-content {
padding: 14px 24px 14px 16px;
}
}
}

.filter {
margin-left: 8px;
color: #999;
}

.filterItems {
display: flex;
flex-direction: column;
width: 200px;

.selectTitle {
color: var(--primary-color);

h2 {
color: #333;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: normal;
}

display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border-radius: 8px;
}

a {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border-radius: 8px;

svg {
color: var(--primary-color);
}

&:hover {
background: var(--primary-hover-bg-color);
cursor: pointer;
}
}
}
2 changes: 1 addition & 1 deletion src/components/XUDTTag/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const XUDTTag = ({ tagName }: { tagName: string }) => {
const { push } = useHistory()

let tag = tagName
let content = t(`xudt.${tag}`)
let content = t(`xudt.tags.${tag}`)
if (tag.startsWith('verified-on-')) {
// FIXME: should be i18n
content = content.replace('Platform', tag.replace('verified-on-', ''))
Expand Down
27 changes: 16 additions & 11 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,9 @@
"repeat_inscription_symbol": "This inscription is a duplicate with an earlier release of the same symbol."
},
"xudt": {
"title": {
"tags": "Tags"
},
"holder_allocation": "Holder Allocation",
"holder_allocation_description": "There are {{ckb}} CKB Holder addresses and {{btc}} BTC holder addresses of the current asset.",
"lock_hash": "Lock Hash",
Expand All @@ -762,17 +765,19 @@
"address_count": "Address Count",
"created_time": "Created Time",
"tokens_empty": "There are no xUDTs at this time.",
"invalid": "Invalid",
"suspicious": "Suspicious",
"out-of-length-range": "Out Of Length Range",
"duplicate": "Duplicate",
"layer-1-asset": "Layer 1 Asset",
"layer-2-asset": "Layer 2 Asset",
"verified-on": "Verified On Platform",
"supply-limited": "Supply Limited",
"supply-unlimited": "Supply Unlimited",
"rgbpp-compatible": "RGB++ Compatible",
"category": "Category"
"tags": {
"invalid": "Invalid",
"suspicious": "Suspicious",
"out-of-length-range": "Out Of Length Range",
"duplicate": "Duplicate",
"layer-1-asset": "Layer 1 Asset",
"layer-2-asset": "Layer 2 Asset",
"verified-on": "Verified On Platform",
"supply-limited": "Supply Limited",
"supply-unlimited": "Supply Unlimited",
"rgbpp-compatible": "RGB++ Compatible",
"category": "Category"
}
},
"nft": {
"nft_collection": "NFT Collection",
Expand Down
27 changes: 16 additions & 11 deletions src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,9 @@
"repeat_inscription_symbol": "此铭文与早期发布的铭文同名"
},
"xudt": {
"title": {
"tags": "标签"
},
"holder_allocation": "地址分布",
"holder_allocation_description": "当前资产有 {{ckb}} 个 CKB 用户地址及 {{btc}} 个 BTC 用户地址",
"lock_hash": "Lock Hash",
Expand All @@ -763,17 +766,19 @@
"address_count": "用户数",
"created_time": "创建时间",
"tokens_empty": "目前没有 xUDT。",
"invalid": "无效",
"suspicious": "可疑",
"out-of-length-range": "超长",
"duplicate": "重复",
"layer-1-asset": "Layer 1 资产",
"layer-2-asset": "Layer 2 资产",
"verified-on": "Platform 平台认证",
"supply-limited": "有限供应资产",
"supply-unlimited": "无限供应资产",
"rgbpp-compatible": "RGB++兼容",
"category": "类别"
"tags": {
"invalid": "无效",
"suspicious": "可疑",
"out-of-length-range": "超长",
"duplicate": "重复",
"layer-1-asset": "Layer 1 资产",
"layer-2-asset": "Layer 2 资产",
"verified-on": "Platform 平台认证",
"supply-limited": "有限供应资产",
"supply-unlimited": "无限供应资产",
"rgbpp-compatible": "RGB++兼容",
"category": "类别"
}
},
"nft": {
"nft_collection": "NFT 藏品",
Expand Down
81 changes: 78 additions & 3 deletions src/pages/Xudts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Link } from '../../components/Link'
import Content from '../../components/Content'
import Pagination from '../../components/Pagination'
import SortButton from '../../components/SortButton'
import FilterButton from '../../components/FilterButton'
import MultiFilterButton from '../../components/MultiFilterButton'
import { TokensPanel, TokensContentEmpty, TokensLoadingPanel } from './styled'
import { localeNumberString } from '../../utils/number'
import Loading from '../../components/Loading'
Expand Down Expand Up @@ -116,6 +116,10 @@ export function TokensCard({
{t('xudt.created_time')}
<SortButton field="created_time" sortParam={sortParam} />
</span>
<span className={styles.sortOption}>
{t('xudt.title.tags')}
<MultiFilterButton filterName="tags" key="" filteredList={getFilterList()} />
</span>
</FilterSortContainerOnMobile>
</Card>

Expand All @@ -140,6 +144,77 @@ export function TokensCard({
)
}

const getFilterList = (): { key: string; value: string; to: string; title: string | JSX.Element }[] => {
return [
{
key: 'invalid',
value: 'invalid',
title: <XUDTTag tagName="invalid" />,
to: '',
},
{
key: 'suspicious',
value: 'suspicious',
title: <XUDTTag tagName="suspicious" />,
to: '',
},
{
key: 'out-of-length-range',
value: 'out-of-length-range',
title: <XUDTTag tagName="out-of-length-range" />,
to: '',
},
{
key: 'duplicate',
value: 'duplicate',
title: <XUDTTag tagName="duplicate" />,
to: '',
},
{
key: 'layer-1-asset',
value: 'layer-1-asset',
title: <XUDTTag tagName="layer-1-asset" />,
to: '',
},
{
key: 'layer-2-asset',
value: 'layer-2-asset',
title: <XUDTTag tagName="layer-2-asset" />,
to: '',
},
{
key: 'verified-on',
value: 'verified-on',
title: <XUDTTag tagName="verified-on" />,
to: '',
},
{
key: 'supply-limited',
value: 'supply-limited',
title: <XUDTTag tagName="supply-limited" />,
to: '',
},
{
key: 'supply-unlimited',
value: 'supply-unlimited',
title: <XUDTTag tagName="supply-unlimited" />,
to: '',
},
{
key: 'rgbpp-compatible',
value: 'rgbpp-compatible',
title: <XUDTTag tagName="rgbpp-compatible" />,
to: '',
},
{
key: 'category',
value: 'category',
title: <XUDTTag tagName="category" />,
to: '',
},
]
}

const TokenTable: FC<{
query: UseQueryResult<
{
Expand Down Expand Up @@ -183,8 +258,8 @@ const TokenTable: FC<{
{
title: (
<>
{t('xudt.tags')}
<FilterButton filterName="type" key="" filteredList={[]} />
{t('xudt.title.tags')}
<MultiFilterButton filterName="tags" key="" filteredList={getFilterList()} />
</>
),
className: styles.colTags,
Expand Down

0 comments on commit c33e859

Please sign in to comment.