Fix custom responses #388

This commit is contained in:
Ivan Diaz 2018-11-15 12:53:23 -03:00
parent 9d67a19c35
commit a2e505c33d

View File

@ -21,21 +21,27 @@ import TextEditor from 'core-components/text-editor';
class AdminPanelCustomResponses extends React.Component { class AdminPanelCustomResponses extends React.Component {
static defaultProps = { static defaultProps = {
items: [] items: [],
}; };
state = { state = {
formClicked: false,
showForm: false,
formLoading: false, formLoading: false,
selectedIndex: -1, selectedIndex: -1,
edited: false,
errors: {}, errors: {},
originalForm: {
title: '',
content: TextEditor.createEmpty(),
language: this.props.language
},
form: { form: {
title: '', title: '',
content: TextEditor.createEmpty(), content: TextEditor.createEmpty(),
language: 'en' language: this.props.language
} }
}; };
componentDidMount() { componentDidMount() {
if (!this.props.loaded) { if (!this.props.loaded) {
this.retrieveCustomResponses(); this.retrieveCustomResponses();
@ -57,25 +63,7 @@ class AdminPanelCustomResponses extends React.Component {
<div className="col-md-3"> <div className="col-md-3">
<Listing {...this.getListingProps()}/> <Listing {...this.getListingProps()}/>
</div> </div>
<div className="col-md-9"> {this.state.showForm ? this.renderForm() : null}
<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 className="col-md-5">
<FormField label={i18n('LANGUAGE')} name="language" field="input" decorator={LanguageSelector} fieldProps={{size: 'medium'}} />
</div>
</div>
<FormField label={i18n('CONTENT')} name="content" validation="TEXT_AREA" required field="textarea" />
<div className="admin-panel-custom-responses__actions">
<div className="admin-panel-custom-responses__save-button">
<SubmitButton type="secondary" size="small">{i18n('SAVE')}</SubmitButton>
</div>
{(this.state.selectedIndex !== -1) ? this.renderOptionalButtons() : null}
</div>
</Form>
</div>
</div> </div>
); );
} }
@ -88,11 +76,35 @@ class AdminPanelCustomResponses extends React.Component {
); );
} }
renderForm() {
return (
<div className="col-md-9">
<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 className="col-md-5">
<FormField label={i18n('LANGUAGE')} name="language" field="input" decorator={LanguageSelector} fieldProps={{size: 'medium'}} />
</div>
</div>
<FormField label={i18n('CONTENT')} name="content" validation="TEXT_AREA" required field="textarea" />
<div className="admin-panel-custom-responses__actions">
<div className="admin-panel-custom-responses__save-button">
<SubmitButton type="secondary" size="small">{i18n('SAVE')}</SubmitButton>
</div>
{(this.state.selectedIndex !== -1) ? this.renderOptionalButtons() : null}
</div>
</Form>
</div>
);
}
renderOptionalButtons() { renderOptionalButtons() {
return ( return (
<div className="admin-panel-custom-responses__optional-buttons"> <div className="admin-panel-custom-responses__optional-buttons">
<div className="admin-panel-custom-responses__discard-button"> <div className="admin-panel-custom-responses__discard-button">
<Button onClick={this.onDiscardChangesClick.bind(this)}>{i18n('DISCARD_CHANGES')}</Button> {this.isEdited() ? <Button onClick={this.onDiscardChangesClick.bind(this)}>{i18n('DISCARD_CHANGES')}</Button> : null}
</div> </div>
<div className="admin-panel-custom-responses__delete-button"> <div className="admin-panel-custom-responses__delete-button">
<Button onClick={this.onDeleteClick.bind(this)}>{i18n('DELETE')}</Button> <Button onClick={this.onDeleteClick.bind(this)}>{i18n('DELETE')}</Button>
@ -117,7 +129,8 @@ class AdminPanelCustomResponses extends React.Component {
values: this.state.form, values: this.state.form,
errors: this.state.errors, errors: this.state.errors,
loading: this.state.formLoading, loading: this.state.formLoading,
onChange: (form) => {this.setState({form, edited: true})}, onClick: () => this.setState({formClicked: true}),
onChange: (form) => this.setState({form}),
onValidateErrors: (errors) => {this.setState({errors})}, onValidateErrors: (errors) => {this.setState({errors})},
onSubmit: this.onFormSubmit.bind(this) onSubmit: this.onFormSubmit.bind(this)
} }
@ -139,7 +152,7 @@ class AdminPanelCustomResponses extends React.Component {
} }
onItemChange(index) { onItemChange(index) {
if(this.state.edited) { if(this.isEdited()) {
AreYouSure.openModal(i18n('WILL_LOSE_CHANGES'), this.updateForm.bind(this, index)); AreYouSure.openModal(i18n('WILL_LOSE_CHANGES'), this.updateForm.bind(this, index));
} else { } else {
this.updateForm(index); this.updateForm(index);
@ -147,28 +160,30 @@ class AdminPanelCustomResponses extends React.Component {
} }
onFormSubmit(form) { onFormSubmit(form) {
const {items, allowedLanguages} = this.props;
this.setState({formLoading: true}); this.setState({formLoading: true});
if(this.state.selectedIndex !== -1) { if(this.state.selectedIndex !== -1) {
API.call({ API.call({
path: '/ticket/edit-custom-response', path: '/ticket/edit-custom-response',
data: { data: {
id: this.props.items[this.state.selectedIndex].id, id: items[this.state.selectedIndex].id,
name: form.name, name: form.title,
content: form.content, content: form.content,
language: form.language language: _.includes(allowedLanguages, form.language) ? form.language : allowedLanguages[0]
} }
}).then(() => { }).then(() => {
this.setState({formLoading: false}); this.setState({formLoading: false, originalForm: form});
this.retrieveCustomResponses(); this.retrieveCustomResponses();
}).catch(this.onItemChange.bind(this, -1)); }).catch(this.onItemChange.bind(this, -1));
} else { } else {
this.setState({form, originalForm: form});
API.call({ API.call({
path: '/ticket/add-custom-response', path: '/ticket/add-custom-response',
data: { data: {
name: form.title, name: form.title,
content: form.content, content: form.content,
language: form.language language: _.includes(allowedLanguages, form.language) ? form.language : allowedLanguages[0]
} }
}).then(() => { }).then(() => {
this.retrieveCustomResponses(); this.retrieveCustomResponses();
@ -204,12 +219,14 @@ class AdminPanelCustomResponses extends React.Component {
form.title = (this.props.items[index] && this.props.items[index].name) || ''; form.title = (this.props.items[index] && this.props.items[index].name) || '';
form.content = TextEditor.getEditorStateFromHTML((this.props.items[index] && this.props.items[index].content) || ''); form.content = TextEditor.getEditorStateFromHTML((this.props.items[index] && this.props.items[index].content) || '');
form.language = (this.props.items[index] && this.props.items[index].language) || 'en'; form.language = (this.props.items[index] && this.props.items[index].language) || this.props.language;
this.setState({ this.setState({
formClicked: false,
showForm: true,
selectedIndex: index, selectedIndex: index,
edited: false,
formLoading: false, formLoading: false,
originalForm: form,
form: form, form: form,
errors: {} errors: {}
}); });
@ -217,14 +234,21 @@ class AdminPanelCustomResponses extends React.Component {
retrieveCustomResponses() { retrieveCustomResponses() {
this.props.dispatch(AdminDataActions.retrieveCustomResponses()); this.props.dispatch(AdminDataActions.retrieveCustomResponses());
this.setState({ }
edited: false
}); isEdited() {
return this.state.form.title && this.state.formClicked && (
this.state.form.title != this.state.originalForm.title ||
this.state.form.content != this.state.originalForm.content ||
this.state.form.language != this.state.originalForm.language
);
} }
} }
export default connect((store) => { export default connect((store) => {
return { return {
allowedLanguages: store.config.allowedLanguages,
language: store.config.language,
loaded: store.adminData.customResponsesLoaded, loaded: store.adminData.customResponsesLoaded,
items: store.adminData.customResponses items: store.adminData.customResponses
}; };