Ivan - Add list users view with search [skip ci]

This commit is contained in:
ivan 2016-11-28 15:37:27 -03:00
parent b0bb878e4b
commit 9c027c91c0
7 changed files with 232 additions and 20 deletions

View File

@ -1,15 +1,37 @@
import React from 'react'; import React from 'react';
import i18n from 'lib-app/i18n'; import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call';
import DateTransformer from 'lib-core/date-transformer';
import Header from 'core-components/header'; import Header from 'core-components/header';
import Table from 'core-components/table'; import Table from 'core-components/table';
import SearchBox from 'core-components/search-box';
import Button from 'core-components/button';
class AdminPanelListUsers extends React.Component { class AdminPanelListUsers extends React.Component {
state = {
loading: true,
users: [],
page: 1,
pages: 1
};
componentDidMount() {
this.retrieveUsers({
page: 1,
orderBy: 'id',
desc: true,
search: ''
});
}
render() { render() {
return ( return (
<div> <div className="admin-panel-list-users">
<Header title={i18n('LIST_USERS')} description={i18n('LIST_USERS_DESCRIPTION')} /> <Header title={i18n('LIST_USERS')} description={i18n('LIST_USERS_DESCRIPTION')} />
<SearchBox className="admin-panel-list-users__search-box" placeholder={i18n('SEARCH_USERS')} onSearch={this.onSearch.bind(this)} />
<Table {...this.getTableProps()} /> <Table {...this.getTableProps()} />
</div> </div>
); );
@ -17,13 +39,14 @@ class AdminPanelListUsers extends React.Component {
getTableProps() { getTableProps() {
return { return {
loading: this.props.loading, className: 'admin-panel-list-users__table',
loading: this.state.loading,
headers: this.getTableHeaders(), headers: this.getTableHeaders(),
rows: this.getTableRows(), rows: this.state.users.map(this.getUserRow.bind(this)),
pageSize: 10, pageSize: 10,
page: this.props.page, page: this.state.page,
pages: this.props.pages, pages: this.state.pages,
onPageChange: this.props.onPageChange onPageChange: this.onPageChange.bind(this)
}; };
} }
@ -32,30 +55,81 @@ class AdminPanelListUsers extends React.Component {
{ {
key: 'name', key: 'name',
value: i18n('NAME'), value: i18n('NAME'),
className: 'ticket-list__number col-md-3' className: 'admin-panel-list-users__table-name col-md-3'
}, },
{ {
key: 'email', key: 'email',
value: i18n('EMAIL'), value: i18n('EMAIL'),
className: 'col-md-5' className: 'admin-panel-list-users__table-email col-md-5'
}, },
{ {
key: 'tickets', key: 'tickets',
value: i18n('TICKETS'), value: i18n('TICKETS'),
className: 'col-md-2' className: 'admin-panel-list-users__table-tickets col-md-2'
}, },
{ {
key: 'date', key: 'signupDate',
value: i18n('SIGNUP_DATE'), value: i18n('SIGNUP_DATE'),
className: 'col-md-2' className: 'admin-panel-list-users__table-date col-md-2'
} }
]; ];
} }
getTableRows() { getUserRow(user) {
return [ return {
name: (
]; <Button className="admin-panel-list-users__name-link" type="link" route={{to: '/admin/panel/users/view-user/' + user.id}}>
{user.name}
</Button>
),
email: user.email,
tickets: (
<span className="admin-panel-list-users__tickets-number">
{user.tickets}
</span>
),
signupDate: DateTransformer.transformToString(user.signupDate)
};
}
onSearch(query) {
this.retrieveUsers({
page: 1,
orderBy: 'id',
desc: true,
search: query
});
}
onPageChange(event) {
this.retrieveUsers({
page: event.target.value,
orderBy: this.state.orderBy,
desc: this.state.desc,
search: this.state.search
});
}
retrieveUsers(data) {
this.setState({
loading: true
});
API.call({
path: '/user/get-users',
data: data
}).then(this.onUsersRetrieved.bind(this));
}
onUsersRetrieved(result) {
this.setState({
page: result.data.page,
pages: result.data.pages,
users: result.data.users,
orderBy: result.data.orderBy,
desc: result.data.desc,
loading: false
});
} }
} }

View File

