Merged in os-125-admin-departments-view (pull request #94)
Os 125 admin departments view
This commit is contained in:
commit
8b69934d36
|
@ -26,5 +26,15 @@ export default {
|
|||
type: 'CHANGE_LANGUAGE',
|
||||
payload: newLanguage
|
||||
};
|
||||
},
|
||||
|
||||
updateData() {
|
||||
return {
|
||||
type: 'UPDATE_DEPARTMENTS',
|
||||
payload: API.call({
|
||||
path: '/system/get-settings',
|
||||
data: {}
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
|
@ -6,7 +6,7 @@ import ModalContainer from 'app-components/modal-container';
|
|||
|
||||
class AreYouSure extends React.Component {
|
||||
static propTypes = {
|
||||
description: React.PropTypes.string,
|
||||
description: React.PropTypes.node,
|
||||
onYes: React.PropTypes.func
|
||||
};
|
||||
|
||||
|
|
|
@ -1,14 +1,221 @@
|
|||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import {connect} from 'react-redux';
|
||||
import RichTextEditor from 'react-rte-browserify';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import API from 'lib-app/api-call';
|
||||
import ConfigActions from 'actions/config-actions';
|
||||
|
||||
import AreYouSure from 'app-components/are-you-sure';
|
||||
|
||||
import InfoTooltip from 'core-components/info-tooltip';
|
||||
import Button from 'core-components/button';
|
||||
import Header from 'core-components/header';
|
||||
import Listing from 'core-components/listing';
|
||||
import Form from 'core-components/form';
|
||||
import FormField from 'core-components/form-field';
|
||||
import SubmitButton from 'core-components/submit-button';
|
||||
import DropDown from 'core-components/drop-down';
|
||||
|
||||
class AdminPanelDepartments extends React.Component {
|
||||
static defaultProps = {
|
||||
items: []
|
||||
};
|
||||
|
||||
state = {
|
||||
formLoading: false,
|
||||
selectedIndex: -1,
|
||||
selectedDropDownIndex: 0,
|
||||
edited: false,
|
||||
errors: {},
|
||||
form: {
|
||||
title: '',
|
||||
content: RichTextEditor.createEmptyValue(),
|
||||
language: 'en'
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
/admin/panel/staff/departments
|
||||
<div className="admin-panel-departments">
|
||||
<Header title={i18n('DEPARTMENTS')} description={i18n('DEPARTMENTS_DESCRIPTION')} />
|
||||
<div className="row">
|
||||
<div className="col-md-4">
|
||||
<Listing {...this.getListingProps()}/>
|
||||
</div>
|
||||
<div className="col-md-8">
|
||||
<Form {...this.getFormProps()}>
|
||||
<FormField label={i18n('NAME')} name="name" validation="NAME" required fieldProps={{size: 'large'}}/>
|
||||
<SubmitButton size="medium" className="admin-panel-departments__update-name-button" type="secondary">
|
||||
{i18n((this.state.selectedIndex !== -1) ? 'UPDATE_DEPARTMENT' : 'ADD_DEPARTMENT')}
|
||||
</SubmitButton>
|
||||
</Form>
|
||||
{(this.state.selectedIndex !== -1 && this.props.departments.length) ? this.renderOptionalButtons() : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderOptionalButtons() {
|
||||
return (
|
||||
<div className="admin-panel-departments__optional-buttons">
|
||||
<div className="admin-panel-departments__discard-button">
|
||||
<Button onClick={this.onDiscardChangesClick.bind(this)} size="medium">{i18n('DISCARD_CHANGES')}</Button>
|
||||
</div>
|
||||
<div className="admin-panel-departments__delete-button">
|
||||
<Button onClick={this.onDeleteClick.bind(this)} size="medium">{i18n('DELETE')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDelete() {
|
||||
return (
|
||||
<div>
|
||||
{i18n('WILL_DELETE_DEPARTMENT')}
|
||||
<div className="admin-panel-departments__transfer-tickets">
|
||||
<span className="admin-panel-departments__transfer-tickets-title">{i18n('TRANSFER_TICKETS_TO')}</span>
|
||||
<DropDown className="admin-panel-departments__transfer-tickets-drop-down" items={this.props.departments.filter((department, index) => index !== this.state.selectedIndex).map(department => {
|
||||
return {
|
||||
content: department.name
|
||||
};
|
||||
})} onChange={(department, index) => this.setState({selectedDropDownIndex: index})} size="medium"/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getListingProps() {
|
||||
return {
|
||||
className: 'admin-panel-departments__list',
|
||||
title: i18n('DEPARTMENTS'),
|
||||
items: this.props.departments.map(department => {
|
||||
return {
|
||||
content: (
|
||||
<span>
|
||||
{department.name}
|
||||
{(!department.owners) ? (
|
||||
<span className="admin-panel-departments__warning">
|
||||
<InfoTooltip type="warning" text={i18n('NO_STAFF_ASSIGNED')}/>
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
)
|
||||
};
|
||||
}),
|
||||
selectedIndex: this.state.selectedIndex,
|
||||
enableAddNew: true,
|
||||
onChange: this.onItemChange.bind(this),
|
||||
onAddClick: this.onItemChange.bind(this, -1)
|
||||
};
|
||||
}
|
||||
|
||||
getFormProps() {
|
||||
return {
|
||||
values: this.state.form,
|
||||
errors: this.state.errors,
|
||||
loading: this.state.formLoading,
|
||||
onChange: (form) => {this.setState({form, edited: true})},
|
||||
onValidateErrors: (errors) => {this.setState({errors})},
|
||||
onSubmit: this.onFormSubmit.bind(this)
|
||||
};
|
||||
}
|
||||
|
||||
onItemChange(index) {
|
||||
if(this.state.edited) {
|
||||
AreYouSure.openModal(i18n('WILL_LOSE_CHANGES'), this.updateForm.bind(this, index));
|
||||
} else {
|
||||
this.updateForm(index);
|
||||
}
|
||||
}
|
||||
|
||||
onFormSubmit(form) {
|
||||
this.setState({formLoading: true, edited: false});
|
||||
|
||||
if(this.state.selectedIndex !== -1) {
|
||||
API.call({
|
||||
path: '/staff/edit-department',
|
||||
data: {
|
||||
departmentId: this.getCurrentDepartment().id,
|
||||
name: form.name
|
||||
}
|
||||
}).then(() => {
|
||||
this.setState({formLoading: false});
|
||||
this.retrieveDepartments();
|
||||
}).catch(this.onItemChange.bind(this, -1));
|
||||
} else {
|
||||
API.call({
|
||||
path: '/staff/add-department',
|
||||
data: {
|
||||
name: form.title
|
||||
}
|
||||
}).then(() => {
|
||||
this.retrieveDepartments();
|
||||
this.onItemChange(-1);
|
||||
}).catch(this.onItemChange.bind(this, -1));
|
||||
}
|
||||
}
|
||||
|
||||
onDiscardChangesClick() {
|
||||
this.onItemChange(this.state.selectedIndex);
|
||||
}
|
||||
|
||||
onDeleteClick() {
|
||||
this.setState({
|
||||
selectedDropDownIndex: 0
|
||||
});
|
||||
|
||||
AreYouSure.openModal(this.renderDelete(), this.deleteDepartment.bind(this));
|
||||
}
|
||||
|
||||
deleteDepartment() {
|
||||
API.call({
|
||||
path: '/staff/delete-department',
|
||||
data: {
|
||||
departmentId: this.getCurrentDepartment().id,
|
||||
transferDepartmentId: this.getDropDownItemId()
|
||||
}
|
||||
}).then(() => {
|
||||
this.retrieveDepartments();
|
||||
this.onItemChange(-1);
|
||||
});
|
||||
}
|
||||
|
||||
updateForm(index) {
|
||||
let form = _.clone(this.state.form);
|
||||
let department = this.getCurrentDepartment(index);
|
||||
|
||||
form.name = (department && department.name) || '';
|
||||
|
||||
this.setState({
|
||||
selectedIndex: index,
|
||||
edited: false,
|
||||
formLoading: false,
|
||||
form: form,
|
||||
errors: {}
|
||||
});
|
||||
}
|
||||
|
||||
retrieveDepartments() {
|
||||
this.props.dispatch(ConfigActions.updateData());
|
||||
this.setState({
|
||||
edited: false
|
||||
});
|
||||
}
|
||||
|
||||
getCurrentDepartment(index) {
|
||||
return this.props.departments[(index == undefined) ? this.state.selectedIndex : index];
|
||||
}
|
||||
|
||||
getDropDownItemId() {
|
||||
return this.props.departments.filter((department, index) => index !== this.state.selectedIndex)[this.state.selectedDropDownIndex].id;
|
||||
}
|
||||
}
|
||||
|
||||
export default AdminPanelDepartments;
|
||||
export default connect((store) => {
|
||||
return {
|
||||
departments: store.config.departments
|
||||
};
|
||||
})(AdminPanelDepartments);
|
|
@ -0,0 +1,41 @@
|
|||
@import "../../../../scss/vars";
|
||||
|
||||
.admin-panel-departments {
|
||||
|
||||
|
||||
&__list {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__update-name-button {
|
||||
float: left;
|
||||
}
|
||||
|
||||
&__optional-buttons {
|
||||
float: right;
|
||||
}
|
||||
|
||||
&__discard-button,
|
||||
&__delete-button {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
&__warning {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
&__transfer-tickets {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
&__transfer-tickets-title {
|
||||
margin-right: 20px;
|
||||
color: $primary-black;
|
||||
}
|
||||
|
||||
&__transfer-tickets-drop-down {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Menu from 'core-components/menu';
|
||||
import Button from 'core-components/button';
|
||||
|
@ -20,7 +21,7 @@ class Listing extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div className="listing">
|
||||
<div className={this.getClass()}>
|
||||
<div className="listing__header">
|
||||
{this.props.title}
|
||||
</div>
|
||||
|
@ -42,6 +43,16 @@ class Listing extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
getClass() {
|
||||
let classes = {
|
||||
'listing': true
|
||||
};
|
||||
|
||||
classes[this.props.className] = (this.props.className);
|
||||
|
||||
return classNames(classes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Listing;
|
|
@ -14,8 +14,8 @@ module.exports = [
|
|||
level: 1,
|
||||
staff: true,
|
||||
departments: [
|
||||
{id: 1, name: 'Sales Support'},
|
||||
{id: 2, name: 'Technical Issues'}
|
||||
{id: 1, name: 'Sales Support', owners: 2},
|
||||
{id: 2, name: 'Technical Issues', owners: 5}
|
||||
],
|
||||
tickets: [
|
||||
{
|
||||
|
@ -24,7 +24,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 2,
|
||||
name: 'Technical Issues'
|
||||
name: 'Technical Issues',
|
||||
owners: 5
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -143,7 +144,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 2,
|
||||
name: 'Technical Issues'
|
||||
name: 'Technical Issues',
|
||||
owners: 5
|
||||
},
|
||||
date: '20160415',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -259,7 +261,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 2,
|
||||
name: 'Technical Issues'
|
||||
name: 'Technical Issues',
|
||||
owners: 5
|
||||
},
|
||||
date: '20150409',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -375,7 +378,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 1,
|
||||
name: 'Sales Support'
|
||||
name: 'Sales Support',
|
||||
owners: 2
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -413,7 +417,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 2,
|
||||
name: 'Technical Issues'
|
||||
name: 'Technical Issues',
|
||||
owners: 5
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -532,7 +537,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 2,
|
||||
name: 'Technical Issues'
|
||||
name: 'Technical Issues',
|
||||
owners: 5
|
||||
},
|
||||
date: '20160415',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -648,7 +654,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 2,
|
||||
name: 'Technical Issues'
|
||||
name: 'Technical Issues',
|
||||
owners: 5
|
||||
},
|
||||
date: '20150409',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -764,7 +771,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 1,
|
||||
name: 'Sales Support'
|
||||
name: 'Sales Support',
|
||||
owners: 2
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -801,7 +809,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 1,
|
||||
name: 'Sales Support'
|
||||
name: 'Sales Support',
|
||||
owners: 2
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -827,7 +836,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 1,
|
||||
name: 'Sales Support'
|
||||
name: 'Sales Support',
|
||||
owners: 2
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -853,7 +863,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 2,
|
||||
name: 'Technical Issues'
|
||||
name: 'Technical Issues',
|
||||
owners: 2
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -891,7 +902,8 @@ module.exports = [
|
|||
content: 'I had a problem with the installation of the php server',
|
||||
department: {
|
||||
id: 1,
|
||||
name: 'Sales Support'
|
||||
name: 'Sales Support',
|
||||
owners: 2
|
||||
},
|
||||
date: '20160416',
|
||||
file: 'http://www.opensupports.com/some_file.zip',
|
||||
|
@ -1035,5 +1047,35 @@ module.exports = [
|
|||
data: {}
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/staff/add-department',
|
||||
time: 100,
|
||||
response: function () {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/staff/edit-department',
|
||||
time: 100,
|
||||
response: function () {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/staff/delete-department',
|
||||
time: 100,
|
||||
response: function () {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
];
|
|
@ -9,9 +9,9 @@ module.exports = [
|
|||
'language': 'en',
|
||||
'reCaptchaKey': '6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS',
|
||||
'departments': [
|
||||
{id: 1, name: 'Sales Support'},
|
||||
{id: 2, name: 'Technical Issues'},
|
||||
{id: 3, name: 'System and Administration'}
|
||||
{id: 1, name: 'Sales Support', owners: 2},
|
||||
{id: 2, name: 'Technical Issues', owners: 5},
|
||||
{id: 3, name: 'System and Administration', owners: 0}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
|
|
@ -111,6 +111,9 @@ export default {
|
|||
'UPDATE_LEVEL': 'Update level',
|
||||
'UPDATE_DEPARTMENTS': 'Update departments',
|
||||
'EDIT_STAFF': 'Edit staff member',
|
||||
'ADD_DEPARTMENT': 'Add department',
|
||||
'UPDATE_DEPARTMENT': 'Update department',
|
||||
'TRANSFER_TICKETS_TO': 'Transfer tickets to',
|
||||
|
||||
//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.',
|
||||
|
@ -137,6 +140,7 @@ export default {
|
|||
'ADD_STAFF_DESCRIPTION': 'Here you can add staff members to your teams.',
|
||||
'EDIT_STAFF_DESCRIPTION': 'Here you can edit information about a staff member.',
|
||||
'MY_ACCOUNT_DESCRIPTION': 'Here you can edit information about you.',
|
||||
'DEPARTMENTS_DESCRIPTION': 'A department is a group where the tickets can go. They are used to categorize the tickets. You can assign them to other staff members.',
|
||||
|
||||
//ERRORS
|
||||
'EMAIL_OR_PASSWORD': 'Email or password invalid',
|
||||
|
@ -163,5 +167,7 @@ export default {
|
|||
'PASSWORD_CHANGED': 'Password has been changed successfully',
|
||||
'OLD_PASSWORD_INCORRECT': 'Old password is incorrect',
|
||||
'WILL_LOSE_CHANGES': 'You haven\'t save. Your changes will be lost.',
|
||||
'WILL_DELETE_CUSTOM_RESPONSE': 'The custom response will be deleted.'
|
||||
'WILL_DELETE_CUSTOM_RESPONSE': 'The custom response will be deleted.',
|
||||
'WILL_DELETE_DEPARTMENT': 'The department will be deleted. All the tickets will be transfer to the department selected.',
|
||||
'NO_STAFF_ASSIGNED': 'No staff member is assigned to this department.'
|
||||
};
|
||||
|
|
|
@ -14,7 +14,8 @@ class ConfigReducer extends Reducer {
|
|||
getTypeHandlers() {
|
||||
return {
|
||||
'CHANGE_LANGUAGE': this.onLanguageChange,
|
||||
'INIT_CONFIGS_FULFILLED': this.onInitConfigs
|
||||
'INIT_CONFIGS_FULFILLED': this.onInitConfigs,
|
||||
'UPDATE_DATA_FULFILLED': this.onInitConfigs
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,7 +30,7 @@ class ConfigReducer extends Reducer {
|
|||
onInitConfigs(state, payload) {
|
||||
const currentLanguage = sessionStore.getItem('language');
|
||||
|
||||
sessionStore.storeConfigs(_.extend(payload.data, {
|
||||
sessionStore.storeConfigs(_.extend({}, payload.data, {
|
||||
language: currentLanguage || payload.language
|
||||
}));
|
||||
|
||||
|
|
Loading…
Reference in New Issue