Requests (WIP)

This commit is contained in:
Jaco Greeff 2017-04-24 13:40:23 +02:00
parent 0c70cee503
commit 1725c708fe
21 changed files with 77 additions and 515 deletions

View File

@ -55,11 +55,11 @@
"secure": true
},
{
"id": "home",
"url": "home",
"src": "Home",
"name": "Home",
"description": "Display the status of the node, recently accessed applications, accounts and news",
"id": "requests",
"url": "requests",
"src": "Signer",
"name": "Requests",
"description": "Display the current and historic Signer requests",
"author": "Parity Team <admin@ethcore.io>",
"version": "2.0.0",
"visible": true,

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import HistoryStore from '~/mobx/historyStore';
import { Application, Dapp, Dapps, Signer, Web } from '~/views';
import { Application, Dapp, Dapps, Web } from '~/views';
import builtinDapps from '~/config/dappsBuiltin.json';
import viewsDapps from '~/config/dappsViews.json';
@ -68,8 +68,7 @@ const childRoutes = [
},
{ path: 'apps', component: Dapps },
{ path: 'web', component: Web },
{ path: 'web/:url', component: Web },
{ path: 'signer', component: Signer }
{ path: 'web/:url', component: Web }
];
// TODO : use ES6 imports when supported

View File

@ -1,17 +0,0 @@
// 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 './tab';

View File

@ -1,75 +0,0 @@
// 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 { Tab as MUITab } from 'material-ui/Tabs';
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { Badge } from '~/ui';
import styles from '../tabBar.css';
const SIGNER_ID = 'signer';
export default class Tab extends Component {
static propTypes = {
pendings: PropTypes.number,
view: PropTypes.object.isRequired
};
render () {
const { view } = this.props;
return (
<MUITab
icon={ view.icon }
label={
view.id === SIGNER_ID
? this.renderSignerLabel()
: this.renderLabel(view.id)
}
/>
);
}
renderLabel (id, bubble) {
return (
<div className={ styles.label }>
<FormattedMessage
id={ `settings.views.${id}.label` }
/>
{ bubble }
</div>
);
}
renderSignerLabel () {
const { pendings } = this.props;
let bubble;
if (pendings) {
bubble = (
<Badge
color='red'
className={ styles.labelBubble }
value={ pendings }
/>
);
}
return this.renderLabel(SIGNER_ID, bubble);
}
}

View File

@ -1,77 +0,0 @@
// 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 sinon from 'sinon';
import Tab from './';
let component;
let instance;
function render (id = 'signer') {
component = shallow(
<Tab
pending={ 5 }
view={ { id } }
/>
);
instance = component.instance();
return component;
}
describe('views/Application/TabBar/Tab', () => {
beforeEach(() => {
render();
});
it('renders defaults', () => {
expect(component).to.be.ok;
});
describe('instance methods', () => {
describe('renderLabel', () => {
it('renders the label with correct label', () => {
expect(
shallow(instance.renderLabel('test')).find('FormattedMessage').props().id
).to.equal('settings.views.test.label');
});
it('renders the bubble when passed', () => {
expect(
shallow(instance.renderLabel('test', 'testBubble')).text()
).to.equal('<FormattedMessage />testBubble');
});
});
describe('renderSignerLabel', () => {
beforeEach(() => {
sinon.stub(instance, 'renderLabel');
});
afterEach(() => {
instance.renderLabel.restore();
});
it('calls renderLabel with the details', () => {
instance.renderSignerLabel();
expect(instance.renderLabel).to.have.been.calledWith('signer');
});
});
});
});

View File

@ -1,17 +0,0 @@
// 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 './tabBar';

View File

