Allow tags for Accounts, Addresses and Contracts (#2712)
* Added tag to the editMeta Modal (#2643) * Added Tags to ui and to contract/address/account Header (#2643) * Added tags to summary (#2643) * Added Search capabilities to contracts/address book/accounts from tokens (#2643) * fixes eslint * Using Chips/Tokens for search (#2643) * Add search tokens, clickable from List (#2643) * Add sort capabilities to Accounts / Addresses / Contracts (#2643) * Fixes formatting issues + state updates after component unmount bug (#2643) * Remove unused import * Small fixes for PR #2697 * Added default sort order for Contracts/Addresses/Accounts * Using official `material-ui-chip-input` NPM package * Removed LESS from webpack
This commit is contained in:
committed by
Gav Wood
parent
dadd6b1e7c
commit
cc10f412dc
17
js/src/ui/Actionbar/Search/index.js
Normal file
17
js/src/ui/Actionbar/Search/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (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 './search';
|
||||
43
js/src/ui/Actionbar/Search/search.css
Normal file
43
js/src/ui/Actionbar/Search/search.css
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright 2015, 2016 Ethcore (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/>.
|
||||
*/
|
||||
.searchcontainer {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.searchButton {
|
||||
min-width: 50px !important;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 500px !important;
|
||||
}
|
||||
|
||||
.inputContainer {
|
||||
transition: width 450ms ease-in-out 0ms, height 0ms ease-in-out 0ms;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
width: 500px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inputContainerShown {
|
||||
transition: width 450ms ease-in-out 0ms, height 0ms ease-in-out 400ms;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
176
js/src/ui/Actionbar/Search/search.js
Normal file
176
js/src/ui/Actionbar/Search/search.js
Normal file
@@ -0,0 +1,176 @@
|
||||
// Copyright 2015, 2016 Ethcore (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 ChipInput from 'material-ui-chip-input';
|
||||
import ChipInput from 'material-ui-chip-input/src/ChipInput';
|
||||
import ActionSearch from 'material-ui/svg-icons/action/search';
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
import { Button } from '../../';
|
||||
|
||||
import styles from './search.css';
|
||||
|
||||
export default class ActionbarSearch extends Component {
|
||||
static propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
tokens: PropTypes.array
|
||||
};
|
||||
|
||||
state = {
|
||||
showSearch: false,
|
||||
stateChanging: false,
|
||||
inputValue: '',
|
||||
timeoutIds: []
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { tokens } = nextProps;
|
||||
|
||||
if (tokens.length > 0 && this.props.tokens.length === 0) {
|
||||
this.handleOpenSearch(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
const { timeoutIds } = this.state;
|
||||
|
||||
if (timeoutIds.length > 0) {
|
||||
timeoutIds.map(id => window.clearTimeout(id));
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { showSearch } = this.state;
|
||||
const { tokens } = this.props;
|
||||
|
||||
const inputContainerClasses = [ styles.inputContainer ];
|
||||
|
||||
if (!showSearch) {
|
||||
inputContainerClasses.push(styles.inputContainerShown);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={ styles.searchcontainer }
|
||||
key='searchAccount'>
|
||||
<div className={ inputContainerClasses.join(' ') }>
|
||||
<ChipInput
|
||||
clearOnBlur={ false }
|
||||
className={ styles.input }
|
||||
hintText='Enter search input...'
|
||||
hintStyle={ {
|
||||
transition: 'none'
|
||||
} }
|
||||
ref='searchInput'
|
||||
value={ tokens }
|
||||
onBlur={ this.handleSearchBlur }
|
||||
onRequestAdd={ this.handleTokenAdd }
|
||||
onRequestDelete={ this.handleTokenDelete }
|
||||
onUpdateInput={ this.handleInputChange } />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className={ styles.searchButton }
|
||||
icon={ <ActionSearch /> }
|
||||
label=''
|
||||
onClick={ this.handleSearchClick } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
handleTokenAdd = (value) => {
|
||||
const { tokens } = this.props;
|
||||
|
||||
const newSearchValues = uniq([].concat(tokens, value));
|
||||
|
||||
this.setState({
|
||||
inputValue: ''
|
||||
});
|
||||
|
||||
this.handleSearchChange(newSearchValues);
|
||||
}
|
||||
|
||||
handleTokenDelete = (value) => {
|
||||
const { tokens } = this.props;
|
||||
|
||||
const newSearchValues = []
|
||||
.concat(tokens)
|
||||
.filter(v => v !== value);
|
||||
|
||||
this.setState({
|
||||
inputValue: ''
|
||||
});
|
||||
|
||||
this.handleSearchChange(newSearchValues);
|
||||
this.refs.searchInput.focus();
|
||||
}
|
||||
|
||||
handleInputChange = (value) => {
|
||||
this.setState({ inputValue: value });
|
||||
}
|
||||
|
||||
handleSearchChange = (searchValues) => {
|
||||
const { onChange } = this.props;
|
||||
const newSearchValues = searchValues.filter(v => v.length > 0);
|
||||
|
||||
onChange(newSearchValues);
|
||||
}
|
||||
|
||||
handleSearchClick = () => {
|
||||
const { showSearch } = this.state;
|
||||
|
||||
this.handleOpenSearch(!showSearch);
|
||||
}
|
||||
|
||||
handleSearchBlur = () => {
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
const { inputValue } = this.state;
|
||||
const { tokens } = this.props;
|
||||
|
||||
if (tokens.length === 0 && inputValue.length === 0) {
|
||||
this.handleOpenSearch(false);
|
||||
}
|
||||
}, 250);
|
||||
|
||||
this.setState({
|
||||
timeoutIds: [].concat(this.state.timeoutIds, timeoutId)
|
||||
});
|
||||
}
|
||||
|
||||
handleOpenSearch = (showSearch, force) => {
|
||||
if (this.state.stateChanging && !force) return false;
|
||||
|
||||
this.setState({
|
||||
showSearch: showSearch,
|
||||
stateChanging: true
|
||||
});
|
||||
|
||||
if (showSearch) {
|
||||
this.refs.searchInput.focus();
|
||||
} else {
|
||||
this.refs.searchInput.getInputNode().blur();
|
||||
}
|
||||
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
this.setState({ stateChanging: false });
|
||||
}, 450);
|
||||
|
||||
this.setState({
|
||||
timeoutIds: [].concat(this.state.timeoutIds, timeoutId)
|
||||
});
|
||||
}
|
||||
}
|
||||
17
js/src/ui/Actionbar/Sort/index.js
Normal file
17
js/src/ui/Actionbar/Sort/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (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 './sort';
|
||||
20
js/src/ui/Actionbar/Sort/sort.css
Normal file
20
js/src/ui/Actionbar/Sort/sort.css
Normal file
@@ -0,0 +1,20 @@
|
||||
/* Copyright 2015, 2016 Ethcore (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/>.
|
||||
*/
|
||||
|
||||
.sortButton {
|
||||
min-width: 50px !important;
|
||||
}
|
||||
73
js/src/ui/Actionbar/Sort/sort.js
Normal file
73
js/src/ui/Actionbar/Sort/sort.js
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2015, 2016 Ethcore (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 IconMenu from 'material-ui/IconMenu';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
|
||||
import SortIcon from 'material-ui/svg-icons/content/sort';
|
||||
|
||||
import { Button } from '../../';
|
||||
|
||||
import styles from './sort.css';
|
||||
|
||||
export default class ActionbarSort extends Component {
|
||||
static propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
order: PropTypes.string
|
||||
};
|
||||
|
||||
state = {
|
||||
menuOpen: false
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<IconMenu
|
||||
iconButtonElement={
|
||||
<Button
|
||||
className={ styles.sortButton }
|
||||
label=''
|
||||
icon={ <SortIcon /> }
|
||||
onClick={ this.handleMenuOpen }
|
||||
/>
|
||||
}
|
||||
open={ this.state.menuOpen }
|
||||
onRequestChange={ this.handleMenuChange }
|
||||
onItemTouchTap={ this.handleSortChange }
|
||||
targetOrigin={ { horizontal: 'right', vertical: 'top' } }
|
||||
anchorOrigin={ { horizontal: 'right', vertical: 'top' } }
|
||||
>
|
||||
<MenuItem value='' primaryText='Default' />
|
||||
<MenuItem value='tags' primaryText='Sort by tags' />
|
||||
<MenuItem value='name' primaryText='Sort by name' />
|
||||
</IconMenu>
|
||||
);
|
||||
}
|
||||
|
||||
handleSortChange = (event, child) => {
|
||||
const order = child.props.value;
|
||||
this.props.onChange(order);
|
||||
}
|
||||
|
||||
handleMenuOpen = () => {
|
||||
this.setState({ menuOpen: true });
|
||||
}
|
||||
|
||||
handleMenuChange = (open) => {
|
||||
this.setState({ menuOpen: open });
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,15 @@
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
padding: 0em
|
||||
padding: 0em;
|
||||
}
|
||||
|
||||
.padded {
|
||||
padding: 1.5em;
|
||||
background: rgba(0, 0, 0, 0.8) !important;
|
||||
border-radius: 0 !important;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.light .padded {
|
||||
|
||||
17
js/src/ui/Tags/index.js
Normal file
17
js/src/ui/Tags/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (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 './tags';
|
||||
36
js/src/ui/Tags/tags.css
Normal file
36
js/src/ui/Tags/tags.css
Normal file
@@ -0,0 +1,36 @@
|
||||
/* Copyright 2015, 2016 Ethcore (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/>.
|
||||
*/
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
position: absolute;
|
||||
right: 0.25rem;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 0.75rem;
|
||||
background: rgba(255, 255, 255, 0.07);
|
||||
border-radius: 16px;
|
||||
margin: 0.75em 0.5em 0 0;
|
||||
padding: 0.25em 1em;
|
||||
}
|
||||
|
||||
.tagClickable:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
56
js/src/ui/Tags/tags.js
Normal file
56
js/src/ui/Tags/tags.js
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2015, 2016 Ethcore (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 styles from './tags.css';
|
||||
|
||||
export default class Tags extends Component {
|
||||
static propTypes = {
|
||||
tags: PropTypes.array,
|
||||
handleAddSearchToken: PropTypes.func
|
||||
}
|
||||
|
||||
render () {
|
||||
return (<div className={ styles.tags }>
|
||||
{ this.renderTags() }
|
||||
</div>);
|
||||
}
|
||||
|
||||
renderTags () {
|
||||
const { handleAddSearchToken } = this.props;
|
||||
const tags = this.props.tags || [];
|
||||
|
||||
const tagClasses = handleAddSearchToken
|
||||
? [ styles.tag, styles.tagClickable ]
|
||||
: [ styles.tag ];
|
||||
|
||||
return tags.map((tag, idx) => {
|
||||
const onClick = handleAddSearchToken
|
||||
? () => handleAddSearchToken(tag)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={ idx }
|
||||
className={ tagClasses.join(' ') }
|
||||
onClick={ onClick }>
|
||||
{ tag }
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import Actionbar from './Actionbar';
|
||||
import ActionbarSearch from './Actionbar/Search';
|
||||
import ActionbarSort from './Actionbar/Sort';
|
||||
import Badge from './Badge';
|
||||
import Balance from './Balance';
|
||||
import Button from './Button';
|
||||
@@ -31,11 +33,14 @@ import muiTheme from './Theme';
|
||||
import Page from './Page';
|
||||
import ParityBackground from './ParityBackground';
|
||||
import SignerIcon from './SignerIcon';
|
||||
import Tags from './Tags';
|
||||
import Tooltips, { Tooltip } from './Tooltips';
|
||||
import TxHash from './TxHash';
|
||||
|
||||
export {
|
||||
Actionbar,
|
||||
ActionbarSearch,
|
||||
ActionbarSort,
|
||||
AddressSelect,
|
||||
Badge,
|
||||
Balance,
|
||||
@@ -62,6 +67,7 @@ export {
|
||||
Page,
|
||||
ParityBackground,
|
||||
SignerIcon,
|
||||
Tags,
|
||||
Tooltip,
|
||||
Tooltips,
|
||||
TxHash
|
||||
|
||||
Reference in New Issue
Block a user