Skip to content

Commit

Permalink
Merge branch 'feature/improve-todo-example' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
gocreating committed Oct 15, 2016
2 parents 82c8b59 + 4807348 commit daf1773
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 34 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@
"semi": [2, "always"],
"max-len": [2, { "code": 80, "ignoreComments": true, "ignoreUrls": true }],
"space-before-function-paren": [2, "never"],
"comma-dangle": [2, "always-multiline"],
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "ignore"
}],
"handle-callback-err": 1,
"no-multi-spaces": 0,
"operator-linebreak": [2, "after"],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"chai": "^3.5.0",
"css-loader": "^0.23.1",
"del": "^2.2.0",
"eslint": "^3.2.0",
"eslint": "^3.8.0",
"eslint-config-standard": "^5.3.5",
"eslint-plugin-promise": "^2.0.0",
"eslint-plugin-react": "^5.2.2",
Expand Down
1 change: 1 addition & 0 deletions src/common/api/todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export default (apiEngine) => ({
// }),
list: () => apiEngine.get('/api/todos'),
create: (todo) => apiEngine.post('/api/todos', { data: todo }),
update: (id, todo) => apiEngine.put(`/api/todos/${id}`, { data: todo }),
remove: (id) => apiEngine.del(`/api/todos/${id}`),
});
128 changes: 105 additions & 23 deletions src/common/components/pages/todo/ListPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,101 @@ import {
} from '../../../actions/todoActions';
import PageLayout from '../../layouts/PageLayout';

let TodoItem = ({ onRemoveClick, text }) => (
<li>
<button onClick={onRemoveClick}>x</button>
{text}
</li>
);
class TodoItem extends Component {
constructor() {
super();
this.state = {
isEditable: false,
inputValue: '',
};
}

renderInput() {
let { inputValue } = this.state;

return (
<input
type="text"
value={inputValue}
onChange={(e) => this.setState({
inputValue: e.target.value,
})}
/>
);
}

renderControlButtons() {
let { text, onSaveClick } = this.props;
let { isEditable, inputValue } = this.state;

return isEditable ? (
<span>
<button
onClick={() => (
onSaveClick(inputValue)
.then(() => this.setState({ isEditable: false }))
)}
>
Save
</button>
<button onClick={() => this.setState({ isEditable: false })}>
Cancel
</button>
</span>
) : (
<span>
<button
onClick={() => this.setState({ isEditable: true, inputValue: text })}
>
Edit
</button>
</span>
);
}

render() {
let { onRemoveClick, text } = this.props;
let { isEditable } = this.state;

return (
<li>
{text}
{isEditable && this.renderInput()}
{this.renderControlButtons()}
<button onClick={onRemoveClick}>x</button>
</li>
);
}
}

class ListPage extends Component {
constructor(props) {
super(props);
this._handleAddClick = this._handleAddClick.bind(this);
this.handleAddClick = this._handleAddClick.bind(this);
}

componentDidMount() {
const { dispatch, apiEngine } = this.props;
if (this.props.todos.length === 0) {
todoAPI(apiEngine)
.list()
.catch((err) => {
dispatch(pushErrors(err));
throw err;
})
.then((json) => {
dispatch(setTodo(json.todos));
});
let { todos } = this.props;

if (todos.length === 0) {
this.fetchTodos();
}
}

fetchTodos() {
let { dispatch, apiEngine } = this.props;

todoAPI(apiEngine)
.list()
.catch((err) => {
dispatch(pushErrors(err));
throw err;
})
.then((json) => {
dispatch(setTodo(json.todos));
});
}

_handleAddClick() {
const { dispatch, apiEngine } = this.props;
const text = this.refs.todotext.value;
Expand All @@ -53,7 +120,21 @@ class ListPage extends Component {
});
}

_handleRemoveClick(id) {
handleSaveClick(id, newText) {
let { dispatch, apiEngine } = this.props;

return todoAPI(apiEngine)
.update(id, { text: newText })
.catch((err) => {
dispatch(pushErrors(err));
throw err;
})
.then((json) => {
this.fetchTodos();
});
}

handleRemoveClick(id) {
const { dispatch, apiEngine } = this.props;
todoAPI(apiEngine)
.remove(id)
Expand All @@ -71,12 +152,13 @@ class ListPage extends Component {
<PageLayout>
<PageHeader>Todo List</PageHeader>
<input type="text" ref="todotext" />
<button onClick={this._handleAddClick}>Add Todo</button>
<button onClick={this.handleAddClick}>Add Todo</button>
<ul>
{this.props.todos.map((todo, index) =>
{this.props.todos.map((todo) =>
<TodoItem
key={index}
onRemoveClick={this._handleRemoveClick.bind(this, todo._id)}
key={todo._id}
onRemoveClick={this.handleRemoveClick.bind(this, todo._id)}
onSaveClick={this.handleSaveClick.bind(this, todo._id)}
text={todo.text} />)}
</ul>
</PageLayout>
Expand Down
4 changes: 2 additions & 2 deletions src/common/components/utils/BsForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class BsForm extends Component {
labelDimensions, // hold props to avoid passing down
fieldDimensions, // hold props to avoid passing down
children,
...rest,
...rest
} = this.props;

return (
Expand Down Expand Up @@ -58,7 +58,7 @@ BsForm.childContextTypes = {
};

let BsFormField = ({
label, input, type, meta, options, ...rest,
label, input, type, meta, options, ...rest
}, {
labelDimensions, fieldDimensions, horizontal,
}) => {
Expand Down
2 changes: 1 addition & 1 deletion src/common/components/utils/BsNavbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class BsNavbar extends Component {
fixedTop,
staticTop,
children,
...rest,
...rest
} = this.props;
const cx = classNames(
'navbar',
Expand Down
28 changes: 23 additions & 5 deletions src/server/controllers/todo.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import assign from 'object-assign';
import { handleDbError } from '../decorators/handleError';
import filterAttribute from '../utils/filterAttribute';
import Todo from '../models/Todo';

export default {
list(req, res) {
Todo.find({}, handleDbError(res)((todos) => {
res.json({
todos: todos,
});
}));
},

create(req, res) {
const todo = Todo({
text: req.body.text,
Expand All @@ -14,11 +24,19 @@ export default {
}));
},

list(req, res) {
Todo.find({}, handleDbError(res)((todos) => {
res.json({
todos: todos,
});
update(req, res) {
let modifiedTodo = filterAttribute(req.body, [
'text',
]);

Todo.findById(req.params.id, handleDbError(res)((todo) => {
todo = assign(todo, modifiedTodo);
todo.save(handleDbError(res)(() => {
res.json({
originAttributes: req.body,
updatedAttributes: todo,
});
}));
}));
},

Expand Down
3 changes: 2 additions & 1 deletion src/server/routes/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export default ({ app }) => {
app.get('/api/locales/:locale', localeController.show);

// todo
app.post('/api/todos', bodyParser.json, todoController.create);
app.get('/api/todos', todoController.list);
app.post('/api/todos', bodyParser.json, todoController.create);
app.put('/api/todos/:id', bodyParser.json, todoController.update);
app.delete('/api/todos/:id', todoController.remove);
};

0 comments on commit daf1773

Please sign in to comment.