feat: support asset filter (#10423)
This commit is contained in:
parent
ad67bab70f
commit
3392970904
@ -1145,6 +1145,7 @@
|
||||
"approval / {{percent}}%": "",
|
||||
"approval type": "",
|
||||
"approved": "",
|
||||
"asset id or name to query": "",
|
||||
"asset decimals": "",
|
||||
"asset id": "",
|
||||
"asset name": "",
|
||||
|
||||
@ -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": "可用的",
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
|
||||
55
packages/page-assets/src/Overview/Query.tsx
Normal file
55
packages/page-assets/src/Overview/Query.tsx
Normal 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);
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user