Trigger accounts/contracts search on search input change (#2838)
* Styling Chips in search bar (#2766) * Styling search chips // Add chip on space/comma/... (#2766) * Update search on input (#2766) * Fixing search triggers bugs (#2766) * removed console logs * Use props instead of weird CSS selectors for Search Bar * Add tags on space and commas in EditMeta modal (#2766) * Fixed empty input in EditMeta modal ; tokens input
This commit is contained in:
parent
24fa2888ab
commit
487da9c9c6
@ -36,7 +36,7 @@ export default class EditMeta extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
meta: this.props.account.meta,
|
meta: Object.assign({}, this.props.account.meta),
|
||||||
metaErrors: {},
|
metaErrors: {},
|
||||||
name: this.props.account.name,
|
name: this.props.account.name,
|
||||||
nameError: null
|
nameError: null
|
||||||
@ -102,20 +102,55 @@ export default class EditMeta extends Component {
|
|||||||
renderTags () {
|
renderTags () {
|
||||||
const { meta } = this.state;
|
const { meta } = this.state;
|
||||||
const { tags } = meta || [];
|
const { tags } = meta || [];
|
||||||
const onChange = (chips) => this.onMetaChange('tags', chips);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChipInput
|
<ChipInput
|
||||||
defaultValue={ tags }
|
ref='tagsInput'
|
||||||
onChange={ onChange }
|
value={ tags }
|
||||||
|
onRequestAdd={ this.onAddTag }
|
||||||
|
onRequestDelete={ this.onDeleteTag }
|
||||||
floatingLabelText='(optional) tags'
|
floatingLabelText='(optional) tags'
|
||||||
hintText='press <Enter> to add a tag'
|
hintText='press <Enter> to add a tag'
|
||||||
|
onUpdateInput={ this.onTagsInputChange }
|
||||||
floatingLabelFixed
|
floatingLabelFixed
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAddTag = (tag) => {
|
||||||
|
const { meta } = this.state;
|
||||||
|
const { tags } = meta || [];
|
||||||
|
|
||||||
|
this.onMetaChange('tags', [].concat(tags, tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeleteTag = (tag) => {
|
||||||
|
const { meta } = this.state;
|
||||||
|
const { tags } = meta || [];
|
||||||
|
|
||||||
|
const newTags = tags
|
||||||
|
.filter(t => t !== tag);
|
||||||
|
|
||||||
|
this.onMetaChange('tags', newTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
onTagsInputChange = (value) => {
|
||||||
|
const { meta } = this.state;
|
||||||
|
const { tags } = meta || [];
|
||||||
|
|
||||||
|
const tokens = value.split(/[\s,;]+/);
|
||||||
|
|
||||||
|
const newTokens = tokens
|
||||||
|
.slice(0, -1)
|
||||||
|
.filter(t => t.length > 0);
|
||||||
|
|
||||||
|
const inputValue = tokens.slice(-1)[0].trim();
|
||||||
|
|
||||||
|
this.onMetaChange('tags', [].concat(tags, newTokens));
|
||||||
|
this.refs.tagsInput.setState({ inputValue });
|
||||||
|
}
|
||||||
|
|
||||||
onNameChange = (name) => {
|
onNameChange = (name) => {
|
||||||
this.setState(validateName(name));
|
this.setState(validateName(name));
|
||||||
}
|
}
|
||||||
|
@ -41,3 +41,11 @@
|
|||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chip > svg {
|
||||||
|
width: 1.2rem !important;
|
||||||
|
height: 1.2rem !important;
|
||||||
|
margin: initial !important;
|
||||||
|
margin-right: 4px !important;
|
||||||
|
padding: 4px 0 !important;
|
||||||
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import { Chip } from 'material-ui';
|
||||||
|
import { blue300 } from 'material-ui/styles/colors';
|
||||||
// import ChipInput from 'material-ui-chip-input';
|
// import ChipInput from 'material-ui-chip-input';
|
||||||
import ChipInput from 'material-ui-chip-input/src/ChipInput';
|
import ChipInput from 'material-ui-chip-input/src/ChipInput';
|
||||||
import ActionSearch from 'material-ui/svg-icons/action/search';
|
import ActionSearch from 'material-ui/svg-icons/action/search';
|
||||||
@ -43,6 +45,10 @@ export default class ActionbarSearch extends Component {
|
|||||||
if (tokens.length > 0 && this.props.tokens.length === 0) {
|
if (tokens.length > 0 && this.props.tokens.length === 0) {
|
||||||
this.handleOpenSearch(true, true);
|
this.handleOpenSearch(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tokens.length !== this.props.tokens.length) {
|
||||||
|
this.handleSearchChange(tokens);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
@ -71,16 +77,26 @@ export default class ActionbarSearch extends Component {
|
|||||||
<ChipInput
|
<ChipInput
|
||||||
clearOnBlur={ false }
|
clearOnBlur={ false }
|
||||||
className={ styles.input }
|
className={ styles.input }
|
||||||
|
chipRenderer={ this.chipRenderer }
|
||||||
hintText='Enter search input...'
|
hintText='Enter search input...'
|
||||||
hintStyle={ {
|
|
||||||
transition: 'none'
|
|
||||||
} }
|
|
||||||
ref='searchInput'
|
ref='searchInput'
|
||||||
value={ tokens }
|
value={ tokens }
|
||||||
onBlur={ this.handleSearchBlur }
|
onBlur={ this.handleSearchBlur }
|
||||||
onRequestAdd={ this.handleTokenAdd }
|
onRequestAdd={ this.handleTokenAdd }
|
||||||
onRequestDelete={ this.handleTokenDelete }
|
onRequestDelete={ this.handleTokenDelete }
|
||||||
onUpdateInput={ this.handleInputChange } />
|
onUpdateInput={ this.handleInputChange }
|
||||||
|
hintStyle={ {
|
||||||
|
bottom: 16,
|
||||||
|
left: 2,
|
||||||
|
transition: 'none'
|
||||||
|
} }
|
||||||
|
inputStyle={ {
|
||||||
|
marginBottom: 18
|
||||||
|
} }
|
||||||
|
textFieldStyle={ {
|
||||||
|
height: 42
|
||||||
|
} }
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -92,42 +108,83 @@ export default class ActionbarSearch extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chipRenderer = (state, key) => {
|
||||||
|
const { value, isFocused, isDisabled, handleClick, handleRequestDelete } = state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Chip
|
||||||
|
key={ key }
|
||||||
|
className={ styles.chip }
|
||||||
|
style={ {
|
||||||
|
margin: '8px 8px 0 0',
|
||||||
|
float: 'left',
|
||||||
|
pointerEvents: isDisabled ? 'none' : undefined,
|
||||||
|
alignItems: 'center'
|
||||||
|
} }
|
||||||
|
labelStyle={ {
|
||||||
|
paddingRight: 6,
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
lineHeight: 'initial'
|
||||||
|
} }
|
||||||
|
backgroundColor={ isFocused ? blue300 : 'rgba(0, 0, 0, 0.73)' }
|
||||||
|
onTouchTap={ handleClick }
|
||||||
|
onRequestDelete={ handleRequestDelete }
|
||||||
|
>
|
||||||
|
{ value }
|
||||||
|
</Chip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
handleTokenAdd = (value) => {
|
handleTokenAdd = (value) => {
|
||||||
const { tokens } = this.props;
|
const { tokens } = this.props;
|
||||||
|
|
||||||
const newSearchValues = uniq([].concat(tokens, value));
|
const newSearchTokens = uniq([].concat(tokens, value));
|
||||||
|
|
||||||
this.setState({
|
this.handleSearchChange(newSearchTokens);
|
||||||
inputValue: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
this.handleSearchChange(newSearchValues);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTokenDelete = (value) => {
|
handleTokenDelete = (value) => {
|
||||||
const { tokens } = this.props;
|
const { tokens } = this.props;
|
||||||
|
|
||||||
const newSearchValues = []
|
const newSearchTokens = []
|
||||||
.concat(tokens)
|
.concat(tokens)
|
||||||
.filter(v => v !== value);
|
.filter(v => v !== value);
|
||||||
|
|
||||||
this.setState({
|
this.handleSearchChange(newSearchTokens);
|
||||||
inputValue: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
this.handleSearchChange(newSearchValues);
|
|
||||||
this.refs.searchInput.focus();
|
this.refs.searchInput.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInputChange = (value) => {
|
handleInputChange = (value) => {
|
||||||
this.setState({ inputValue: value });
|
const splitTokens = value.split(/[\s,;]/);
|
||||||
|
|
||||||
|
const inputValue = (splitTokens.length <= 1)
|
||||||
|
? value
|
||||||
|
: splitTokens.slice(-1)[0].trim();
|
||||||
|
|
||||||
|
this.refs.searchInput.setState({ inputValue });
|
||||||
|
this.setState({ inputValue }, () => {
|
||||||
|
if (splitTokens.length > 1) {
|
||||||
|
const tokensToAdd = splitTokens.slice(0, -1);
|
||||||
|
tokensToAdd.forEach(token => this.handleTokenAdd(token));
|
||||||
|
} else {
|
||||||
|
this.handleSearchChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSearchChange = (searchValues) => {
|
handleSearchChange = (searchTokens) => {
|
||||||
const { onChange } = this.props;
|
const { onChange, tokens } = this.props;
|
||||||
const newSearchValues = searchValues.filter(v => v.length > 0);
|
const { inputValue } = this.state;
|
||||||
|
|
||||||
onChange(newSearchValues);
|
const newSearchTokens = []
|
||||||
|
.concat(searchTokens || tokens)
|
||||||
|
.filter(v => v.length > 0);
|
||||||
|
|
||||||
|
const newSearchValues = []
|
||||||
|
.concat(searchTokens || tokens, inputValue)
|
||||||
|
.filter(v => v.length > 0);
|
||||||
|
|
||||||
|
onChange(newSearchTokens, newSearchValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSearchClick = () => {
|
handleSearchClick = () => {
|
||||||
|
@ -41,7 +41,8 @@ class Accounts extends Component {
|
|||||||
addressBook: false,
|
addressBook: false,
|
||||||
newDialog: false,
|
newDialog: false,
|
||||||
sortOrder: '',
|
sortOrder: '',
|
||||||
searchValues: []
|
searchValues: [],
|
||||||
|
searchTokens: []
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -69,14 +70,14 @@ class Accounts extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderSearchButton () {
|
renderSearchButton () {
|
||||||
const onChange = (searchValues) => {
|
const onChange = (searchTokens, searchValues) => {
|
||||||
this.setState({ searchValues });
|
this.setState({ searchTokens, searchValues });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionbarSearch
|
<ActionbarSearch
|
||||||
key='searchAccount'
|
key='searchAccount'
|
||||||
tokens={ this.state.searchValues }
|
tokens={ this.state.searchTokens }
|
||||||
onChange={ onChange } />
|
onChange={ onChange } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -136,9 +137,9 @@ class Accounts extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAddSearchToken = (token) => {
|
onAddSearchToken = (token) => {
|
||||||
const { searchValues } = this.state;
|
const { searchTokens } = this.state;
|
||||||
const newSearchValues = uniq([].concat(searchValues, token));
|
const newSearchTokens = uniq([].concat(searchTokens, token));
|
||||||
this.setState({ searchValues: newSearchValues });
|
this.setState({ searchTokens: newSearchTokens });
|
||||||
}
|
}
|
||||||
|
|
||||||
onNewAccountClick = () => {
|
onNewAccountClick = () => {
|
||||||
|
@ -40,7 +40,8 @@ class Addresses extends Component {
|
|||||||
state = {
|
state = {
|
||||||
showAdd: false,
|
showAdd: false,
|
||||||
sortOrder: '',
|
sortOrder: '',
|
||||||
searchValues: []
|
searchValues: [],
|
||||||
|
searchTokens: []
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -79,14 +80,14 @@ class Addresses extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderSearchButton () {
|
renderSearchButton () {
|
||||||
const onChange = (searchValues) => {
|
const onChange = (searchTokens, searchValues) => {
|
||||||
this.setState({ searchValues });
|
this.setState({ searchTokens, searchValues });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionbarSearch
|
<ActionbarSearch
|
||||||
key='searchAddress'
|
key='searchAddress'
|
||||||
tokens={ this.state.searchValues }
|
tokens={ this.state.searchTokens }
|
||||||
onChange={ onChange } />
|
onChange={ onChange } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -127,9 +128,9 @@ class Addresses extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAddSearchToken = (token) => {
|
onAddSearchToken = (token) => {
|
||||||
const { searchValues } = this.state;
|
const { searchTokens } = this.state;
|
||||||
const newSearchValues = uniq([].concat(searchValues, token));
|
const newSearchTokens = uniq([].concat(searchTokens, token));
|
||||||
this.setState({ searchValues: newSearchValues });
|
this.setState({ searchTokens: newSearchTokens });
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenAdd = () => {
|
onOpenAdd = () => {
|
||||||
|
@ -43,7 +43,8 @@ class Contracts extends Component {
|
|||||||
addContract: false,
|
addContract: false,
|
||||||
deployContract: false,
|
deployContract: false,
|
||||||
sortOrder: '',
|
sortOrder: '',
|
||||||
searchValues: []
|
searchValues: [],
|
||||||
|
searchTokens: []
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -84,14 +85,14 @@ class Contracts extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderSearchButton () {
|
renderSearchButton () {
|
||||||
const onChange = (searchValues) => {
|
const onChange = (searchTokens, searchValues) => {
|
||||||
this.setState({ searchValues });
|
this.setState({ searchTokens, searchValues });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionbarSearch
|
<ActionbarSearch
|
||||||
key='searchContract'
|
key='searchContract'
|
||||||
tokens={ this.state.searchValues }
|
tokens={ this.state.searchTokens }
|
||||||
onChange={ onChange } />
|
onChange={ onChange } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -152,9 +153,9 @@ class Contracts extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAddSearchToken = (token) => {
|
onAddSearchToken = (token) => {
|
||||||
const { searchValues } = this.state;
|
const { searchTokens } = this.state;
|
||||||
const newSearchValues = uniq([].concat(searchValues, token));
|
const newSearchTokens = uniq([].concat(searchTokens, token));
|
||||||
this.setState({ searchValues: newSearchValues });
|
this.setState({ searchTokens: newSearchTokens });
|
||||||
}
|
}
|
||||||
|
|
||||||
onDeployContractClose = () => {
|
onDeployContractClose = () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user