@ -1,90 +0,0 @@
/* 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/>.
*/
.toolbar {
background: none !important;
height: 72px !important;
position: relative;
}
.tabs {
width: 100%;
position: relative;
display: flex;
& > * {
flex: 1;
}
}
.tabLink {
display: flex;
> * {
flex: 1;
}
&:hover {
background: rgba(0, 0, 0, 0.4) !important;
}
&.tabactive, &.tabactive:hover {
background: rgba(0, 0, 0, 0.25) !important;
border-radius: 4px 4px 0 0;
* {
color: white !important;
}
}
}
.tabLink,
.settings,
.first,
.last {
background: rgba(0, 0, 0, 0.5) !important; /* rgba(0, 0, 0, 0.25) !important; */
}
.tabbarTooltip {
left: 3em;
top: 4em;
}
.label {
position: relative;
}
.labelBubble {
position: absolute;
top: -12px;
right: -12px;
}
.first,
.last {
margin: 0;
padding: 36px 12px;
white-space: nowrap;
}
.first {
margin-left: -24px;
}
.last {
margin-right: -24px;
}

View File

@ -1,125 +0,0 @@
// 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 { connect } from 'react-redux';
import { Link } from 'react-router';
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
import { isEqual } from 'lodash';
import { Tooltip } from '~/ui';
import Tab from './Tab';
import styles from './tabBar.css';
class TabBar extends Component {
static contextTypes = {
router: PropTypes.object.isRequired
};
static propTypes = {
pending: PropTypes.array,
views: PropTypes.array.isRequired
};
static defaultProps = {
pending: []
};
render () {
return (
<Toolbar className={ styles.toolbar }>
<ToolbarGroup className={ styles.first }>
<div />
</ToolbarGroup>
<div className={ styles.tabs }>
{ this.renderTabItems() }
<Tooltip
className={ styles.tabbarTooltip }
text={
<FormattedMessage
id='tabBar.tooltip.overview'
defaultMessage='navigate between the different parts and views of the application, switching between an account view, token view and distributed application view'
/>
}
/>
</div>
<ToolbarGroup className={ styles.last }>
<div />
</ToolbarGroup>
</Toolbar>
);
}
renderTabItems () {
const { views, pending } = this.props;
return views.map((view, index) => {
return (
<Link
activeClassName={ styles.tabactive }
className={ styles.tabLink }
key={ view.id }
to={ view.route }
>
<Tab
pendings={ pending.length }
view={ view }
/>
</Link>
);
});
}
}
function mapStateToProps (initState) {
const { views } = initState.settings;
let filteredViewIds = Object
.keys(views)
.filter((id) => views[id].fixed || views[id].active);
let filteredViews = filteredViewIds.map((id) => ({
...views[id],
id
}));
return (state) => {
const { views } = state.settings;
const viewIds = Object
.keys(views)
.filter((id) => views[id].fixed || views[id].active);
if (isEqual(viewIds, filteredViewIds)) {
return { views: filteredViews };
}
filteredViewIds = viewIds;
filteredViews = viewIds.map((id) => ({
...views[id],
id
}));
return { views: filteredViews };
};
}
export default connect(
mapStateToProps,
null
)(TabBar);

View File

@ -1,63 +0,0 @@
// 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 sinon from 'sinon';
import TabBar from './';
let component;
let store;
function createStore () {
store = {
dispatch: sinon.stub(),
subscribe: sinon.stub(),
getState: () => {
return {
settings: {
views: {
settings: { fixed: true }
}
}
};
}
};
return store;
}
function render (props = {}) {
component = shallow(
<TabBar { ...props } />,
{
context: { store: createStore() }
}
).find('TabBar').shallow();
return component;
}
describe('views/Application/TabBar', () => {
beforeEach(() => {
render();
});
it('renders defaults', () => {
expect(component).to.be.ok;
});
});

View File

