edit stags feature
This commit is contained in:
parent
6e0b7b7c80
commit
37ab1c5817
|
@ -35,7 +35,6 @@ import AdminPanelNewTickets from 'app/admin/panel/tickets/admin-panel-new-ticket
|
|||
import AdminPanelAllTickets from 'app/admin/panel/tickets/admin-panel-all-tickets';
|
||||
import AdminPanelViewTicket from 'app/admin/panel/tickets/admin-panel-view-ticket';
|
||||
import AdminPanelCustomResponses from 'app/admin/panel/tickets/admin-panel-custom-responses';
|
||||
import AdminPanelCustomTags from 'app/admin/panel/tickets/admin-panel-custom-tags';
|
||||
|
||||
import AdminPanelListUsers from 'app/admin/panel/users/admin-panel-list-users';
|
||||
import AdminPanelViewUser from 'app/admin/panel/users/admin-panel-view-user';
|
||||
|
@ -52,6 +51,7 @@ import AdminPanelViewStaff from 'app/admin/panel/staff/admin-panel-view-staff';
|
|||
import AdminPanelSystemPreferences from 'app/admin/panel/settings/admin-panel-system-preferences';
|
||||
import AdminPanelAdvancedSettings from 'app/admin/panel/settings/admin-panel-advanced-settings';
|
||||
import AdminPanelEmailSettings from 'app/admin/panel/settings/admin-panel-email-settings';
|
||||
import AdminPanelCustomTags from 'app/admin/panel/settings/admin-panel-custom-tags';
|
||||
|
||||
// INSTALLATION
|
||||
import InstallLayout from 'app/install/install-layout';
|
||||
|
@ -115,7 +115,6 @@ export default (
|
|||
<Route path="all-tickets" component={AdminPanelAllTickets} />
|
||||
<Route path="custom-responses" component={AdminPanelCustomResponses} />
|
||||
<Route path="view-ticket/:ticketNumber" component={AdminPanelViewTicket} />
|
||||
<Route path="custom-tags" component={AdminPanelCustomTags} />
|
||||
</Route>
|
||||
|
||||
<Route path="users">
|
||||
|
@ -144,6 +143,7 @@ export default (
|
|||
<Route path="system-preferences" component={AdminPanelSystemPreferences} />
|
||||
<Route path="advanced-settings" component={AdminPanelAdvancedSettings} />
|
||||
<Route path="email-settings" component={AdminPanelEmailSettings} />
|
||||
<Route path="custom-tags" component={AdminPanelCustomTags} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Route>
|
||||
|
|
|
@ -135,11 +135,6 @@ class AdminPanelMenu extends React.Component {
|
|||
name: i18n('CUSTOM_RESPONSES'),
|
||||
path: '/admin/panel/tickets/custom-responses',
|
||||
level: 2
|
||||
},
|
||||
{
|
||||
name: i18n('CUSTOM_TAGS'),
|
||||
path: '/admin/panel/tickets/custom-tags',
|
||||
level: 1
|
||||
}
|
||||
])
|
||||
},
|
||||
|
@ -219,6 +214,11 @@ class AdminPanelMenu extends React.Component {
|
|||
name: i18n('EMAIL_SETTINGS'),
|
||||
path: '/admin/panel/settings/email-settings',
|
||||
level: 3
|
||||
},
|
||||
{
|
||||
name: i18n('CUSTOM_TAGS'),
|
||||
path: '/admin/panel/settings/custom-tags',
|
||||
level: 3
|
||||
}
|
||||
])
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import AdminPanelCustomTagsModal from 'app/admin/panel/tickets/admin-panel-custom-tags-modal';
|
||||
|
||||
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 ModalContainer from 'app-components/modal-container';
|
||||
|
||||
import Icon from 'core-components/icon';
|
||||
import Button from 'core-components/button';
|
||||
import Header from 'core-components/header';
|
||||
import Tag from 'core-components/tag';
|
||||
|
||||
class AdminPanelCustomTags extends React.Component {
|
||||
static propTypes = {
|
||||
tags: React.PropTypes.arrayOf(
|
||||
React.PropTypes.shape({
|
||||
name: React.PropTypes.string,
|
||||
color: React.PropTypes.string,
|
||||
id: React.PropTypes.number
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.retrieveCustomTags();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="admin-panel-custom-tags">
|
||||
<Header title={i18n('CUSTOM_TAGS')} description={i18n('CUSTOM_TAGS_DESCRIPTION')} />
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
return (
|
||||
<div className="admin-panel-custom-tags__content">
|
||||
<div>
|
||||
<Button onClick={this.openTagModal.bind(this)} type="secondary">
|
||||
{i18n('ADD_CUSTOM_TAG')}<Icon className="admin-panel-custom-tags__add-button-icon" name="plus"/>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="admin-panel-custom-tags__tag-list">
|
||||
{this.props.tags.map(this.renderTag.bind(this))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTag(tag, index) {
|
||||
return(
|
||||
<div key={index} className="admin-panel-custom-tags__tag-container" >
|
||||
<Tag color={tag.color} name={tag.name} onEditClick={this.openEditTagModal.bind(this, tag.id, tag.name, tag.color)} onRemoveClick={this.onDeleteClick.bind(this, tag.id)} size='large' showEditButton showDeleteButton />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
openTagModal() {
|
||||
ModalContainer.openModal(
|
||||
<AdminPanelCustomTagsModal onTagCreated={this.retrieveCustomTags.bind(this)} createTag />
|
||||
);
|
||||
}
|
||||
openEditTagModal(tagId,tagName,tagColor, event) {
|
||||
ModalContainer.openModal(
|
||||
<AdminPanelCustomTagsModal defaultValues={{name: tagName , color: tagColor}} id={tagId} onTagChange={this.retrieveCustomTags.bind(this)}/>
|
||||
);
|
||||
}
|
||||
|
||||
onDeleteClick(tagId, event) {
|
||||
event.preventDefault();
|
||||
AreYouSure.openModal(i18n('WILL_DELETE_CUSTOM_RESPONSE'), this.deleteCustomTag.bind(this, tagId));
|
||||
}
|
||||
|
||||
deleteCustomTag(tagId) {
|
||||
API.call({
|
||||
path: '/ticket/delete-tag',
|
||||
data: {
|
||||
tagId,
|
||||
}
|
||||
}).then(() => {
|
||||
this.retrieveCustomTags()
|
||||
});
|
||||
}
|
||||
|
||||
retrieveCustomTags() {
|
||||
this.props.dispatch(ConfigActions.updateData());
|
||||
}
|
||||
}
|
||||
|
||||
export default connect((store) => {
|
||||
return {
|
||||
tags: store.config['tags']
|
||||
};
|
||||
})(AdminPanelCustomTags);
|
|
@ -0,0 +1,18 @@
|
|||
.admin-panel-custom-tags {
|
||||
|
||||
&__content {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&__add-button-icon{
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
&__tag-list{
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
&__tag-container{
|
||||
margin-top:5px ;
|
||||
}
|
||||
}
|
|
@ -26,13 +26,45 @@ class AdminPanelCustomTagsModal extends React.Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
return(
|
||||
this.props.createTag ? this.renderCreateTagContent() : this.renderEditTagContent()
|
||||
);
|
||||
}
|
||||
|
||||
renderEditTagContent() {
|
||||
return (
|
||||
<div className='admin-panel-custom-tags-modal'>
|
||||
<Header title={i18n('EDIT_CUSTOM_TAG')} description={i18n('DESCRIPTION_EDIT_CUSTOM_TAG')} />
|
||||
<Form
|
||||
values={this.state.form}
|
||||
onChange={this.onFormChange.bind(this)}
|
||||
onSubmit={this.onSubmitEditTag.bind(this)}
|
||||
errors={this.state.errors}
|
||||
onValidateErrors={errors => this.setState({errors})}
|
||||
loading={this.state.loading}>
|
||||
<FormField name="name" label={i18n('NAME')} fieldProps={{size: 'large'}}/>
|
||||
<FormField name="color" label={i18n('COLOR')} decorator={ColorSelector} />
|
||||
<div className='admin-panel-custom-tags-modal__actions'>
|
||||
<SubmitButton type="secondary" size="small">
|
||||
{i18n('SAVE')}
|
||||
</SubmitButton>
|
||||
<Button onClick={this.onDiscardClick.bind(this)} size="small">
|
||||
{i18n('CANCEL')}
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderCreateTagContent() {
|
||||
return (
|
||||
<div className='admin-panel-custom-tags-modal'>
|
||||
<Header title={i18n('ADD_CUSTOM_TAG')} description={i18n('DESCRIPTION_ADD_CUSTOM_TAG')} />
|
||||
<Form
|
||||
values={this.state.form}
|
||||
onChange={this.onFormChange.bind(this)}
|
||||
onSubmit={this.onSubmitTag.bind(this)}
|
||||
onSubmit={this.onSubmitNewTag.bind(this)}
|
||||
errors={this.state.errors}
|
||||
onValidateErrors={errors => this.setState({errors})}
|
||||
loading={this.state.loading}>
|
||||
|
@ -56,8 +88,39 @@ class AdminPanelCustomTagsModal extends React.Component {
|
|||
form
|
||||
});
|
||||
}
|
||||
onSubmitEditTag(form) {
|
||||
this.setState({
|
||||
loading: true
|
||||
});
|
||||
|
||||
onSubmitTag(form) {
|
||||
API.call({
|
||||
path: '/ticket/edit-tag',
|
||||
data: {
|
||||
tagId: this.props.id,
|
||||
name: form.name,
|
||||
color: form.color,
|
||||
}
|
||||
}).then(() => {
|
||||
this.context.closeModal();
|
||||
this.setState({
|
||||
loading: false,
|
||||
errors: {}
|
||||
});
|
||||
if(this.props.onTagChange) {
|
||||
this.props.onTagChange();
|
||||
}
|
||||
}).catch((result) => {
|
||||
|
||||
this.setState({
|
||||
loading: false,
|
||||
errors: {
|
||||
'name': result.message
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
onSubmitNewTag(form) {
|
||||
this.setState({
|
||||
loading: true
|
||||
});
|
||||
|
|
|
@ -16,11 +16,21 @@ class Tag extends React.Component {
|
|||
return (
|
||||
<div className={this.getClass()} style={{backgroundColor:this.props.color}} onClick={event => event.stopPropagation()} >
|
||||
<span className="tag__name">{this.props.name}</span>
|
||||
{this.props.showDeleteButton ? this.renderRemoveButton() : null}
|
||||
<span>
|
||||
{this.props.showEditButton ? this.renderEditButton() : null}
|
||||
{this.props.showDeleteButton ? this.renderRemoveButton() : null}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderEditButton() {
|
||||
return (
|
||||
<span onClick={this.props.onEditClick} className="tag__edit" >
|
||||
<Icon name="pencil" size="small"/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
renderRemoveButton() {
|
||||
return (
|
||||
<span onClick={this.props.onRemoveClick} className="tag__remove" >
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
margin-left: 5px;
|
||||
margin-top: 3px;
|
||||
padding: 3px;
|
||||
font-size: 13px;
|
||||
cursor: default;
|
||||
|
@ -17,6 +18,12 @@
|
|||
color: $light-grey;
|
||||
}
|
||||
}
|
||||
&__edit {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: $light-grey;
|
||||
}
|
||||
}
|
||||
|
||||
&_small {
|
||||
font-size: 11px;
|
||||
|
|
|
@ -106,6 +106,7 @@ export default {
|
|||
'LAST_EDITED_IN': 'Last edited in {date}',
|
||||
'EDIT': 'Edit',
|
||||
'ADD_CUSTOM_TAG': 'Add custom tag',
|
||||
'EDIT_CUSTOM_TAG': 'Edit custom tag',
|
||||
'NO_RESULTS': 'No results',
|
||||
'DELETE_AND_BAN': 'Delete and ban',
|
||||
'STAFF_LEVEL': 'Staff Level',
|
||||
|
@ -209,6 +210,7 @@ export default {
|
|||
'OPTIONS': 'Options',
|
||||
'FIELD_DESCRIPTION': 'Field description (Optional)',
|
||||
'DESCRIPTION_ADD_CUSTOM_TAG': 'here you can add a new custom tag',
|
||||
'DESCRIPTION_EDIT_CUSTOM_TAG': 'here you can edit a custom tag',
|
||||
'CUSTOM_FIELDS': 'Custom fields',
|
||||
|
||||
'CHART_CREATE_TICKET': 'Tickets created',
|
||||
|
|
|
@ -12,7 +12,7 @@ DataValidator::with('CustomValidations', true);
|
|||
*
|
||||
* @apiDescription This path creates a new tag.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} name The new name of the tag.
|
||||
* @apiParam {String} color The new color of the tag.
|
||||
|
@ -31,7 +31,7 @@ class CreateTagController extends Controller {
|
|||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::length(2, 100),
|
||||
|
|
|
@ -12,7 +12,7 @@ DataValidator::with('CustomValidations', true);
|
|||
*
|
||||
* @apiDescription This path delete a tag.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} tagId The id of the tag.
|
||||
*
|
||||
|
@ -29,7 +29,7 @@ class DeleteTagController extends Controller {
|
|||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'tagId' => [
|
||||
'validation' => DataValidator::dataStoreId('tag'),
|
||||
|
|
|
@ -12,7 +12,7 @@ DataValidator::with('CustomValidations', true);
|
|||
*
|
||||
* @apiDescription This path edit tags.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} tagId The id of the tag.
|
||||
* @apiParam {Number} name The new name of the tag.
|
||||
|
@ -32,7 +32,7 @@ class EditTagController extends Controller {
|
|||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'tagId' => [
|
||||
'validation' => DataValidator::dataStoreId('tag'),
|
||||
|
|
|
@ -12,7 +12,7 @@ DataValidator::with('CustomValidations', true);
|
|||
*
|
||||
* @apiDescription This path returns all the tags.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
|
@ -26,14 +26,14 @@ class GetTagsController extends Controller {
|
|||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$tags = Tag::getAll();
|
||||
|
||||
|
||||
Response::respondSuccess($tags->toArray());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue