diff --git a/js/src/api/format/input.js b/js/src/api/format/input.js
index 4307fc912..7a41da109 100644
--- a/js/src/api/format/input.js
+++ b/js/src/api/format/input.js
@@ -24,6 +24,10 @@ export function inAddress (address) {
return inHex(address);
}
+export function inAddresses (addresses) {
+ return (addresses || []).map(inAddress);
+}
+
export function inBlockNumber (blockNumber) {
if (isString(blockNumber)) {
switch (blockNumber) {
diff --git a/js/src/api/format/output.js b/js/src/api/format/output.js
index 870e28fe3..cf707cbd1 100644
--- a/js/src/api/format/output.js
+++ b/js/src/api/format/output.js
@@ -42,6 +42,10 @@ export function outAddress (address) {
return toChecksumAddress(address);
}
+export function outAddresses (addresses) {
+ return (addresses || []).map(outAddress);
+}
+
export function outBlock (block) {
if (block) {
Object.keys(block).forEach((key) => {
diff --git a/js/src/api/rpc/parity/parity.js b/js/src/api/rpc/parity/parity.js
index e5ca31d89..174ad3fbf 100644
--- a/js/src/api/rpc/parity/parity.js
+++ b/js/src/api/rpc/parity/parity.js
@@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
-import { inAddress, inData, inHex, inNumber16, inOptions } from '../../format/input';
-import { outAccountInfo, outAddress, outChainStatus, outHistogram, outNumber, outPeers, outTransaction } from '../../format/output';
+import { inAddress, inAddresses, inData, inHex, inNumber16, inOptions } from '../../format/input';
+import { outAccountInfo, outAddress, outAddresses, outChainStatus, outHistogram, outNumber, outPeers, outTransaction } from '../../format/output';
export default class Parity {
constructor (transport) {
@@ -128,6 +128,18 @@ export default class Parity {
.execute('parity_generateSecretPhrase');
}
+ getDappsAddresses (dappId) {
+ return this._transport
+ .execute('parity_getDappsAddresses', dappId)
+ .then(outAddresses);
+ }
+
+ getNewDappsWhitelist () {
+ return this._transport
+ .execute('parity_getNewDappsWhitelist')
+ .then((addresses) => addresses ? addresses.map(outAddress) : null);
+ }
+
hashContent (url) {
return this._transport
.execute('parity_hashContent', url);
@@ -135,8 +147,8 @@ export default class Parity {
importGethAccounts (accounts) {
return this._transport
- .execute('parity_importGethAccounts', (accounts || []).map(inAddress))
- .then((accounts) => (accounts || []).map(outAddress));
+ .execute('parity_importGethAccounts', inAddresses)
+ .then(outAddresses);
}
killAccount (account, password) {
@@ -144,6 +156,11 @@ export default class Parity {
.execute('parity_killAccount', inAddress(account), password);
}
+ listRecentDapps () {
+ return this._transport
+ .execute('parity_listRecentDapps');
+ }
+
removeAddress (address) {
return this._transport
.execute('parity_removeAddress', inAddress(address));
@@ -152,7 +169,7 @@ export default class Parity {
listGethAccounts () {
return this._transport
.execute('parity_listGethAccounts')
- .then((accounts) => (accounts || []).map(outAddress));
+ .then(outAddresses);
}
localTransactions () {
@@ -289,6 +306,11 @@ export default class Parity {
.execute('parity_setAuthor', inAddress(address));
}
+ setDappsAddresses (dappId, addresses) {
+ return this._transport
+ .execute('parity_setDappsAddresses', dappId, inAddresses(addresses));
+ }
+
setExtraData (data) {
return this._transport
.execute('parity_setExtraData', inData(data));
@@ -309,6 +331,11 @@ export default class Parity {
.execute('parity_setMode', mode);
}
+ setNewDappsWhitelist (addresses) {
+ return this._transport
+ .execute('parity_setNewDappsWhitelist', addresses ? inAddresses(addresses) : null);
+ }
+
setTransactionsLimit (quantity) {
return this._transport
.execute('parity_setTransactionsLimit', inNumber16(quantity));
diff --git a/js/src/jsonrpc/interfaces/parity.js b/js/src/jsonrpc/interfaces/parity.js
index 2c0cefaef..1f6caca4a 100644
--- a/js/src/jsonrpc/interfaces/parity.js
+++ b/js/src/jsonrpc/interfaces/parity.js
@@ -236,6 +236,29 @@ export default {
}
},
+ getDappsAddresses: {
+ desc: 'Returns the list of accounts available to a specific dapp',
+ params: [
+ {
+ type: String,
+ desc: 'Dapp Id'
+ }
+ ],
+ returns: {
+ type: Array,
+ desc: 'The list of available accounts'
+ }
+ },
+
+ getNewDappsWhitelist: {
+ desc: 'Returns the list of accounts available to a new dapps',
+ params: [],
+ returns: {
+ type: Array,
+ desc: 'The list of available accounts'
+ }
+ },
+
hashContent: {
desc: 'Creates a hash of the file as retrieved',
params: [
@@ -282,6 +305,15 @@ export default {
}
},
+ listRecentDapps: {
+ desc: 'Returns a list of the most recent active dapps',
+ params: [],
+ returns: {
+ type: Array,
+ desc: 'Array of Dapp Ids'
+ }
+ },
+
removeAddress: {
desc: 'Removes an address from the addressbook',
params: [
@@ -586,6 +618,24 @@ export default {
}
},
+ setDappsAddresses: {
+ desc: 'Sets the available addresses for a dapp',
+ params: [
+ {
+ type: String,
+ desc: 'Dapp Id'
+ },
+ {
+ type: Array,
+ desc: 'Array of available accounts available to the dapp'
+ }
+ ],
+ returns: {
+ type: Boolean,
+ desc: 'True if the call succeeded'
+ }
+ },
+
setExtraData: {
desc: 'Changes extra data for newly mined blocks',
params: [
@@ -645,6 +695,20 @@ export default {
}
},
+ setNewDappsWhitelist: {
+ desc: 'Sets the list of accounts available to new dapps',
+ params: [
+ {
+ type: Array,
+ desc: 'List of accounts available by default'
+ }
+ ],
+ returns: {
+ type: Boolean,
+ desc: 'True if the call succeeded'
+ }
+ },
+
setTransactionsLimit: {
desc: 'Changes limit for transactions in queue.',
params: [
diff --git a/js/src/views/Dapps/AddDapps/AddDapps.css b/js/src/modals/AddDapps/addDapps.css
similarity index 100%
rename from js/src/views/Dapps/AddDapps/AddDapps.css
rename to js/src/modals/AddDapps/addDapps.css
diff --git a/js/src/views/Dapps/AddDapps/AddDapps.js b/js/src/modals/AddDapps/addDapps.js
similarity index 94%
rename from js/src/views/Dapps/AddDapps/AddDapps.js
rename to js/src/modals/AddDapps/addDapps.js
index cc2b60552..f079c900f 100644
--- a/js/src/views/Dapps/AddDapps/AddDapps.js
+++ b/js/src/modals/AddDapps/addDapps.js
@@ -14,16 +14,16 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
+import { Checkbox } from 'material-ui';
+import { List, ListItem } from 'material-ui/List';
+import { observer } from 'mobx-react';
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
-import { observer } from 'mobx-react';
-import DoneIcon from 'material-ui/svg-icons/action/done';
-import { List, ListItem } from 'material-ui/List';
-import Checkbox from 'material-ui/Checkbox';
import { Modal, Button } from '~/ui';
+import { DoneIcon } from '~/ui/Icons';
-import styles from './AddDapps.css';
+import styles from './addDapps.css';
@observer
export default class AddDapps extends Component {
@@ -40,25 +40,24 @@ export default class AddDapps extends Component {
return (
}
+ key='done'
+ label={
+
+ }
+ onClick={ store.closeModal } />
+ ] }
compact
title={
}
- actions={ [
-
- }
- key='done'
- onClick={ store.closeModal }
- icon={ }
- />
- ] }>
+ visible>
{
this.renderList(store.sortedLocal,
diff --git a/js/src/modals/AddDapps/addDapps.spec.js b/js/src/modals/AddDapps/addDapps.spec.js
new file mode 100644
index 000000000..66bd286bc
--- /dev/null
+++ b/js/src/modals/AddDapps/addDapps.spec.js
@@ -0,0 +1,46 @@
+// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { shallow } from 'enzyme';
+import React from 'react';
+
+import AddDapps from './';
+
+function renderShallow (store = {}) {
+ return shallow(
+
+ );
+}
+
+describe('modals/AddDapps', () => {
+ describe('rendering', () => {
+ it('renders defaults', () => {
+ expect(renderShallow()).to.be.ok;
+ });
+
+ it('does not render the modal with modalOpen = false', () => {
+ expect(
+ renderShallow({ modalOpen: false }).find('Connect(Modal)')
+ ).to.have.length(0);
+ });
+
+ it('does render the modal with modalOpen = true', () => {
+ expect(
+ renderShallow({ modalOpen: true }).find('Connect(Modal)')
+ ).to.have.length(1);
+ });
+ });
+});
diff --git a/js/src/views/Dapps/AddDapps/index.js b/js/src/modals/AddDapps/index.js
similarity index 95%
rename from js/src/views/Dapps/AddDapps/index.js
rename to js/src/modals/AddDapps/index.js
index 209e1e54c..928d2405b 100644
--- a/js/src/views/Dapps/AddDapps/index.js
+++ b/js/src/modals/AddDapps/index.js
@@ -14,4 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
-export default from './AddDapps';
+export default from './addDapps';
diff --git a/js/src/modals/DappPermissions/dappPermissions.css b/js/src/modals/DappPermissions/dappPermissions.css
new file mode 100644
index 000000000..64be7dea8
--- /dev/null
+++ b/js/src/modals/DappPermissions/dappPermissions.css
@@ -0,0 +1,47 @@
+/* Copyright 2015, 2016 Parity Technologies (UK) Ltd.
+/* This file is part of Parity.
+/*
+/* Parity is free software: you can redistribute it and/or modify
+/* it under the terms of the GNU General Public License as published by
+/* the Free Software Foundation, either version 3 of the License, or
+/* (at your option) any later version.
+/*
+/* Parity is distributed in the hope that it will be useful,
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+/* GNU General Public License for more details.
+/*
+/* You should have received a copy of the GNU General Public License
+/* along with Parity. If not, see .
+*/
+
+.item {
+ .info {
+ display: inline-block;
+
+ .address {
+ opacity: 0.75;
+ }
+
+ .description {
+ margin-top: 0.5em;
+ opacity: 0.75;
+ }
+
+ .name {
+ margin: 0.5em 0;
+ text-transform: uppercase;
+ }
+ }
+}
+
+.selected, .unselected {
+ margin-bottom: 0.25em;
+}
+
+.selected {
+ background: rgba(255, 255, 255, 0.15);
+}
+
+.unselected {
+}
diff --git a/js/src/modals/DappPermissions/dappPermissions.js b/js/src/modals/DappPermissions/dappPermissions.js
new file mode 100644
index 000000000..c6498b282
--- /dev/null
+++ b/js/src/modals/DappPermissions/dappPermissions.js
@@ -0,0 +1,112 @@
+// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { Checkbox } from 'material-ui';
+import { List, ListItem } from 'material-ui/List';
+import { observer } from 'mobx-react';
+import React, { Component, PropTypes } from 'react';
+import { FormattedMessage } from 'react-intl';
+
+import { Button, IdentityIcon, Modal } from '~/ui';
+import { DoneIcon } from '~/ui/Icons';
+
+import styles from './dappPermissions.css';
+
+@observer
+export default class DappPermissions extends Component {
+ static propTypes = {
+ store: PropTypes.object.isRequired
+ };
+
+ render () {
+ const { store } = this.props;
+
+ if (!store.modalOpen) {
+ return null;
+ }
+
+ return (
+ }
+ key='done'
+ label={
+
+ }
+ onClick={ store.closeModal } />
+ ] }
+ compact
+ title={
+
+ }
+ visible>
+
+ { this.renderListItems() }
+
+
+ );
+ }
+
+ renderListItems () {
+ const { store } = this.props;
+
+ return store.accounts.map((account) => {
+ const onCheck = () => {
+ store.selectAccount(account.address);
+ };
+
+ // TODO: Once new modal & account selection is in, this should be updated
+ // to conform to the new (as of this code WIP) look & feel for selection.
+ // For now in the current/old style, not as pretty but consistent.
+ return (
+
+ }
+ primaryText={
+
+
+
+
+ { account.name }
+
+
+ { account.address }
+
+
+ { account.description }
+
+
+
+ } />
+ );
+ });
+ }
+}
diff --git a/js/src/modals/DappPermissions/dappPermissions.spec.js b/js/src/modals/DappPermissions/dappPermissions.spec.js
new file mode 100644
index 000000000..674e4959c
--- /dev/null
+++ b/js/src/modals/DappPermissions/dappPermissions.spec.js
@@ -0,0 +1,46 @@
+// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { shallow } from 'enzyme';
+import React from 'react';
+
+import DappPermissions from './';
+
+function renderShallow (store = {}) {
+ return shallow(
+
+ );
+}
+
+describe('modals/DappPermissions', () => {
+ describe('rendering', () => {
+ it('renders defaults', () => {
+ expect(renderShallow()).to.be.ok;
+ });
+
+ it('does not render the modal with modalOpen = false', () => {
+ expect(
+ renderShallow({ modalOpen: false }).find('Connect(Modal)')
+ ).to.have.length(0);
+ });
+
+ it('does render the modal with modalOpen = true', () => {
+ expect(
+ renderShallow({ modalOpen: true, accounts: [] }).find('Connect(Modal)')
+ ).to.have.length(1);
+ });
+ });
+});
diff --git a/js/src/modals/DappPermissions/index.js b/js/src/modals/DappPermissions/index.js
new file mode 100644
index 000000000..fc930c575
--- /dev/null
+++ b/js/src/modals/DappPermissions/index.js
@@ -0,0 +1,17 @@
+// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+export default from './dappPermissions';
diff --git a/js/src/modals/DappPermissions/store.js b/js/src/modals/DappPermissions/store.js
new file mode 100644
index 000000000..21aa8707f
--- /dev/null
+++ b/js/src/modals/DappPermissions/store.js
@@ -0,0 +1,94 @@
+// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { action, observable, transaction } from 'mobx';
+
+export default class Store {
+ @observable accounts = [];
+ @observable modalOpen = false;
+ @observable whitelist = [];
+
+ constructor (api) {
+ this._api = api;
+
+ this.loadWhitelist();
+ }
+
+ @action closeModal = () => {
+ transaction(() => {
+ const accounts = this.accounts
+ .filter((account) => account.checked)
+ .map((account) => account.address);
+
+ this.modalOpen = false;
+ this.updateWhitelist(accounts.length === this.accounts.length ? null : accounts);
+ });
+ }
+
+ @action openModal = (accounts) => {
+ transaction(() => {
+ this.accounts = Object
+ .values(accounts)
+ .map((account) => {
+ return {
+ address: account.address,
+ checked: this.whitelist
+ ? this.whitelist.includes(account.address)
+ : true,
+ description: account.meta.description,
+ name: account.name
+ };
+ });
+ this.modalOpen = true;
+ });
+ }
+
+ @action selectAccount = (address) => {
+ this.accounts = this.accounts.map((account) => {
+ if (account.address === address) {
+ account.checked = !account.checked;
+ }
+
+ return account;
+ });
+ }
+
+ @action setWhitelist = (whitelist) => {
+ this.whitelist = whitelist;
+ }
+
+ loadWhitelist () {
+ return this._api.parity
+ .getNewDappsWhitelist()
+ .then((whitelist) => {
+ this.setWhitelist(whitelist);
+ })
+ .catch((error) => {
+ console.warn('loadWhitelist', error);
+ });
+ }
+
+ updateWhitelist (whitelist) {
+ return this._api.parity
+ .setNewDappsWhitelist(whitelist)
+ .then(() => {
+ this.setWhitelist(whitelist);
+ })
+ .catch((error) => {
+ console.warn('updateWhitelist', error);
+ });
+ }
+}
diff --git a/js/src/modals/DappPermissions/store.spec.js b/js/src/modals/DappPermissions/store.spec.js
new file mode 100644
index 000000000..819099a19
--- /dev/null
+++ b/js/src/modals/DappPermissions/store.spec.js
@@ -0,0 +1,100 @@
+// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import sinon from 'sinon';
+
+import Store from './store';
+
+const ACCOUNTS = {
+ '123': { address: '123', name: '123', meta: { description: '123' } },
+ '456': { address: '456', name: '456', meta: { description: '456' } },
+ '789': { address: '789', name: '789', meta: { description: '789' } }
+};
+const WHITELIST = ['123', '456'];
+
+describe('modals/DappPermissions/store', () => {
+ let api;
+ let store;
+
+ beforeEach(() => {
+ api = {
+ parity: {
+ getNewDappsWhitelist: sinon.stub().resolves(WHITELIST),
+ setNewDappsWhitelist: sinon.stub().resolves(true)
+ }
+ };
+
+ store = new Store(api);
+ });
+
+ describe('constructor', () => {
+ it('retrieves the whitelist via api', () => {
+ expect(api.parity.getNewDappsWhitelist).to.be.calledOnce;
+ });
+
+ it('sets the retrieved whitelist', () => {
+ expect(store.whitelist.peek()).to.deep.equal(WHITELIST);
+ });
+ });
+
+ describe('@actions', () => {
+ describe('openModal', () => {
+ beforeEach(() => {
+ store.openModal(ACCOUNTS);
+ });
+
+ it('sets the modalOpen status', () => {
+ expect(store.modalOpen).to.be.true;
+ });
+
+ it('sets accounts with checked interfaces', () => {
+ expect(store.accounts.peek()).to.deep.equal([
+ { address: '123', name: '123', description: '123', checked: true },
+ { address: '456', name: '456', description: '456', checked: true },
+ { address: '789', name: '789', description: '789', checked: false }
+ ]);
+ });
+ });
+
+ describe('closeModal', () => {
+ beforeEach(() => {
+ store.openModal(ACCOUNTS);
+ store.selectAccount('789');
+ store.closeModal();
+ });
+
+ it('calls setNewDappsWhitelist', () => {
+ expect(api.parity.setNewDappsWhitelist).to.have.been.calledOnce;
+ });
+ });
+
+ describe('selectAccount', () => {
+ beforeEach(() => {
+ store.openModal(ACCOUNTS);
+ store.selectAccount('123');
+ store.selectAccount('789');
+ });
+
+ it('unselects previous selected accounts', () => {
+ expect(store.accounts.find((account) => account.address === '123').checked).to.be.false;
+ });
+
+ it('selects previous unselected accounts', () => {
+ expect(store.accounts.find((account) => account.address === '789').checked).to.be.true;
+ });
+ });
+ });
+});
diff --git a/js/src/modals/index.js b/js/src/modals/index.js
index 4534c8aba..702f4d414 100644
--- a/js/src/modals/index.js
+++ b/js/src/modals/index.js
@@ -16,8 +16,10 @@
import AddAddress from './AddAddress';
import AddContract from './AddContract';
+import AddDapps from './AddDapps';
import CreateAccount from './CreateAccount';
import CreateWallet from './CreateWallet';
+import DappPermissions from './DappPermissions';
import DeleteAccount from './DeleteAccount';
import DeployContract from './DeployContract';
import EditMeta from './EditMeta';
@@ -35,8 +37,10 @@ import WalletSettings from './WalletSettings';
export {
AddAddress,
AddContract,
+ AddDapps,
CreateAccount,
CreateWallet,
+ DappPermissions,
DeleteAccount,
DeployContract,
EditMeta,
diff --git a/js/src/ui/Icons/index.js b/js/src/ui/Icons/index.js
index 78846881b..84061f8ed 100644
--- a/js/src/ui/Icons/index.js
+++ b/js/src/ui/Icons/index.js
@@ -20,10 +20,12 @@ import CheckIcon from 'material-ui/svg-icons/navigation/check';
import CloseIcon from 'material-ui/svg-icons/navigation/close';
import ContractIcon from 'material-ui/svg-icons/action/code';
import DoneIcon from 'material-ui/svg-icons/action/done-all';
-import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back';
+import LockedIcon from 'material-ui/svg-icons/action/lock-outline';
import NextIcon from 'material-ui/svg-icons/navigation/arrow-forward';
+import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back';
import SaveIcon from 'material-ui/svg-icons/content/save';
import SnoozeIcon from 'material-ui/svg-icons/av/snooze';
+import VisibleIcon from 'material-ui/svg-icons/image/remove-red-eye';
export {
AddIcon,
@@ -32,8 +34,10 @@ export {
CloseIcon,
ContractIcon,
DoneIcon,
- PrevIcon,
+ LockedIcon,
NextIcon,
+ PrevIcon,
SaveIcon,
- SnoozeIcon
+ SnoozeIcon,
+ VisibleIcon
};
diff --git a/js/src/views/Dapps/dapps.js b/js/src/views/Dapps/dapps.js
index 9760382c2..6462e1af9 100644
--- a/js/src/views/Dapps/dapps.js
+++ b/js/src/views/Dapps/dapps.js
@@ -14,29 +14,35 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
-import React, { Component, PropTypes } from 'react';
-import { FormattedMessage } from 'react-intl';
import { Checkbox } from 'material-ui';
import { observer } from 'mobx-react';
+import React, { Component, PropTypes } from 'react';
+import { FormattedMessage } from 'react-intl';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
-import { Actionbar, Page } from '~/ui';
-import FlatButton from 'material-ui/FlatButton';
-import EyeIcon from 'material-ui/svg-icons/image/remove-red-eye';
+import { AddDapps, DappPermissions } from '~/modals';
+import PermissionStore from '~/modals/DappPermissions/store';
+import { Actionbar, Button, Page } from '~/ui';
+import { LockedIcon, VisibleIcon } from '~/ui/Icons';
import DappsStore from './dappsStore';
-
-import AddDapps from './AddDapps';
import Summary from './Summary';
import styles from './dapps.css';
@observer
-export default class Dapps extends Component {
+class Dapps extends Component {
static contextTypes = {
api: PropTypes.object.isRequired
}
+ static propTypes = {
+ accounts: PropTypes.object.isRequired
+ };
+
store = DappsStore.get(this.context.api);
+ permissionStore = new PermissionStore(this.context.api);
render () {
let externalOverlay = null;
@@ -68,6 +74,7 @@ export default class Dapps extends Component {
return (