Skip to content

Commit

Permalink
feat(tasks): editing of tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Wu committed Nov 3, 2017
1 parent 9621a92 commit c8b2fdb
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 25 deletions.
7 changes: 4 additions & 3 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"presets":[
"env", "react"
]
"plugins": ["transform-object-rest-spread"],
"presets":[
"env", "react"
]
}
10 changes: 10 additions & 0 deletions client/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export const closeTask = (id) => ({
type: 'CLOSE',
id
});

export const deleteTask = (id) => ({
type: 'DELETE',
id
Expand All @@ -17,6 +22,11 @@ export const newTask = () => ({
type: 'NEW'
});

export const openTask = (id) => ({
type: 'OPEN',
id
});

export const save = () => ({
type: 'SAVE'
});
44 changes: 43 additions & 1 deletion client/components/TaskList/Task.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,48 @@ const TrashButton = styled(Button)`
padding: 0;
`;

const handleInputChange = (handler) => {
return (event) => {
handler(event.target.value);
};
}

const handleKeyDown = (handler) => {
return (event) => {
// pressed enter, escape, or tab
if (event.key === 'Enter' || event.keyCode === 27 || event.keyCode === 9) {
event.preventDefault();
handler();
}
};
}

const Task = ({
closeTask,
deleteTask,
editTask,
openTask,
isOpened,
text
}) => (
<StyledTask>
<StyledTaskText>{text}</StyledTaskText>
{isOpened
? <input
autoFocus
onBlur={closeTask}
onChange={handleInputChange(editTask)}
onKeyDown={handleKeyDown(closeTask)}
placeholder='Edit task description'
type='text'
/>
: <StyledTaskText
onClick={openTask}
onFocus={openTask}
tabIndex={0}
>
{text}
</StyledTaskText>
}
<TrashButton onClick={deleteTask}>
<i className="fa fa-trash-o"></i>
</TrashButton>
Expand All @@ -41,11 +77,17 @@ const Task = ({

Task.propTypes = {
deleteTask: PropTypes.func,
editTask: PropTypes.func,
openTask: PropTypes.func,
isOpened: PropTypes.bool,
text: PropTypes.string
}

Task.defaultProps = {
deleteTask: null,
editTask: null,
openTask: null,
isOpened: false,
text: PropTypes.string
}

Expand Down
25 changes: 16 additions & 9 deletions client/components/TaskList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,32 @@ const EmptyTaskList = Wrapper.extend`
`;

const TaskList = ({
closeTask,
deleteTask,
editTask,
openTask,
tasks
}) => (
<StyledTaskList>
{tasks.length
? tasks.map((task) => {
return (
<Task
key={task.id}
deleteTask={() => { deleteTask(task.id); }}
text={task.text}
/>
);
})
? tasks.map((task) => (
<Task
key={task.id}
closeTask={() => { closeTask(task.id); }}
deleteTask={() => { deleteTask(task.id); }}
editTask={(text) => { editTask(task.id, text); }}
openTask={() => { openTask(task.id); }}
isOpened={task.isOpened}
text={task.text}
/>
))
: <EmptyTaskList>You don't have any tasks. Start by clicking "Add Task"!</EmptyTaskList>
}
</StyledTaskList>
);

TaskList.propTypes = {
deleteTask: PropTypes.func,
tasks: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
Expand All @@ -52,6 +58,7 @@ TaskList.propTypes = {
}

TaskList.defaultProps = {
deleteTask: null,
tasks: []
}

Expand Down
8 changes: 6 additions & 2 deletions client/containers/TaskListContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import React from 'react';
import { connect } from 'react-redux';

import {
closeTask,
deleteTask,
editTask
editTask,
openTask
} from '../actions';
import TaskList from '../components/TaskList';

Expand All @@ -12,8 +14,10 @@ const mapStateToProps = (state) => ({
});

const mapDispatchToProps = {
closeTask,
deleteTask,
editTask
editTask,
openTask
}

const TaskListContainer = connect(
Expand Down
44 changes: 34 additions & 10 deletions client/reducers/taskReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@ const DEFAULT_TODO = 'New task';

const getNextId = () => Math.random(); // TODO: how to generate more stably?

// inserts element without modification
const insert = (array, index, item) => {
return [
...array.slice(0, index),
item,
...array.slice(index+1)
];
}

const taskReducer = (state = [], action) => {
switch (action.type) {
case 'NEW': {
const newTask = {
id: getNextId(),
text: DEFAULT_TODO
case 'CLOSE': {
const i = state.findIndex((task) => task.id === action.id);
const closeTask = {
...state[i],
isOpened: false
};
return [newTask, ...state];
return insert(state, i, closeTask);
}

case 'DELETE':
Expand All @@ -18,20 +28,34 @@ const taskReducer = (state = [], action) => {
case 'EDIT': {
const i = state.findIndex((task) => task.id === action.id);
const editedTask = {
id: action.id,
...state[i],
text: action.text
};
return state
.slice(0, i)
.concat([editedTask])
.concat(state.slice(i+1));
return insert(state, i, editedTask);
}

case 'GET': {
// TODO: use thunk to make API request
console.log('get');
}

case 'NEW': {
const newTask = {
id: getNextId(),
text: DEFAULT_TODO
};
return insert(state, 0, newTask);
}

case 'OPEN': {
const i = state.findIndex((task) => task.id === action.id);
const openedTask = {
...state[i],
isOpened: true
};
return insert(state, i, openedTask);
}

case 'SAVE': {
// TODO: use thunk to make API request
console.log('save');
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.7",
Expand Down
11 changes: 11 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,10 @@ babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
version "6.18.0"
resolved "https://martifactory.io/api/npm/virtual-npm/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"

babel-plugin-syntax-object-rest-spread@^6.8.0:
version "6.13.0"
resolved "https://martifactory.io/api/npm/virtual-npm/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"

babel-plugin-syntax-trailing-function-commas@^6.22.0:
version "6.22.0"
resolved "https://martifactory.io/api/npm/virtual-npm/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
Expand Down Expand Up @@ -615,6 +619,13 @@ babel-plugin-transform-flow-strip-types@^6.22.0:
babel-plugin-syntax-flow "^6.18.0"
babel-runtime "^6.22.0"

babel-plugin-transform-object-rest-spread@^6.26.0:
version "6.26.0"
resolved "https://martifactory.io/api/npm/virtual-npm/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
dependencies:
babel-plugin-syntax-object-rest-spread "^6.8.0"
babel-runtime "^6.26.0"

babel-plugin-transform-react-display-name@^6.23.0:
version "6.25.0"
resolved "https://martifactory.io/api/npm/virtual-npm/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1"
Expand Down

0 comments on commit c8b2fdb

Please sign in to comment.