Hide edit on injected accounts, Button w/ tooltip (#1192)

* Hide edit on injected accounts, Button w/ tooltip

* Don't display "add tags" when not isEditable

* Indentation
This commit is contained in:
Jaco Greeff 2019-05-22 22:01:55 +02:00 committed by GitHub
parent c77c0e63ac
commit 9426ec9c31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 117 additions and 116 deletions

View File

@ -3,12 +3,11 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ActionStatus } from '@polkadot/ui-app/Status/types';
import { I18nProps } from './types';
import { I18nProps } from '@polkadot/ui-app/types';
import { Button as SUIB, Popup } from 'semantic-ui-react';
import React from 'react';
import styled from 'styled-components';
import { AddressSummary, Available, Balance, Bonded, CryptoType, Nonce, Unlocking } from '@polkadot/ui-app';
import { AddressSummary, Available, Balance, Bonded, Button, CryptoType, Nonce, Unlocking } from '@polkadot/ui-app';
import keyring from '@polkadot/ui-keyring';
import Backup from './modals/Backup';
@ -22,6 +21,7 @@ type Props = I18nProps & {
type State = {
isBackupOpen: boolean,
isEditable: boolean,
isForgetOpen: boolean,
isPasswordOpen: boolean
};
@ -109,6 +109,7 @@ class Account extends React.PureComponent<Props> {
this.state = {
isBackupOpen: false,
isEditable: !(keyring.getAccount(props.address).getMeta().isInjected),
isForgetOpen: false,
isPasswordOpen: false
};
@ -116,14 +117,17 @@ class Account extends React.PureComponent<Props> {
render () {
const { address } = this.props;
const { isEditable } = this.state;
// FIXME It is a bit heavy-handled switching of being editable here completely
// (and removing the tags, however the keyring cannot save these)
return (
<Wrapper className='overview--Account'>
{this.renderModals()}
<AddressSummary
value={address}
identIconSize={96}
isEditable
isEditable={isEditable}
withBalance={false}
withNonce={false}
withTags
@ -307,42 +311,35 @@ class Account extends React.PureComponent<Props> {
}
private renderButtons () {
const { t } = this.props;
const { isEditable } = this.state;
if (!isEditable) {
return null;
}
// FIXME: The <Popup /> event trigger on='hover' does not work together with the ui-app'
// <Button /> component. That's why the original Semantic UI component is being used here.
return (
<div className='accounts--Account-buttons'>
<Popup
content='Delete this account'
trigger={
<SUIB
negative
onClick={this.toggleForget}
icon='trash'
size='small'
/>
}
wide='very'
<Button
isNegative
onClick={this.toggleForget}
icon='trash'
size='small'
tooltip={t('Forget this account')}
/>
<Popup
content='Create a backup file for this account'
trigger={
<SUIB
icon='cloud download'
onClick={this.toggleBackup}
size='small'
/>
}
<Button
icon='cloud download'
isPrimary
onClick={this.toggleBackup}
size='small'
tooltip={t('Create a backup file for this account')}
/>
<Popup
content="Change this account's password"
trigger={
<SUIB
icon='key'
onClick={this.togglePass}
size='small'
/>
}
<Button
icon='key'
isPrimary
onClick={this.togglePass}
size='small'
tooltip={t("Change this account's password")}
/>
</div>
);

View File

@ -9,9 +9,7 @@ import { Route } from '@polkadot/apps-routing/types';
import React from 'react';
import { NavLink } from 'react-router-dom';
// FIXME Use Tooltip from ui-app
import ReactTooltip from 'react-tooltip';
import { Icon, Menu } from '@polkadot/ui-app';
import { Icon, Menu, Tooltip } from '@polkadot/ui-app';
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
import { withApi,withCalls, withMulti, withObservable } from '@polkadot/ui-api';
import { isFunction } from '@polkadot/util';
@ -24,17 +22,7 @@ type Props = I18nProps & ApiProps & {
sudo_key: string
};
interface Tooltip {
'data-tip': boolean;
'data-for': string;
'data-tip-disable'?: boolean;
}
class Item extends React.PureComponent<Props> {
componentWillUpdate () {
ReactTooltip.rebuild();
}
render () {
const { route: { i18n, icon, name }, t, isCollapsed } = this.props;
@ -42,33 +30,25 @@ class Item extends React.PureComponent<Props> {
return null;
}
const tooltip: Tooltip = {
'data-for': `nav-${name}`,
'data-tip': true,
'data-tip-disable': !isCollapsed
};
return (
<Menu.Item className='apps--SideBar-Item'>
<NavLink
activeClassName='apps--SideBar-Item-NavLink-active'
className='apps--SideBar-Item-NavLink'
data-for={`nav-${name}`}
data-tip
data-tip-disable={!isCollapsed}
onClick={this.props.onClick}
to={`/${name}`}
{...tooltip}
>
<Icon name={icon} />
<span className='text'>{t(`sidebar.${name}`, i18n)}</span>
<ReactTooltip
delayShow={750}
effect='solid'
id={`nav-${name}`}
offset={ { right: -4 } }
place='right'
>
<span>{t(`sidebar.${name}`, i18n)}
</span>
</ReactTooltip>
<Tooltip
offset={{ right: -4 }}
place='right'
text={t(`sidebar.${name}`, i18n)}
trigger={`nav-${name}`}
/>
</NavLink>
</Menu.Item>
);

View File

@ -375,14 +375,14 @@ class AddressSummary extends React.PureComponent<Props, State> {
>
{
!tags.length
? <span>add tags</span>
: tags.map((tag) => {
return (
<Label key={tag} size='tiny' color='grey'>
{tag}
</Label>
);
})
? (isEditable ? <span>add tags</span> : undefined)
: tags.map((tag) => {
return (
<Label key={tag} size='tiny' color='grey'>
{tag}
</Label>
);
})
}
{isEditable && this.renderEditIcon(this.toggleTagsEditor)}
</div>;

View File

@ -6,17 +6,24 @@ import { ButtonProps } from './types';
import React from 'react';
import SUIButton from 'semantic-ui-react/dist/commonjs/elements/Button/Button';
import { isUndefined } from '@polkadot/util';
import Tooltip from '../Tooltip';
let idCounter = 0;
export default class Button extends React.PureComponent<ButtonProps> {
private id: string = `button-${++idCounter}`;
render () {
const { children, className, floated, icon, isBasic = false, isCircular = false, isDisabled = false, isLoading = false, isNegative = false, isPositive = false, isPrimary = false, label, onClick, size, style, tabIndex } = this.props;
const { children, className, floated, icon, isBasic = false, isCircular = false, isDisabled = false, isLoading = false, isNegative = false, isPositive = false, isPrimary = false, label, onClick, size, style, tabIndex, tooltip } = this.props;
const props = {
basic: isBasic,
circular: isCircular,
className,
'data-tip': !!tooltip,
'data-for': this.id,
disabled: isDisabled,
floated,
icon,
@ -31,15 +38,22 @@ export default class Button extends React.PureComponent<ButtonProps> {
tabIndex
};
return isUndefined(label) && isUndefined(children)
? (
<SUIButton {...props} />
)
: (
<SUIButton {...props}>
{label}{children}
</SUIButton>
);
return (
<>
{
isUndefined(label) && isUndefined(children)
? <SUIButton {...props} />
: <SUIButton {...props}>{label}{children}</SUIButton>
}
{tooltip && (
<Tooltip
place='top'
text={tooltip}
trigger={this.id}
/>
)}
</>
);
}
click = () => {

View File

@ -6,13 +6,15 @@ import { ButtonType } from './types';
import './Button.css';
import Button from './Button';
import IButton from './Button';
import Divider from './Divider';
import Group from './Group';
import Or from './Or';
(Button as any as ButtonType).Divider = Divider;
(Button as any as ButtonType).Group = Group;
(Button as any as ButtonType).Or = Or;
const Button = IButton as any as ButtonType;
export default (Button as any as ButtonType);
Button.Divider = Divider;
Button.Group = Group;
Button.Or = Or;
export default Button;

View File

@ -21,7 +21,8 @@ export type ButtonProps = BareProps & {
onClick?: () => void | Promise<void>,
ref?: any,
size?: Button$Sizes,
tabIndex?: number
tabIndex?: number,
tooltip?: React.ReactNode
};
export type DividerProps = BareProps;

View File

@ -137,16 +137,17 @@ export default class Labelled extends React.PureComponent<Props, State> {
onMouseOut={this.toggleTooltip}
/>
{tooltipOpen && (
<Tooltip trigger='controlled-trigger'>
{help}
</Tooltip>
<Tooltip
text={help}
trigger='controlled-trigger'
/>
)}
</label>
: <label>{displayLabel}</label>;
}
private toggleTooltip = () => {
this.setState(({ tooltipOpen }: State) => ({
this.setState(({ tooltipOpen }) => ({
tooltipOpen: !tooltipOpen
}));
}

View File

@ -72,9 +72,8 @@ class RecentlyOffline extends React.PureComponent<Props, State> {
</div>
<Tooltip
trigger={`offline-${accountId}`}
>
{text}
</Tooltip>
text={text}
/>
</div>
);
}

View File

@ -11,10 +11,13 @@ import { BareProps } from './types';
const rootElement = document.getElementById('tooltips');
type Props = BareProps & {
trigger: string,
delayShow?: number,
place?: 'bottom' | 'top' | 'right' | 'left',
dataFor?: string,
effect?: 'solid' | 'float'
offset?: { bottom?: number, left?: number, right?: number, top?: number },
place?: 'bottom' | 'top' | 'right' | 'left',
text: React.ReactNode,
trigger: string
};
export default class Tooltip extends React.PureComponent<Props> {
@ -25,10 +28,11 @@ export default class Tooltip extends React.PureComponent<Props> {
className: 'ui--Tooltip'
};
tooltipContainer: HTMLElement;
private tooltipContainer: HTMLElement;
constructor (props: Props) {
super(props);
this.tooltipContainer = document.createElement('div');
}
@ -45,17 +49,18 @@ export default class Tooltip extends React.PureComponent<Props> {
}
render () {
const { children, trigger, delayShow, effect, place, className } = this.props;
const { className, delayShow, effect, offset, place, text, trigger } = this.props;
return ReactDOM.createPortal(
<ReactTooltip
id={trigger}
delayShow={delayShow}
effect={effect}
offset={offset}
place={place}
className={className}
>
{children}
{text}
</ReactTooltip>,
this.tooltipContainer
);

View File

@ -35,11 +35,6 @@ export class UnlockingDisplay extends React.PureComponent<Props, State> {
};
}
toggleTooltip () {
const { tooltipOpen } = this.state;
this.setState({ tooltipOpen: !tooltipOpen });
}
render () {
const { unlockings } = this.props;
@ -52,7 +47,6 @@ export class UnlockingDisplay extends React.PureComponent<Props, State> {
}
private groupByEra (list: UnlockChunk[]) {
return list.reduce((map, { era, value }) => {
const key = era.toString();
@ -93,29 +87,31 @@ export class UnlockingDisplay extends React.PureComponent<Props, State> {
{groupedUnlockings && Object.keys(groupedUnlockings).map(eraString => (
<React.Fragment key={eraString}>
<span
className={className + ' label-locked'}
className={`${className} label-locked`}
>
{t('locked')}
</span>
<span
className={className + ' result-locked'}
className={`${className} result-locked`}
>
{formatBalance(groupedUnlockings[eraString])}
<Icon
name='info circle'
data-tip
data-for={'controlled-trigger' + eraString}
onMouseOver={() => this.toggleTooltip()}
onMouseOut={() => this.toggleTooltip()}
data-for={`controlled-trigger${eraString}`}
onMouseOver={this.toggleTooltip}
onMouseOut={this.toggleTooltip}
/>
{tooltipOpen && (
<Tooltip trigger={'controlled-trigger' + eraString}>
{t('{{remaining}} blocks left', {
<Tooltip
text={t('{{remaining}} blocks left', {
replace: {
remaining: this.remainingBlocks(new BlockNumber(eraString))
}
})}
</Tooltip>)}
trigger={`controlled-trigger${eraString}`}
/>
)}
</span>
</React.Fragment>
))}
@ -156,6 +152,12 @@ export class UnlockingDisplay extends React.PureComponent<Props, State> {
: null
);
}
private toggleTooltip = () => {
this.setState(({ tooltipOpen }) => ({
tooltipOpen: !tooltipOpen
}));
}
}
export default translate(