From 937421e90c50ad4dcdc3506818b73db97ef08285 Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Thu, 30 Jul 2020 18:59:12 -0400 Subject: [PATCH 01/13] [#1526] Add ellipsis to sidebar file names --- client/modules/IDE/components/FileNode.jsx | 43 +++++++++++++++++++++- client/modules/IDE/pages/IDEView.jsx | 2 +- client/styles/components/_sidebar.scss | 25 +++++++++++-- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/client/modules/IDE/components/FileNode.jsx b/client/modules/IDE/components/FileNode.jsx index 57238cf8..7bfaa5de 100644 --- a/client/modules/IDE/components/FileNode.jsx +++ b/client/modules/IDE/components/FileNode.jsx @@ -10,6 +10,47 @@ import FolderRightIcon from '../../../images/triangle-arrow-right.svg'; import FolderDownIcon from '../../../images/triangle-arrow-down.svg'; import FileIcon from '../../../images/file.svg'; +function FileName({ name }) { + const nameArray = name.split('.'); + if (nameArray.length > 1) { + const extension = `.${nameArray[nameArray.length - 1]}`; + const fileName = nameArray.slice(0, -1).join(''); + const firstLetter = fileName[0]; + const lastLetter = fileName[fileName.length - 1]; + const middleText = fileName.slice(1, -1); + return ( + + {firstLetter} + {fileName.length > 2 && + {middleText} + } + {fileName.length > 1 && + {lastLetter} + } + {extension} + + ); + } + const firstLetter = name[0]; + const lastLetter = name[name.length - 1]; + const middleText = name.slice(1, -1); + return ( + + {firstLetter} + {name.length > 2 && + {middleText} + } + {name.length > 1 && + {lastLetter} + } + + ); +} + +FileName.propTypes = { + name: PropTypes.string.isRequired +}; + export class FileNode extends React.Component { constructor(props) { super(props); @@ -210,7 +251,7 @@ export class FileNode extends React.Component { className="sidebar__file-item-name" onClick={this.handleFileClick} > - {this.state.updatedName} + this.setState({ sidebarSize: size })} onDragFinished={this._handleSidebarPaneOnDragFinished} allowResize={this.props.ide.sidebarIsExpanded} - minSize={20} + minSize={125} > Date: Mon, 3 Aug 2020 13:52:07 -0400 Subject: [PATCH 02/13] [#1526] Refactor FileName component - Create function parseFileName to separate a file name into first letter, last letter, middle, extension --- client/modules/IDE/components/FileNode.jsx | 52 ++++++++++++++-------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/client/modules/IDE/components/FileNode.jsx b/client/modules/IDE/components/FileNode.jsx index 7bfaa5de..4e54460b 100644 --- a/client/modules/IDE/components/FileNode.jsx +++ b/client/modules/IDE/components/FileNode.jsx @@ -10,39 +10,53 @@ import FolderRightIcon from '../../../images/triangle-arrow-right.svg'; import FolderDownIcon from '../../../images/triangle-arrow-down.svg'; import FileIcon from '../../../images/file.svg'; -function FileName({ name }) { +function parseFileName(name) { const nameArray = name.split('.'); if (nameArray.length > 1) { const extension = `.${nameArray[nameArray.length - 1]}`; - const fileName = nameArray.slice(0, -1).join(''); - const firstLetter = fileName[0]; - const lastLetter = fileName[fileName.length - 1]; - const middleText = fileName.slice(1, -1); - return ( - - {firstLetter} - {fileName.length > 2 && - {middleText} - } - {fileName.length > 1 && - {lastLetter} - } - {extension} - - ); + const baseName = nameArray.slice(0, -1).join(''); + const firstLetter = baseName[0]; + const lastLetter = baseName[baseName.length - 1]; + const middleText = baseName.slice(1, -1); + return { + baseName, + firstLetter, + lastLetter, + middleText, + extension + }; } const firstLetter = name[0]; const lastLetter = name[name.length - 1]; const middleText = name.slice(1, -1); + return { + baseName: name, + firstLetter, + lastLetter, + middleText + }; +} + +function FileName({ name }) { + const { + baseName, + firstLetter, + lastLetter, + middleText, + extension + } = parseFileName(name); return ( {firstLetter} - {name.length > 2 && + {baseName.length > 2 && {middleText} } - {name.length > 1 && + {baseName.length > 1 && {lastLetter} } + {extension && + {extension} + } ); } From db9a703def0ac6455f24b5ad8903d44c3b4112ce Mon Sep 17 00:00:00 2001 From: josephmwells Date: Mon, 3 Aug 2020 11:40:48 -0700 Subject: [PATCH 03/13] 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 855dceaafe05762d9d0bd2959918098d244655e9 Mon Sep 17 00:00:00 2001 From: Neelesh Date: Tue, 4 Aug 2020 00:26:31 +0530 Subject: [PATCH 04/13] Order files alphabetically in sidebar and nested folders. This commit solves issue #704. I added a function to get sorted children of the parent file when ever a file is created of renamed. This function is only called on the parent of the file that is create or renamed. --- client/modules/IDE/reducers/files.js | 35 ++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/client/modules/IDE/reducers/files.js b/client/modules/IDE/reducers/files.js index 7710074d..9c07cbbc 100644 --- a/client/modules/IDE/reducers/files.js +++ b/client/modules/IDE/reducers/files.js @@ -45,7 +45,7 @@ const initialState = () => { name: 'root', id: r, _id: r, - children: [a, b, c], + children: [b, a, c], fileType: 'folder', content: '' }, @@ -110,6 +110,12 @@ function deleteMany(state, ids) { return newState; } +function sortedChildrenId(state, children) { + const childrenArray = state.filter(file => children.includes(file.id)); + childrenArray.sort((a, b) => (a.name > b.name ? 1 : -1)); + return childrenArray.map(child => child.id); +} + const files = (state, action) => { if (state === undefined) { state = initialState(); // eslint-disable-line @@ -138,7 +144,7 @@ const files = (state, action) => { return initialState(); case ActionTypes.CREATE_FILE: // eslint-disable-line { - const newState = state.map((file) => { + let newState = state.map((file) => { if (file.id === action.parentId) { const newFile = Object.assign({}, file); newFile.children = [...newFile.children, action.id]; @@ -146,7 +152,8 @@ const files = (state, action) => { } return file; }); - return [...newState, + newState = [ + ...newState, { name: action.name, id: action.id, @@ -154,17 +161,31 @@ const files = (state, action) => { content: action.content, url: action.url, children: action.children, - fileType: action.fileType || 'file' - }]; + fileType: action.fileType || 'file', + }, + ]; + return newState.map((file) => { + if (file.id === action.parentId) { + file.children = sortedChildrenId(newState, file.children); + } + return file; + }); } case ActionTypes.UPDATE_FILE_NAME: - return state.map((file) => { + { + const newState = state.map((file) => { if (file.id !== action.id) { return file; } - return Object.assign({}, file, { name: action.name }); }); + return newState.map((file) => { + if (file.children.includes(action.id)) { + file.children = sortedChildrenId(newState, file.children); + } + return file; + }); + } case ActionTypes.DELETE_FILE: { const newState = deleteMany(state, [action.id, ...getAllDescendantIds(state, action.id)]); From 76bcf9cb097285495b2a8c22a68cc7f06e0c0d2f Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Mon, 3 Aug 2020 16:42:28 -0400 Subject: [PATCH 05/13] [#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 4b022dd0e861ce312e6eb48ec0190e7362cd03d3 Mon Sep 17 00:00:00 2001 From: Neelesh Date: Tue, 4 Aug 2020 10:28:21 +0530 Subject: [PATCH 06/13] Refactored CREATE_FILE and UPDATE_FILE_NAME case into smaller functions --- client/modules/IDE/reducers/files.js | 44 ++++++++++++++++------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/client/modules/IDE/reducers/files.js b/client/modules/IDE/reducers/files.js index 9c07cbbc..1f03e8de 100644 --- a/client/modules/IDE/reducers/files.js +++ b/client/modules/IDE/reducers/files.js @@ -116,6 +116,26 @@ function sortedChildrenId(state, children) { return childrenArray.map(child => child.id); } +function udpateParent(state, action) { + return state.map((file) => { + if (file.id === action.parentId) { + const newFile = Object.assign({}, file); + newFile.children = [...newFile.children, action.id]; + return newFile; + } + return file; + }); +} + +function renameFile(state, action) { + return state.map((file) => { + if (file.id !== action.id) { + return file; + } + return Object.assign({}, file, { name: action.name }); + }); +} + const files = (state, action) => { if (state === undefined) { state = initialState(); // eslint-disable-line @@ -144,16 +164,8 @@ const files = (state, action) => { return initialState(); case ActionTypes.CREATE_FILE: // eslint-disable-line { - let newState = state.map((file) => { - if (file.id === action.parentId) { - const newFile = Object.assign({}, file); - newFile.children = [...newFile.children, action.id]; - return newFile; - } - return file; - }); - newState = [ - ...newState, + const newState = [ + ...udpateParent(state, action), { name: action.name, id: action.id, @@ -161,9 +173,8 @@ const files = (state, action) => { content: action.content, url: action.url, children: action.children, - fileType: action.fileType || 'file', - }, - ]; + fileType: action.fileType || 'file' + }]; return newState.map((file) => { if (file.id === action.parentId) { file.children = sortedChildrenId(newState, file.children); @@ -173,12 +184,7 @@ const files = (state, action) => { } case ActionTypes.UPDATE_FILE_NAME: { - const newState = state.map((file) => { - if (file.id !== action.id) { - return file; - } - return Object.assign({}, file, { name: action.name }); - }); + const newState = renameFile(state, action); return newState.map((file) => { if (file.children.includes(action.id)) { file.children = sortedChildrenId(newState, file.children); From 932f24cd9e2b43ca8374e299169719614e2d4c5d Mon Sep 17 00:00:00 2001 From: Neelesh Date: Tue, 4 Aug 2020 21:54:45 +0530 Subject: [PATCH 07/13] corrected a typo --- client/modules/IDE/reducers/files.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/modules/IDE/reducers/files.js b/client/modules/IDE/reducers/files.js index 1f03e8de..9be4667e 100644 --- a/client/modules/IDE/reducers/files.js +++ b/client/modules/IDE/reducers/files.js @@ -116,7 +116,7 @@ function sortedChildrenId(state, children) { return childrenArray.map(child => child.id); } -function udpateParent(state, action) { +function updateParent(state, action) { return state.map((file) => { if (file.id === action.parentId) { const newFile = Object.assign({}, file); @@ -165,7 +165,7 @@ const files = (state, action) => { case ActionTypes.CREATE_FILE: // eslint-disable-line { const newState = [ - ...udpateParent(state, action), + ...updateParent(state, action), { name: action.name, id: action.id, From 1c02d45fd72f73e66f3585fa586e1b31138a953b Mon Sep 17 00:00:00 2001 From: Neelesh Singh Date: Tue, 4 Aug 2020 23:46:25 +0530 Subject: [PATCH 08/13] sort existing files before displaying --- client/modules/IDE/reducers/files.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/modules/IDE/reducers/files.js b/client/modules/IDE/reducers/files.js index 9be4667e..404a1aee 100644 --- a/client/modules/IDE/reducers/files.js +++ b/client/modules/IDE/reducers/files.js @@ -227,7 +227,12 @@ const files = (state, action) => { return file; }); default: - return state; + return state.map((file) => { + if (file.name === 'root') { + file.children = sortedChildrenId(state, file.children); + } + return file; + }); } }; From 9c8a8a411053472b48f5d02057c5688b96438b62 Mon Sep 17 00:00:00 2001 From: Neelesh Singh Date: Wed, 5 Aug 2020 00:32:02 +0530 Subject: [PATCH 09/13] Sort nested folders in existing sketch --- client/modules/IDE/reducers/files.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/modules/IDE/reducers/files.js b/client/modules/IDE/reducers/files.js index 404a1aee..80557fb3 100644 --- a/client/modules/IDE/reducers/files.js +++ b/client/modules/IDE/reducers/files.js @@ -228,9 +228,7 @@ const files = (state, action) => { }); default: return state.map((file) => { - if (file.name === 'root') { - file.children = sortedChildrenId(state, file.children); - } + file.children = sortedChildrenId(state, file.children); return file; }); } From 3aa26120c2c9b1479d363887bfd11ac2558d9836 Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Wed, 5 Aug 2020 16:43:32 -0400 Subject: [PATCH 10/13] [#1532] Update project when deleting file --- client/modules/IDE/actions/files.js | 3 ++- server/controllers/file.controller.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/modules/IDE/actions/files.js b/client/modules/IDE/actions/files.js index e17e46c5..c8a656c8 100644 --- a/client/modules/IDE/actions/files.js +++ b/client/modules/IDE/actions/files.js @@ -160,7 +160,8 @@ export function deleteFile(id, parentId) { } }; apiClient.delete(`/projects/${state.project.id}/files/${id}`, deleteConfig) - .then(() => { + .then((response) => { + dispatch(setProjectSavedTime(response.data.project.updatedAt)); dispatch({ type: ActionTypes.DELETE_FILE, id, diff --git a/server/controllers/file.controller.js b/server/controllers/file.controller.js index 4ccb6db2..542a40fd 100644 --- a/server/controllers/file.controller.js +++ b/server/controllers/file.controller.js @@ -103,8 +103,8 @@ export function deleteFile(req, res) { const idsToDelete = getAllDescendantIds(project.files, req.params.file_id); deleteMany(project.files, [req.params.file_id, ...idsToDelete]); project.files = deleteChild(project.files, req.query.parentId, req.params.file_id); - project.save((innerErr) => { - res.json(project.files); + project.save((innerErr, savedProject) => { + res.json({ project: savedProject }); }); }); } From a56740c7c4a3930ebfbf49583f4d6499849b4e52 Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Wed, 5 Aug 2020 17:50:07 -0400 Subject: [PATCH 11/13] [#1532] Fix labels for files --- client/modules/IDE/components/FileNode.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/modules/IDE/components/FileNode.jsx b/client/modules/IDE/components/FileNode.jsx index 4e54460b..4f16387d 100644 --- a/client/modules/IDE/components/FileNode.jsx +++ b/client/modules/IDE/components/FileNode.jsx @@ -261,7 +261,7 @@ export class FileNode extends React.Component { } diff --git a/client/modules/IDE/components/FileNode.test.jsx b/client/modules/IDE/components/FileNode.test.jsx index cc913858..ddb8fec7 100644 --- a/client/modules/IDE/components/FileNode.test.jsx +++ b/client/modules/IDE/components/FileNode.test.jsx @@ -13,7 +13,7 @@ describe('', () => { }; const expectFileNameToBe = async (expectedName) => { - const name = screen.getByLabelText(/Name/i); + const name = screen.getByTestId('file-name'); await waitFor(() => within(name).queryByText(expectedName)); }; From 6827983adcfd19b70dba9e42018c95a99b29e930 Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Thu, 6 Aug 2020 12:47:07 -0400 Subject: [PATCH 13/13] 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",