Merged in OS-130-create-system-preferences-view (pull request #111)

OS-130 create system preferences view
This commit is contained in:
Ivan Diaz 2017-01-05 15:04:57 -03:00
commit fe0ac93311
9 changed files with 395 additions and 17 deletions

View File

@ -0,0 +1,32 @@
import React from 'react';
import i18n from 'lib-app/i18n';
class ToggleButton extends React.Component {
static propTypes = {
value: React.PropTypes.bool,
onChange: React.PropTypes.func
};
render() {
return (
<div className="toggle-button" onClick={this.onClick.bind(this)}>
{this.props.value ? i18n('ON') : i18n('OFF')}
</div>
);
}
onClick() {
if (this.props.onChange) {
this.props.onChange({
target: {
value: !this.props.value
}
});
}
}
}
export default ToggleButton;

View File

@ -0,0 +1,9 @@
@import "../scss/vars";
.toggle-button {
background-color: $light-grey;
width: 80px;
padding: 2px;
border-radius: 4px;
text-align: center;
}

View File

@ -1,14 +1,230 @@
import React from 'react';
import _ from 'lodash';
import languageList from 'data/language-list';
import Form from 'core-components/form';
import FormField from 'core-components/form-field';
import Header from 'core-components/header';
import SubmitButton from 'core-components/submit-button';
import Button from 'core-components/button';
import Message from 'core-components/message';
import API from 'lib-app/api-call';
import i18n from 'lib-app/i18n';
import LanguageSelector from 'app-components/language-selector';
import ToggleButton from 'app-components/toggle-button';
class AdminPanelSystemPreferences extends React.Component {
state = {
loading: true,
message: null,
values: {
'maintenance': false
}
};
componentDidMount() {
this.recoverSettings();
}
render() {
return (
<div>
/admin/panel/settings/system-preferences
<div className="admin-panel-system-preferences">
<Header title={i18n('SYSTEM_PREFERENCES')} description="Here you can adjust your system preferences :)"/>
<Form values={this.state.values} onChange={values => this.setState({values, message: null})} onSubmit={this.onSubmit.bind(this)} loading={this.state.loading}>
<div className="row">
<div className="col-md-12">
<div className="admin-panel-system-preferences__maintenance">
<span>Maintenance Mode</span>
<FormField className="admin-panel-system-preferences__maintenance-field" name="maintenance-mode" decorator={ToggleButton}/>
</div>
</div>
</div>
<div className="row">
<div className="col-md-12">
<span className="separator" />
</div>
</div>
<div className="row">
<div className="col-md-6">
<FormField label={i18n('SUPPORT_CENTER_URL')} fieldProps={{size: 'large'}} name="url"/>
<FormField label={i18n('SUPPORT_CENTER_LAYOUT')} fieldProps={{size: 'large', items: [{content: i18n('BOXED')}, {content: i18n('FULL_WIDTH')}]}} field="select" name="layout"/>
</div>
<div className="col-md-6">
<FormField label={i18n('SUPPORT_CENTER_TITLE')} fieldProps={{size: 'large'}} name="title"/>
<FormField label={i18n('DEFAULT_TIMEZONE')} fieldProps={{size: 'large'}} name="time-zone"/>
</div>
</div>
<div className="row">
<div className="col-md-12">
<span className="separator" />
<div className="row">
<div className="col-md-6">
<FormField label={i18n('NOREPLY_EMAIL')} fieldProps={{size: 'large'}} name="no-reply-email"/>
<FormField label={i18n('SMTP_USER')} fieldProps={{size: 'large'}} name="smtp-user"/>
</div>
<div className="col-md-6">
<div className="row">
<div className="col-md-9">
<FormField label={i18n('SMTP_SERVER')} fieldProps={{size: 'large'}} name="smtp-host"/>
<FormField label={i18n('SMTP_PASSWORD')} fieldProps={{size: 'large', password: true}} name="smtp-pass"/>
</div>
<div className="col-md-3">
<FormField label={i18n('PORT')} fieldProps={{size: 'auto'}} name="smtp-port"/>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-md-12">
<span className="separator" />
</div>
<div className="col-md-6">
<div className="row admin-panel-system-preferences__languages">
<div className="col-md-6 admin-panel-system-preferences__languages-allowed">
<div>{i18n('ALLOWED_LANGUAGES')}</div>
<FormField name="allowedLanguages" field="checkbox-group" fieldProps={{items: this.getLanguageList()}} />
</div>
<div className="col-md-6 admin-panel-system-preferences__languages-supported">
<div>{i18n('SUPPORTED_LANGUAGES')}</div>
<FormField name="supportedLanguages" field="checkbox-group" fieldProps={{items: this.getLanguageList()}} />
</div>
</div>
</div>
<div className="col-md-6">
<FormField label={i18n('RECAPTCHA_PUBLIC_KEY')} fieldProps={{size: 'large'}} name="reCaptchaKey"/>
<FormField label={i18n('RECAPTCHA_PRIVATE_KEY')} fieldProps={{size: 'large'}} name="reCaptchaPrivate"/>
<div className="admin-panel-system-preferences__file-attachments">
<span>{i18n('ALLOW_FILE_ATTACHMENTS')}</span>
<FormField className="admin-panel-system-preferences__file-attachments-field" name="allow-attachments" decorator={ToggleButton}/>
</div>
<div className="admin-panel-system-preferences__max-size">
<span>{i18n('MAX_SIZE_KB')}</span>
<FormField className="admin-panel-system-preferences__max-size-field" fieldProps={{size: 'small'}} name="max-size"/>
</div>
<FormField className="admin-panel-system-preferences__default-language-field" name="language" label={i18n('DEFAULT_LANGUAGE')} decorator={LanguageSelector} />
</div>
</div>
<div className="row">
<div className="col-md-12">
<span className="separator" />
</div>
</div>
<div className="row">
<div className="col-md-4 col-md-offset-2">
<SubmitButton type="secondary">{i18n('UPDATE_SETTINGS')}</SubmitButton>
</div>
<div className="col-md-4">
<Button onClick={this.onDiscardChangesSubmit.bind(this)}>{i18n('DISCARD_CHANGES')}</Button>
</div>
</div>
</Form>
{this.renderMessage()}
</div>
);
}
renderMessage() {
switch (this.state.message) {
case 'success':
return <Message className="admin-panel-system-preferences__message" type="success">{i18n('SETTINGS_UPDATED')}</Message>;
case 'fail':
return <Message className="admin-panel-system-preferences__message" type="error">{i18n('ERROR_UPDATING_SETTINGS')}</Message>;
default:
return null;
}
}
onSubmit(form) {
let fullList = Object.keys(languageList);
this.setState({loading: true});
API.call({
path: '/system/edit-settings',
data: {
'language': form.language,
'recaptcha-public': form.reCaptchaKey,
'recaptcha-private': form.reCaptchaPrivate,
'url': form['url'],
'title': form['title'],
'layout': form['layout'] == 1 ? 'Full width' : 'Boxed',
'time-zone': form['time-zone'],
'no-reply-email': form['no-reply-email'],
'smtp-host': form['smtp-host'],
'smtp-port': form['smtp-port'],
'smtp-user': form['smtp-user'],
'smtp-pass': form['smtp-password'],
'maintenance-mode': form['maintenance-mode'],
'allow-attachments': form['allow-attachments'],
'max-size': form['max-size'],
'allowedLanguages': JSON.stringify(form.allowedLanguages.map(index => fullList[index])),
'supportedLanguages': JSON.stringify(form.supportedLanguages.map(index => fullList[index]))
}
}).then(this.onSubmitSuccess.bind(this)).catch(() => this.setState({loading: false, message: 'fail'}));
}
onSubmitSuccess() {
this.recoverSettings();
this.setState({
message: 'success',
loading: false
});
}
getLanguageList() {
return Object.keys(languageList).map(key => languageList[key].name);
}
recoverSettings() {
API.call({
path: '/system/get-settings',
data: {
allSettings: true
}
}).then(this.onRecoverSettingsSuccess.bind(this)).catch(this.onRecoverSettingsFail.bind(this));
}
onRecoverSettingsSuccess(result) {
let fullList = Object.keys(languageList);
this.setState({
loading: false,
values: {
'language': result.data.language,
'reCaptchaKey': result.data.reCaptchaKey,
'reCaptchaPrivate': result.data.reCaptchaPrivate,
'url': result.data['url'],
'title': result.data['title'],
'layout': result.data['layout'] == 'Full width' ? 1 : 0,
'time-zone': result.data['time-zone'],
'no-reply-email': result.data['no-reply-email'],
'smtp-host': result.data['smtp-host'],
'smtp-port': result.data['smtp-port'],
'smtp-user': result.data['smtp-user'],
'smtp-pass': '',
'maintenance-mode': result.data['maintenance-mode'],
'allow-attachments': result.data['allow-attachments'],
'max-size': result.data['max-size'],
'allowedLanguages': result.data.allowedLanguages.map(lang => (_.indexOf(fullList, lang))),
'supportedLanguages': result.data.supportedLanguages.map(lang => (_.indexOf(fullList, lang)))
}
});
}
onRecoverSettingsFail(result) {
this.setState({
message: 'error'
});
}
onDiscardChangesSubmit(event) {
event.preventDefault();
this.setState({loading: true});
this.recoverSettings();
}
}
export default AdminPanelSystemPreferences;

View File

@ -0,0 +1,54 @@
@import "../../../../scss/vars";
.admin-panel-system-preferences {
&__maintenance {
text-align: left;
}
&__maintenance-field {
display: inline-block;
margin-left: 30px;
}
&__file-attachments {
margin-top: 8px;
text-align: left;
}
&__file-attachments-field {
display: inline-block;
margin-left: 30px;
}
&__max-size {
text-align: left;
}
&__max-size-field {
display: inline-block;
margin-left: 30px;
}
&__languages {
margin: 0 auto;
&-allowed {
text-align: left;
display: inline-block;
}
&-supported {
text-align: left;
display: inline-block;
}
}
&__default-language-field {
text-align: left;
}
&__message {
margin-top: 20px;
}
}

View File

@ -16,6 +16,7 @@ const Menu = require('core-components/menu');
const Tooltip = require('core-components/tooltip');
const Table = require('core-components/table');
const InfoTooltip = require('core-components/info-tooltip');
const ToggleButton = require('app-components/toggle-button');
let dropDownItems = [{content: 'English'}, {content: 'Spanish'}, {content: 'German'}, {content: 'Portuguese'}, {content: 'Japanese'}];
let secondaryMenuItems = [

View File

@ -14,7 +14,7 @@ class Input extends React.Component {
value: React.PropTypes.string,
validation: React.PropTypes.string,
onChange: React.PropTypes.func,
size: React.PropTypes.oneOf(['small', 'medium', 'large']),
size: React.PropTypes.oneOf(['small', 'medium', 'large', 'auto']),
password: React.PropTypes.bool,
required: React.PropTypes.bool,
icon: React.PropTypes.string,

View File

@ -19,6 +19,10 @@
}
}
&_auto {
width: 100%;
}
&_small {
width: 200px;
}

View File

@ -2,22 +2,62 @@ module.exports = [
{
path: '/system/get-settings',
time: 1000,
response: function () {
response: function (params) {
if(params && params.allSettings) {
return {
status: 'success',
data: {
'language': 'en',
'reCaptchaKey': '6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS',
'reCaptchaPrivate': 'LALA',
'url': 'hola@lala.com',
'title': 'Very Cool',
'layout': 'Boxed',
'time-zone': 3,
'no-reply-email': 'shitr@post.com',
'smtp-host': 'localhost',
'smtp-port': '7070',
'smtp-user': 'Wesa',
'maintenance-mode': false,
'allow-attachments': true,
'max-size': 500,
'departments': [
{id: 1, name: 'Sales Support', owners: 2},
{id: 2, name: 'Technical Issues', owners: 5},
{id: 3, name: 'System and Administration', owners: 0}
],
'allowedLanguages': ['en', 'es', 'de', 'fr', 'pt', 'jp', 'ru', 'cn', 'in', 'tr'],
'supportedLanguages': ['en', 'es', 'de']
}
};
} else {
return {
status: 'success',
data: {
'language': 'en',
'reCaptchaKey': '6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS',
'maintenance-mode': false,
'departments': [
{id: 1, name: 'Sales Support', owners: 2},
{id: 2, name: 'Technical Issues', owners: 5},
{id: 3, name: 'System and Administration', owners: 0}
],
'allowedLanguages': ['en', 'es', 'de', 'fr', 'pt', 'jp', 'ru', 'cn', 'in', 'tr'],
'supportedLanguages': ['en', 'es', 'de']
}
};
}
}
},
{
path: '/system/edit-settings',
time: 50,
response: function() {
return {
status: 'success',
data: {
'language': 'en',
'reCaptchaKey': '6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS',
'maintenance-mode': false,
'departments': [
{id: 1, name: 'Sales Support', owners: 2},
{id: 2, name: 'Technical Issues', owners: 5},
{id: 3, name: 'System and Administration', owners: 0}
],
'allowedLanguages': ['en', 'es', 'de', 'fr', 'pt', 'jp', 'ru', 'cn', 'in', 'tr'],
'supportedLanguages': ['en', 'es', 'de']
}
};
data: {}
}
}
},
{

View File

@ -119,6 +119,28 @@ export default {
'DELETE_STAFF_MEMBER': 'Delete staff member',
'MAINTENANCE_MODE': 'Maintenance mode',
'RECOVER_DEFAULT': 'Recover default',
'SUPPORT_CENTER_URL': 'Support Center URL',
'SUPPORT_CENTER_TITLE': 'Support Center Title',
'SUPPORT_CENTER_LAYOUT': 'Support Center Layout',
'DEFAULT_TIMEZONE': 'Default Timezone',
'NOREPLY_EMAIL': 'Noreply Email',
'SMTP_USER': 'SMTP User',
'SMTP_SERVER': 'SMTP Server',
'SMTP_PASSWORD': 'SMTP Password',
'PORT': 'Port',
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha Public Key',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Private Key',
'ALLOW_FILE_ATTACHMENTS': 'Allow file attachments',
'MAX_SIZE_KB': 'Max Size (KB)',
'UPDATE_SETTINGS': 'Update settings',
'DEFAULT_LANGUAGE': 'Default Language',
'SUPPORTED_LANGUAGES': 'Supported Languages',
'ALLOWED_LANGUAGES': 'Allowed Languages',
'SETTINGS_UPDATED': 'Settings have been updated',
'ON': 'On',
'OFF': 'Off',
'BOXED': 'Boxed',
'FULL_WIDTH': 'Full width',
//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.',