feat: support asset filter (#10423)

This commit is contained in:
Levi 2024-04-04 22:20:55 +08:00 committed by GitHub
parent ad67bab70f
commit 3392970904
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 81 additions and 7 deletions

View File

@ -1145,6 +1145,7 @@
"approval / {{percent}}%": "",
"approval type": "",
"approved": "",
"asset id or name to query": "",
"asset decimals": "",
"asset id": "",
"asset name": "",

View File

@ -925,6 +925,7 @@
"amount to use for estimation": "用于估算的金额",
"approval type": "批准类型",
"approved": "已赞成",
"asset id or name to query": "要查询的资产id或名称",
"asset id": "资产 id",
"auto-selected targets for nomination": "自动选择的提名对象",
"available": "可用的",

View File

@ -1,9 +1,10 @@
// Copyright 2017-2024 @polkadot/app-assets authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { DropdownItemProps } from 'semantic-ui-react';
import type { AssetInfo, AssetInfoComplete } from '../types.js';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Dropdown, styled, Table } from '@polkadot/react-components';
import { formatNumber } from '@polkadot/util';
@ -39,9 +40,9 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
);
const assetOptions = useMemo(
() => completeInfos.map(({ id, metadata }, index) => ({
() => completeInfos.map(({ id, metadata }) => ({
text: `${metadata.name.toUtf8()} (${formatNumber(id)})`,
value: index
value: id.toNumber()
})),
[completeInfos]
);
@ -53,10 +54,20 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
[info]
);
const onSearch = useCallback(
(options: DropdownItemProps[], value: string): DropdownItemProps[] =>
options.filter((options) => {
const { text: optText, value: optValue } = options as { text: string, value: number };
return parseInt(value) === optValue || optText.includes(value);
}),
[]
);
useEffect((): void => {
setInfo(() =>
infoIndex >= 0 && infoIndex < completeInfos.length
? completeInfos[infoIndex]
infoIndex >= 0
? completeInfos.find(({ id }) => id.toNumber() === infoIndex) ?? null
: null
);
}, [completeInfos, infoIndex]);
@ -71,6 +82,7 @@ function Balances ({ className, infos = [] }: Props): React.ReactElement<Props>
isFull
label={t('the asset to query for balances')}
onChange={setInfoIndex}
onSearch={onSearch}
options={assetOptions}
value={infoIndex}
/>

View File

@ -0,0 +1,55 @@
// Copyright 2017-2024 @polkadot/app-explorer authors & contributors
// SPDX-License-Identifier: Apache-2.0
import React, { useCallback, useState } from 'react';
import { Button, FilterOverlay, Input, styled } from '@polkadot/react-components';
import { useTranslation } from '../translate.js';
interface Props {
className?: string;
onQuery?: (value: string) => void;
}
function Query ({ className = '', onQuery }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [input, setInput] = useState('');
const _onChange = useCallback(
(value: string): void => setInput(value),
[]
);
const _onQuery = useCallback(
(): void => {
onQuery && onQuery(input);
},
[input, onQuery]
);
return (
<StyledFilterOverlay className={`${className} ui--FilterOverlay hasOwnMaxWidth`}>
<Input
className='asset--query'
onChange={_onChange}
onEnter={_onQuery}
placeholder={t('asset id or name to query')}
withLabel={false}
>
<Button
icon='play'
onClick={_onQuery}
/>
</Input>
</StyledFilterOverlay>
);
}
const StyledFilterOverlay = styled(FilterOverlay)`
.asset--query {
width: 20em;
}
`;
export default React.memo(Query);

View File

@ -4,12 +4,13 @@
import type { BN } from '@polkadot/util';
import type { AssetInfo } from '../types.js';
import React from 'react';
import React, { useState } from 'react';
import { Button } from '@polkadot/react-components';
import Create from './Create/index.js';
import Assets from './Assets.js';
import Query from './Query.js';
import Summary from './Summary.js';
interface Props {
@ -20,16 +21,20 @@ interface Props {
}
function Overview ({ className, ids, infos, openId }: Props): React.ReactElement<Props> {
const [keyword, setKeyword] = useState('');
const filteredInfos = keyword ? infos?.filter(({ key, metadata }) => key === keyword || metadata?.name.toUtf8().includes(keyword)) : infos;
return (
<div className={className}>
<Summary numAssets={ids?.length} />
<Query onQuery={setKeyword} />
<Button.Group>
<Create
assetIds={ids}
openId={openId}
/>
</Button.Group>
<Assets infos={infos} />
<Assets infos={filteredInfos} />
</div>
);
}