2020-01-21 21:34:59 +03:00
|
|
|
import React from 'react'
|
|
|
|
|
2020-01-23 18:31:00 +03:00
|
|
|
import Task from '@wasp/entities/task/Task'
|
2020-01-21 21:34:59 +03:00
|
|
|
import NewTaskForm from '@wasp/entities/task/components/NewTaskForm'
|
2020-01-29 14:53:22 +03:00
|
|
|
import TaskList from '@wasp/entities/task/components/TaskList'
|
2020-01-21 21:34:59 +03:00
|
|
|
|
|
|
|
import * as config from './config'
|
|
|
|
|
2020-01-30 13:23:04 +03:00
|
|
|
const TASK_FILTER_TYPES = Object.freeze({
|
|
|
|
ALL: 'all',
|
|
|
|
ACTIVE: 'active',
|
|
|
|
COMPLETED: 'completed'
|
|
|
|
})
|
|
|
|
|
|
|
|
const TASK_FILTERS = Object.freeze({
|
|
|
|
[TASK_FILTER_TYPES.ALL]: null,
|
|
|
|
[TASK_FILTER_TYPES.ACTIVE]: task => !task.isDone,
|
|
|
|
[TASK_FILTER_TYPES.COMPLETED]: task => task.isDone
|
|
|
|
})
|
2020-01-21 21:34:59 +03:00
|
|
|
|
|
|
|
export default class Todo extends React.Component {
|
2020-01-30 13:23:04 +03:00
|
|
|
|
|
|
|
state = {
|
|
|
|
taskFilterName: TASK_FILTER_TYPES.ALL
|
|
|
|
}
|
|
|
|
|
2020-01-23 18:31:00 +03:00
|
|
|
toggleIsDoneForAllTasks = () => {
|
|
|
|
const areAllDone = this.props.taskList.every(t => t.isDone)
|
|
|
|
{/* TODO: This feels clumsy / complicated. Is there a better way than using id (maybe not)?
|
|
|
|
Should we consider passing just data to update, not the whole object, so we don't have to
|
|
|
|
create new object here? Maybe we can change this update, or have a second update method. */}
|
|
|
|
this.props.taskList.map(
|
|
|
|
(t) => this.props.updateTask(t.id, new Task ({ ...t.toData(), isDone: !areAllDone }))
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
deleteCompletedTasks = () => {
|
|
|
|
this.props.taskList.map((t) => { if (t.isDone) this.props.removeTask(t.id) })
|
|
|
|
}
|
|
|
|
|
2020-01-30 13:23:04 +03:00
|
|
|
TaskFilterButton = ({ filterType, label }) => (
|
|
|
|
<button
|
|
|
|
className={this.state.taskFilterName === filterType ? 'selected' : null}
|
|
|
|
onClick={() => this.setState({ taskFilterName: filterType })}
|
|
|
|
>
|
|
|
|
{label}
|
|
|
|
</button>
|
|
|
|
)
|
|
|
|
|
2020-01-21 21:34:59 +03:00
|
|
|
render = () => {
|
2020-01-23 18:31:00 +03:00
|
|
|
return (
|
|
|
|
<div className="mainContainer">
|
|
|
|
<h1> { config.appName } </h1>
|
2020-01-21 21:34:59 +03:00
|
|
|
|
2020-01-23 18:31:00 +03:00
|
|
|
<button onClick={this.toggleIsDoneForAllTasks}>
|
2020-01-29 14:53:22 +03:00
|
|
|
Toggle completion {/* TODO: Use icon (but we need to either install @material-ui/icons
|
|
|
|
or add font-awesome to the index.html. */}
|
2020-01-23 18:31:00 +03:00
|
|
|
</button>
|
2020-01-21 21:34:59 +03:00
|
|
|
|
2020-01-23 18:31:00 +03:00
|
|
|
<NewTaskForm
|
|
|
|
onCreate={task => this.props.addTask(task)}
|
|
|
|
submitButtonLabel={'Create new task'}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<div className="taskListContainer">
|
2020-01-30 13:23:04 +03:00
|
|
|
<TaskList
|
|
|
|
editable
|
|
|
|
filter={TASK_FILTERS[this.state.taskFilterName]}
|
|
|
|
/>
|
2020-01-23 18:31:00 +03:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className="footer">
|
2020-01-30 13:23:04 +03:00
|
|
|
<div>
|
|
|
|
{ this.props.taskList.filter(task => !task.isDone).length } items left
|
2020-01-21 21:34:59 +03:00
|
|
|
|
2020-01-30 13:23:04 +03:00
|
|
|
{ this.props.taskList.some(t => t.isDone) &&
|
|
|
|
<button onClick={this.deleteCompletedTasks}>Clear completed</button>
|
|
|
|
}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<this.TaskFilterButton filterType={TASK_FILTER_TYPES.ALL} label="All" />
|
|
|
|
<this.TaskFilterButton filterType={TASK_FILTER_TYPES.ACTIVE} label="Active" />
|
|
|
|
<this.TaskFilterButton filterType={TASK_FILTER_TYPES.COMPLETED} label="Completed" />
|
|
|
|
</div>
|
2020-01-23 18:31:00 +03:00
|
|
|
</div>
|
2020-01-21 21:34:59 +03:00
|
|
|
</div>
|
2020-01-23 18:31:00 +03:00
|
|
|
)
|
2020-01-21 21:34:59 +03:00
|
|
|
}
|
|
|
|
}
|