Available Dapp selection alignment with Permissions (Portal) (#4374)
* Manage default accounts * Portal * Portal * Allow Portal to be used in as both top-level and popover * modal/popover variable naming * Move to Portal * export Portal in ~/ui * WIP * Tags handle empty values * Export AccountCard in ~/ui * Allow ETH-only & zero display * Use ui/Balance for balance display * Add tests for Balance & Tags component availability * WIP * Default overlay display to block (not flex) * Revert block * WIP * Add className, optional handlers only * WIP * Properly handle optional onKeyDown * Selection updated * Align margins * Remove old code * Remove debug logging * TransitionGroup for animations * No anim * Cleanups * Revert addons removal * Fix tests * WIP * Add onClick to Container * Create ui/DappCard component * WIP * Pass dummy displayApps * Rename DappsVisible back to AddDapps (easier git diff) * Rename CSS * Fix tests after merge
This commit is contained in:
parent
1547af191b
commit
535ebb1f2f
@ -15,15 +15,24 @@
|
|||||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
margin-top: .5em !important;
|
margin-top: .5em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
|
||||||
.background {
|
.background {
|
||||||
background: rgba(255, 255, 255, 0.2);
|
padding: 0.5em 0;
|
||||||
margin: 0 -1.5em;
|
|
||||||
padding: 0.5em 1.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@ -37,3 +46,26 @@
|
|||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.selectIcon {
|
||||||
|
position: absolute;
|
||||||
|
right: 0.5em;
|
||||||
|
top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected,
|
||||||
|
.unselected {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unselected {
|
||||||
|
background: rgba(0, 0, 0, 0.4) !important;
|
||||||
|
|
||||||
|
.selectIcon {
|
||||||
|
opacity: 0.15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background: rgba(255, 255, 255, 0.15) !important;
|
||||||
|
}
|
||||||
|
@ -14,14 +14,12 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { Checkbox } from 'material-ui';
|
|
||||||
import { List, ListItem } from 'material-ui/List';
|
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { Modal, Button } from '~/ui';
|
import { ContainerTitle, DappCard, Portal, SectionList } from '~/ui';
|
||||||
import { DoneIcon } from '~/ui/Icons';
|
import { CheckIcon } from '~/ui/Icons';
|
||||||
|
|
||||||
import styles from './addDapps.css';
|
import styles from './addDapps.css';
|
||||||
|
|
||||||
@ -39,32 +37,23 @@ export default class AddDapps extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Portal
|
||||||
actions={ [
|
className={ styles.modal }
|
||||||
<Button
|
onClose={ store.closeModal }
|
||||||
icon={ <DoneIcon /> }
|
open
|
||||||
key='done'
|
>
|
||||||
label={
|
<ContainerTitle
|
||||||
<FormattedMessage
|
|
||||||
id='dapps.add.button.done'
|
|
||||||
defaultMessage='Done'
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onClick={ store.closeModal }
|
|
||||||
/>
|
|
||||||
] }
|
|
||||||
compact
|
|
||||||
title={
|
title={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='dapps.add.label'
|
id='dapps.add.label'
|
||||||
defaultMessage='visible applications'
|
defaultMessage='visible applications'
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
visible
|
/>
|
||||||
>
|
<div className={ styles.container }>
|
||||||
<div className={ styles.warning } />
|
<div className={ styles.warning } />
|
||||||
{
|
{
|
||||||
this.renderList(store.sortedLocal,
|
this.renderList(store.sortedLocal, store.displayApps,
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='dapps.add.local.label'
|
id='dapps.add.local.label'
|
||||||
defaultMessage='Applications locally available'
|
defaultMessage='Applications locally available'
|
||||||
@ -76,7 +65,7 @@ export default class AddDapps extends Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.renderList(store.sortedBuiltin,
|
this.renderList(store.sortedBuiltin, store.displayApps,
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='dapps.add.builtin.label'
|
id='dapps.add.builtin.label'
|
||||||
defaultMessage='Applications bundled with Parity'
|
defaultMessage='Applications bundled with Parity'
|
||||||
@ -88,7 +77,7 @@ export default class AddDapps extends Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.renderList(store.sortedNetwork,
|
this.renderList(store.sortedNetwork, store.displayApps,
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='dapps.add.network.label'
|
id='dapps.add.network.label'
|
||||||
defaultMessage='Applications on the global network'
|
defaultMessage='Applications on the global network'
|
||||||
@ -99,11 +88,12 @@ export default class AddDapps extends Component {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Modal>
|
</div>
|
||||||
|
</Portal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderList (items, header, byline) {
|
renderList (items, visibleItems, header, byline) {
|
||||||
if (!items || !items.length) {
|
if (!items || !items.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -114,41 +104,40 @@ export default class AddDapps extends Component {
|
|||||||
<div className={ styles.header }>{ header }</div>
|
<div className={ styles.header }>{ header }</div>
|
||||||
<div className={ styles.byline }>{ byline }</div>
|
<div className={ styles.byline }>{ byline }</div>
|
||||||
</div>
|
</div>
|
||||||
<List>
|
<SectionList
|
||||||
{ items.map(this.renderApp) }
|
items={ items }
|
||||||
</List>
|
noStretch
|
||||||
|
renderItem={ this.renderApp }
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderApp = (app) => {
|
renderApp = (app) => {
|
||||||
const { store } = this.props;
|
const { store } = this.props;
|
||||||
const isHidden = !store.displayApps[app.id].visible;
|
const isVisible = store.displayApps[app.id].visible;
|
||||||
|
|
||||||
const onCheck = () => {
|
const onClick = () => {
|
||||||
if (isHidden) {
|
if (isVisible) {
|
||||||
store.showApp(app.id);
|
|
||||||
} else {
|
|
||||||
store.hideApp(app.id);
|
store.hideApp(app.id);
|
||||||
|
} else {
|
||||||
|
store.showApp(app.id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListItem
|
<DappCard
|
||||||
|
app={ app }
|
||||||
|
className={
|
||||||
|
isVisible
|
||||||
|
? styles.selected
|
||||||
|
: styles.unselected
|
||||||
|
}
|
||||||
key={ app.id }
|
key={ app.id }
|
||||||
leftCheckbox={
|
onClick={ onClick }
|
||||||
<Checkbox
|
>
|
||||||
checked={ !isHidden }
|
<CheckIcon className={ styles.selectIcon } />
|
||||||
onCheck={ onCheck }
|
</DappCard>
|
||||||
/>
|
|
||||||
}
|
|
||||||
primaryText={ app.name }
|
|
||||||
secondaryText={
|
|
||||||
<div className={ styles.description }>
|
|
||||||
{ app.description }
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,13 @@ describe('modals/AddDapps', () => {
|
|||||||
|
|
||||||
it('does not render the modal with modalOpen = false', () => {
|
it('does not render the modal with modalOpen = false', () => {
|
||||||
expect(
|
expect(
|
||||||
renderShallow({ modalOpen: false }).find('Connect(Modal)')
|
renderShallow({ modalOpen: false }).find('Portal')
|
||||||
).to.have.length(0);
|
).to.have.length(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does render the modal with modalOpen = true', () => {
|
it('does render the modal with modalOpen = true', () => {
|
||||||
expect(
|
expect(
|
||||||
renderShallow({ modalOpen: true }).find('Connect(Modal)')
|
renderShallow({ modalOpen: true }).find('Portal')
|
||||||
).to.have.length(1);
|
).to.have.length(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
import AddAddress from './AddAddress';
|
import AddAddress from './AddAddress';
|
||||||
import AddContract from './AddContract';
|
import AddContract from './AddContract';
|
||||||
import AddDapps from './AddDapps';
|
|
||||||
import CreateAccount from './CreateAccount';
|
import CreateAccount from './CreateAccount';
|
||||||
import CreateWallet from './CreateWallet';
|
import CreateWallet from './CreateWallet';
|
||||||
import DappPermissions from './DappPermissions';
|
import DappPermissions from './DappPermissions';
|
||||||
|
import DappsVisible from './AddDapps';
|
||||||
import DeleteAccount from './DeleteAccount';
|
import DeleteAccount from './DeleteAccount';
|
||||||
import DeployContract from './DeployContract';
|
import DeployContract from './DeployContract';
|
||||||
import EditMeta from './EditMeta';
|
import EditMeta from './EditMeta';
|
||||||
@ -37,10 +37,10 @@ import WalletSettings from './WalletSettings';
|
|||||||
export {
|
export {
|
||||||
AddAddress,
|
AddAddress,
|
||||||
AddContract,
|
AddContract,
|
||||||
AddDapps,
|
|
||||||
CreateAccount,
|
CreateAccount,
|
||||||
CreateWallet,
|
CreateWallet,
|
||||||
DappPermissions,
|
DappPermissions,
|
||||||
|
DappsVisible,
|
||||||
DeleteAccount,
|
DeleteAccount,
|
||||||
DeployContract,
|
DeployContract,
|
||||||
EditMeta,
|
EditMeta,
|
||||||
|
@ -29,15 +29,14 @@ export default class Container extends Component {
|
|||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
compact: PropTypes.bool,
|
compact: PropTypes.bool,
|
||||||
light: PropTypes.bool,
|
light: PropTypes.bool,
|
||||||
|
onClick: PropTypes.func,
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
tabIndex: PropTypes.number,
|
tabIndex: PropTypes.number,
|
||||||
title: nodeOrStringProptype()
|
title: nodeOrStringProptype()
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, className, compact, light, style, tabIndex } = this.props;
|
const { children, className, compact, light, onClick, style, tabIndex } = this.props;
|
||||||
const classes = `${styles.container} ${light ? styles.light : ''} ${className}`;
|
|
||||||
|
|
||||||
const props = {};
|
const props = {};
|
||||||
|
|
||||||
if (Number.isInteger(tabIndex)) {
|
if (Number.isInteger(tabIndex)) {
|
||||||
@ -45,8 +44,27 @@ export default class Container extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ classes } style={ style } { ...props }>
|
<div
|
||||||
<Card className={ compact ? styles.compact : styles.padded }>
|
className={
|
||||||
|
[
|
||||||
|
styles.container,
|
||||||
|
light
|
||||||
|
? styles.light
|
||||||
|
: '',
|
||||||
|
className
|
||||||
|
].join(' ')
|
||||||
|
}
|
||||||
|
style={ style }
|
||||||
|
{ ...props }
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
className={
|
||||||
|
compact
|
||||||
|
? styles.compact
|
||||||
|
: styles.padded
|
||||||
|
}
|
||||||
|
onClick={ onClick }
|
||||||
|
>
|
||||||
{ this.renderTitle() }
|
{ this.renderTitle() }
|
||||||
{ children }
|
{ children }
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -17,59 +17,80 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
import { Container, ContainerTitle, DappIcon, Tags } from '~/ui';
|
import Container, { Title as ContainerTitle } from '~/ui/Container';
|
||||||
|
import DappIcon from '~/ui/DappIcon';
|
||||||
|
import Tags from '~/ui/Tags';
|
||||||
|
|
||||||
import styles from './summary.css';
|
import styles from './dappCard.css';
|
||||||
|
|
||||||
export default class Summary extends Component {
|
export default class DappCard extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
app: PropTypes.object.isRequired,
|
app: PropTypes.object.isRequired,
|
||||||
children: PropTypes.node
|
children: PropTypes.node,
|
||||||
}
|
className: PropTypes.string,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
showLink: PropTypes.bool,
|
||||||
|
showTags: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
showLink: false,
|
||||||
|
showTags: false
|
||||||
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { app } = this.props;
|
const { app, children, className, onClick, showLink, showTags } = this.props;
|
||||||
|
|
||||||
if (!app) {
|
if (!app) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const link = this.renderLink(app);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className={ styles.container }>
|
<Container
|
||||||
|
className={
|
||||||
|
[styles.container, className].join(' ')
|
||||||
|
}
|
||||||
|
onClick={ onClick }
|
||||||
|
>
|
||||||
<DappIcon
|
<DappIcon
|
||||||
app={ app }
|
app={ app }
|
||||||
className={ styles.image }
|
className={ styles.image }
|
||||||
/>
|
/>
|
||||||
<Tags tags={ [app.type] } />
|
<Tags
|
||||||
|
tags={
|
||||||
|
showTags
|
||||||
|
? [app.type]
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
/>
|
||||||
<div className={ styles.description }>
|
<div className={ styles.description }>
|
||||||
<ContainerTitle
|
<ContainerTitle
|
||||||
className={ styles.title }
|
className={ styles.title }
|
||||||
title={ link }
|
title={
|
||||||
|
showLink
|
||||||
|
? this.renderLink(app)
|
||||||
|
: app.name
|
||||||
|
}
|
||||||
byline={ app.description }
|
byline={ app.description }
|
||||||
/>
|
/>
|
||||||
<div className={ styles.author }>
|
<div className={ styles.author }>
|
||||||
{ app.author }, v{ app.version }
|
{ app.author }, v{ app.version }
|
||||||
</div>
|
</div>
|
||||||
{ this.props.children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLink (app) {
|
renderLink (app) {
|
||||||
// Special case for web dapp
|
|
||||||
if (app.url === 'web') {
|
|
||||||
return (
|
return (
|
||||||
<Link to={ `/web` }>
|
<Link
|
||||||
{ app.name }
|
to={
|
||||||
</Link>
|
app.url === 'web'
|
||||||
);
|
? '/web'
|
||||||
|
: `/app/${app.id}`
|
||||||
}
|
}
|
||||||
|
>
|
||||||
return (
|
|
||||||
<Link to={ `/app/${app.id}` }>
|
|
||||||
{ app.name }
|
{ app.name }
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
@ -14,4 +14,4 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
export default from './summary';
|
export default from './dappCard';
|
@ -30,6 +30,7 @@ import Container, { Title as ContainerTitle } from './Container';
|
|||||||
import ContextProvider from './ContextProvider';
|
import ContextProvider from './ContextProvider';
|
||||||
import CopyToClipboard from './CopyToClipboard';
|
import CopyToClipboard from './CopyToClipboard';
|
||||||
import CurrencySymbol from './CurrencySymbol';
|
import CurrencySymbol from './CurrencySymbol';
|
||||||
|
import DappCard from './DappCard';
|
||||||
import DappIcon from './DappIcon';
|
import DappIcon from './DappIcon';
|
||||||
import Editor from './Editor';
|
import Editor from './Editor';
|
||||||
import Errors from './Errors';
|
import Errors from './Errors';
|
||||||
@ -79,6 +80,7 @@ export {
|
|||||||
CopyToClipboard,
|
CopyToClipboard,
|
||||||
CurrencySymbol,
|
CurrencySymbol,
|
||||||
DappIcon,
|
DappIcon,
|
||||||
|
DappCard,
|
||||||
Editor,
|
Editor,
|
||||||
Errors,
|
Errors,
|
||||||
FEATURES,
|
FEATURES,
|
||||||
|
@ -21,14 +21,13 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { AddDapps, DappPermissions } from '~/modals';
|
import { DappPermissions, DappsVisible } from '~/modals';
|
||||||
import PermissionStore from '~/modals/DappPermissions/store';
|
import PermissionStore from '~/modals/DappPermissions/store';
|
||||||
import { Actionbar, Button, Page } from '~/ui';
|
import { Actionbar, Button, DappCard, Page } from '~/ui';
|
||||||
import { LockedIcon, VisibleIcon } from '~/ui/Icons';
|
import { LockedIcon, VisibleIcon } from '~/ui/Icons';
|
||||||
|
|
||||||
import UrlButton from './UrlButton';
|
import UrlButton from './UrlButton';
|
||||||
import DappsStore from './dappsStore';
|
import DappsStore from './dappsStore';
|
||||||
import Summary from './Summary';
|
|
||||||
|
|
||||||
import styles from './dapps.css';
|
import styles from './dapps.css';
|
||||||
|
|
||||||
@ -82,8 +81,8 @@ class Dapps extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AddDapps store={ this.store } />
|
|
||||||
<DappPermissions store={ this.permissionStore } />
|
<DappPermissions store={ this.permissionStore } />
|
||||||
|
<DappsVisible store={ this.store } />
|
||||||
<Actionbar
|
<Actionbar
|
||||||
className={ styles.toolbar }
|
className={ styles.toolbar }
|
||||||
title={
|
title={
|
||||||
@ -146,7 +145,11 @@ class Dapps extends Component {
|
|||||||
className={ styles.item }
|
className={ styles.item }
|
||||||
key={ app.id }
|
key={ app.id }
|
||||||
>
|
>
|
||||||
<Summary app={ app } />
|
<DappCard
|
||||||
|
app={ app }
|
||||||
|
showLink
|
||||||
|
showTags
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user