Expander with optional meta (#2452)
This commit is contained in:
parent
facfb5bba9
commit
c3d8a0be0b
@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { FunctionMetadataLatest, Hash, Proposal } from '@polkadot/types/interfaces';
|
||||
import { Hash, Proposal } from '@polkadot/types/interfaces';
|
||||
|
||||
import React from 'react';
|
||||
import { registry } from '@polkadot/react-api';
|
||||
@ -16,21 +16,6 @@ interface Props {
|
||||
proposalHash: Hash | string;
|
||||
}
|
||||
|
||||
function formatDocs (meta?: FunctionMetadataLatest): React.ReactNode | null {
|
||||
if (!meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const strings = meta.documentation.map((doc): string => doc.toString().trim());
|
||||
const firstEmpty = strings.findIndex((doc): boolean => !doc.length);
|
||||
|
||||
if (!firstEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return strings.slice(0, firstEmpty).join(' ');
|
||||
}
|
||||
|
||||
function ProposalCell ({ className, proposal, proposalHash }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -48,7 +33,7 @@ function ProposalCell ({ className, proposal, proposalHash }: Props): React.Reac
|
||||
return (
|
||||
<td className={`${className} all top`}>
|
||||
<div>{section}.{method}</div>
|
||||
<Expander summary={formatDocs(meta) || t('Details')}>
|
||||
<Expander summaryMeta={meta}>
|
||||
<Call
|
||||
labelHash={t('proposal hash')}
|
||||
value={proposal}
|
||||
|
||||
@ -50,7 +50,7 @@ function renderExtrinsic (props: Props, extrinsic: Extrinsic, index: number, t:
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Expander summary={meta?.documentation.join(' ') || t('Details')}>
|
||||
<Expander summaryMeta={meta}>
|
||||
<Call
|
||||
className='details'
|
||||
mortality={
|
||||
|
||||
@ -53,13 +53,7 @@ function Events ({ emptyLabel, eventClassName, events, withoutIndex }: Props): R
|
||||
}
|
||||
</h3>
|
||||
</div>
|
||||
<Expander
|
||||
summary={
|
||||
event.meta && event.meta.documentation
|
||||
? event.meta.documentation.join(' ')
|
||||
: 'Details'
|
||||
}
|
||||
>
|
||||
<Expander summaryMeta={event.meta}>
|
||||
<EventDisplay
|
||||
className='details'
|
||||
value={event}
|
||||
|
||||
@ -7,19 +7,48 @@ import { BareProps } from './types';
|
||||
import React, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useToggle } from '@polkadot/react-hooks';
|
||||
import { Text } from '@polkadot/types';
|
||||
|
||||
import { useTranslation } from './translate';
|
||||
import Icon from './Icon';
|
||||
|
||||
interface Meta {
|
||||
documentation: Text[];
|
||||
}
|
||||
|
||||
export interface Props extends BareProps {
|
||||
children?: React.ReactNode;
|
||||
isOpen?: boolean;
|
||||
summary: React.ReactNode;
|
||||
summary?: React.ReactNode;
|
||||
summaryMeta?: Meta;
|
||||
withDot?: boolean;
|
||||
withHidden?: boolean;
|
||||
}
|
||||
|
||||
function Expander ({ children, className, isOpen, summary, withDot, withHidden }: Props): React.ReactElement<Props> {
|
||||
function formatMeta (meta?: Meta): React.ReactNode | null {
|
||||
if (!meta || !meta.documentation.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const strings = meta.documentation.map((doc): string => doc.toString().trim());
|
||||
const firstEmpty = strings.findIndex((doc): boolean => !doc.length);
|
||||
|
||||
return firstEmpty === -1
|
||||
? strings.join(' ')
|
||||
: strings.slice(0, firstEmpty).join(' ');
|
||||
}
|
||||
|
||||
function Expander ({ children, className, isOpen, summary, summaryMeta, withDot, withHidden }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const [isExpanded, toggleExpanded] = useToggle(isOpen);
|
||||
const headerMain = useMemo(
|
||||
() => summary || formatMeta(summaryMeta),
|
||||
[summary, summaryMeta]
|
||||
);
|
||||
const headerSub = useMemo(
|
||||
() => summary ? formatMeta(summaryMeta) : null,
|
||||
[summary, summaryMeta]
|
||||
);
|
||||
const hasContent = useMemo(
|
||||
(): boolean => !!children && (!Array.isArray(children) || children.length !== 0),
|
||||
[children]
|
||||
@ -31,12 +60,17 @@ function Expander ({ children, className, isOpen, summary, withDot, withHidden }
|
||||
onClick={toggleExpanded}
|
||||
>
|
||||
<div className='ui--Expander-summary'>
|
||||
{hasContent
|
||||
? <Icon name={isExpanded ? 'angle double down' : 'angle double right'} />
|
||||
: withDot
|
||||
? <Icon name='circle outline' />
|
||||
: undefined
|
||||
}{summary}
|
||||
<div className='ui--Expander-summary-header'>
|
||||
{hasContent
|
||||
? <Icon name={isExpanded ? 'angle double down' : 'angle double right'} />
|
||||
: withDot
|
||||
? <Icon name='circle outline' />
|
||||
: undefined
|
||||
}{headerMain || t('Details')}
|
||||
</div>
|
||||
{headerSub && (
|
||||
<div className='ui--Expander-summary-sub'>{headerSub}</div>
|
||||
)}
|
||||
</div>
|
||||
{hasContent && (isExpanded || withHidden) && (
|
||||
<div className='ui--Expander-contents'>{children}</div>
|
||||
@ -68,5 +102,11 @@ export default React.memo(styled(Expander)`
|
||||
i.icon {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.ui--Expander-summary-sub {
|
||||
font-size: 1rem;
|
||||
opacity: 0.6;
|
||||
padding-left: 1.75rem;
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
@ -22,7 +22,6 @@ interface Props {
|
||||
insetProps?: Partial<InsetProps>;
|
||||
proposal?: Proposal | null;
|
||||
idNumber: BN | number | string;
|
||||
isCollapsible?: boolean;
|
||||
withLinks?: boolean;
|
||||
expandNested?: boolean;
|
||||
}
|
||||
@ -41,7 +40,7 @@ export const styles = `
|
||||
}
|
||||
`;
|
||||
|
||||
function ProposedAction ({ className, asInset, idNumber, insetProps, isCollapsible = true, proposal, withLinks, expandNested }: Props): React.ReactElement<Props> {
|
||||
function ProposedAction ({ className, asInset, idNumber, insetProps, proposal, withLinks, expandNested }: Props): React.ReactElement<Props> {
|
||||
const stringId = isString(idNumber)
|
||||
? idNumber
|
||||
: formatNumber(idNumber);
|
||||
@ -92,21 +91,9 @@ function ProposedAction ({ className, asInset, idNumber, insetProps, isCollapsib
|
||||
return (
|
||||
<div className={`ui--ProposedAction ${className}`}>
|
||||
<h3>{header}</h3>
|
||||
{isCollapsible
|
||||
? (
|
||||
<Expander>
|
||||
{documentation}
|
||||
{params}
|
||||
</Expander>
|
||||
)
|
||||
: (
|
||||
<>
|
||||
<Expander>
|
||||
{documentation}
|
||||
</Expander>
|
||||
{params}
|
||||
</>
|
||||
)}
|
||||
<Expander summaryMeta={meta}>
|
||||
{params}
|
||||
</Expander>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { FunctionMetadataLatest } from '@polkadot/types/interfaces';
|
||||
import { QueueTx } from '@polkadot/react-components/Status/types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
@ -24,25 +23,6 @@ interface Props {
|
||||
value: QueueTx;
|
||||
}
|
||||
|
||||
function formatMeta (meta?: FunctionMetadataLatest): React.ReactNode | null {
|
||||
if (!meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const strings = meta.documentation.map((doc): string => doc.toString().trim());
|
||||
const firstEmpty = strings.findIndex((doc): boolean => !doc.length);
|
||||
|
||||
if (!firstEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='meta'>
|
||||
{strings.slice(0, firstEmpty).join(' ')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Transaction ({ children, className, hideDetails, isSendable, onError, value: { accountId, extrinsic, isUnsigned }, tip }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -75,8 +55,8 @@ function Transaction ({ children, className, hideDetails, isSendable, onError, v
|
||||
})</span>
|
||||
</>
|
||||
}
|
||||
summaryMeta={meta}
|
||||
>
|
||||
{formatMeta(meta)}
|
||||
<Call
|
||||
onError={onError}
|
||||
value={extrinsic}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user