Merged in os-136-email-templates-view (pull request #109)

Os 136 email templates view
This commit is contained in:
Ivan Diaz 2017-01-05 13:26:43 -03:00
commit bfd01dfc36
4 changed files with 321 additions and 7 deletions

View File

@ -1,14 +1,237 @@
import React from 'react';
import _ from 'lodash';
import RichTextEditor from 'react-rte-browserify';
import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call';
import AreYouSure from 'app-components/are-you-sure';
import LanguageSelector from 'app-components/language-selector';
import Button from 'core-components/button';
import Header from 'core-components/header';
import Listing from 'core-components/listing';
import Loading from 'core-components/loading';
import Form from 'core-components/form';
import FormField from 'core-components/form-field';
import SubmitButton from 'core-components/submit-button';
class AdminPanelEmailTemplates extends React.Component {
state = {
loaded: false,
items: [],
formLoading: false,
selectedIndex: 0,
edited: false,
errors: {},
language: 'en',
form: {
title: '',
content: RichTextEditor.createEmptyValue()
}
};
componentDidMount() {
this.retrieveEmailTemplates();
}
render() {
return (
<div>
/admin/panel/settings/email-templates
<div className="admin-panel-email-templates">
<Header title={i18n('EMAIL_TEMPLATES')} description={i18n('EMAIL_TEMPLATES_DESCRIPTION')} />
{(this.state.loaded) ? this.renderContent() : this.renderLoading()}
</div>
);
}
renderContent() {
return (
<div className="row">
<div className="col-md-3">
<Listing {...this.getListingProps()}/>
</div>
<div className="col-md-9">
<FormField label={i18n('LANGUAGE')} decorator={LanguageSelector} value={this.state.language} onChange={event => this.onItemChange(this.state.selectedIndex, event.target.value)} fieldProps={{
type: 'allowed',
size: 'medium'
}}/>
<Form {...this.getFormProps()}>
<div className="row">
<div className="col-md-7">
<FormField label={i18n('TITLE')} name="title" validation="TITLE" required fieldProps={{size: 'large'}}/>
</div>
</div>
<FormField label={i18n('CONTENT')} name="content" validation="TEXT_AREA" required field="textarea" />
<div className="admin-panel-email-templates__actions">
<div className="admin-panel-email-templates__save-button">
<SubmitButton type="secondary" size="small">{i18n('SAVE')}</SubmitButton>
</div>
<div className="admin-panel-email-templates__optional-buttons">
{(this.state.edited) ? this.renderDiscardButton() : null}
<div className="admin-panel-email-templates__recover-button">
<Button onClick={this.onRecoverClick.bind(this)} size="medium">
{i18n('RECOVER_DEFAULT')}
</Button>
</div>
</div>
</div>
</Form>
</div>
</div>
);
}
renderLoading() {
return (
<div className="admin-panel-email-templates__loading">
<Loading backgrounded size="large"/>
</div>
);
}
renderDiscardButton() {
return (
<div className="admin-panel-email-templates__discard-button">
<Button onClick={this.onDiscardChangesClick.bind(this)} size="medium">
{i18n('DISCARD_CHANGES')}
</Button>
</div>
);
}
getListingProps() {
return {
title: i18n('EMAIL_TEMPLATES'),
items: this.getItems(),
selectedIndex: this.state.selectedIndex,
onChange: this.onItemChange.bind(this)
};
}
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)
}
}
getItems() {
return this.state.items.map((item) => {
return {
content: i18n(item.type)
};
});
}
onItemChange(index, language) {
if(this.state.edited) {
AreYouSure.openModal(i18n('WILL_LOSE_CHANGES'), this.updateForm.bind(this, index, language));
} else {
this.updateForm(index, language);
}
}
onFormSubmit(form) {
this.setState({formLoading: true});
API.call({
path: '/system/edit-mail-template',
data: {
templateType: this.state.items[this.state.selectedIndex].type,
subject: form.title,
body: form.content,
language: this.state.language
}
}).then(() => {
this.setState({formLoading: false});
this.retrieveEmailTemplates();
});
}
onDiscardChangesClick(event) {
event.preventDefault();
this.onItemChange(this.state.selectedIndex);
}
onRecoverClick(event) {
event.preventDefault();
AreYouSure.openModal(i18n('WILL_RECOVER_EMAIL_TEMPLATE'), this.recoverEmailTemplate.bind(this));
}
recoverEmailTemplate() {
API.call({
path: '/system/recover-mail-template',
data: {
templateType: this.state.items[this.state.selectedIndex].type,
language: this.state.language
}
}).then(() => {
this.retrieveEmailTemplates();
});
}
updateForm(index, language) {
let form = _.clone(this.state.form);
let items = this.state.items;
language = language || this.state.language;
form.title = (items[index] && items[index][language].subject) || '';
form.content = RichTextEditor.createValueFromString((items[index] && items[index][language].body) || '', 'html');
this.setState({
selectedIndex: index,
language: language,
edited: false,
formLoading: false,
form: form,
errors: {}
});
}
retrieveEmailTemplates() {
return API.call({
path: '/system/get-mail-templates',
data: {}
}).then((result) => this.setState({
edited: false,
loaded: true,
items: this.getParsedItems(result.data)
}, this.updateForm.bind(this, this.state.selectedIndex)));
}
getParsedItems(items) {
let parsedItems = {};
_.forEach(items, (item) => {
if(parsedItems[item.type]) {
parsedItems[item.type][item.language] = {
subject: item.subject,
body: item.body
};
} else {
parsedItems[item.type] = {
[item.language]: {
subject: item.subject,
body: item.body
}
};
}
});
parsedItems = Object.keys(parsedItems).map((type) => {
return _.extend({
type: type
}, parsedItems[type]);
});
return parsedItems;
}
}
export default AdminPanelEmailTemplates;
export default AdminPanelEmailTemplates;

