Hover & signer name updates (#646)
* Hover should not hop all over the screen * Rework signer with name/address display
This commit is contained in:
parent
e695149786
commit
077dfc398d
@ -27,7 +27,6 @@ class Events extends React.PureComponent<Props> {
|
||||
<h1>{t('events')}</h1>
|
||||
<div className='explorer--BlockByHash-flexable'>
|
||||
<EventsDisplay
|
||||
isSummary
|
||||
eventClassName='explorer--BlockByHash-block'
|
||||
value={value}
|
||||
/>
|
||||
|
||||
@ -60,17 +60,21 @@ class Extrinsics extends React.PureComponent<Props> {
|
||||
<h3>
|
||||
{section}.{method} (#{numberFormat(index)})
|
||||
</h3>
|
||||
<div className='ui--hover description'>{
|
||||
meta && meta.documentation && meta.documentation.length
|
||||
? meta.documentation.map((doc) => doc.toString()).join(' ')
|
||||
: ''
|
||||
}</div>
|
||||
{this.renderSigner(extrinsic)}
|
||||
</div>
|
||||
<Call
|
||||
className='ui--hover details'
|
||||
value={extrinsic}
|
||||
/>
|
||||
<div className='ui--hover'>
|
||||
<div className='ui--hover-content'>
|
||||
<div className='description'>{
|
||||
meta && meta.documentation && meta.documentation.length
|
||||
? meta.documentation.map((doc) => doc.toString()).join(' ')
|
||||
: ''
|
||||
}</div>
|
||||
<Call
|
||||
className='details'
|
||||
value={extrinsic}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -48,18 +48,17 @@ class Logs extends React.PureComponent<Props> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className='ui--hoverable explorer--BlockByHash-block'
|
||||
className='explorer--BlockByHash-block'
|
||||
key={index}
|
||||
>
|
||||
<article className='explorer--Container'>
|
||||
<article className='explorer--Container ui--hoverable'>
|
||||
<div className='header'>
|
||||
<h3>
|
||||
{item.type.toString()}
|
||||
</h3>
|
||||
<div className='ui--hover description' />
|
||||
<h3>{item.type.toString()}</h3>
|
||||
</div>
|
||||
<div className='ui--hover details'>
|
||||
{content}
|
||||
<div className='ui--hover'>
|
||||
<div className='ui--hover-content'>
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
@ -10,23 +10,6 @@
|
||||
.explorer--BlockHeader {
|
||||
animation: fadein 1.5s;
|
||||
|
||||
> div {
|
||||
padding: 0.5em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&.ui--hoverable {
|
||||
.details > .contains {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.details > .contains {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.author {
|
||||
font-size: 1rem;
|
||||
text-align: right;
|
||||
@ -37,6 +20,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.header-outer {
|
||||
padding: 0.5rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
@ -61,7 +49,6 @@
|
||||
.hash {
|
||||
font-size: 1.5rem;
|
||||
font-family: sans-serif;
|
||||
/*opacity: 0.75;*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,34 +63,26 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.details {
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
.contains {
|
||||
border: 0;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
|
||||
> .contains {
|
||||
border: 0;
|
||||
margin-top: 0.5rem;
|
||||
opacity: 0.75;
|
||||
> .info {
|
||||
margin-bottom: 0.125em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
> .info {
|
||||
margin-bottom: 0.125em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
> div {
|
||||
display: inline-block;
|
||||
padding: 0 0.25em;
|
||||
vertical-align: middle;
|
||||
|
||||
> div {
|
||||
display: inline-block;
|
||||
padding: 0 0.25em;
|
||||
vertical-align: middle;
|
||||
|
||||
&.type {
|
||||
opacity: 0.75;
|
||||
text-align: right;
|
||||
width: 10em;
|
||||
}
|
||||
&.type {
|
||||
opacity: 0.75;
|
||||
text-align: right;
|
||||
width: 10em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ export default class BlockHeader extends React.PureComponent<Props> {
|
||||
|
||||
return (
|
||||
<article className={['explorer--BlockHeader', isSummary ? 'ui--hoverable summary' : ''].join(' ')}>
|
||||
<div className='details'>
|
||||
<div className='header-outer'>
|
||||
<div className='header'>
|
||||
<div className='number'>{
|
||||
withLink
|
||||
@ -50,7 +50,9 @@ export default class BlockHeader extends React.PureComponent<Props> {
|
||||
: undefined
|
||||
}</div>
|
||||
</div>
|
||||
<div className='ui--hover contains'>
|
||||
</div>
|
||||
<div className='ui--hover'>
|
||||
<div className='ui--hover-content contains'>
|
||||
<div className='info'>
|
||||
<div className='type'>parentHash</div>
|
||||
<div className='hash'>{
|
||||
|
||||
@ -45,9 +45,9 @@ class BlockHeaders extends React.PureComponent<Props> {
|
||||
|
||||
return (
|
||||
<div className='explorer--BlockHeaders'>
|
||||
{headers.map((header, index) => (
|
||||
{headers.map((header) => (
|
||||
<BlockHeader
|
||||
isSummary={index !== 0}
|
||||
isSummary
|
||||
key={header.blockNumber.toString()}
|
||||
value={header}
|
||||
withLink={!header.blockNumber.isZero()}
|
||||
|
||||
@ -12,7 +12,6 @@ import { numberFormat } from '@polkadot/ui-reactive/util/index';
|
||||
import translate from './translate';
|
||||
|
||||
type Props = I18nProps & {
|
||||
isSummary?: boolean,
|
||||
value?: Array<EventRecord>,
|
||||
emptyLabel?: React.ReactNode,
|
||||
eventClassName?: string,
|
||||
@ -46,14 +45,14 @@ class Events extends React.PureComponent<Props> {
|
||||
}
|
||||
|
||||
private renderEvent = ({ event, phase }: EventRecord, index: number) => {
|
||||
const { isSummary, withoutIndex } = this.props;
|
||||
const { withoutIndex } = this.props;
|
||||
const extIndex = !withoutIndex && phase.type === 'ApplyExtrinsic'
|
||||
? phase.asApplyExtrinsic
|
||||
: -1;
|
||||
|
||||
return (
|
||||
<article
|
||||
className={['explorer--Container', (isSummary || index) ? 'ui--hoverable' : ''].join(' ')}
|
||||
className={['explorer--Container', 'ui--hoverable'].join(' ')}
|
||||
key={index}
|
||||
>
|
||||
<div className='header'>
|
||||
@ -64,18 +63,23 @@ class Events extends React.PureComponent<Props> {
|
||||
: ''
|
||||
}
|
||||
</h3>
|
||||
<div className='ui--hover description'>
|
||||
{
|
||||
event.meta.documentation && event.meta.documentation.length
|
||||
? event.meta.documentation.map((doc) => doc.toString()).join(' ')
|
||||
: ''
|
||||
}
|
||||
|
||||
</div>
|
||||
<div className='ui--hover'>
|
||||
<div className='ui--hover-content'>
|
||||
<div className='description'>
|
||||
{
|
||||
event.meta.documentation && event.meta.documentation.length
|
||||
? event.meta.documentation.map((doc) => doc.toString()).join(' ')
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
<EventDisplay
|
||||
className='details'
|
||||
value={event}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<EventDisplay
|
||||
className='ui--hover details'
|
||||
value={event}
|
||||
/>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
@ -45,11 +45,6 @@
|
||||
.explorer--Container {
|
||||
color: inherit;
|
||||
|
||||
&:not(.ui--hoverable) .header .description,
|
||||
&.ui--hoverable:hover .header .description {
|
||||
margin: 0.25rem 0 0.5rem 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
@ -57,14 +52,15 @@
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.description {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
margin: 0rem 0 0.5rem 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
> .details {
|
||||
|
||||
@ -24,9 +24,9 @@ class AddressRow extends AddressSummary {
|
||||
{this.renderAddress()}
|
||||
{this.renderBalance()}
|
||||
{this.renderNonce()}
|
||||
{this.renderChildren()}
|
||||
</div>
|
||||
</div>
|
||||
{this.renderChildren()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -196,8 +196,10 @@ class AddressSummary extends React.PureComponent<Props> {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='ui--AddressSummary-children ui--hover'>
|
||||
{children}
|
||||
<div className='ui--hover'>
|
||||
<div className='ui--AddressSummary-children ui--hover-content'>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import React from 'react';
|
||||
import store from 'store';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
import keyringOption from '@polkadot/ui-keyring/options';
|
||||
import makeOption from '@polkadot/ui-keyring/options/item';
|
||||
import createItem from '@polkadot/ui-keyring/options/item';
|
||||
import { withMulti, withObservable } from '@polkadot/ui-api/index';
|
||||
|
||||
import Dropdown from '../Dropdown';
|
||||
@ -25,7 +25,7 @@ type Props = BareProps & {
|
||||
isError?: boolean,
|
||||
isInput?: boolean,
|
||||
label?: string,
|
||||
onChange: (value: string | null) => void,
|
||||
onChange?: (value: string | null) => void,
|
||||
optionsAll?: KeyringOptions,
|
||||
placeholder?: string,
|
||||
type?: KeyringOption$Type,
|
||||
@ -59,6 +59,22 @@ const transformToAccountId = (value: string): string | null => {
|
||||
: accountId;
|
||||
};
|
||||
|
||||
const createOption = (address: string) => {
|
||||
let name: string | undefined;
|
||||
|
||||
try {
|
||||
name = keyring.getAccount(address).getMeta().name;
|
||||
} catch (error) {
|
||||
try {
|
||||
name = keyring.getAddress(address).getMeta().name;
|
||||
} catch (error) {
|
||||
// ok, we don't have account or address
|
||||
}
|
||||
}
|
||||
|
||||
return createItem(address, name);
|
||||
};
|
||||
|
||||
class InputAddress extends React.PureComponent<Props, State> {
|
||||
constructor (props: Props) {
|
||||
super(props);
|
||||
@ -126,7 +142,7 @@ class InputAddress extends React.PureComponent<Props, State> {
|
||||
onSearch={this.onSearch}
|
||||
options={
|
||||
isDisabled && actualValue
|
||||
? [makeOption(actualValue)]
|
||||
? [createOption(actualValue)]
|
||||
: optionsAll[type]
|
||||
}
|
||||
style={style}
|
||||
@ -169,7 +185,7 @@ class InputAddress extends React.PureComponent<Props, State> {
|
||||
|
||||
InputAddress.setLastValue(type, address);
|
||||
|
||||
onChange(transformToAccountId(address));
|
||||
onChange && onChange(transformToAccountId(address));
|
||||
}
|
||||
|
||||
private onSearch = (filteredOptions: KeyringSectionOptions, _query: string): KeyringSectionOptions => {
|
||||
|
||||
@ -69,11 +69,6 @@ header .ui--Button-Group {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ui--AddressRow {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui--AddressRow-base {
|
||||
display: flex;
|
||||
}
|
||||
@ -100,25 +95,13 @@ header .ui--Button-Group {
|
||||
}
|
||||
|
||||
.ui--AddressSummary-children {
|
||||
padding-top: 0.5rem;
|
||||
margin-top: 0.5rem !important;
|
||||
}
|
||||
|
||||
.ui--AddressRow .ui--AddressSummary-children {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ui--hoverable {
|
||||
.ui--AddressSummary-children.ui--hover {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.ui--AddressSummary-children.ui--hover {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui--AddressSummary .rx--updated {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
@ -2,19 +2,34 @@
|
||||
/* This software may be modified and distributed under the terms
|
||||
/* of the Apache-2.0 license. See the LICENSE file for details. */
|
||||
|
||||
.ui--hoverable {
|
||||
article.ui--hoverable {
|
||||
.ui--hover {
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
transition: none;
|
||||
transform: scale(0);
|
||||
position: relative;
|
||||
margin: 0 -1.5rem;
|
||||
}
|
||||
|
||||
&:hover .ui--hover {
|
||||
height: auto;
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
transition: all 0.25s ease-in;
|
||||
.ui--hover-content {
|
||||
border: 1px solid #4e4e4e;
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
border-top-width: 0;
|
||||
border-left-width: 0.25rem;
|
||||
background: white;
|
||||
display: none !important;
|
||||
left: -0.25rem;
|
||||
padding: 0.5rem 1.5rem 1rem;
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
top: -1px;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
border-color: #4e4e4e;
|
||||
|
||||
.ui--hover-content {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
background-color: $button-primary-color;
|
||||
}
|
||||
|
||||
|
||||
.ui.primary.button:hover,
|
||||
.ui.buttons .primary.button:hover {
|
||||
background-color: $button-primary-color-hover;
|
||||
@ -97,4 +96,15 @@
|
||||
.ui.red.progress .bar {
|
||||
background-color: $red;
|
||||
}
|
||||
|
||||
article.ui--hoverable {
|
||||
.ui--hover-content {
|
||||
border-color: $wild-orchid;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
border-color: $wild-orchid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
.ui--Params-Content {
|
||||
box-sizing: border-box;
|
||||
padding-left: 2em;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.ui--Param-text {
|
||||
|
||||
@ -6,9 +6,8 @@ import { I18nProps } from '@polkadot/ui-app/types';
|
||||
import { QueueTx } from '@polkadot/ui-app/Status/types';
|
||||
|
||||
import React from 'react';
|
||||
import { Trans } from 'react-i18next';
|
||||
import { Method } from '@polkadot/types';
|
||||
import { Call, IdentityIcon, Modal } from '@polkadot/ui-app/index';
|
||||
import { Call, InputAddress, Modal } from '@polkadot/ui-app/index';
|
||||
|
||||
import Fees from './Fees';
|
||||
import translate from './translate';
|
||||
@ -20,47 +19,52 @@ type Props = I18nProps & {
|
||||
|
||||
class Transaction extends React.PureComponent<Props> {
|
||||
render () {
|
||||
const { children, t, value: { accountId, extrinsic, isUnsigned } } = this.props;
|
||||
const { children, value: { extrinsic } } = this.props;
|
||||
|
||||
if (!extrinsic) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { method, section } = Method.findFunction(extrinsic.callIndex);
|
||||
const header = isUnsigned
|
||||
? (
|
||||
<Trans i18nKey='decoded.short-unsigned'>You are about to submit an (unsigned) inherent transaction calling <span className='code'>{section}.{method}</span></Trans>
|
||||
)
|
||||
: (
|
||||
<Trans i18nKey='decoded.short-signed'>You are about to sign a transaction from <span className='code'>{accountId}</span> calling <span className='code'>{section}.{method}</span> </Trans>
|
||||
);
|
||||
const icon = isUnsigned
|
||||
? undefined
|
||||
: (
|
||||
<IdentityIcon
|
||||
className='icon'
|
||||
value={accountId}
|
||||
/>
|
||||
);
|
||||
|
||||
return [
|
||||
<Modal.Header key='header'>
|
||||
{t('Submit Transaction')}
|
||||
{section}.{method}
|
||||
</Modal.Header>,
|
||||
<Modal.Content className='ui--signer-Signer-Content' key='content'>
|
||||
<div className='ui--signer-Signer-Decoded'>
|
||||
<div className='expanded'>
|
||||
<p>{header}</p>
|
||||
<div className='ui--signer-Signer-children'>
|
||||
{this.renderAccount()}
|
||||
{children}
|
||||
</div>
|
||||
<Call value={extrinsic} />
|
||||
{this.renderFees()}
|
||||
</div>
|
||||
{icon}
|
||||
</div>
|
||||
{children}
|
||||
</Modal.Content>
|
||||
];
|
||||
}
|
||||
|
||||
private renderAccount () {
|
||||
const { t, value: { accountId, isUnsigned } } = this.props;
|
||||
|
||||
if (isUnsigned || !accountId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<InputAddress
|
||||
className='full'
|
||||
defaultValue={accountId}
|
||||
isDisabled
|
||||
isInput
|
||||
label={t('from my account')}
|
||||
withLabel
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private renderFees () {
|
||||
const { value: { accountId, extrinsic, isUnsigned } } = this.props;
|
||||
|
||||
@ -69,12 +73,10 @@ class Transaction extends React.PureComponent<Props> {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='ui--Params-Content'>
|
||||
<Fees
|
||||
accountId={accountId}
|
||||
extrinsic={extrinsic}
|
||||
/>
|
||||
</div>
|
||||
<Fees
|
||||
accountId={accountId}
|
||||
extrinsic={extrinsic}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ class Unlock extends React.PureComponent<Props, State> {
|
||||
autoFocus={autoFocus}
|
||||
className='medium'
|
||||
isError={isError}
|
||||
label={label || t('unlock account using the password')}
|
||||
label={label || t('unlocked using the password')}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
tabIndex={tabIndex}
|
||||
|
||||
@ -11,12 +11,14 @@
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.ui--signer-Signer-Unlock {
|
||||
padding-top: 1.5rem;
|
||||
.ui--signer-Signer-children {
|
||||
padding: 0.25rem 0 0 0;
|
||||
}
|
||||
|
||||
.ui--signer-Signer-Content .expanded {
|
||||
padding-right: 2em;
|
||||
h3 {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.code {
|
||||
background: #f5f5f5;
|
||||
@ -28,6 +30,10 @@
|
||||
word-break: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.hl {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.ui--signer-Status {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user