Skip to content

Commit

Permalink
Merge pull request #2364 from kobotoolbox/2245-improve-translations-m…
Browse files Browse the repository at this point in the history
…odal

Improvements to translations modal
  • Loading branch information
magicznyleszek authored Aug 17, 2019
2 parents aaaf29c + 19963e7 commit 083b462
Show file tree
Hide file tree
Showing 6 changed files with 13,524 additions and 194 deletions.
6 changes: 5 additions & 1 deletion jsapp/js/components/modal.es6
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,11 @@ class Modal extends React.Component {
/>
}
{ this.props.params.type == MODAL_TYPES.FORM_TRANSLATIONS_TABLE &&
<TranslationTable asset={this.props.params.asset} langIndex={this.props.params.langIndex} />
<TranslationTable
asset={this.props.params.asset}
langString={this.props.params.langString}
langIndex={this.props.params.langIndex}
/>
}
</ui.Modal.Body>
</ui.Modal>
Expand Down
158 changes: 158 additions & 0 deletions jsapp/js/components/modalForms/languageForm.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import React from 'react';
import autoBind from 'react-autobind';
import bem from 'js/bem';
import TextBox from 'js/components/textBox';
import {t, getLangAsObject} from 'utils';

/*
Properties:
- langString <string>: follows pattern "NAME (CODE)"
- langIndex <string>
- onLanguageChange <function>: required
- existingLanguages <langString[]>: for validation purposes
- isDefault <boolean>: for default language only
*/
class LanguageForm extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
nameError: null,
code: '',
codeError: null
};

if (this.props.langString) {
const lang = getLangAsObject(this.props.langString);

if (lang) {
this.state = {
name: lang.name || '',
code: lang.code || ''
};
} else {
// if language isn't in "English (en)" format, assume it is a simple language name string
this.state = {
name: this.props.langString,
code: ''
};
}
}

autoBind(this);
}
isLanguageNameValid() {
if (this.props.existingLanguages) {
let isNameUnique = true;
this.props.existingLanguages.forEach((langString) => {
if (this.props.langString && langString === this.props.langString) {
// skip comparing to itself (editing language context)
} else if (langString !== null) {
const langObj = getLangAsObject(langString);
if (langObj && langObj.name === this.state.name) {
isNameUnique = false;
}
}
});
return isNameUnique;
} else {
return true;
}
}
isLanguageCodeValid() {
if (this.props.existingLanguages) {
let isCodeUnique = true;
this.props.existingLanguages.forEach((langString) => {
if (this.props.langString && langString === this.props.langString) {
// skip comparing to itself (editing language context)
} else if (langString !== null) {
const langObj = getLangAsObject(langString);
if (langObj && langObj.code === this.state.code) {
isCodeUnique = false;
}
}
});
return isCodeUnique;
} else {
return true;
}
}
onSubmit(evt) {
evt.preventDefault();
evt.currentTarget.disabled = true;

const isNameValid = this.isLanguageNameValid();
if (!isNameValid) {
this.setState({nameError: t('Name must be unique!')});
evt.currentTarget.disabled = false;
} else {
this.setState({nameError: null});
}

const isCodeValid = this.isLanguageCodeValid();
if (!isCodeValid) {
this.setState({codeError: t('Code must be unique!')});
evt.currentTarget.disabled = false;
} else {
this.setState({codeError: null});
}

if (isNameValid && isCodeValid) {
let langIndex = (this.props.isDefault) ? 0 : -1;
if (this.props.langIndex !== undefined) {
langIndex = this.props.langIndex;
}
this.props.onLanguageChange({
name: this.state.name,
code: this.state.code
}, langIndex);
}
}
onNameChange (newName) {
this.setState({name: newName.trim()});
}
onCodeChange (newCode) {
this.setState({code: newCode.trim()});
}
render () {
let isAnyFieldEmpty = this.state.name.length === 0 || this.state.code.length === 0;

return (
<bem.FormView__form m='add-language-fields'>
<bem.FormView__cell m='lang-name'>
<bem.FormModal__item>
<label>{(this.props.isDefault) ? t('Default language name') : t('Language name')}</label>
<TextBox
value={this.state.name}
onChange={this.onNameChange}
errors={this.state.nameError}
/>
</bem.FormModal__item>
</bem.FormView__cell>

<bem.FormView__cell m='lang-code'>
<bem.FormModal__item>
<label>{(this.props.isDefault) ? t('Default language code') : t('Language code')}</label>
<TextBox
value={this.state.code}
onChange={this.onCodeChange}
errors={this.state.codeError}
/>
</bem.FormModal__item>
</bem.FormView__cell>

<bem.FormView__cell m='submit-button'>
<button
className='mdl-button mdl-js-button mdl-button--raised mdl-button--colored'
onClick={this.onSubmit} type='submit'
disabled={isAnyFieldEmpty}
>
{this.props.langIndex !== undefined ? t('Update') : (this.props.isDefault) ? t('Set') : t('Add')}
</button>
</bem.FormView__cell>
</bem.FormView__form>
);
}
}

export default LanguageForm;
Loading

0 comments on commit 083b462

Please sign in to comment.