From 443a9f57d527da8841c788c0cd19e69e513aec74 Mon Sep 17 00:00:00 2001 From: catarak Date: Wed, 3 Aug 2016 17:10:03 -0400 Subject: [PATCH] add file renaming --- client/constants.js | 2 + client/modules/IDE/actions/files.js | 14 +++++++ client/modules/IDE/components/Sidebar.js | 8 +++- client/modules/IDE/components/SidebarItem.js | 44 +++++++++++++++++--- client/modules/IDE/pages/IDEView.js | 8 +++- client/modules/IDE/reducers/files.js | 16 +++++++ client/styles/components/_sidebar.scss | 17 ++++++++ 7 files changed, 102 insertions(+), 7 deletions(-) diff --git a/client/constants.js b/client/constants.js index 8e41ad91..aaa4973a 100644 --- a/client/constants.js +++ b/client/constants.js @@ -47,6 +47,8 @@ export const HIDE_FILE_OPTIONS = 'HIDE_FILE_OPTIONS'; export const UPDATE_FILE_NAME = 'UPDATE_FILE_NAME'; export const DELETE_FILE = 'DELETE_FILE'; +export const SHOW_EDIT_FILE_NAME = 'SHOW_EDIT_FILE_NAME'; +export const HIDE_EDIT_FILE_NAME = 'HIDE_EDIT_FILE_NAME'; // eventually, handle errors more specifically and better export const ERROR = 'ERROR'; diff --git a/client/modules/IDE/actions/files.js b/client/modules/IDE/actions/files.js index e7bed3a2..788871c1 100644 --- a/client/modules/IDE/actions/files.js +++ b/client/modules/IDE/actions/files.js @@ -127,6 +127,20 @@ export function hideFileOptions(fileId) { }; } +export function showEditFileName(id) { + return { + type: ActionTypes.SHOW_EDIT_FILE_NAME, + id + }; +} + +export function hideEditFileName(id) { + return { + type: ActionTypes.HIDE_EDIT_FILE_NAME, + id + }; +} + export function updateFileName(id, name) { return { type: ActionTypes.UPDATE_FILE_NAME, diff --git a/client/modules/IDE/components/Sidebar.js b/client/modules/IDE/components/Sidebar.js index 54bcd246..3ee28506 100644 --- a/client/modules/IDE/components/Sidebar.js +++ b/client/modules/IDE/components/Sidebar.js @@ -61,6 +61,9 @@ class Sidebar extends React.Component { hideFileOptions={this.props.hideFileOptions} deleteFile={this.props.deleteFile} resetSelectedFile={this.resetSelectedFile} + showEditFileName={this.props.showEditFileName} + hideEditFileName={this.props.hideEditFileName} + updateFileName={this.props.updateFileName} /> )} @@ -78,7 +81,10 @@ Sidebar.propTypes = { expandSidebar: PropTypes.func.isRequired, showFileOptions: PropTypes.func.isRequired, hideFileOptions: PropTypes.func.isRequired, - deleteFile: PropTypes.func.isRequired + deleteFile: PropTypes.func.isRequired, + showEditFileName: PropTypes.func.isRequired, + hideEditFileName: PropTypes.func.isRequired, + updateFileName: PropTypes.func.isRequired }; export default Sidebar; diff --git a/client/modules/IDE/components/SidebarItem.js b/client/modules/IDE/components/SidebarItem.js index 6b749307..4a00c8dd 100644 --- a/client/modules/IDE/components/SidebarItem.js +++ b/client/modules/IDE/components/SidebarItem.js @@ -4,16 +4,31 @@ import classNames from 'classnames'; const downArrowUrl = require('../../../images/down-arrow.svg'); class SidebarItem extends React.Component { - onFocus() { + constructor(props) { + super(props); + this.handleKeyPress = this.handleKeyPress.bind(this); + this.handleFileNameChange = this.handleFileNameChange.bind(this); + } + handleFileNameChange(event) { + this.props.updateFileName(this.props.file.id, event.target.value); + } + + handleKeyPress(event) { + console.log(event.key); + if (event.key === 'Enter') { + this.props.hideEditFileName(this.props.file.id); + } } render() { let itemClass = classNames({ 'sidebar__file-item': true, 'sidebar__file-item--selected': this.props.file.isSelected, - 'sidebar__file-item--open': this.props.file.isOptionsOpen + 'sidebar__file-item--open': this.props.file.isOptionsOpen, + 'sidebar__file-item--editing': this.props.file.isEditingName }); + return (
  • this.props.setSelectedFile(this.props.file.id)} >{this.props.file.name} + this.props.hideEditFileName(this.props.file.id)} + onKeyPress={this.handleKeyPress} + /> this.props.showFileOptions(this.props.file.id)} @@ -32,7 +57,12 @@ class SidebarItem extends React.Component {
    • - + { + this.props.showEditFileName(this.props.file.id); + setTimeout(() => this.refs.fileNameInput.focus(), 0); + }} + > Rename
    • @@ -60,14 +90,18 @@ SidebarItem.propTypes = { id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, isSelected: PropTypes.bool, - isOptionsOpen: PropTypes.bool + isOptionsOpen: PropTypes.bool, + isEditingName: PropTypes.bool }).isRequired, setSelectedFile: PropTypes.func.isRequired, fileIndex: PropTypes.number.isRequired, showFileOptions: PropTypes.func.isRequired, hideFileOptions: PropTypes.func.isRequired, deleteFile: PropTypes.func.isRequired, - resetSelectedFile: PropTypes.func.isRequired + resetSelectedFile: PropTypes.func.isRequired, + showEditFileName: PropTypes.func.isRequired, + hideEditFileName: PropTypes.func.isRequired, + updateFileName: PropTypes.func.isRequired }; export default SidebarItem; diff --git a/client/modules/IDE/pages/IDEView.js b/client/modules/IDE/pages/IDEView.js index db31bedb..6d8eb7ca 100644 --- a/client/modules/IDE/pages/IDEView.js +++ b/client/modules/IDE/pages/IDEView.js @@ -58,6 +58,9 @@ class IDEView extends React.Component { showFileOptions={this.props.showFileOptions} hideFileOptions={this.props.hideFileOptions} deleteFile={this.props.deleteFile} + showEditFileName={this.props.showEditFileName} + hideEditFileName={this.props.hideEditFileName} + updateFileName={this.props.updateFileName} />
      { }); case ActionTypes.DELETE_FILE: return state.filter(file => file.id !== action.id); + case ActionTypes.SHOW_EDIT_FILE_NAME: + return state.map(file => { + if (file.id !== action.id) { + return file; + } + + return Object.assign({}, file, { isEditingName: true }); + }); + case ActionTypes.HIDE_EDIT_FILE_NAME: + return state.map(file => { + if (file.id !== action.id) { + return file; + } + + return Object.assign({}, file, { isEditingName: false }); + }); default: return state; } diff --git a/client/styles/components/_sidebar.scss b/client/styles/components/_sidebar.scss index b42dd303..c54ff31c 100644 --- a/client/styles/components/_sidebar.scss +++ b/client/styles/components/_sidebar.scss @@ -46,6 +46,12 @@ } } +.sidebar__file-item-name { + .sidebar__file-item--editing & { + display: none; + } +} + .sidebar__file-item-show-options { @extend %icon; display: none; @@ -69,6 +75,17 @@ } } +.sidebar__file-item-input { + display: none; + padding: 0; + border: 0; + background-color: transparent; + max-width: 90%; + .sidebar__file-item--editing & { + display: inline-block; + } +} + .sidebar__contract { @extend %icon; height: #{14 / $base-font-size}rem;