From 937421e90c50ad4dcdc3506818b73db97ef08285 Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Thu, 30 Jul 2020 18:59:12 -0400 Subject: [PATCH 01/10] [#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/10] [#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 855dceaafe05762d9d0bd2959918098d244655e9 Mon Sep 17 00:00:00 2001 From: Neelesh Date: Tue, 4 Aug 2020 00:26:31 +0530 Subject: [PATCH 03/10] 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 4b022dd0e861ce312e6eb48ec0190e7362cd03d3 Mon Sep 17 00:00:00 2001 From: Neelesh Date: Tue, 4 Aug 2020 10:28:21 +0530 Subject: [PATCH 04/10] 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 05/10] 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 06/10] 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 07/10] 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 08/10] [#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 09/10] [#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)); };