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:
@@ -14,6 +14,7 @@
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||
|
||||
import Button from '../Button';
|
||||
import Modal from '../Modal';
|
||||
import Portal from '../Portal';
|
||||
import { CancelIcon, CheckIcon } from '../Icons';
|
||||
|
||||
import styles from './confirmDialog.css';
|
||||
@@ -42,47 +42,58 @@ export default class ConfirmDialog extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
className: PropTypes.string,
|
||||
disabledConfirm: PropTypes.bool,
|
||||
disabledDeny: PropTypes.bool,
|
||||
busy: PropTypes.bool,
|
||||
iconConfirm: PropTypes.node,
|
||||
iconDeny: PropTypes.node,
|
||||
labelConfirm: PropTypes.string,
|
||||
labelDeny: PropTypes.string,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onDeny: PropTypes.func.isRequired,
|
||||
open: PropTypes.bool,
|
||||
title: nodeOrStringProptype().isRequired,
|
||||
visible: PropTypes.bool.isRequired
|
||||
visible: PropTypes.bool
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, className, title, visible } = this.props;
|
||||
const { busy, children, className, disabledConfirm, disabledDeny, iconConfirm, iconDeny, labelConfirm, labelDeny, onConfirm, onDeny, open, title, visible } = this.props;
|
||||
|
||||
// TODO: visible is for compatibility with existing, open aligns with Portal.
|
||||
// (Cleanup once all uses of ConfirmDialog has been migrated)
|
||||
if (!visible && !open) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
<Portal
|
||||
buttons={ [
|
||||
<Button
|
||||
disabled={ disabledDeny }
|
||||
icon={ iconDeny || <CancelIcon /> }
|
||||
key='deny'
|
||||
label={ labelDeny || DEFAULT_NO }
|
||||
onClick={ onDeny }
|
||||
/>,
|
||||
<Button
|
||||
disabled={ disabledConfirm }
|
||||
icon={ iconConfirm || <CheckIcon /> }
|
||||
key='confirm'
|
||||
label={ labelConfirm || DEFAULT_YES }
|
||||
onClick={ onConfirm }
|
||||
/>
|
||||
] }
|
||||
busy={ busy }
|
||||
className={ className }
|
||||
actions={ this.renderActions() }
|
||||
isSmallModal
|
||||
onClose={ onDeny }
|
||||
title={ title }
|
||||
visible={ visible }
|
||||
open
|
||||
>
|
||||
<div className={ styles.body }>
|
||||
{ children }
|
||||
</div>
|
||||
</Modal>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
renderActions () {
|
||||
const { iconConfirm, iconDeny, labelConfirm, labelDeny, onConfirm, onDeny } = this.props;
|
||||
|
||||
return [
|
||||
<Button
|
||||
icon={ iconDeny || <CancelIcon /> }
|
||||
label={ labelDeny || DEFAULT_NO }
|
||||
onClick={ onDeny }
|
||||
/>,
|
||||
<Button
|
||||
icon={ iconConfirm || <CheckIcon /> }
|
||||
label={ labelConfirm || DEFAULT_YES }
|
||||
onClick={ onConfirm }
|
||||
/>
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,41 +15,24 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React, { PropTypes } from 'react';
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import muiTheme from '../Theme';
|
||||
|
||||
import ConfirmDialog from './';
|
||||
|
||||
let component;
|
||||
let instance;
|
||||
let onConfirm;
|
||||
let onDeny;
|
||||
|
||||
function createRedux () {
|
||||
return {
|
||||
dispatch: sinon.stub(),
|
||||
subscribe: sinon.stub(),
|
||||
getState: () => {
|
||||
return {
|
||||
settings: {
|
||||
backgroundSeed: 'xyz'
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function render (props = {}) {
|
||||
onConfirm = sinon.stub();
|
||||
onDeny = sinon.stub();
|
||||
|
||||
if (props.visible === undefined) {
|
||||
props.visible = true;
|
||||
if (props.open === undefined) {
|
||||
props.open = true;
|
||||
}
|
||||
|
||||
const baseComponent = shallow(
|
||||
component = shallow(
|
||||
<ConfirmDialog
|
||||
{ ...props }
|
||||
title='test title'
|
||||
@@ -62,57 +45,54 @@ function render (props = {}) {
|
||||
</ConfirmDialog>
|
||||
);
|
||||
|
||||
instance = baseComponent.instance();
|
||||
component = baseComponent.find('Connect(Modal)').shallow({
|
||||
childContextTypes: {
|
||||
muiTheme: PropTypes.object,
|
||||
store: PropTypes.object
|
||||
},
|
||||
context: {
|
||||
muiTheme,
|
||||
store: createRedux()
|
||||
}
|
||||
});
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('ui/ConfirmDialog', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(render()).to.be.ok;
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('renders the body as provided', () => {
|
||||
expect(render().find('div[id="testContent"]').text()).to.equal('some test content');
|
||||
expect(component.find('div[id="testContent"]').text()).to.equal('some test content');
|
||||
});
|
||||
|
||||
describe('properties', () => {
|
||||
describe('Portal properties', () => {
|
||||
let props;
|
||||
|
||||
beforeEach(() => {
|
||||
props = render().props();
|
||||
});
|
||||
|
||||
it('passes the actions', () => {
|
||||
expect(props.actions).to.deep.equal(instance.renderActions());
|
||||
props = component.find('Portal').props();
|
||||
});
|
||||
|
||||
it('passes title', () => {
|
||||
expect(props.title).to.equal('test title');
|
||||
});
|
||||
|
||||
it('passes visiblity flag', () => {
|
||||
expect(props.visible).to.be.true;
|
||||
it('passes open flag', () => {
|
||||
expect(props.open).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('renderActions', () => {
|
||||
describe('defaults', () => {
|
||||
it('passes the small flag', () => {
|
||||
expect(props.isSmallModal).to.be.true;
|
||||
});
|
||||
|
||||
it('maps onClose to onDeny', () => {
|
||||
expect(props.onClose).to.equal(onDeny);
|
||||
});
|
||||
|
||||
describe('buttons', () => {
|
||||
let buttons;
|
||||
|
||||
beforeEach(() => {
|
||||
render();
|
||||
buttons = instance.renderActions();
|
||||
buttons = component.props().buttons;
|
||||
});
|
||||
|
||||
it('passes the buttons', () => {
|
||||
expect(buttons.length).to.equal(2);
|
||||
});
|
||||
|
||||
it('renders with supplied onConfim/onDeny callbacks', () => {
|
||||
@@ -129,29 +109,27 @@ describe('ui/ConfirmDialog', () => {
|
||||
expect(buttons[0].props.icon.type.displayName).to.equal('ContentClear');
|
||||
expect(buttons[1].props.icon.type.displayName).to.equal('NavigationCheck');
|
||||
});
|
||||
});
|
||||
|
||||
describe('overrides', () => {
|
||||
let buttons;
|
||||
|
||||
beforeEach(() => {
|
||||
render({
|
||||
labelConfirm: 'labelConfirm',
|
||||
labelDeny: 'labelDeny',
|
||||
iconConfirm: 'iconConfirm',
|
||||
iconDeny: 'iconDeny'
|
||||
describe('overrides', () => {
|
||||
beforeEach(() => {
|
||||
render({
|
||||
labelConfirm: 'labelConfirm',
|
||||
labelDeny: 'labelDeny',
|
||||
iconConfirm: 'iconConfirm',
|
||||
iconDeny: 'iconDeny'
|
||||
});
|
||||
buttons = component.props().buttons;
|
||||
});
|
||||
buttons = instance.renderActions();
|
||||
});
|
||||
|
||||
it('renders supplied labels', () => {
|
||||
expect(buttons[0].props.label).to.equal('labelDeny');
|
||||
expect(buttons[1].props.label).to.equal('labelConfirm');
|
||||
});
|
||||
it('renders supplied labels', () => {
|
||||
expect(buttons[0].props.label).to.equal('labelDeny');
|
||||
expect(buttons[1].props.label).to.equal('labelConfirm');
|
||||
});
|
||||
|
||||
it('renders supplied icons', () => {
|
||||
expect(buttons[0].props.icon).to.equal('iconDeny');
|
||||
expect(buttons[1].props.icon).to.equal('iconConfirm');
|
||||
it('renders supplied icons', () => {
|
||||
expect(buttons[0].props.icon).to.equal('iconDeny');
|
||||
expect(buttons[1].props.icon).to.equal('iconConfirm');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user