Split Sidebar flags (& use <Tag /> component) (#2609)

* Split Sidebar flags (& use <Tag /> component)

* Fix Account flags expansion
This commit is contained in:
Jaco Greeff 2020-04-23 10:49:34 +02:00 committed by GitHub
parent e8a5dc13f7
commit 67b69dc976
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 121 additions and 107 deletions

View File

@ -51,7 +51,7 @@ function Account ({ account: { address, meta }, className, filter, isFavorite, s
const recoveryInfo = useCall<RecoveryConfig | null>(api.api.query.recovery?.recoverable, [address], {
transform: (opt: Option<RecoveryConfig>) => opt.unwrapOr(null)
});
const { genesisHash, isDevelopment, isEditable, isExternal, name: accName, onSaveGenesisHash, tags } = useAccountInfo(address);
const { flags: { isDevelopment, isEditable, isExternal }, genesisHash, name: accName, onSaveGenesisHash, tags } = useAccountInfo(address);
const [isVisible, setIsVisible] = useState(true);
const [isBackupOpen, toggleBackup] = useToggle();
const [isDeriveOpen, toggleDerive] = useToggle();

View File

@ -0,0 +1,72 @@
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AddressFlags } from '@polkadot/react-hooks/types';
import React from 'react';
import { Tag } from '@polkadot/react-components';
import { useTranslation } from '../translate';
interface Props {
flags: AddressFlags;
}
function Flags ({ flags: { isCouncil, isDevelopment, isExternal, isSociety, isSudo, isTechCommittee } }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const hasFlags = isDevelopment || isExternal || isSociety || isCouncil || isTechCommittee || isSudo;
if (!hasFlags) {
return null;
}
return (
<div className='ui--AddressMenu-flags'>
{isExternal && (
<Tag
color='grey'
label={t('Injected')}
size='tiny'
/>
)}
{isDevelopment && (
<Tag
color='grey'
label={t('Test account')}
size='tiny'
/>
)}
{isCouncil && (
<Tag
color='blue'
label={t('Council')}
size='tiny'
/>
)}
{isSociety && (
<Tag
color='green'
label={t('Society')}
size='tiny'
/>
)}
{isTechCommittee && (
<Tag
color='orange'
label={t('Technical committee')}
size='tiny'
/>
)}
{isSudo && (
<Tag
color='pink'
label={t('Sudo key')}
size='tiny'
/>
)}
</div>
);
}
export default React.memo(Flags);

View File

@ -6,15 +6,15 @@ import { BareProps } from '@polkadot/react-components/types';
import { AccountId, Address } from '@polkadot/types/interfaces';
import React, { useCallback } from 'react';
import { Label } from 'semantic-ui-react';
import styled from 'styled-components';
import { useAccountInfo, useApi, useRegistrars, useToggle } from '@polkadot/react-hooks';
import { classes } from '@polkadot/react-components/util';
import { colorLink } from '@polkadot/react-components/styles/theme';
import { AccountNameJudgement, AccountName, AddressMini, AvatarItem, Button, Icon, IconLink, IdentityIcon, Input, InputTags, LinkExternal, Transfer } from '@polkadot/react-components';
import { AccountNameJudgement, AccountName, AddressMini, AvatarItem, Button, Icon, IconLink, IdentityIcon, Input, InputTags, LinkExternal, Tag, Transfer } from '@polkadot/react-components';
import { isHex } from '@polkadot/util';
import { useTranslation } from '../translate';
import Flags from './Flags';
interface Props extends BareProps {
address: AccountId | Address | string | Uint8Array;
@ -26,7 +26,7 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
const { t } = useTranslation();
const { api } = useApi();
const { isRegistrar, registrars } = useRegistrars();
const { identity, isCouncil, isDevelopment, isEditable, isEditingName, isEditingTags, isExternal, isInContacts, isOwned, isSociety, isSudo, isTechCommittee, name, onForgetAddress, onSaveName, onSaveTags, setName, setTags, tags, toggleIsEditingName, toggleIsEditingTags } = useAccountInfo(address);
const { flags, identity, isEditingName, isEditingTags, name, onForgetAddress, onSaveName, onSaveTags, setName, setTags, tags, toggleIsEditingName, toggleIsEditingTags } = useAccountInfo(address);
const [isHoveringButton, toggleIsHoveringButton] = useToggle();
const [isTransferOpen, toggleIsTransferOpen] = useToggle();
const [isJudgementOpen, toggleIsJudgementOpen] = useToggle();
@ -48,7 +48,6 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
);
const useIdentity = !!api.query.identity?.identityOf;
const hasFlags = isDevelopment || isExternal || isSociety || isCouncil || isTechCommittee || isSudo;
return (
<>
@ -72,7 +71,7 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
{address.toString()}
</div>
<AccountName
onClick={(isEditable && !isEditingName) ? toggleIsEditingName : undefined}
onClick={(flags.isEditable && !isEditingName) ? toggleIsEditingName : undefined}
override={
isEditingName
? (
@ -80,19 +79,19 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
autoFocus
className='name--input'
defaultValue={name}
onBlur={(isInContacts || isOwned) ? _onUpdateName : undefined}
onBlur={(flags.isInContacts || flags.isOwned) ? _onUpdateName : undefined}
onChange={setName}
withLabel={false}
/>
)
: isEditable
: flags.isEditable
? (name.toUpperCase() || t('<unknown>'))
: undefined
}
value={address}
withSidebar={false}
>
{(!isEditingName && isEditable) && (
{(!isEditingName && flags.isEditable) && (
<Icon
className='inline-icon'
name='edit'
@ -120,20 +119,19 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
>
{tags.length
? tags.map((tag): React.ReactNode => (
<Label
<Tag
color='grey'
key={tag}
label={tag}
size='tiny'
>
{tag}
</Label>
/>
))
: <label>{t('no tags')}</label>
}
</div>
)
}
{(!isEditingTags && (isInContacts || isOwned)) && (
{(!isEditingTags && (flags.isInContacts || flags.isOwned)) && (
<Icon
className='inline-icon'
name='edit'
@ -141,64 +139,7 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
/>
)}
</div>
{hasFlags && (
<div className='ui--AddressMenu-flags'>
{isExternal && (
<Label
color='grey'
size='tiny'
tag
>
{t('Injected')}
</Label>
)}
{isDevelopment && (
<Label
color='grey'
size='tiny'
tag
>
{t('Test account')}
</Label>
)}
{isCouncil && (
<Label
color='blue'
size='tiny'
tag
>
{t('Council')}
</Label>
)}
{isSociety && (
<Label
color='green'
size='tiny'
tag
>
{t('Society')}
</Label>
)}
{isTechCommittee && (
<Label
color='orange'
size='tiny'
tag
>
{t('Technical committee')}
</Label>
)}
{isSudo && (
<Label
color='pink'
size='tiny'
tag
>
{t('Sudo key')}
</Label>
)}
</div>
)}
<Flags flags={flags} />
<div className='ui-AddressMenu--button'>
<Button.Group>
<Button
@ -206,7 +147,7 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
label={t('Deposit')}
onClick={toggleIsTransferOpen}
/>
{isOwned && (
{flags.isOwned && (
<Button
className='basic'
icon='check'
@ -217,7 +158,7 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
size='tiny'
/>
)}
{!isOwned && !isInContacts && (
{!flags.isOwned && !flags.isInContacts && (
<Button
icon='add'
isPositive
@ -228,7 +169,7 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
size='tiny'
/>
)}
{!isOwned && isInContacts && (
{!flags.isOwned && flags.isInContacts && (
<Button
className={`ui--AddressMenu-button icon ${isHoveringButton ? '' : 'basic'}`}
isAnimated
@ -241,12 +182,12 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
>
<Button.Content visible>
<Icon name='check' />
{' '}
&nbsp;
{t('Saved')}
</Button.Content>
<Button.Content hidden>
<Icon name='ban' />
{' '}
&nbsp;
{t('Remove')}
</Button.Content>
</Button>
@ -259,10 +200,10 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
<div className='ui--AddressMenu-sectionHeader'>
<div>
<Icon name='address card' />
{' '}
&nbsp;
{t('identity')}
</div>
<Label
<Tag
color={
identity.isGood
? 'green'
@ -270,20 +211,22 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
? 'red'
: 'yellow'
}
isTag={false}
label={
<>
<b>{identity.judgements.length}&nbsp;</b>
{
identity.judgements.length
? (identity.isGood
? (identity.isKnownGood ? t('Known good') : t('Reasonable'))
: (identity.isErroneous ? t('Erroneous') : t('Low quality'))
)
: t('No judgments')
}
</>
}
size='tiny'
>
<b>{identity.judgements.length}</b>
<Label.Detail>
{
identity.judgements.length
? (identity.isGood
? (identity.isKnownGood ? t('Known good') : t('Reasonable'))
: (identity.isErroneous ? t('Erroneous') : t('Low quality'))
)
: t('No judgments')
}
</Label.Detail>
</Label>
/>
</div>
<div>
<AvatarItem
@ -564,13 +507,7 @@ export default React.memo(styled(Sidebar)`
.inline-icon {
cursor: pointer;
margin: 0 0 0 0.6rem;
color: rgba(200, 200, 200, 0.8);
}
&:hover {
.inline-icon {
color: ${colorLink}
}
color: ${colorLink};
}
.name--input {

View File

@ -12,22 +12,26 @@ interface Props {
className?: string;
color?: 'green' | 'grey' | 'red';
hover?: React.ReactNode;
isTag?: boolean;
label: React.ReactNode;
size?: 'small' | 'tiny';
}
let tagId = 0;
function Tag ({ className, color, hover, label }: Props): React.ReactElement<Props> {
function Tag ({ className, color, hover, isTag = true, label, size = 'small' }: Props): React.ReactElement<Props> {
const [trigger] = useState(`tag-hover-${Date.now()}-${tagId++}`);
const tooltipProps = hover
? { 'data-for': trigger, 'data-tip': true }
: {};
return (
<Label
className={className}
color={color || 'grey'}
data-for={trigger}
data-tip={true}
size='small'
tag
size={size}
tag={isTag}
{...tooltipProps}
>
{label}
{hover && (

View File

@ -94,7 +94,8 @@ export interface AddressIdentity extends DeriveAccountRegistration {
waitCount: number;
}
export interface UseAccountInfo extends AddressFlags {
export interface UseAccountInfo {
flags: AddressFlags;
name: string;
setName: React.Dispatch<string>;
tags: string[];

View File

@ -186,6 +186,7 @@ export default function useAccountInfo (_value: AccountId | Address | string | U
);
return {
flags,
genesisHash,
identity,
isEditingName,
@ -200,7 +201,6 @@ export default function useAccountInfo (_value: AccountId | Address | string | U
setTags,
tags,
toggleIsEditingName,
toggleIsEditingTags,
...flags
toggleIsEditingTags
};
}