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/client/modules/IDE/components/FileNode.jsx b/client/modules/IDE/components/FileNode.jsx
index 57238cf8..e7869f26 100644
--- a/client/modules/IDE/components/FileNode.jsx
+++ b/client/modules/IDE/components/FileNode.jsx
@@ -10,6 +10,61 @@ import FolderRightIcon from '../../../images/triangle-arrow-right.svg';
import FolderDownIcon from '../../../images/triangle-arrow-down.svg';
import FileIcon from '../../../images/file.svg';
+function parseFileName(name) {
+ const nameArray = name.split('.');
+ if (nameArray.length > 1) {
+ const extension = `.${nameArray[nameArray.length - 1]}`;
+ 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}
+ {baseName.length > 2 &&
+ {middleText}
+ }
+ {baseName.length > 1 &&
+ {lastLetter}
+ }
+ {extension &&
+ {extension}
+ }
+
+ );
+}
+
+FileName.propTypes = {
+ name: PropTypes.string.isRequired
+};
+
export class FileNode extends React.Component {
constructor(props) {
super(props);
@@ -206,11 +261,12 @@ export class FileNode extends React.Component {
}
', () => {
};
const expectFileNameToBe = async (expectedName) => {
- const name = screen.getByLabelText(/Name/i);
+ const name = screen.getByTestId('file-name');
await waitFor(() => within(name).queryByText(expectedName));
};
diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx
index 956fd974..4979eaee 100644
--- a/client/modules/IDE/pages/IDEView.jsx
+++ b/client/modules/IDE/pages/IDEView.jsx
@@ -301,7 +301,7 @@ class IDEView extends React.Component {
onChange={size => this.setState({ sidebarSize: size })}
onDragFinished={this._handleSidebarPaneOnDragFinished}
allowResize={this.props.ide.sidebarIsExpanded}
- minSize={20}
+ minSize={125}
>
{
name: 'root',
id: r,
_id: r,
- children: [a, b, c],
+ children: [b, a, c],
fileType: 'folder',
content: ''
},
@@ -110,6 +110,32 @@ 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);
+}
+
+function updateParent(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
@@ -138,15 +164,8 @@ const files = (state, action) => {
return initialState();
case ActionTypes.CREATE_FILE: // eslint-disable-line
{
- const newState = state.map((file) => {
- if (file.id === action.parentId) {
- const newFile = Object.assign({}, file);
- newFile.children = [...newFile.children, action.id];
- return newFile;
- }
- return file;
- });
- return [...newState,
+ const newState = [
+ ...updateParent(state, action),
{
name: action.name,
id: action.id,
@@ -156,15 +175,23 @@ const files = (state, action) => {
children: action.children,
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) => {
- if (file.id !== action.id) {
- return file;
+ {
+ const newState = renameFile(state, action);
+ return newState.map((file) => {
+ if (file.children.includes(action.id)) {
+ file.children = sortedChildrenId(newState, file.children);
}
-
- return Object.assign({}, file, { name: action.name });
+ return file;
});
+ }
case ActionTypes.DELETE_FILE:
{
const newState = deleteMany(state, [action.id, ...getAllDescendantIds(state, action.id)]);
@@ -200,7 +227,10 @@ const files = (state, action) => {
return file;
});
default:
- return state;
+ return state.map((file) => {
+ file.children = sortedChildrenId(state, file.children);
+ return file;
+ });
}
};
diff --git a/client/styles/components/_sidebar.scss b/client/styles/components/_sidebar.scss
index ffafc439..761bda91 100644
--- a/client/styles/components/_sidebar.scss
+++ b/client/styles/components/_sidebar.scss
@@ -110,8 +110,28 @@
}
}
+.sidebar__file-item-name--ellipsis {
+ overflow-x: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ min-width: #{15 / $base-font-size}rem;
+}
+
+.sidebar__file-item-name-text {
+ display: flex;
+ width: 100%;
+ overflow: hidden;
+ min-width: #{50 / $base-font-size}rem;
+ white-space: nowrap;
+ text-align: left;
+}
+
.sidebar__file-item-name {
padding: #{4 / $base-font-size}rem 0;
+ padding-right: #{25 / $base-font-size}rem;
+ font-family: Inconsolata, monospace;
+ font-size: #{14 / $base-font-size}rem;
+ overflow: hidden;
.sidebar__file-item--editing & {
display: none;
}
@@ -174,6 +194,8 @@
padding: 0;
border: 0;
width: calc(100% - #{63 / $base-font-size}rem);
+ font-family: Inconsolata, monospace;
+ font-size: #{14 / $base-font-size}rem;
.sidebar__file-item--editing & {
display: inline-block;
}
@@ -254,9 +276,6 @@
fill: getThemifyVariable('secondary-text-color');
}
}
- & svg {
- height: #{10 / $base-font-size}rem;
- }
background-color: transparent;
border: none;
}
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 });
});
});
}