Ivan - Add form form custom responses [skip ci]

This commit is contained in:
ivan 2016-10-12 00:08:20 -03:00
parent 23ccc17a85
commit d75ad2e165
11 changed files with 91 additions and 20 deletions

View File

@ -4,7 +4,7 @@ import classNames from 'classnames';
import { connect } from 'react-redux'
import { browserHistory } from 'react-router';
import ModalContainer from 'app/modal-container';
import ModalContainer from 'app-components/modal-container';
class App extends React.Component {
static contextTypes = {

View File

@ -1,18 +1,33 @@
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 AdminDataActions from 'actions/admin-data-actions';
import ModalContainer from 'app-components/modal-container';
import AreYouSure from 'app-components/are-you-sure';
import Icon from 'core-components/icon';
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 AdminPanelCustomResponses extends React.Component {
static defaultProps = {
items: []
};
state = {
selectedIndex: -1,
edited: false,
errors: {},
form: {}
};
componentDidMount() {
if (!this.props.loaded) {
@ -36,7 +51,11 @@ class AdminPanelCustomResponses extends React.Component {
<Listing {...this.getListingProps()}/>
</div>
<div className="col-md-9">
Custom response form
<Form {...this.getFormProps()}>
<FormField label={i18n('TITLE')} name="title" validation="TITLE" required fieldProps={{size: 'large'}}/>
<FormField label={i18n('CONTENT')} name="content" validation="TEXT_AREA" required field="textarea" />
<SubmitButton>{i18n('SAVE')}</SubmitButton>
</Form>
</div>
</div>
);
@ -52,12 +71,24 @@ class AdminPanelCustomResponses extends React.Component {
getListingProps() {
return {
title: 'Custom Responses',
title: i18n('CUSTOM_RESPONSES'),
items: this.getItems(),
enableAddNew: true
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,
onChange: (form) => {this.setState({form, edited: true})},
onValidateErrors: (errors) => {this.setState({errors})}
}
}
getItems() {
return this.props.items.map((item) => {
return {
@ -72,6 +103,30 @@ class AdminPanelCustomResponses extends React.Component {
};
});
}
onItemChange(index) {
if(this.state.edited) {
ModalContainer.openModal(
<AreYouSure description={i18n('WILL_LOSE_CHANGES')} onYes={this.updateForm.bind(this, index)} />
);
} else {
this.updateForm(index);
}
}
updateForm(index) {
let form = _.clone(this.state.form);
form.title = (this.props.items[index] && this.props.items[index].name) || '';
form.content = RichTextEditor.createValueFromString((this.props.items[index] && this.props.items[index].content) || '', 'html');
this.setState({
selectedIndex: index,
edited: false,
form: form,
errors: {}
});
}
}
export default connect((store) => {

View File

@ -3,7 +3,7 @@
const React = require('react');
const DocumentTitle = require('react-document-title');
const ModalContainer = require('app/modal-container');
const ModalContainer = require('app-components/modal-container');
const AreYouSure = require('app-components/are-you-sure');
const Button = require('core-components/button');

View File

@ -1,15 +1,16 @@
import React from 'react';
import API from 'lib-app/api-call';
import i18n from 'lib-app/i18n';
import ModalContainer from 'app-components/modal-container';
import AreYouSure from 'app-components/are-you-sure';
import Header from 'core-components/header';
import Form from 'core-components/form';
import FormField from 'core-components/form-field';
import SubmitButton from 'core-components/submit-button';
import ModalContainer from 'app/modal-container';
import AreYouSure from 'app-components/are-you-sure';
import Message from 'core-components/message';
import i18n from 'lib-app/i18n';
class DashboardEditProfilePage extends React.Component {

View File

@ -14,6 +14,8 @@ class Form extends React.Component {
loading: React.PropTypes.bool,
errors: React.PropTypes.object,
onValidateErrors: React.PropTypes.func,
onChange: React.PropTypes.func,
values: React.PropTypes.object,
onSubmit: React.PropTypes.func
};
@ -58,6 +60,8 @@ class Form extends React.Component {
delete props.errors;
delete props.loading;
delete props.onValidateErrors;
delete props.values;
delete props.onChange;
return props;
}
@ -80,7 +84,7 @@ class Form extends React.Component {
additionalProps = {
ref: fieldName,
value: this.state.form[fieldName] || props.value,
value: this.getFormValue()[fieldName],
error: this.getFieldError(fieldName),
onChange: this.handleFieldChange.bind(this, fieldName),
onBlur: this.validateField.bind(this, fieldName)
@ -111,8 +115,8 @@ class Form extends React.Component {
}
getAllFieldErrors() {
let form = this.state.form;
let fields = Object.keys(this.state.form);
let form = this.getFormValue();
let fields = Object.keys(form);
let errors = {};
_.each(fields, (fieldName) => {
@ -122,7 +126,7 @@ class Form extends React.Component {
return errors;
}
getErrorsWithValidatedField(fieldName, form = this.state.form, errors = this.state.errors) {
getErrorsWithValidatedField(fieldName, form = this.getFormValue(), errors = this.state.errors) {
let newErrors = _.clone(errors);
if (this.state.validations[fieldName]) {
@ -156,7 +160,7 @@ class Form extends React.Component {
handleSubmit(event) {
event.preventDefault();
const form = _.mapValues(this.state.form, (field) => {
const form = _.mapValues(this.getFormValue(), (field) => {
if (field instanceof RichTextEditor.EditorValue) {
return field.toString('html');
} else {
@ -172,13 +176,18 @@ class Form extends React.Component {
}
handleFieldChange(fieldName, event) {
let form = _.clone(this.state.form);
let form = _.clone(this.getFormValue());
form[fieldName] = event.target.value;
this.setState({
form: form
});
if (this.props.onChange) {
this.props.onChange(form);
}
}
isValidField(node) {
@ -203,6 +212,10 @@ class Form extends React.Component {
}
}
getFormValue() {
return this.props.values || this.state.form;
}
focusFirstErrorField() {
let firstErrorField = this.getFirstErrorField();

View File

@ -35,7 +35,7 @@ class Listing extends React.Component {
renderAddButton() {
return (
<div className="listing__add">
<Button type="secondary" size="auto" className="listing__add-button">
<Button type="secondary" size="auto" className="listing__add-button" onClick={this.props.onAddClick}>
<Icon name="plus-circle"/> {this.props.addNewText}
</Button>
</div>

View File

@ -37,7 +37,7 @@ class TextEditor extends React.Component {
getEditorProps() {
return {
className: 'text-editor__editor',
value: this.state.value,
value: this.props.value || this.state.value,
ref: 'editor',
onChange: this.onEditorChange.bind(this),
onFocus: this.onEditorFocus.bind(this),

View File

@ -17,7 +17,7 @@ const languages = {
};
const i18nData = function (key, lang) {
return languages[lang][key];
return (languages[lang] && languages[lang][key]) || key;
};
export default i18nData

View File

@ -55,7 +55,8 @@ export default {
'MEDIUM': 'Medium',
'LOW': 'Low',
'TITLE': 'Title',
'CONTENT': 'Content',
//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.',
'TICKET_LIST_DESCRIPTION': 'Here you can find a list of all tickets you have sent to our support team.',
@ -86,5 +87,6 @@ export default {
'ARE_YOU_SURE': 'Are you sure?',
'EMAIL_CHANGED': 'Email has been changed successfully',
'PASSWORD_CHANGED': 'Password has been changed successfully',
'OLD_PASSWORD_INCORRECT': 'Old password is incorrect'
'OLD_PASSWORD_INCORRECT': 'Old password is incorrect',
'WILL_LOSE_CHANGES': 'You haven\'t save. Your changes will be lost.'
};

View File

@ -8,7 +8,7 @@ class AlphaNumericValidator extends Validator {
}
validate(value, form) {
let alphaMatch = /^[-\sa-zA-Z.]+$/;
let alphaMatch = /^[ A-Za-z0-9_@./#&+-]*$/;
if (!alphaMatch.test(value)) return this.getError(this.errorKey);
}