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 ( + + ); + } + })()} +
    + ); + } +} + +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(){