From db9a703def0ac6455f24b5ad8903d44c3b4112ce Mon Sep 17 00:00:00 2001 From: josephmwells Date: Mon, 3 Aug 2020 11:40:48 -0700 Subject: [PATCH 1/4] Add character limit to sketch name on the back end #568 --- server/controllers/project.controller/createProject.js | 3 ++- server/models/project.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/controllers/project.controller/createProject.js b/server/controllers/project.controller/createProject.js index e4040268..3c12fd37 100644 --- a/server/controllers/project.controller/createProject.js +++ b/server/controllers/project.controller/createProject.js @@ -8,8 +8,9 @@ export default function createProject(req, res) { projectValues = Object.assign(projectValues, req.body); + // TODO: Error handling to match spec function sendFailure() { - res.json({ success: false }); + res.status(422).json({ success: false }); } function populateUserData(newProject) { diff --git a/server/models/project.js b/server/models/project.js index bf8c992e..98f83d92 100644 --- a/server/models/project.js +++ b/server/models/project.js @@ -29,7 +29,7 @@ fileSchema.set('toJSON', { const projectSchema = new Schema( { - name: { type: String, default: "Hello p5.js, it's the server" }, + name: { type: String, default: "Hello p5.js, it's the server", maxlength: 256 }, user: { type: Schema.Types.ObjectId, ref: 'User' }, serveSecure: { type: Boolean, default: false }, files: { type: [fileSchema] }, From 76bcf9cb097285495b2a8c22a68cc7f06e0c0d2f Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Mon, 3 Aug 2020 16:42:28 -0400 Subject: [PATCH 2/4] [#1529] Send status codes, run validator --- server/controllers/project.controller.js | 7 ++++--- server/controllers/project.controller/createProject.js | 3 +-- server/models/project.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/server/controllers/project.controller.js b/server/controllers/project.controller.js index 7f118c23..2a83aa6a 100644 --- a/server/controllers/project.controller.js +++ b/server/controllers/project.controller.js @@ -30,14 +30,15 @@ export function updateProject(req, res) { $set: req.body }, { - new: true + new: true, + runValidators: true } ) .populate('user', 'username') .exec((updateProjectErr, updatedProject) => { if (updateProjectErr) { console.log(updateProjectErr); - res.json({ success: false }); + res.status(400).json({ success: false }); return; } if (req.body.files && updatedProject.files.length !== req.body.files.length) { @@ -50,7 +51,7 @@ export function updateProject(req, res) { updatedProject.save((innerErr, savedProject) => { if (innerErr) { console.log(innerErr); - res.json({ success: false }); + res.status(400).json({ success: false }); return; } res.json(savedProject); diff --git a/server/controllers/project.controller/createProject.js b/server/controllers/project.controller/createProject.js index 3c12fd37..74529c0d 100644 --- a/server/controllers/project.controller/createProject.js +++ b/server/controllers/project.controller/createProject.js @@ -8,9 +8,8 @@ export default function createProject(req, res) { projectValues = Object.assign(projectValues, req.body); - // TODO: Error handling to match spec function sendFailure() { - res.status(422).json({ success: false }); + res.status(400).json({ success: false }); } function populateUserData(newProject) { diff --git a/server/models/project.js b/server/models/project.js index 98f83d92..3581e998 100644 --- a/server/models/project.js +++ b/server/models/project.js @@ -29,7 +29,7 @@ fileSchema.set('toJSON', { const projectSchema = new Schema( { - name: { type: String, default: "Hello p5.js, it's the server", maxlength: 256 }, + name: { type: String, default: "Hello p5.js, it's the server", maxlength: 128 }, user: { type: Schema.Types.ObjectId, ref: 'User' }, serveSecure: { type: Boolean, default: false }, files: { type: [fileSchema] }, From 6827983adcfd19b70dba9e42018c95a99b29e930 Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Thu, 6 Aug 2020 12:47:07 -0400 Subject: [PATCH 3/4] 1.0.7 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04592b99..8abec584 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "p5.js-web-editor", - "version": "1.0.6", + "version": "1.0.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ba2680a8..01f558f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "p5.js-web-editor", - "version": "1.0.6", + "version": "1.0.7", "description": "The web editor for p5.js.", "scripts": { "clean": "rimraf dist", From 3253770ff6a14b87bc8b497945179927ca7ba283 Mon Sep 17 00:00:00 2001 From: ov Date: Tue, 11 Aug 2020 14:56:45 +0100 Subject: [PATCH 4/4] Spanish Translation Modals for Sketch Menu (#1538) * NewFileModal spanish transaltion translations.json (both languages EN - ES) changes in NewFileForm.jsx and NewFileModal.jsx to link the new keys. * NewFolderModal spanish translation translations.json (both languages EN - ES) changes in NewFileForm.jsx and NewFileModal.jsx to link the new keys. --- client/modules/IDE/components/NewFileForm.jsx | 10 +++++---- .../modules/IDE/components/NewFileModal.jsx | 17 ++++++++------- .../modules/IDE/components/NewFolderForm.jsx | 11 ++++++---- .../modules/IDE/components/NewFolderModal.jsx | 19 ++++++++++------- translations/locales/en-US/translations.json | 21 +++++++++++++++++++ translations/locales/es-419/translations.json | 21 +++++++++++++++++++ 6 files changed, 76 insertions(+), 23 deletions(-) diff --git a/client/modules/IDE/components/NewFileForm.jsx b/client/modules/IDE/components/NewFileForm.jsx index 9c0234f7..748bd3c2 100644 --- a/client/modules/IDE/components/NewFileForm.jsx +++ b/client/modules/IDE/components/NewFileForm.jsx @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { withTranslation } from 'react-i18next'; import { domOnlyProps } from '../../../utils/reduxFormUtils'; import Button from '../../../common/Button'; @@ -30,14 +31,14 @@ class NewFileForm extends React.Component { className="new-file-form__name-input" id="name" type="text" - placeholder="Name" + placeholder={this.props.t('NewFileForm.Placeholder')} maxLength="128" {...domOnlyProps(name)} ref={(element) => { this.fileName = element; }} /> {name.touched && name.error && {name.error}} @@ -52,7 +53,8 @@ NewFileForm.propTypes = { }).isRequired, handleSubmit: 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); diff --git a/client/modules/IDE/components/NewFileModal.jsx b/client/modules/IDE/components/NewFileModal.jsx index 412d9895..791cb0af 100644 --- a/client/modules/IDE/components/NewFileModal.jsx +++ b/client/modules/IDE/components/NewFileModal.jsx @@ -3,6 +3,8 @@ import React from 'react'; import { connect } from 'react-redux'; import { bindActionCreators, compose } from 'redux'; import { reduxForm } from 'redux-form'; +import { withTranslation } from 'react-i18next'; +import i18n from 'i18next'; import NewFileForm from './NewFileForm'; import { closeNewFileModal } from '../actions/ide'; import { createFile } from '../actions/files'; @@ -33,11 +35,11 @@ class NewFileModal extends React.Component {
{ this.modal = element; }}>
-

