diff --git a/client/modules/IDE/components/FileNode.js b/client/modules/IDE/components/FileNode.js
new file mode 100644
index 00000000..5d4d8bb4
--- /dev/null
+++ b/client/modules/IDE/components/FileNode.js
@@ -0,0 +1,146 @@
+import React, { PropTypes } from 'react';
+import * as FileActions from '../actions/files';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+import InlineSVG from 'react-inlinesvg';
+const downArrowUrl = require('../../../images/down-arrow.svg');
+import classNames from 'classnames';
+
+export class FileNode extends React.Component {
+ constructor(props) {
+ super(props);
+ this.renderChild = this.renderChild.bind(this);
+ this.handleKeyPress = this.handleKeyPress.bind(this);
+ this.handleFileNameChange = this.handleFileNameChange.bind(this);
+ this.validateFileName = this.validateFileName.bind(this);
+ }
+
+ handleFileNameChange(event) {
+ this.props.updateFileName(this.props.id, event.target.value);
+ }
+
+ handleKeyPress(event) {
+ if (event.key === 'Enter') {
+ this.props.hideEditFileName(this.props.id);
+ }
+ }
+
+ validateFileName() {
+ const oldFileExtension = this.originalFileName.match(/\.[0-9a-z]+$/i);
+ const newFileExtension = this.props.name.match(/\.[0-9a-z]+$/i);
+ if (oldFileExtension && !newFileExtension) {
+ this.props.updateFileName(this.props.id, this.originalFileName);
+ }
+ if (oldFileExtension && newFileExtension && oldFileExtension[0] !== newFileExtension[0]) {
+ this.props.updateFileName(this.props.id, this.originalFileName);
+ }
+ }
+
+ renderChild(childId) {
+ return (
+
+
+
+ );
+ }
+
+ render() {
+ let itemClass = classNames({
+ 'sidebar__file-item': true,
+ 'sidebar__file-item--selected': this.props.isSelected,
+ 'sidebar__file-item--open': this.props.isOptionsOpen,
+ 'sidebar__file-item--editing': this.props.isEditingName
+ });
+ return (
+
+
{this.props.name}
+
{
+ this.validateFileName();
+ this.props.hideEditFileName(this.props.id);
+ }}
+ onKeyPress={this.handleKeyPress}
+ />
+
+
+ {(() => { // eslint-disable-line
+ console.log(this.props.children);
+ if (this.props.children) {
+ return (
+
+ {this.props.children.map(this.renderChild)}
+
+ );
+ }
+ })()}
+
+ );
+ }
+}
+
+FileNode.propTypes = {
+ id: PropTypes.string.isRequired,
+ children: PropTypes.array,
+ name: PropTypes.string.isRequired,
+ isSelected: PropTypes.bool,
+ isOptionsOpen: PropTypes.bool,
+ isEditingName: PropTypes.bool,
+ setSelectedFile: PropTypes.func.isRequired,
+ fileIndex: PropTypes.number.isRequired,
+ showFileOptions: PropTypes.func.isRequired,
+ hideFileOptions: PropTypes.func.isRequired,
+ deleteFile: PropTypes.func.isRequired,
+ resetSelectedFile: PropTypes.func.isRequired,
+ showEditFileName: PropTypes.func.isRequired,
+ hideEditFileName: PropTypes.func.isRequired,
+ updateFileName: PropTypes.func.isRequired
+};
+
+function mapStateToProps(state, ownProps) {
+ return state.files.find((file) => file.id === ownProps.id);
+}
+
+function mapDispatchToProps(dispatch) {
+ return bindActionCreators(FileActions, dispatch);
+}
+
+const ConnectedFileNode = connect(mapStateToProps, mapDispatchToProps)(FileNode);
+export default ConnectedFileNode;
diff --git a/client/modules/IDE/components/Sidebar.js b/client/modules/IDE/components/Sidebar.js
index f472189b..7fae0857 100644
--- a/client/modules/IDE/components/Sidebar.js
+++ b/client/modules/IDE/components/Sidebar.js
@@ -4,6 +4,7 @@ import InlineSVG from 'react-inlinesvg';
import SidebarItem from './SidebarItem';
const rightArrowUrl = require('../../../images/right-arrow.svg');
const leftArrowUrl = require('../../../images/left-arrow.svg');
+import ConnectedFileNode from './FileNode';
class Sidebar extends React.Component {
constructor(props) {
@@ -66,6 +67,7 @@ class Sidebar extends React.Component {
/>
)}
+
);
}
diff --git a/client/modules/IDE/reducers/files.js b/client/modules/IDE/reducers/files.js
index 0f19f511..ab4ee3e7 100644
--- a/client/modules/IDE/reducers/files.js
+++ b/client/modules/IDE/reducers/files.js
@@ -47,6 +47,11 @@ const initialState = [
name: 'style.css',
content: defaultCSS,
id: '3'
+ },
+ {
+ name: 'root',
+ id: '0',
+ children: ['1', '2', '3']
}];
diff --git a/server/models/project.js b/server/models/project.js
index 3ae5c195..520ef75c 100644
--- a/server/models/project.js
+++ b/server/models/project.js
@@ -36,7 +36,9 @@ const defaultCSS =
const fileSchema = new Schema({
name: { type: String, default: 'sketch.js' },
content: { type: String },
- url: { type: String }
+ url: { type: String },
+ children: { type: [Schema.Types.ObjectId], default: [] },
+ fileType: { type: String }
}, { timestamps: true, _id: true });
fileSchema.virtual('id').get(function(){