View File

@ -0,0 +1,21 @@
.admin-panel-email-templates {
&__save-button {
display: inline-block;
float: left;
}
&__optional-buttons {
display: inline-block;
float: right;
}
&__discard-button {
display: inline-block;
}
&__recover-button {
display: inline-block;
margin-left: 10px;
}
}

View File

@ -21,7 +21,7 @@ module.exports = [
}
},
{
path: '/staff/add-department',
path: '/system/add-department',
time: 100,
response: function () {
return {
@ -31,7 +31,7 @@ module.exports = [
}
},
{
path: '/staff/edit-department',
path: '/system/edit-department',
time: 100,
response: function () {
return {
@ -41,7 +41,7 @@ module.exports = [
}
},
{
path: '/staff/delete-department',
path: '/system/delete-department',
time: 100,
response: function () {
return {
@ -49,5 +49,72 @@ module.exports = [
data: {}
};
}
},
{
path: '/system/edit-mail-template',
time: 100,
response: function () {
return {
status: 'success',
data: {}
};
}
},
{
path: '/system/recover-mail-template',
time: 100,
response: function () {
return {
status: 'success',
data: {}
};
}
},
{
path: '/system/get-mail-templates',
time: 100,
response: function () {
return {
status: 'success',
data: [
{
type: 'USER_SINGUP',
language: 'en',
subject: 'Signup {{to}} - OpenSupports',
body : 'This is the user signup content {{name}}'
},
{
type: 'USER_SINGUP',
language: 'es',
subject: 'Registrado {{to}} - OpenSupports',
body : 'Este es el contenido de signup {{name}}'
},
{
type: 'USER_SINGUP',
language: 'de',
subject: 'Anmelden {{to}} - OpenSupports',
body : 'Dies ist der User Signup Content {{name}}'
},
{
type: 'USER_EDIT_PASSWORD',
language: 'en',
subject: 'Password changed {{to}} - OpenSupports',
body : 'Password has been edited {{name}}'
},
{
type: 'USER_EDIT_PASSWORD',
language: 'es',
subject: 'Password cambiado {{to}} - OpenSupports',
body : 'El password ha sido editado {{name}}'
},
{
type: 'USER_EDIT_PASSWORD',
language: 'de',
subject: 'Passwort geändert {{to}} - OpenSupports',
body : 'Passwort wurde bearbeitet {{name}}'
}
]
};
}
}
];

View File

@ -118,6 +118,7 @@ export default {
'COMMENTS': 'Comments',
'DELETE_STAFF_MEMBER': 'Delete staff member',
'MAINTENANCE_MODE': 'Maintenance mode',
'RECOVER_DEFAULT': 'Recover default',
//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.',
@ -147,6 +148,7 @@ export default {
'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.',
'MAINTENANCE_MODE_DESCRIPTION': 'The support system is in maintenance mode, thus unavailable at the moment. We will come back as soon as possible.',
'EMAIL_TEMPLATES_DESCRIPTION': 'Here you can edit the templates of the emails that will be sent to users. Remember that the double brackets curly braces indicate a variable value. For example, \'name\' represents the user\'s name.',
//ERRORS
'EMAIL_OR_PASSWORD': 'Email or password invalid',
@ -186,5 +188,6 @@ export default {
'DEPARTMENTS_UPDATED': 'Departments have been updated successfully.',
'FAILED_EDIT_STAFF': 'An error occurred while trying to edit staff member.',
'EMAIL_BANNED_SUCCESSFULLY': 'Email has been banned successfully',
'WILL_DELETE_STAFF': 'This staff member will be deleted and all its tickets will be unassigned.'
'WILL_DELETE_STAFF': 'This staff member will be deleted and all its tickets will be unassigned.',
'WILL_RECOVER_EMAIL_TEMPLATE': 'This email template will be recover to it\'s default value on this language.'
};