@ -0,0 +1,24 @@
@import '../../../../scss/vars';
.admin-panel-list-users {
&__search-box {
margin: 20px;
}
&__table {
text-align: left;
}
&__name-link {
color: $secondary-blue;
}
&__tickets-number {
background-color: white;
border-radius: 10px;
width: 70px;
display: inline-block;
text-align: center;
}
}

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames';
import Input from 'core-components/input'; import Input from 'core-components/input';
import Icon from 'core-components/icon'; import Icon from 'core-components/icon';
@ -7,7 +8,8 @@ import keyCode from 'keycode';
class SearchBox extends React.Component { class SearchBox extends React.Component {
static propTypes = { static propTypes = {
onSearch: React.PropTypes.func onSearch: React.PropTypes.func,
placeholder: React.PropTypes.string
}; };
state = { state = {
@ -16,8 +18,8 @@ class SearchBox extends React.Component {
render() { render() {
return ( return (
<div className="search-box"> <div className={this.getClass()}>
<Input className="search-box__text" value={this.state.value} onChange={this.onChange.bind(this)} onKeyDown={this.onKeyDown.bind(this)} /> <Input className="search-box__text" value={this.state.value} placeholder={this.props.placeholder} onChange={this.onChange.bind(this)} onKeyDown={this.onKeyDown.bind(this)} />
<span className="search-box__icon"> <span className="search-box__icon">
<Icon name="search" /> <Icon name="search" />
</span> </span>
@ -25,6 +27,16 @@ class SearchBox extends React.Component {
); );
} }
getClass() {
let classes = {
'search-box': true
};
classes[this.props.className] = (this.props.className);
return classNames(classes);
}
onChange(event) { onChange(event) {
this.setState({ this.setState({
value: event.target.value value: event.target.value

View File

@ -32,7 +32,7 @@ class Table extends React.Component {
render() { render() {
return ( return (
<div className="table__wrapper"> <div className={this.getClass()}>
<table className="table table-responsive"> <table className="table table-responsive">
<thead> <thead>
<tr className="table__header"> <tr className="table__header">
@ -92,7 +92,7 @@ class Table extends React.Component {
const items = _.range(1, this.getPages()).map((index) => {return {content: index};}); const items = _.range(1, this.getPages()).map((index) => {return {content: index};});
return ( return (
<Menu className="table__navigation" type="navigation" items={items} selectedIndex={this.getPageNumber() - 1} onItemClick={this.onNavigationItemClick.bind(this)} /> <Menu className="table__navigation" type="navigation" items={items} selectedIndex={this.getPageNumber() - 1} onItemClick={this.onNavigationItemClick.bind(this)} tabbable/>
); );
} }
@ -104,6 +104,16 @@ class Table extends React.Component {
) )
} }
getClass() {
let classes = {
'table__wrapper': true
};
classes[this.props.className] = (this.props.className);
return classNames(classes);
}
onNavigationItemClick(index) { onNavigationItemClick(index) {
this.setState({ this.setState({
page: index + 1 page: index + 1

View File

@ -124,6 +124,94 @@ module.exports = [
}; };
} }
}, },
{
path: '/user/get-users',
time: 100,
response: function (data) {
return {
status: 'success',
data: {
page: data.page,
pages: 10,
orderBy: 'date',
desc: true,
search: '',
users: [
{
id: 101,
name: 'Haskell Curry',
email: 'haskell@currycurrylady.com',
tickets: 5,
signupDate: 20160415
},
{
id: 97,
name: 'Alan Turing',
email: 'turing@currycurrylady.com',
tickets: 1,
signupDate: 20160401
},
{
id: 89,
name: 'David Hilbert',
email: 'hilbert@currycurrylady.com',
tickets: 2,
signupDate: 20160208
},
{
id: 83,
name: 'Kurt Gödel',
email: 'kurt@currycurrylady.com',
tickets: 10,
signupDate: 20160110
},
{
id: 79,
name: 'Mojzesz Presburger',
email: 'presburger@currycurrylady.com',
tickets: 6,
signupDate: 20150415
},
{
id: 73,
name: 'Haskell Curry',
email: 'haskell@currycurrylady.com',
tickets: 5,
signupDate: 20160415
},
{
id: 71,
name: 'Alan Turing',
email: 'turing@currycurrylady.com',
tickets: 1,
signupDate: 20160401
},
{
id: 67,
name: 'David Hilbert',
email: 'hilbert@currycurrylady.com',
tickets: 2,
signupDate: 20160208
},
{
id: 61,
name: 'Kurt Gödel',
email: 'kurt@currycurrylady.com',
tickets: 10,
signupDate: 20160110
},
{
id: 59,
name: 'Mojzesz Presburger',
email: 'presburger@currycurrylady.com',
tickets: 6,
signupDate: 20150415
}
]
}
};
}
},
{ {
path: '/user/get', path: '/user/get',
time: 100, time: 100,

View File

@ -75,6 +75,9 @@ export default {
'WARNING': 'Warning', 'WARNING': 'Warning',
'INFO': 'Information', 'INFO': 'Information',
'ALL_DEPARTMENTS': 'All Departments', 'ALL_DEPARTMENTS': 'All Departments',
'NAME': 'Name',
'SIGNUP_DATE': 'Sign up date',
'SEARCH_USERS': 'Search users...',
//VIEW DESCRIPTIONS //VIEW DESCRIPTIONS
'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.',

View File

@ -2,6 +2,7 @@ let month = ["", "Jan", "Feb", "Mar", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
export default { export default {
transformToString (date) { transformToString (date) {
date += ''; //Transform to string
let y = date.substring(0, 4); let y = date.substring(0, 4);
let m = date.substring(4, 6); let m = date.substring(4, 6);
let d = date.substring(6, 8); let d = date.substring(6, 8);