diff --git a/client/src/app-components/article-add-modal.js b/client/src/app-components/article-add-modal.js index 613abbc7..e0e34d86 100644 --- a/client/src/app-components/article-add-modal.js +++ b/client/src/app-components/article-add-modal.js @@ -19,13 +19,13 @@ class ArticleAddModal extends React.Component { render() { return ( -
+
{i18n('ADD_ARTICLE')} - diff --git a/client/src/app-components/article-add-modal.scss b/client/src/app-components/article-add-modal.scss index 50ba5b88..3634480e 100644 --- a/client/src/app-components/article-add-modal.scss +++ b/client/src/app-components/article-add-modal.scss @@ -1,4 +1,5 @@ -.article-add-article { +.article-add-modal { + width: 800px; &__cancel-button { float: right; diff --git a/client/src/app-components/articles-list.js b/client/src/app-components/articles-list.js index ed77d30c..586babc3 100644 --- a/client/src/app-components/articles-list.js +++ b/client/src/app-components/articles-list.js @@ -11,6 +11,7 @@ import TopicEditModal from 'app-components/topic-edit-modal'; import Loading from 'core-components/loading'; import Button from 'core-components/button'; import Icon from 'core-components/icon'; +import Message from 'core-components/message'; class ArticlesList extends React.Component { @@ -18,6 +19,7 @@ class ArticlesList extends React.Component { editable: React.PropTypes.bool, articlePath: React.PropTypes.string, loading: React.PropTypes.bool, + errored: React.PropTypes.bool, topics: React.PropTypes.array, retrieveOnMount: React.PropTypes.bool }; @@ -34,6 +36,10 @@ class ArticlesList extends React.Component { } render() { + if(this.props.errored) { + return {i18n('ERROR_RETRIEVING_ARTICLES')}; + } + return (this.props.loading) ? : this.renderContent(); } @@ -84,6 +90,7 @@ class ArticlesList extends React.Component { export default connect((store) => { return { topics: store.articles.topics, + errored: store.articles.errored, loading: store.articles.loading }; })(ArticlesList); diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js index 70a37feb..6a636bd3 100644 --- a/client/src/app-components/people-list.js +++ b/client/src/app-components/people-list.js @@ -10,7 +10,7 @@ class PeopleList extends React.Component { static propTypes = { list: React.PropTypes.arrayOf(React.PropTypes.shape({ profilePic: React.PropTypes.string, - name: React.PropTypes.string, + name: React.PropTypes.node, assignedTickets: React.PropTypes.number, closedTickets: React.PropTypes.number, lastLogin: React.PropTypes.number diff --git a/client/src/app-components/ticket-event.scss b/client/src/app-components/ticket-event.scss index 5e36aaa0..50105bbe 100644 --- a/client/src/app-components/ticket-event.scss +++ b/client/src/app-components/ticket-event.scss @@ -47,6 +47,7 @@ &__comment { position: relative; + word-break: break-all; &-pointer { right: 100%; diff --git a/client/src/app-components/ticket-info.js b/client/src/app-components/ticket-info.js index 788bd423..0feaa64b 100644 --- a/client/src/app-components/ticket-info.js +++ b/client/src/app-components/ticket-info.js @@ -1,4 +1,6 @@ import React from 'react'; +import _ from 'lodash'; + import i18n from 'lib-app/i18n'; class TicketInfo extends React.Component { @@ -16,12 +18,12 @@ class TicketInfo extends React.Component { {this.props.ticket.content}
- Author: {this.props.ticket.author.name} + {i18n('AUTHOR')}: {this.props.ticket.author.name}
- Status: + {i18n('STATUS')}: {(this.props.ticket.closed) ? 'closed' : 'open'} @@ -29,7 +31,7 @@ class TicketInfo extends React.Component {
- Priority: + {i18n('PRIORITY')}: {this.props.ticket.priority} @@ -37,24 +39,25 @@ class TicketInfo extends React.Component {
- Owned: + {i18n('OWNED')}: - - none + + {(this.props.ticket.owner) ? i18n('YES') : i18n('NO')}
- Comments: + {i18n('COMMENTS')}: - 21 + {_.filter(this.props.ticket.events, event => event.type === 'COMMENT').length}
); } + getStatusClass() { if(this.props.ticket.closed) { return 'ticket-info__properties__badge-red'; @@ -63,6 +66,14 @@ class TicketInfo extends React.Component { } } + getOwnedClass() { + if(this.props.ticket.owner) { + return 'ticket-info__properties__badge-green'; + } else { + return 'ticket-info__properties__badge-red'; + } + } + getPriorityClass() { let priorityClasses = { 'low': 'ticket-info__properties__badge-green', diff --git a/client/src/app-components/ticket-info.scss b/client/src/app-components/ticket-info.scss index fde38901..13ccaf62 100644 --- a/client/src/app-components/ticket-info.scss +++ b/client/src/app-components/ticket-info.scss @@ -3,19 +3,28 @@ .ticket-info { width: 300px; font-weight: normal; - &__title{ + + &__title { color: $primary-black; - font-variant: small-caps; + font-size: $font-size--md; } - &__description{ - color: $grey; + + &__description { + margin-top: 5px; font-size: small; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; } - &__author{ + + &__author { color: $primary-blue; - margin-bottom: 12px; + font-weight: bold; + margin-top: 10px; + margin-bottom: 5px; } - &__properties{ + + &__properties { background-color: $grey; padding: 10px; font-variant: small-caps; @@ -35,7 +44,7 @@ &__badge-green, &__badge-blue, - &__badge-red{ + &__badge-red { color: white; border-radius: 7px; display: inline-block; @@ -44,19 +53,19 @@ margin-left: 5px; } - &__badge-green{ + &__badge-green { background-color: $primary-green; } - &__badge-blue{ + &__badge-blue { background-color: $secondary-blue; } - &__badge-red{ + &__badge-red { background-color: $primary-red; } - &__label{ + &__label { text-align: right; width: 71px; display: inline-block; @@ -64,10 +73,11 @@ } &__status, - &__owner{ + &__owner { margin-right: 10px; width: 125px; - .ticket-info__properties__label{ + + .ticket-info__properties__label { width: 48px; } } diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index bce229eb..262a7b9a 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -14,6 +14,7 @@ import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; import DropDown from 'core-components/drop-down'; import Button from 'core-components/button'; +import Message from 'core-components/message'; class TicketViewer extends React.Component { static propTypes = { @@ -188,6 +189,7 @@ class TicketViewer extends React.Component { {i18n('RESPOND_TICKET')} + {(this.state.commentError) ? this.renderCommentError() : null} ); } @@ -216,6 +218,12 @@ class TicketViewer extends React.Component { return customResponsesNode; } + renderCommentError() { + return ( + {i18n('TICKET_COMMENT_ERROR')} + ); + } + getCommentFormProps() { return { onSubmit: this.onSubmit.bind(this), @@ -316,7 +324,8 @@ class TicketViewer extends React.Component { onCommentSuccess() { this.setState({ - loading: false + loading: false, + commentError: false }); this.onTicketModification(); @@ -324,7 +333,8 @@ class TicketViewer extends React.Component { onCommentFail() { this.setState({ - loading: false + loading: false, + commentError: true }); } diff --git a/client/src/app-components/topic-viewer.js b/client/src/app-components/topic-viewer.js index fc923ea5..2009da8c 100644 --- a/client/src/app-components/topic-viewer.js +++ b/client/src/app-components/topic-viewer.js @@ -1,4 +1,5 @@ import React from 'react'; +import ReactDOM from 'react-dom'; import _ from 'lodash'; import classNames from 'classnames'; import {Link} from 'react-router'; @@ -78,11 +79,33 @@ class TopicViewer extends React.Component { } renderArticleItem(article, index) { + let props = { + className: 'topic-viewer__list-item', + key: index, + draggable: true + }; + + if(this.props.editable) { + _.extend(props, { + onDragOver: (this.state.currentDraggedId) ? this.onItemDragOver.bind(this, article, index) : null, + onDrop: (this.state.currentDraggedId) ? this.onItemDrop.bind(this, article, index) : null, + onDragStart: () => { + this.setState({currentDraggedId: article.id}) + }, + onDragEnd: () => { + if(this.state.currentDraggedId) { + this.setState({articles: this.props.articles, currentDraggedId: 0}); + } + } + }); + } + return ( -
  • +
  • {article.title} +
  • ); } @@ -126,31 +149,16 @@ class TopicViewer extends React.Component { ); } - getArticleLinkProps(article, index) { + getArticleLinkProps(article) { let classes = { 'topic-viewer__list-item-button': true, 'topic-viewer__list-item-hidden': article.hidden }; - - let props = { + + return { className: classNames(classes), to: this.props.articlePath + article.id }; - - if(this.props.editable) { - _.extend(props, { - onDragOver: this.onItemDragOver.bind(this, article, index), - onDrop: this.onItemDrop.bind(this, article, index), - onDragStart: () => this.setState({currentDraggedId: article.id}), - onDragEnd: () => { - if(this.state.currentDraggedId) { - this.setState({articles: this.props.articles}); - } - } - }); - } - - return props; } onDeleteClick() { diff --git a/client/src/app-components/topic-viewer.scss b/client/src/app-components/topic-viewer.scss index 0f489be2..f674fd88 100644 --- a/client/src/app-components/topic-viewer.scss +++ b/client/src/app-components/topic-viewer.scss @@ -38,12 +38,22 @@ width: 50%; color: $secondary-blue; margin-bottom: 10px; + user-select: none; &-hidden { - width: 80%; - display: inline-block; opacity: 0; } + + &:hover { + .topic-viewer__grab-icon { + display: inline-block; + left: 0; + } + } + + &-button { + user-select: none; + } } &-item:before { @@ -52,10 +62,18 @@ } &-item-button { + display: inline-block; color: $secondary-blue; } } + &__grab-icon { + color: $grey; + cursor: move; + margin-left: 10px; + display: none; + } + &__add-item { color: $dark-grey; } diff --git a/client/src/app/admin/panel/articles/admin-panel-view-article.js b/client/src/app/admin/panel/articles/admin-panel-view-article.js index 13c0af00..13ec35c2 100644 --- a/client/src/app/admin/panel/articles/admin-panel-view-article.js +++ b/client/src/app/admin/panel/articles/admin-panel-view-article.js @@ -1,6 +1,7 @@ import React from 'react'; import _ from 'lodash'; import {connect} from 'react-redux'; +import {browserHistory} from 'react-router'; import RichTextEditor from 'react-rte-browserify'; import ArticlesActions from 'actions/articles-actions'; @@ -9,6 +10,7 @@ import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; import DateTransformer from 'lib-core/date-transformer'; +import AreYouSure from 'app-components/are-you-sure'; import Header from 'core-components/header'; import Loading from 'core-components/loading'; import Button from 'core-components/button'; @@ -61,10 +63,14 @@ class AdminPanelViewArticle extends React.Component { renderArticlePreview(article) { return (
    -
    - +
    + +
    -
    @@ -116,6 +122,10 @@ class AdminPanelViewArticle extends React.Component { }); } + onDeleteClick(article) { + AreYouSure.openModal(i18n('DELETE_ARTICLE_DESCRIPTION'), this.onArticleDeleted.bind(this, article)); + } + onFormSubmit(form) { API.call({ path: '/article/edit', @@ -139,6 +149,15 @@ class AdminPanelViewArticle extends React.Component { editable: false }); } + + onArticleDeleted(article) { + API.call({ + path: '/article/delete', + data: { + articleId: article.id + } + }).then(() => browserHistory.push('/admin/panel/articles/list-articles')); + } } export default connect((store) => { diff --git a/client/src/app/admin/panel/articles/admin-panel-view-article.scss b/client/src/app/admin/panel/articles/admin-panel-view-article.scss index 300041c9..431fe9a4 100644 --- a/client/src/app/admin/panel/articles/admin-panel-view-article.scss +++ b/client/src/app/admin/panel/articles/admin-panel-view-article.scss @@ -1,10 +1,14 @@ .admin-panel-view-article { - &__edit-button { + &__edit-buttons { text-align: left; margin-bottom: 20px; } + &__edit-button { + margin-right: 20px; + } + &__last-edited { font-style: italic; text-align: right; diff --git a/client/src/app/admin/panel/staff/admin-panel-view-staff.js b/client/src/app/admin/panel/staff/admin-panel-view-staff.js index a1d5d933..3e5a0970 100644 --- a/client/src/app/admin/panel/staff/admin-panel-view-staff.js +++ b/client/src/app/admin/panel/staff/admin-panel-view-staff.js @@ -1,5 +1,5 @@ import React from 'react'; -import {connect} from 'react-redux'; +import {browserHistory} from 'react-router'; import _ from 'lodash'; import i18n from 'lib-app/i18n'; @@ -36,7 +36,8 @@ class AdminPanelViewStaff extends React.Component { getProps() { return _.extend({}, this.state.userData, { - staffId: this.props.params.staffId * 1 + staffId: this.props.params.staffId * 1, + onDelete: this.onDelete.bind(this) }); } @@ -46,6 +47,10 @@ class AdminPanelViewStaff extends React.Component { userData: result.data }); } + + onDelete() { + browserHistory.push('/admin/panel/staff/staff-members'); + } } export default AdminPanelViewStaff; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/staff-editor.js b/client/src/app/admin/panel/staff/staff-editor.js index 4a8905a7..e5513e41 100644 --- a/client/src/app/admin/panel/staff/staff-editor.js +++ b/client/src/app/admin/panel/staff/staff-editor.js @@ -5,10 +5,13 @@ import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; import SessionStore from 'lib-app/session-store'; import TicketList from 'app-components/ticket-list'; +import AreYouSure from 'app-components/are-you-sure'; import Form from 'core-components/form'; import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; +import Message from 'core-components/message'; +import Button from 'core-components/button'; class StaffEditor extends React.Component { static propTypes = { @@ -20,18 +23,21 @@ class StaffEditor extends React.Component { level: React.PropTypes.number.isRequired, tickets: React.PropTypes.array.isRequired, departments: React.PropTypes.array.isRequired, - onChange: React.PropTypes.func + onChange: React.PropTypes.func, + onDelete: React.PropTypes.func }; state = { email: this.props.email, level: this.props.level - 1, + message: null, departments: this.getUserDepartments() }; render() { return (
    + {(this.state.message) ? this.renderMessage() : null}
    @@ -67,12 +73,12 @@ class StaffEditor extends React.Component {
    -
    this.setState({email: form.email})} onSubmit={this.onSubmit.bind(this)}> + this.setState({email: form.email})} onSubmit={this.onSubmit.bind(this, 'EMAIL')}> {i18n('UPDATE_EMAIL')} -
    + {i18n('UPDATE_PASSWORD')} @@ -96,15 +102,41 @@ class StaffEditor extends React.Component {
    {(this.props.tickets) ? this.renderTickets() : null} + {(!this.props.myAccount) ? this.renderDelete() : null}
    ); } + renderMessage() { + let messageType = (this.state.message === 'FAIL') ? 'error' : 'success'; + let message = null; + + switch (this.state.message) { + case 'EMAIL': + message = 'EMAIL_CHANGED'; + break; + case 'PASSWORD': + message = 'PASSWORD_CHANGED'; + break; + case 'LEVEL': + message = 'LEVEL_UPDATED'; + break; + case 'DEPARTMENTS': + message = 'DEPARTMENTS_UPDATED'; + break; + case 'FAIL': + message = 'FAILED_EDIT_STAFF'; + break; + } + + return {i18n(message)}; + } + renderLevelForm() { return (
    - this.setState({level: form.level})} onSubmit={this.onSubmit.bind(this)}> + this.setState({level: form.level})} onSubmit={this.onSubmit.bind(this, 'LEVEL')}> this.setState({departments: form.departments})} onSubmit={this.onSubmit.bind(this)}> + this.setState({departments: form.departments})} onSubmit={this.onSubmit.bind(this, 'DEPARTMENTS')}> {i18n('UPDATE_DEPARTMENTS')} @@ -144,6 +176,22 @@ class StaffEditor extends React.Component {
    ); } + + renderDelete() { + return ( +
    + +
    +
    + {i18n('DELETE_STAFF_MEMBER')} +
    + +
    +
    + ); + } getTicketListProps() { return { @@ -171,7 +219,7 @@ class StaffEditor extends React.Component { return SessionStore.getDepartments().map(department => department.name); } - onSubmit(form) { + onSubmit(eventType, form) { let departments; if(form.departments) { @@ -189,7 +237,29 @@ class StaffEditor extends React.Component { level: (form.level !== undefined) ? form.level + 1 : null, departments: departments && JSON.stringify(departments) } - }).then(this.props.onChange); + }).then(() => { + window.scrollTo(0,0); + this.setState({message: eventType}); + + if(this.props.onChange) { + this.props.onChange(); + } + }).catch(() => { + window.scrollTo(0,0); + this.setState({message: 'FAIL'}); + }); + } + + onDeleteClick() { + API.call({ + path: '/staff/delete', + data: { + staffId: this.props.staffId + } + }).then(this.props.onDelete).catch(() => { + window.scrollTo(0,0); + this.setState({message: 'FAIL'}); + }); } } diff --git a/client/src/app/admin/panel/staff/staff-editor.scss b/client/src/app/admin/panel/staff/staff-editor.scss index 43883a9d..aaf998d5 100644 --- a/client/src/app/admin/panel/staff/staff-editor.scss +++ b/client/src/app/admin/panel/staff/staff-editor.scss @@ -122,4 +122,21 @@ &__separator { margin: 3px 0; } + + &__message { + margin-bottom: 20px; + } + + &__delete { + border: 1px solid $grey; + padding: 20px 50px; + text-align: right; + } + + &__delete-title { + font-size: $font-size--md; + text-align: center; + float: left; + margin-top: 11px; + } } \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js index b721f35f..1f7f6cc2 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js @@ -4,9 +4,11 @@ import {connect} from 'react-redux'; import i18n from 'lib-app/i18n'; import AdminDataAction from 'actions/admin-data-actions'; -import Header from 'core-components/header'; import TicketList from 'app-components/ticket-list'; + +import Header from 'core-components/header'; import SearchBox from 'core-components/search-box'; +import Message from 'core-components/message'; class AdminPanelAllTickets extends React.Component { @@ -31,7 +33,7 @@ class AdminPanelAllTickets extends React.Component {
    - + {(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : }
    ); } @@ -52,7 +54,8 @@ class AdminPanelAllTickets extends React.Component { onSearch(query) { this.setState({query, page: 1}); - if (query) { + + if(query) { this.props.dispatch(AdminDataAction.searchTickets(query)); } else { this.props.dispatch(AdminDataAction.retrieveAllTickets()); @@ -60,9 +63,7 @@ class AdminPanelAllTickets extends React.Component { } onPageChange(event) { - this.setState({ - page: event.target.value - }); + this.setState({page: event.target.value}); if(this.state.query) { this.props.dispatch(AdminDataAction.searchTickets(this.state.query, event.target.value)); @@ -77,6 +78,7 @@ export default connect((store) => { departments: store.session.userDepartments, tickets: store.adminData.allTickets, pages: store.adminData.allTicketsPages, - loading: !store.adminData.allTicketsLoaded + loading: !store.adminData.allTicketsLoaded, + error: store.adminData.allTicketsError }; })(AdminPanelAllTickets); diff --git a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js index 512454b1..e90847ec 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js @@ -4,9 +4,11 @@ import {connect} from 'react-redux'; import i18n from 'lib-app/i18n'; import AdminDataAction from 'actions/admin-data-actions'; -import Header from 'core-components/header'; import TicketList from 'app-components/ticket-list'; +import Header from 'core-components/header'; +import Message from 'core-components/message'; + class AdminPanelMyTickets extends React.Component { static defaultProps = { @@ -22,7 +24,7 @@ class AdminPanelMyTickets extends React.Component { return (
    - + {(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : }
    ); } @@ -42,6 +44,7 @@ export default connect((store) => { return { departments: store.session.userDepartments, tickets: store.adminData.myTickets, - loading: !store.adminData.myTicketsLoaded + loading: !store.adminData.myTicketsLoaded, + error: store.adminData.myTicketsError }; })(AdminPanelMyTickets); diff --git a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js index 819e9b56..bb3240cb 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js @@ -4,9 +4,11 @@ import {connect} from 'react-redux'; import i18n from 'lib-app/i18n'; import AdminDataAction from 'actions/admin-data-actions'; -import Header from 'core-components/header'; import TicketList from 'app-components/ticket-list'; +import Header from 'core-components/header'; +import Message from 'core-components/message'; + class AdminPanelNewTickets extends React.Component { static defaultProps = { @@ -22,7 +24,7 @@ class AdminPanelNewTickets extends React.Component { return (
    - + {(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : }
    ); } @@ -42,6 +44,7 @@ export default connect((store) => { return { departments: store.session.userDepartments, tickets: store.adminData.newTickets, - loading: !store.adminData.newTicketsLoaded + loading: !store.adminData.newTicketsLoaded, + error: store.adminData.newTicketsError }; })(AdminPanelNewTickets); diff --git a/client/src/app/admin/panel/users/admin-panel-ban-users.js b/client/src/app/admin/panel/users/admin-panel-ban-users.js index aac27f29..b4b215bc 100644 --- a/client/src/app/admin/panel/users/admin-panel-ban-users.js +++ b/client/src/app/admin/panel/users/admin-panel-ban-users.js @@ -11,24 +11,35 @@ import Button from 'core-components/button'; import SubmitButton from 'core-components/submit-button'; import Form from 'core-components/form'; import FormField from 'core-components/form-field'; +import Message from 'core-components/message'; class AdminPanelBanUsers extends React.Component { state = { loadingList: true, loadingForm: false, + listError: false, + addBanStatus: 'none', emails: [], filteredEmails: [] }; componentDidMount() { - this.retrieveEmails() + this.retrieveEmails(); } render() { return (
    + {(this.state.listError) ? {i18n('ERROR_RETRIEVING_BAN_LIST')} : this.renderContent()} +
    + ); + } + + renderContent() { + return ( +
    @@ -41,11 +52,23 @@ class AdminPanelBanUsers extends React.Component { {i18n('BAN_EMAIL')} + {this.renderMessage()} ); } + renderMessage() { + switch (this.state.addBanStatus) { + case 'success': + return {i18n('EMAIL_BANNED_SUCCESSFULLY')}; + case 'fail': + return {i18n('ERROR_BANNING_EMAIL')}; + default: + return null; + } + } + getTableProps() { return { loading: this.state.loadingList, @@ -94,7 +117,12 @@ class AdminPanelBanUsers extends React.Component { data: { email: form.email } - }).then(this.retrieveEmails.bind(this)); + }).then(() => { + this.setState({ + addBanStatus: 'success' + }); + this.retrieveEmails(); + }).catch(() => this.setState({addBanStatus: 'fail', loadingForm: false})); } onUnBanClick(email) { @@ -114,14 +142,17 @@ class AdminPanelBanUsers extends React.Component { API.call({ path: '/user/list-ban', data: {} - }).then((result) => { - this.setState({ - loadingList: false, - loadingForm: false, - emails: result.data, - filteredEmails: result.data - }); - }); + }).then(result => this.setState({ + listError: false, + loadingList: false, + loadingForm: false, + emails: result.data, + filteredEmails: result.data + })).catch(() => this.setState({ + listError: true, + loadingList: false, + loadingForm: false + })); } } diff --git a/client/src/app/admin/panel/users/admin-panel-ban-users.scss b/client/src/app/admin/panel/users/admin-panel-ban-users.scss index 799e21fe..379b437c 100644 --- a/client/src/app/admin/panel/users/admin-panel-ban-users.scss +++ b/client/src/app/admin/panel/users/admin-panel-ban-users.scss @@ -3,10 +3,6 @@ .admin-panel-ban-users { padding: 0 20px; - &__email-list { - - } - &__search { margin-bottom: 20px; } @@ -33,4 +29,8 @@ &__input { display: inline-block; } + + &__form-message { + margin-top: 20px; + } } \ No newline at end of file diff --git a/client/src/app/admin/panel/users/admin-panel-list-users.js b/client/src/app/admin/panel/users/admin-panel-list-users.js index 2b23c374..0b2896ec 100644 --- a/client/src/app/admin/panel/users/admin-panel-list-users.js +++ b/client/src/app/admin/panel/users/admin-panel-list-users.js @@ -8,6 +8,7 @@ import Header from 'core-components/header'; import Table from 'core-components/table'; import SearchBox from 'core-components/search-box'; import Button from 'core-components/button'; +import Message from 'core-components/message'; class AdminPanelListUsers extends React.Component { @@ -16,6 +17,7 @@ class AdminPanelListUsers extends React.Component { users: [], orderBy: 'id', desc: true, + error: false, page: 1, pages: 1 }; @@ -34,7 +36,7 @@ class AdminPanelListUsers extends React.Component {
    -
    + {(this.state.error) ? {i18n('ERROR_RETRIEVING_USERS')} :
    } ); } @@ -144,7 +146,7 @@ class AdminPanelListUsers extends React.Component { API.call({ path: '/user/get-users', data: data - }).then(this.onUsersRetrieved.bind(this)); + }).then(this.onUsersRetrieved.bind(this)).catch(this.onUsersRejected.bind(this)); } onUsersRetrieved(result) { @@ -154,6 +156,14 @@ class AdminPanelListUsers extends React.Component { users: result.data.users, orderBy: result.data.orderBy, desc: (result.data.desc === '1'), + error: false, + loading: false + }); + } + + onUsersRejected() { + this.setState({ + error: true, loading: false }); } diff --git a/client/src/app/admin/panel/users/admin-panel-view-user.js b/client/src/app/admin/panel/users/admin-panel-view-user.js index 3b56f132..b18060a2 100644 --- a/client/src/app/admin/panel/users/admin-panel-view-user.js +++ b/client/src/app/admin/panel/users/admin-panel-view-user.js @@ -5,11 +5,13 @@ import {browserHistory} from 'react-router'; import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; -import Header from 'core-components/header'; -import Button from 'core-components/button'; import TicketList from 'app-components/ticket-list'; import AreYouSure from 'app-components/are-you-sure'; +import Header from 'core-components/header'; +import Button from 'core-components/button'; +import Message from 'core-components/message'; + class AdminPanelViewUser extends React.Component { state = { @@ -43,7 +45,7 @@ class AdminPanelViewUser extends React.Component { renderInvalid() { return (
    - {i18n('INVALID_USER')} + {i18n('INVALID_USER')}
    ); } diff --git a/client/src/app/main/dashboard/dashboard-list-articles/dashboard-list-articles-page.js b/client/src/app/main/dashboard/dashboard-list-articles/dashboard-list-articles-page.js index 36837ab9..da942c22 100644 --- a/client/src/app/main/dashboard/dashboard-list-articles/dashboard-list-articles-page.js +++ b/client/src/app/main/dashboard/dashboard-list-articles/dashboard-list-articles-page.js @@ -23,7 +23,7 @@ class DashboardListArticlesPage extends React.Component { render() { return ( -
    +
    {(!this.state.showSearchResults) ? this.renderArticleList() : this.renderSearchResults()} diff --git a/client/src/core-components/icon.js b/client/src/core-components/icon.js index d26123d1..becdb99b 100644 --- a/client/src/core-components/icon.js +++ b/client/src/core-components/icon.js @@ -19,7 +19,7 @@ class Icon extends React.Component { renderFontIcon() { return ( -