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:
parent
c77c0e63ac
commit
9426ec9c31
@ -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>
|
||||
);
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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>;
|
||||
|
||||
@ -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 = () => {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}));
|
||||
}
|
||||
|
||||
@ -72,9 +72,8 @@ class RecentlyOffline extends React.PureComponent<Props, State> {
|
||||
</div>
|
||||
<Tooltip
|
||||
trigger={`offline-${accountId}`}
|
||||
>
|
||||
{text}
|
||||
</Tooltip>
|
||||
text={text}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
@ -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(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user