Swap accounts/addresses/staking to CardGrid & Card layout (#1225)
* Swap accounts/addresses to CardGrid & Card layout * Staking to CardGrid layout * Staking styling adjustments * Edit inputs left align
This commit is contained in:
parent
890ae667f7
commit
4e4e9514e5
@ -6,8 +6,7 @@ import { ActionStatus } from '@polkadot/ui-app/Status/types';
|
||||
import { I18nProps } from '@polkadot/ui-app/types';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { AddressInfo, AddressRow, Button, Icon } from '@polkadot/ui-app';
|
||||
import { AddressInfo, AddressRow, Button, Card, Icon } from '@polkadot/ui-app';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
|
||||
import Backup from './modals/Backup';
|
||||
@ -29,44 +28,6 @@ type State = {
|
||||
isTransferOpen: boolean
|
||||
};
|
||||
|
||||
// FIXME This is duplicated in app-ddresses
|
||||
const Wrapper = styled.article`
|
||||
position: relative;
|
||||
flex: 1 1;
|
||||
min-width: 24%;
|
||||
max-width: 24%;
|
||||
justify-content: space-around;
|
||||
|
||||
.accounts--Account-buttons {
|
||||
text-align: right;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.ui--AddressSummary-base {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.accounts--Account-buttons > button {
|
||||
margin: .2em;
|
||||
}
|
||||
|
||||
@media (max-width: 2060px) {
|
||||
min-width: 32%;
|
||||
max-width: 32%;
|
||||
}
|
||||
|
||||
@media (max-width: 1580px) {
|
||||
min-width: 49%;
|
||||
max-width: 49%;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
class Account extends React.PureComponent<Props> {
|
||||
state: State;
|
||||
|
||||
@ -89,7 +50,7 @@ class Account extends React.PureComponent<Props> {
|
||||
// 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'>
|
||||
<Card>
|
||||
{this.renderModals()}
|
||||
<AddressRow
|
||||
buttons={this.renderButtons()}
|
||||
@ -106,7 +67,7 @@ class Account extends React.PureComponent<Props> {
|
||||
value={address}
|
||||
/>
|
||||
</AddressRow>
|
||||
</Wrapper>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -7,10 +7,9 @@ import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
|
||||
import { ComponentProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
|
||||
import { withMulti, withObservable } from '@polkadot/ui-api';
|
||||
import { Button } from '@polkadot/ui-app';
|
||||
import { Button, CardGrid } from '@polkadot/ui-app';
|
||||
|
||||
import CreateModal from './modals/Create';
|
||||
import ImportModal from './modals/Import';
|
||||
@ -26,19 +25,6 @@ type State = {
|
||||
isImportOpen: boolean
|
||||
};
|
||||
|
||||
const Wrapper = styled.div`
|
||||
.accounts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1;
|
||||
margin: .25rem;
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
class Overview extends React.PureComponent<Props, State> {
|
||||
state: State = {
|
||||
isCreateOpen: false,
|
||||
@ -50,20 +36,23 @@ class Overview extends React.PureComponent<Props, State> {
|
||||
const { isCreateOpen, isImportOpen } = this.state;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Button.Group>
|
||||
<Button
|
||||
isPrimary
|
||||
label={t('Add account')}
|
||||
onClick={this.toggleCreate}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
isPrimary
|
||||
label={t('Restore JSON')}
|
||||
onClick={this.toggleImport}
|
||||
/>
|
||||
</Button.Group>
|
||||
<CardGrid
|
||||
buttons={
|
||||
<Button.Group>
|
||||
<Button
|
||||
isPrimary
|
||||
label={t('Add account')}
|
||||
onClick={this.toggleCreate}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
isPrimary
|
||||
label={t('Restore JSON')}
|
||||
onClick={this.toggleImport}
|
||||
/>
|
||||
</Button.Group>
|
||||
}
|
||||
>
|
||||
{isCreateOpen && (
|
||||
<CreateModal
|
||||
onClose={this.toggleCreate}
|
||||
@ -76,16 +65,13 @@ class Overview extends React.PureComponent<Props, State> {
|
||||
onStatusChange={onStatusChange}
|
||||
/>
|
||||
)}
|
||||
<div className='accounts'>
|
||||
{accounts && Object.keys(accounts).map((address) => (
|
||||
<Account
|
||||
address={address}
|
||||
key={address}
|
||||
/>
|
||||
))}
|
||||
<div className='spacer' />
|
||||
</div>
|
||||
</Wrapper>
|
||||
{accounts && Object.keys(accounts).map((address) => (
|
||||
<Account
|
||||
address={address}
|
||||
key={address}
|
||||
/>
|
||||
))}
|
||||
</CardGrid>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ class AccountsApp extends React.PureComponent<Props, State> {
|
||||
tabs: [
|
||||
{
|
||||
name: 'overview',
|
||||
text: t('Overview')
|
||||
text: t('My accounts')
|
||||
},
|
||||
{
|
||||
name: 'vanity',
|
||||
|
||||
@ -7,8 +7,7 @@ import { ActionStatus } from '@polkadot/ui-app/Status/types';
|
||||
import { I18nProps } from '@polkadot/ui-app/types';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { AddressInfo, AddressRow, Button } from '@polkadot/ui-app';
|
||||
import { AddressInfo, AddressRow, Button, Card } from '@polkadot/ui-app';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
|
||||
import Forgetting from './modals/Forgetting';
|
||||
@ -25,44 +24,6 @@ type State = {
|
||||
isForgetOpen: boolean
|
||||
};
|
||||
|
||||
// FIXME This is duplicated in app-accounts
|
||||
const Wrapper = styled.article`
|
||||
position: relative;
|
||||
flex: 1 1;
|
||||
min-width: 24%;
|
||||
max-width: 24%;
|
||||
justify-content: space-around;
|
||||
|
||||
.accounts--Account-buttons {
|
||||
text-align: right;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.ui--AddressSummary-base {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.accounts--Account-buttons > button {
|
||||
margin: .2em;
|
||||
}
|
||||
|
||||
@media (max-width: 2060px) {
|
||||
min-width: 32%;
|
||||
max-width: 32%;
|
||||
}
|
||||
|
||||
@media (max-width: 1580px) {
|
||||
min-width: 49%;
|
||||
max-width: 49%;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
class Address extends React.PureComponent<Props> {
|
||||
state: State;
|
||||
|
||||
@ -83,7 +44,7 @@ class Address extends React.PureComponent<Props> {
|
||||
const { isEditable } = this.state;
|
||||
|
||||
return (
|
||||
<Wrapper className='overview--Account'>
|
||||
<Card>
|
||||
{this.renderModals()}
|
||||
<AddressRow
|
||||
buttons={this.renderButtons()}
|
||||
@ -100,7 +61,7 @@ class Address extends React.PureComponent<Props> {
|
||||
value={address}
|
||||
/>
|
||||
</AddressRow>
|
||||
</Wrapper>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -7,8 +7,7 @@ import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
|
||||
import { ComponentProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button } from '@polkadot/ui-app';
|
||||
import { Button, CardGrid } from '@polkadot/ui-app';
|
||||
import addressObservable from '@polkadot/ui-keyring/observable/addresses';
|
||||
import { withMulti, withObservable } from '@polkadot/ui-api';
|
||||
|
||||
@ -24,19 +23,6 @@ type State = {
|
||||
isCreateOpen: boolean
|
||||
};
|
||||
|
||||
const Wrapper = styled.div`
|
||||
.addresses {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1;
|
||||
margin: .25rem;
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
class Overview extends React.PureComponent<Props, State> {
|
||||
state: State = {
|
||||
isCreateOpen: false
|
||||
@ -47,30 +33,30 @@ class Overview extends React.PureComponent<Props, State> {
|
||||
const { isCreateOpen } = this.state;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Button.Group>
|
||||
<Button
|
||||
isPrimary
|
||||
label={t('Add contact')}
|
||||
onClick={this.toggleCreate}
|
||||
/>
|
||||
</Button.Group>
|
||||
<CardGrid
|
||||
buttons={
|
||||
<Button.Group>
|
||||
<Button
|
||||
isPrimary
|
||||
label={t('Add contact')}
|
||||
onClick={this.toggleCreate}
|
||||
/>
|
||||
</Button.Group>
|
||||
}
|
||||
>
|
||||
{isCreateOpen && (
|
||||
<CreateModal
|
||||
onClose={this.toggleCreate}
|
||||
onStatusChange={onStatusChange}
|
||||
/>
|
||||
)}
|
||||
<div className='addresses'>
|
||||
{addresses && Object.keys(addresses).map((address) => (
|
||||
<Address
|
||||
address={address}
|
||||
key={address}
|
||||
/>
|
||||
))}
|
||||
<div className='spacer' />
|
||||
</div>
|
||||
</Wrapper>
|
||||
{addresses && Object.keys(addresses).map((address) => (
|
||||
<Address
|
||||
address={address}
|
||||
key={address}
|
||||
/>
|
||||
))}
|
||||
</CardGrid>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ class AddressBookApp extends React.PureComponent<Props, State> {
|
||||
items: [
|
||||
{
|
||||
name: 'overview',
|
||||
text: t('Overview')
|
||||
text: t('My contacts')
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@ -10,7 +10,7 @@ import { I18nProps } from '@polkadot/ui-app/types';
|
||||
import { KeyringSectionOption } from '@polkadot/ui-keyring/options/types';
|
||||
|
||||
import React from 'react';
|
||||
import { AddressInfo, AddressMini, AddressRow, Button, TxButton } from '@polkadot/ui-app';
|
||||
import { AddressInfo, AddressMini, AddressRow, Button, Card, TxButton } from '@polkadot/ui-app';
|
||||
import { withCalls } from '@polkadot/ui-api';
|
||||
|
||||
import Bond from './Bond';
|
||||
@ -107,7 +107,7 @@ class Account extends React.PureComponent<Props, State> {
|
||||
// This is deliberate in order to display the Component modals in a performant matter later on
|
||||
// because their state will already be loaded.
|
||||
return (
|
||||
<article className='staking--Account'>
|
||||
<Card>
|
||||
{this.renderBond()}
|
||||
{this.renderBondExtra()}
|
||||
{this.renderNominating()}
|
||||
@ -136,7 +136,7 @@ class Account extends React.PureComponent<Props, State> {
|
||||
</div>
|
||||
</AddressInfo>
|
||||
</AddressRow>
|
||||
</article>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -6,8 +6,7 @@ import { I18nProps } from '@polkadot/ui-app/types';
|
||||
import { AccountFilter, ComponentProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Dropdown, FilterOverlay } from '@polkadot/ui-app';
|
||||
import { CardGrid, Dropdown, FilterOverlay } from '@polkadot/ui-app';
|
||||
import { getAddrName } from '@polkadot/ui-app/util';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
import createOption from '@polkadot/ui-keyring/options/item';
|
||||
@ -23,19 +22,6 @@ type State = {
|
||||
filterOptions: Array<{ text: React.ReactNode, value: AccountFilter }>
|
||||
};
|
||||
|
||||
const Wrapper = styled.div`
|
||||
.accounts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1;
|
||||
margin: .25rem;
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
class Accounts extends React.PureComponent<Props, State> {
|
||||
state: State;
|
||||
|
||||
@ -62,7 +48,7 @@ class Accounts extends React.PureComponent<Props, State> {
|
||||
const stashOptions = this.getStashOptions();
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<CardGrid>
|
||||
<FilterOverlay>
|
||||
<Dropdown
|
||||
help={t('Select which types of accounts to display, either all, only the stash accounts or the controller accounts.')}
|
||||
@ -72,25 +58,22 @@ class Accounts extends React.PureComponent<Props, State> {
|
||||
value={filter}
|
||||
/>
|
||||
</FilterOverlay>
|
||||
<div className='accounts'>
|
||||
{accounts.map((account) => {
|
||||
const address = account.address();
|
||||
{accounts.map((account) => {
|
||||
const address = account.address();
|
||||
|
||||
return (
|
||||
<Account
|
||||
accountId={address}
|
||||
balances={balances}
|
||||
filter={filter}
|
||||
isValidator={validators.includes(address)}
|
||||
key={address}
|
||||
recentlyOffline={recentlyOffline}
|
||||
stashOptions={stashOptions}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<div className='spacer' />
|
||||
</div>
|
||||
</Wrapper>
|
||||
return (
|
||||
<Account
|
||||
accountId={address}
|
||||
balances={balances}
|
||||
filter={filter}
|
||||
isValidator={validators.includes(address)}
|
||||
key={address}
|
||||
recentlyOffline={recentlyOffline}
|
||||
stashOptions={stashOptions}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</CardGrid>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -190,7 +190,7 @@ class Address extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
return (
|
||||
<details className='staking--Account-detail'>
|
||||
<details>
|
||||
<summary>
|
||||
{t('Nominators ({{count}})', {
|
||||
replace: {
|
||||
|
||||
@ -103,13 +103,18 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.staking--Account-detail,
|
||||
.staking--accounts-info {
|
||||
.staking--Account-detail {
|
||||
text-align: right;
|
||||
|
||||
.staking--label {
|
||||
margin: 0 1.75rem -.75rem 0;
|
||||
margin: 0 1.75rem -0.75rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.staking--accounts-info .staking--label {
|
||||
margin: 0 2.25rem -0.75rem 0;
|
||||
}
|
||||
|
||||
.ui--AddressSummary {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -120,60 +125,3 @@
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.staking--Account {
|
||||
min-width: 31%;
|
||||
|
||||
.ui--AddressMini {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ui--AddressSummary {
|
||||
display: block;
|
||||
|
||||
.ui--AddressSummary-base,
|
||||
.ui--AddressSummary-children {
|
||||
min-width: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ui--AddressSummary-base {
|
||||
min-height: 16rem;
|
||||
}
|
||||
|
||||
.ui--AddressSummary-children {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.staking--Account-expand {
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.staking--Account-links {
|
||||
max-width: 12rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1020px) {
|
||||
.staking--Account {
|
||||
min-width: 48%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
.staking--Account {
|
||||
min-width: 48%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 620px) {
|
||||
.staking--Account {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +191,6 @@ class AddressSummary extends React.PureComponent<Props, State> {
|
||||
<Input
|
||||
autoFocus
|
||||
defaultValue={name}
|
||||
className='full'
|
||||
onBlur={this.saveName}
|
||||
onChange={this.onChangeName}
|
||||
onEnter={this.saveName}
|
||||
|
||||
55
packages/ui-app/src/Card.tsx
Normal file
55
packages/ui-app/src/Card.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-app 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 React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode,
|
||||
className?: string
|
||||
};
|
||||
|
||||
class Card extends React.PureComponent<Props> {
|
||||
render () {
|
||||
const { children, className } = this.props;
|
||||
|
||||
return (
|
||||
<article className={className}>
|
||||
{children}
|
||||
</article>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default styled(Card)`
|
||||
position: relative;
|
||||
flex: 1 1;
|
||||
min-width: 24%;
|
||||
max-width: 24%;
|
||||
justify-content: space-around;
|
||||
|
||||
.ui--AddressSummary-buttons {
|
||||
text-align: right;
|
||||
margin-bottom: 2em;
|
||||
|
||||
button {
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 2060px) {
|
||||
min-width: 32%;
|
||||
max-width: 32%;
|
||||
}
|
||||
|
||||
@media (max-width: 1580px) {
|
||||
min-width: 49%;
|
||||
max-width: 49%;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
`;
|
||||
45
packages/ui-app/src/CardGrid.tsx
Normal file
45
packages/ui-app/src/CardGrid.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-app 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 React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
type Props = {
|
||||
buttons?: React.ReactNode,
|
||||
children: React.ReactNode,
|
||||
className?: string
|
||||
};
|
||||
|
||||
class CardGrid extends React.PureComponent<Props> {
|
||||
render () {
|
||||
const { buttons, children, className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{buttons && (
|
||||
<div className='ui--CardGrid-buttons'>
|
||||
{buttons}
|
||||
</div>
|
||||
)}
|
||||
<div className='ui--CardGrid-grid'>
|
||||
{children}
|
||||
<div className='ui--CardGrid-spacer' />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default styled(CardGrid)`
|
||||
.ui--CardGrid-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
> .ui--CardGrid-spacer {
|
||||
flex: 1 1;
|
||||
margin: .25rem;
|
||||
padding: 1rem 1.5rem;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -12,6 +12,8 @@ export { default as Bonded } from './Bonded';
|
||||
export { default as Bubble } from './Bubble';
|
||||
export { default as Button } from './Button';
|
||||
export { default as Call } from './Call';
|
||||
export { default as Card } from './Card';
|
||||
export { default as CardGrid } from './CardGrid';
|
||||
export { default as CardSummary } from './CardSummary';
|
||||
export { default as Chart } from './Chart';
|
||||
export { default as CopyButton } from './CopyButton';
|
||||
|
||||
@ -319,10 +319,10 @@ button.ui.icon.iconButton {
|
||||
|
||||
.ui--AddressSummary-data .ui--Input input {
|
||||
height: 1em;
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
text-transform: uppercase;
|
||||
margin-top: -.3em;
|
||||
margin-bottom: -.35em;
|
||||
margin-top: -0.3em;
|
||||
margin-bottom: -0.35em;
|
||||
}
|
||||
|
||||
.ui--AddressSummary-tags-input {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user