diff --git a/client/src/app/admin/panel/settings/admin-panel-email-templates.js b/client/src/app/admin/panel/settings/admin-panel-email-templates.js
index d111b0f6..99bdee30 100644
--- a/client/src/app/admin/panel/settings/admin-panel-email-templates.js
+++ b/client/src/app/admin/panel/settings/admin-panel-email-templates.js
@@ -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 (
-
- /admin/panel/settings/email-templates
+
+
+ {(this.state.loaded) ? this.renderContent() : this.renderLoading()}
);
}
+
+ renderContent() {
+ return (
+
+
+
+
+
+
this.onItemChange(this.state.selectedIndex, event.target.value)} fieldProps={{
+ type: 'allowed',
+ size: 'medium'
+ }}/>
+
+
+
+ );
+ }
+
+ renderLoading() {
+ return (
+
+
+
+ );
+ }
+
+ renderDiscardButton() {
+ return (
+
+
+
+ );
+ }
+
+ 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;
\ No newline at end of file
+export default AdminPanelEmailTemplates;
diff --git a/client/src/app/admin/panel/settings/admin-panel-email-templates.scss b/client/src/app/admin/panel/settings/admin-panel-email-templates.scss
new file mode 100644
index 00000000..340c7059
--- /dev/null
+++ b/client/src/app/admin/panel/settings/admin-panel-email-templates.scss
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/client/src/data/fixtures/system-fixtures.js b/client/src/data/fixtures/system-fixtures.js
index a699df1c..e4657991 100644
--- a/client/src/data/fixtures/system-fixtures.js
+++ b/client/src/data/fixtures/system-fixtures.js
@@ -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}}'
+ }
+ ]
+ };
+ }
}
];
diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js
index b1472eee..2fb72996 100644
--- a/client/src/data/languages/en.js
+++ b/client/src/data/languages/en.js
@@ -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.'
};