Vault Management UI (first round) (#4446)
* Add RPCs for parity_vault (create, open, list, etc.)
* WIP
* WIP
* WIP
* WIP (create should create)
* Create & close working
* WIP
* WIP
* WIP
* Open & Close now working
* WIP
* WIP
* Merge relevant changes from js-home
* Hover actions
* WIP (start of account assignment)
* Open, Close & Account assignment works
* Fix margins
* UI updates
* Update tests
* Add the parity_{get|set}VaultMeta calls
* Handle metadata
* Adjust padding in Open/Close modals
* moveAccounts take both in and out
* Adjust padding
* Fix stretch
* Optimize hover stretch
* pre-merge
* Cleanup variable naming (duplication)
* Rename Vault{Close,Open} -> Vault{Lock,Unlock}
* clearVaultFields uses setters
* TODO for small Portal sizes
* Vaults rendering tests
* .only
* libusb compile
* VaultCard rendering tests
* Update message keys (rename gone rouge)
* Display passwordHint op vault unlock
* Update failing tests
* Manually dispatch allAccountsInfo when move completed
* Open/Close always shows vault image in colour
* Password submit submits modal (PR comment)
* Add link to account
This commit is contained in:
17
js/src/ui/VaultCard/Layout/index.js
Normal file
17
js/src/ui/VaultCard/Layout/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './layout';
|
||||
45
js/src/ui/VaultCard/Layout/layout.css
Normal file
45
js/src/ui/VaultCard/Layout/layout.css
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$imageHeight: 56px;
|
||||
|
||||
.layout {
|
||||
display: flex;
|
||||
min-height: $imageHeight;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
|
||||
&.border {
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
padding: 1.5em;
|
||||
}
|
||||
|
||||
.identityIcon {
|
||||
margin-right: 1em;
|
||||
vertical-align: top;
|
||||
|
||||
&.locked {
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.33;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
66
js/src/ui/VaultCard/Layout/layout.js
Normal file
66
js/src/ui/VaultCard/Layout/layout.js
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import Title from '~/ui/Title';
|
||||
import IdentityIcon from '~/ui/IdentityIcon';
|
||||
|
||||
import styles from './layout.css';
|
||||
|
||||
export default class Layout extends Component {
|
||||
static propTypes = {
|
||||
vault: PropTypes.object.isRequired,
|
||||
withBorder: PropTypes.bool
|
||||
};
|
||||
|
||||
render () {
|
||||
const { vault, withBorder } = this.props;
|
||||
const { isOpen, meta, name } = vault;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
[
|
||||
styles.layout,
|
||||
withBorder
|
||||
? styles.border
|
||||
: null
|
||||
].join(' ')
|
||||
}
|
||||
>
|
||||
<IdentityIcon
|
||||
address={ name }
|
||||
center
|
||||
className={
|
||||
[
|
||||
styles.identityIcon,
|
||||
isOpen || withBorder
|
||||
? styles.unlocked
|
||||
: styles.locked
|
||||
].join(' ')
|
||||
}
|
||||
/>
|
||||
<div className={ styles.info }>
|
||||
<Title
|
||||
byline={ meta.description }
|
||||
title={ name }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
90
js/src/ui/VaultCard/Layout/layout.spec.js
Normal file
90
js/src/ui/VaultCard/Layout/layout.spec.js
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import Layout from './';
|
||||
|
||||
const DESCRIPTION = 'some description';
|
||||
const NAME = 'testName';
|
||||
|
||||
let component;
|
||||
|
||||
function render () {
|
||||
component = shallow(
|
||||
<Layout
|
||||
vault={ {
|
||||
isOpen: true,
|
||||
meta: {
|
||||
description: DESCRIPTION,
|
||||
passwordHint: 'some hint'
|
||||
},
|
||||
name: NAME
|
||||
} }
|
||||
/>
|
||||
);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('ui/VaultCard/Layout', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
describe('components', () => {
|
||||
describe('IdentityIcon', () => {
|
||||
let icon;
|
||||
|
||||
beforeEach(() => {
|
||||
icon = component.find('Connect(IdentityIcon)');
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(icon.get(0)).to.be.ok;
|
||||
});
|
||||
|
||||
it('passes the name as address key', () => {
|
||||
expect(icon.props().address).to.equal(NAME);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Title', () => {
|
||||
let title;
|
||||
|
||||
beforeEach(() => {
|
||||
title = component.find('Title');
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(title.get(0)).to.be.ok;
|
||||
});
|
||||
|
||||
it('passes the name as title', () => {
|
||||
expect(title.props().title).to.equal(NAME);
|
||||
});
|
||||
|
||||
it('passes the description as byline', () => {
|
||||
expect(title.props().byline).to.equal(DESCRIPTION);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
17
js/src/ui/VaultCard/index.js
Normal file
17
js/src/ui/VaultCard/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './vaultCard';
|
||||
62
js/src/ui/VaultCard/vaultCard.css
Normal file
62
js/src/ui/VaultCard/vaultCard.css
Normal file
@@ -0,0 +1,62 @@
|
||||
/* Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.container {
|
||||
text-align: left;
|
||||
|
||||
.accounts {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 1.5em;
|
||||
|
||||
.account {
|
||||
margin: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
margin-top: 1.5em;
|
||||
opacity: 0.5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin: -1em -1em 0.75em -1em;
|
||||
text-align: right;
|
||||
|
||||
button.status {
|
||||
min-width: 2em !important;
|
||||
}
|
||||
|
||||
button:not(.status) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.buttons {
|
||||
button.status {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button:not(.status) {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
js/src/ui/VaultCard/vaultCard.js
Normal file
102
js/src/ui/VaultCard/vaultCard.js
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import Button from '~/ui/Button';
|
||||
import Container from '~/ui/Container';
|
||||
import IdentityIcon from '~/ui/IdentityIcon';
|
||||
import { LockedIcon, UnlockedIcon } from '~/ui/Icons';
|
||||
|
||||
import Layout from './Layout';
|
||||
import styles from './vaultCard.css';
|
||||
|
||||
export default class VaultCard extends Component {
|
||||
static propTypes = {
|
||||
accounts: PropTypes.array,
|
||||
buttons: PropTypes.array,
|
||||
vault: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static Layout = Layout;
|
||||
|
||||
render () {
|
||||
const { buttons, vault } = this.props;
|
||||
const { isOpen } = vault;
|
||||
|
||||
return (
|
||||
<Container
|
||||
className={ styles.container }
|
||||
hover={
|
||||
isOpen
|
||||
? this.renderAccounts()
|
||||
: null
|
||||
}
|
||||
>
|
||||
<div className={ styles.buttons }>
|
||||
<Button
|
||||
className={ styles.status }
|
||||
disabled
|
||||
icon={
|
||||
isOpen
|
||||
? <UnlockedIcon />
|
||||
: <LockedIcon />
|
||||
}
|
||||
key='status'
|
||||
/>
|
||||
{ buttons }
|
||||
</div>
|
||||
<Layout vault={ vault } />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
renderAccounts () {
|
||||
const { accounts } = this.props;
|
||||
|
||||
if (!accounts || !accounts.length) {
|
||||
return (
|
||||
<div className={ styles.empty }>
|
||||
<FormattedMessage
|
||||
id='vaults.accounts.empty'
|
||||
defaultMessage='There are no accounts in this vault'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.accounts }>
|
||||
{
|
||||
accounts.map((address) => {
|
||||
return (
|
||||
<Link to={ `/accounts/${address}` }>
|
||||
<IdentityIcon
|
||||
address={ address }
|
||||
center
|
||||
className={ styles.account }
|
||||
key={ address }
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
94
js/src/ui/VaultCard/vaultCard.spec.js
Normal file
94
js/src/ui/VaultCard/vaultCard.spec.js
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2015-2017 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import VaultCard from './';
|
||||
|
||||
const VAULT = { name: 'testing', isOpen: true };
|
||||
|
||||
let component;
|
||||
let instance;
|
||||
|
||||
function render (props = {}) {
|
||||
component = shallow(
|
||||
<VaultCard
|
||||
vault={ VAULT }
|
||||
{ ...props }
|
||||
/>
|
||||
);
|
||||
instance = component.instance();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('ui/VaultCard', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
describe('components', () => {
|
||||
describe('Layout', () => {
|
||||
let layout;
|
||||
|
||||
beforeEach(() => {
|
||||
layout = component.find('Layout');
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(layout.get(0)).to.be.ok;
|
||||
});
|
||||
|
||||
it('passes the vault', () => {
|
||||
expect(layout.props().vault).to.deep.equal(VAULT);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('instance methods', () => {
|
||||
describe('renderAccounts', () => {
|
||||
it('renders empty when no accounts supplied', () => {
|
||||
expect(
|
||||
shallow(instance.renderAccounts()).find('FormattedMessage').props().id
|
||||
).to.equal('vaults.accounts.empty');
|
||||
});
|
||||
|
||||
describe('with accounts', () => {
|
||||
const ACCOUNTS = ['0x123', '0x456'];
|
||||
let identities;
|
||||
|
||||
beforeEach(() => {
|
||||
render({ accounts: ACCOUNTS });
|
||||
identities = shallow(instance.renderAccounts()).find('Connect(IdentityIcon)');
|
||||
});
|
||||
|
||||
it('renders the accounts when supplied', () => {
|
||||
expect(identities).to.have.length(2);
|
||||
});
|
||||
|
||||
it('renders accounts with correct address', () => {
|
||||
console.log(identities.get(0));
|
||||
expect(identities.get(0).props.address).to.equal(ACCOUNTS[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user