@ -30,7 +30,6 @@ import Extension from './Extension';
import FrameError from './FrameError';
import Status from './Status';
import Store from './store';
import TabBar from './TabBar';
import Requests from './Requests';
import styles from './application.css';
@ -86,7 +85,7 @@ class Application extends Component {
}
renderApp () {
const { blockNumber, children, pending } = this.props;
const { blockNumber, children } = this.props;
return (
<Container
@ -94,7 +93,6 @@ class Application extends Component {
onCloseFirstRun={ this.store.closeFirstrun }
showFirstRun={ this.store.firstrunVisible }
>
<TabBar pending={ pending } />
<div className={ styles.content }>
{ children }
</div>
@ -123,12 +121,10 @@ class Application extends Component {
function mapStateToProps (state) {
const { blockNumber } = state.nodeStatus;
const { hasAccounts } = state.personal;
const { pending } = state.signer;
return {
blockNumber,
hasAccounts,
pending
hasAccounts
};
}

View File

@ -27,7 +27,7 @@ import imagesEthcoreBlock from '~/../assets/images/parity-logo-white-no-text.svg
import { AccountCard, Badge, Button, ContainerTitle, IdentityIcon, ParityBackground, SelectionList } from '~/ui';
import { CancelIcon, FingerprintIcon } from '~/ui/Icons';
import DappsStore from '~/views/Dapps/dappsStore';
import { Embedded as Signer } from '~/views/Signer';
import Signer from '~/views/Signer/Embedded';
import AccountStore from './accountStore';
import styles from './parityBar.css';

View File

@ -16,7 +16,7 @@
import React from 'react';
import { AppsIcon, FingerprintIcon } from '~/ui/Icons';
import { AppsIcon } from '~/ui/Icons';
const defaultViews = {
apps: {
@ -24,14 +24,6 @@ const defaultViews = {
icon: <AppsIcon />,
route: '/apps',
value: 'app'
},
signer: {
active: true,
fixed: true,
icon: <FingerprintIcon />,
route: '/signer',
value: 'signer'
}
};

View File

@ -20,11 +20,11 @@ import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Store from '../../store';
import Store from '../store';
import * as RequestsActions from '~/redux/providers/signerActions';
import { Container } from '~/ui';
import RequestPending from '../../components/RequestPending';
import RequestPending from '../components/RequestPending';
import styles from './embedded.css';

View File

@ -21,11 +21,11 @@ import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Store from '../../store';
import Store from '../store';
import * as RequestsActions from '~/redux/providers/signerActions';
import { Container, Page, TxList } from '~/ui';
import RequestPending from '../../components/RequestPending';
import RequestPending from '../components/RequestPending';
import styles from './requestsPage.css';

View File

@ -14,10 +14,32 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import Embedded from './containers/Embedded';
import ReactDOM from 'react-dom';
import React from 'react';
import { hashHistory } from 'react-router';
export default from './signer';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();
export {
Embedded
};
import { api } from './parity';
import ContractInstances from '~/contracts';
import { initStore } from '~/redux';
import ContextProvider from '~/ui/ContextProvider';
import muiTheme from '~/ui/Theme';
import Signer from './signer';
import '~/../assets/fonts/Roboto/font.css';
import '~/../assets/fonts/RobotoMono/font.css';
ContractInstances.get(api);
const store = initStore(api, hashHistory);
ReactDOM.render(
<ContextProvider api={ api } muiTheme={ muiTheme } store={ store }>
<Signer />
</ContextProvider>,
document.querySelector('#container')
);

View File

@ -0,0 +1,19 @@
{
"name": "@parity/view-signer",
"description": "Parity signer views, embedded and requests",
"version": "0.0.0",
"main": "index.js",
"author": "Parity Team <admin@parity.io>",
"maintainers": [],
"contributors": [],
"license": "GPL-3.0",
"repository": {
"type": "git",
"url": "git+https://github.com/paritytech/parity.git"
},
"keywords": [],
"scripts": {},
"devDependencies": {},
"dependencies": {},
"peerDependencies": {}
}

View File

@ -14,26 +14,24 @@
// 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 } from 'react';
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { Actionbar } from '~/ui';
import RequestsPage from './containers/RequestsPage';
import RequestsPage from './RequestsPage';
export default class Signer extends Component {
render () {
return (
<div>
<Actionbar
title={
<FormattedMessage
id='signer.title'
defaultMessage='Trusted Signer'
/>
}
/>
<RequestsPage />
</div>
);
}
export default function Signer () {
return (
<div>
<Actionbar
title={
<FormattedMessage
id='signer.title'
defaultMessage='Trusted Signer'
/>
}
/>
<RequestsPage />
</div>
);
}