Create File

+

{this.props.t('NewFileModal.Title')}

@@ -54,16 +56,17 @@ class NewFileModal extends React.Component { NewFileModal.propTypes = { createFile: PropTypes.func.isRequired, - closeNewFileModal: PropTypes.func.isRequired + closeNewFileModal: PropTypes.func.isRequired, + t: PropTypes.func.isRequired }; function validate(formProps) { const errors = {}; if (!formProps.name) { - errors.name = 'Please enter a name'; + errors.name = i18n.t('NewFileModal.EnterName'); } 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; @@ -77,11 +80,11 @@ function mapDispatchToProps(dispatch) { return bindActionCreators({ createFile, closeNewFileModal }, dispatch); } -export default compose( +export default withTranslation()(compose( connect(mapStateToProps, mapDispatchToProps), reduxForm({ form: 'new-file', fields: ['name'], validate }) -)(NewFileModal); +)(NewFileModal)); diff --git a/client/modules/IDE/components/NewFolderForm.jsx b/client/modules/IDE/components/NewFolderForm.jsx index c5e0b564..ca45d527 100644 --- a/client/modules/IDE/components/NewFolderForm.jsx +++ b/client/modules/IDE/components/NewFolderForm.jsx @@ -1,9 +1,11 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { withTranslation } from 'react-i18next'; import { domOnlyProps } from '../../../utils/reduxFormUtils'; import Button from '../../../common/Button'; + class NewFolderForm extends React.Component { constructor(props) { super(props); @@ -32,13 +34,13 @@ class NewFolderForm extends React.Component { id="name" type="text" maxLength="128" - placeholder="Name" + placeholder={this.props.t('NewFolderForm.Placeholder')} ref={(element) => { this.fileName = element; }} {...domOnlyProps(name)} />
{name.touched && name.error && {name.error}} @@ -55,10 +57,11 @@ NewFolderForm.propTypes = { createFolder: PropTypes.func.isRequired, closeModal: PropTypes.func.isRequired, submitting: PropTypes.bool, - pristine: PropTypes.bool + pristine: PropTypes.bool, + t: PropTypes.func.isRequired }; NewFolderForm.defaultProps = { submitting: false, pristine: true }; -export default NewFolderForm; +export default withTranslation()(NewFolderForm); diff --git a/client/modules/IDE/components/NewFolderModal.jsx b/client/modules/IDE/components/NewFolderModal.jsx index 13029d6c..bf897afa 100644 --- a/client/modules/IDE/components/NewFolderModal.jsx +++ b/client/modules/IDE/components/NewFolderModal.jsx @@ -1,6 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import { reduxForm } from 'redux-form'; +import { withTranslation } from 'react-i18next'; +import i18n from 'i18next'; import NewFolderForm from './NewFolderForm'; import ExitIcon from '../../../images/exit.svg'; @@ -15,11 +17,11 @@ class NewFolderModal extends React.Component {
{ this.newFolderModal = element; }} >
-

Create Folder

+

{this.props.t('NewFolderModal.Title')}

@@ -32,23 +34,24 @@ class NewFolderModal extends React.Component { } NewFolderModal.propTypes = { - closeModal: PropTypes.func.isRequired + closeModal: PropTypes.func.isRequired, + t: PropTypes.func.isRequired }; function validate(formProps) { const errors = {}; if (!formProps.name) { - errors.name = 'Please enter a name'; + errors.name = i18n.t('NewFolderModal.EnterName'); } 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)) { - errors.name = 'Folder name cannot contain an extension'; + errors.name = i18n.t('NewFolderModal.InvalidExtension'); } return errors; } -export default reduxForm({ +export default withTranslation()(reduxForm({ form: 'new-folder', fields: ['name'], validate -})(NewFolderModal); +})(NewFolderModal)); diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json index 56a898f5..d0868580 100644 --- a/translations/locales/en-US/translations.json +++ b/translations/locales/en-US/translations.json @@ -173,5 +173,26 @@ }, "IDEView": { "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" } } diff --git a/translations/locales/es-419/translations.json b/translations/locales/es-419/translations.json index 8b8d8f87..398da8dc 100644 --- a/translations/locales/es-419/translations.json +++ b/translations/locales/es-419/translations.json @@ -172,6 +172,27 @@ }, "IDEView": { "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" } }