mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-27 15:54:23 +02:00
Ivan - Add list users view with search [skip ci]
This commit is contained in:
parent
b0bb878e4b
commit
9c027c91c0
@ -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
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
client/src/app/admin/panel/users/admin-panel-list-users.scss
Normal file
24
client/src/app/admin/panel/users/admin-panel-list-users.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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.',
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user