Merge develop to feature/mobile-examples
This commit is contained in:
commit
888635275f
6 changed files with 81 additions and 24 deletions
|
@ -1,5 +1,6 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||||
|
|
||||||
import Button from '../../../common/Button';
|
import Button from '../../../common/Button';
|
||||||
|
@ -35,14 +36,17 @@ class NewFileForm extends React.Component {
|
||||||
className="new-file-form__name-input"
|
className="new-file-form__name-input"
|
||||||
id="name"
|
id="name"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Name"
|
placeholder={this.props.t('NewFileForm.Placeholder')}
|
||||||
maxLength="128"
|
maxLength="128"
|
||||||
{...domOnlyProps(name)}
|
{...domOnlyProps(name)}
|
||||||
ref={(element) => {
|
ref={(element) => {
|
||||||
this.fileName = element;
|
this.fileName = element;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button type="submit">Add File</Button>
|
<Button
|
||||||
|
type="submit"
|
||||||
|
>{this.props.t('NewFileForm.AddFileSubmit')}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{name.touched && name.error && (
|
{name.touched && name.error && (
|
||||||
<span className="form-error">{name.error}</span>
|
<span className="form-error">{name.error}</span>
|
||||||
|
@ -59,6 +63,7 @@ NewFileForm.propTypes = {
|
||||||
handleSubmit: PropTypes.func.isRequired,
|
handleSubmit: PropTypes.func.isRequired,
|
||||||
createFile: PropTypes.func.isRequired,
|
createFile: PropTypes.func.isRequired,
|
||||||
focusOnModal: PropTypes.func.isRequired,
|
focusOnModal: PropTypes.func.isRequired,
|
||||||
|
t: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NewFileForm;
|
export default withTranslation()(NewFileForm);
|
||||||
|
|
|
@ -3,6 +3,8 @@ import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { bindActionCreators, compose } from 'redux';
|
import { bindActionCreators, compose } from 'redux';
|
||||||
import { reduxForm } from 'redux-form';
|
import { reduxForm } from 'redux-form';
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
|
import i18n from 'i18next';
|
||||||
import NewFileForm from './NewFileForm';
|
import NewFileForm from './NewFileForm';
|
||||||
import { closeNewFileModal } from '../actions/ide';
|
import { closeNewFileModal } from '../actions/ide';
|
||||||
import { createFile } from '../actions/files';
|
import { createFile } from '../actions/files';
|
||||||
|
@ -33,11 +35,11 @@ class NewFileModal extends React.Component {
|
||||||
<section className="modal" ref={(element) => { this.modal = element; }}>
|
<section className="modal" ref={(element) => { this.modal = element; }}>
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div className="modal__header">
|
<div className="modal__header">
|
||||||
<h2 className="modal__title">Create File</h2>
|
<h2 className="modal__title">{this.props.t('NewFileModal.Title')}</h2>
|
||||||
<button
|
<button
|
||||||
className="modal__exit-button"
|
className="modal__exit-button"
|
||||||
onClick={this.props.closeNewFileModal}
|
onClick={this.props.closeNewFileModal}
|
||||||
aria-label="Close New File Modal"
|
aria-label={this.props.t('NewFileModal.CloseButtonARIA')}
|
||||||
>
|
>
|
||||||
<ExitIcon focusable="false" aria-hidden="true" />
|
<ExitIcon focusable="false" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
|
@ -54,16 +56,17 @@ class NewFileModal extends React.Component {
|
||||||
|
|
||||||
NewFileModal.propTypes = {
|
NewFileModal.propTypes = {
|
||||||
createFile: PropTypes.func.isRequired,
|
createFile: PropTypes.func.isRequired,
|
||||||
closeNewFileModal: PropTypes.func.isRequired
|
closeNewFileModal: PropTypes.func.isRequired,
|
||||||
|
t: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
function validate(formProps) {
|
function validate(formProps) {
|
||||||
const errors = {};
|
const errors = {};
|
||||||
|
|
||||||
if (!formProps.name) {
|
if (!formProps.name) {
|
||||||
errors.name = 'Please enter a name';
|
errors.name = i18n.t('NewFileModal.EnterName');
|
||||||
} else if (!formProps.name.match(CREATE_FILE_REGEX)) {
|
} else if (!formProps.name.match(CREATE_FILE_REGEX)) {
|
||||||
errors.name = 'Invalid file type. Valid extensions are .js, .css, .json, .txt, .csv, .tsv, .frag, and .vert.';
|
errors.name = i18n.t('NewFileModal.InvalidType');
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
|
@ -77,11 +80,11 @@ function mapDispatchToProps(dispatch) {
|
||||||
return bindActionCreators({ createFile, closeNewFileModal }, dispatch);
|
return bindActionCreators({ createFile, closeNewFileModal }, dispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
export default withTranslation()(compose(
|
||||||
connect(mapStateToProps, mapDispatchToProps),
|
connect(mapStateToProps, mapDispatchToProps),
|
||||||
reduxForm({
|
reduxForm({
|
||||||
form: 'new-file',
|
form: 'new-file',
|
||||||
fields: ['name'],
|
fields: ['name'],
|
||||||
validate
|
validate
|
||||||
})
|
})
|
||||||
)(NewFileModal);
|
)(NewFileModal));
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||||
|
|
||||||
import Button from '../../../common/Button';
|
import Button from '../../../common/Button';
|
||||||
|
|
||||||
|
|
||||||
class NewFolderForm extends React.Component {
|
class NewFolderForm extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -35,13 +37,14 @@ class NewFolderForm extends React.Component {
|
||||||
id="name"
|
id="name"
|
||||||
type="text"
|
type="text"
|
||||||
maxLength="128"
|
maxLength="128"
|
||||||
placeholder="Name"
|
placeholder={this.props.t('NewFolderForm.Placeholder')}
|
||||||
ref={(element) => {
|
ref={(element) => { this.fileName = element; }}
|
||||||
this.fileName = element;
|
|
||||||
}}
|
|
||||||
{...domOnlyProps(name)}
|
{...domOnlyProps(name)}
|
||||||
/>
|
/>
|
||||||
<Button type="submit">Add Folder</Button>
|
<Button
|
||||||
|
type="submit"
|
||||||
|
>{this.props.t('NewFolderForm.AddFolderSubmit')}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{name.touched && name.error && (
|
{name.touched && name.error && (
|
||||||
<span className="form-error">{name.error}</span>
|
<span className="form-error">{name.error}</span>
|
||||||
|
@ -60,9 +63,10 @@ NewFolderForm.propTypes = {
|
||||||
closeModal: PropTypes.func.isRequired,
|
closeModal: PropTypes.func.isRequired,
|
||||||
submitting: PropTypes.bool,
|
submitting: PropTypes.bool,
|
||||||
pristine: PropTypes.bool,
|
pristine: PropTypes.bool,
|
||||||
|
t: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
NewFolderForm.defaultProps = {
|
NewFolderForm.defaultProps = {
|
||||||
submitting: false,
|
submitting: false,
|
||||||
pristine: true,
|
pristine: true,
|
||||||
};
|
};
|
||||||
export default NewFolderForm;
|
export default withTranslation()(NewFolderForm);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { reduxForm } from 'redux-form';
|
import { reduxForm } from 'redux-form';
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
|
import i18n from 'i18next';
|
||||||
import NewFolderForm from './NewFolderForm';
|
import NewFolderForm from './NewFolderForm';
|
||||||
|
|
||||||
import ExitIcon from '../../../images/exit.svg';
|
import ExitIcon from '../../../images/exit.svg';
|
||||||
|
@ -15,11 +17,11 @@ class NewFolderModal extends React.Component {
|
||||||
<section className="modal" ref={(element) => { this.newFolderModal = element; }} >
|
<section className="modal" ref={(element) => { this.newFolderModal = element; }} >
|
||||||
<div className="modal-content-folder">
|
<div className="modal-content-folder">
|
||||||
<div className="modal__header">
|
<div className="modal__header">
|
||||||
<h2 className="modal__title">Create Folder</h2>
|
<h2 className="modal__title">{this.props.t('NewFolderModal.Title')}</h2>
|
||||||
<button
|
<button
|
||||||
className="modal__exit-button"
|
className="modal__exit-button"
|
||||||
onClick={this.props.closeModal}
|
onClick={this.props.closeModal}
|
||||||
aria-label="Close New Folder Modal"
|
aria-label={this.props.t('NewFolderModal.CloseButtonARIA')}
|
||||||
>
|
>
|
||||||
<ExitIcon focusable="false" aria-hidden="true" />
|
<ExitIcon focusable="false" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
|
@ -32,23 +34,24 @@ class NewFolderModal extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
NewFolderModal.propTypes = {
|
NewFolderModal.propTypes = {
|
||||||
closeModal: PropTypes.func.isRequired
|
closeModal: PropTypes.func.isRequired,
|
||||||
|
t: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
function validate(formProps) {
|
function validate(formProps) {
|
||||||
const errors = {};
|
const errors = {};
|
||||||
if (!formProps.name) {
|
if (!formProps.name) {
|
||||||
errors.name = 'Please enter a name';
|
errors.name = i18n.t('NewFolderModal.EnterName');
|
||||||
} else if (formProps.name.trim().length === 0) {
|
} else if (formProps.name.trim().length === 0) {
|
||||||
errors.name = 'Folder name cannot contain only spaces';
|
errors.name = i18n.t('NewFolderModal.EmptyName');
|
||||||
} else if (formProps.name.match(/\.+/i)) {
|
} else if (formProps.name.match(/\.+/i)) {
|
||||||
errors.name = 'Folder name cannot contain an extension';
|
errors.name = i18n.t('NewFolderModal.InvalidExtension');
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
export default reduxForm({
|
export default withTranslation()(reduxForm({
|
||||||
form: 'new-folder',
|
form: 'new-folder',
|
||||||
fields: ['name'],
|
fields: ['name'],
|
||||||
validate
|
validate
|
||||||
})(NewFolderModal);
|
})(NewFolderModal));
|
||||||
|
|
|
@ -173,5 +173,26 @@
|
||||||
},
|
},
|
||||||
"IDEView": {
|
"IDEView": {
|
||||||
"SubmitFeedback": "Submit Feedback"
|
"SubmitFeedback": "Submit Feedback"
|
||||||
|
},
|
||||||
|
"NewFileModal": {
|
||||||
|
"Title": "Create File",
|
||||||
|
"CloseButtonARIA": "Close New File Modal",
|
||||||
|
"EnterName": "Please enter a name",
|
||||||
|
"InvalidType": "Invalid file type. Valid extensions are .js, .css, .json, .txt, .csv, .tsv, .frag, and .vert."
|
||||||
|
},
|
||||||
|
"NewFileForm": {
|
||||||
|
"AddFileSubmit": "Add File",
|
||||||
|
"Placeholder": "Name"
|
||||||
|
},
|
||||||
|
"NewFolderModal": {
|
||||||
|
"Title": "Create Folder",
|
||||||
|
"CloseButtonARIA": "Close New Folder Modal",
|
||||||
|
"EnterName": "Please enter a name",
|
||||||
|
"EmptyName": "Folder name cannot contain only spaces",
|
||||||
|
"InvalidExtension": "Folder name cannot contain an extension"
|
||||||
|
},
|
||||||
|
"NewFolderForm": {
|
||||||
|
"AddFolderSubmit": "Add Folder",
|
||||||
|
"Placeholder": "Name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,27 @@
|
||||||
},
|
},
|
||||||
"IDEView": {
|
"IDEView": {
|
||||||
"SubmitFeedback": "Enviar retroalimentación"
|
"SubmitFeedback": "Enviar retroalimentación"
|
||||||
|
},
|
||||||
|
"NewFileModal": {
|
||||||
|
"Title": "Crear Archivo",
|
||||||
|
"CloseButtonARIA": "Cerrar diálogo de crear archivo",
|
||||||
|
"EnterName": "Por favor introduce un nombre",
|
||||||
|
"InvalidType": "Tipo de archivo inválido. Las extensiones válidas son .js, .css, .json, .txt, .csv, .tsv, .frag y .vert."
|
||||||
|
},
|
||||||
|
"NewFileForm": {
|
||||||
|
"AddFileSubmit": "Agregar Archivo",
|
||||||
|
"Placeholder": "Nombre"
|
||||||
|
},
|
||||||
|
"NewFolderModal": {
|
||||||
|
"Title": "Crear Directorio",
|
||||||
|
"CloseButtonARIA": "Cerrar Diálogo de Nuevo Directorio",
|
||||||
|
"EnterName": "Por favor introduce un nombre",
|
||||||
|
"EmptyName": " El nombre del directorio no debe contener solo espacios vacíos",
|
||||||
|
"InvalidExtension": "El nombre del directorio no debe contener una extensión"
|
||||||
|
},
|
||||||
|
"NewFolderForm": {
|
||||||
|
"AddFolderSubmit": "Agregar Directorio",
|
||||||
|
"Placeholder": "Nombre"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue