async requests + error handling
This commit is contained in:
parent
c0f136bee3
commit
07f79c1006
110
src/App.js
110
src/App.js
@ -73,7 +73,6 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
handleSubmit(e) {
|
handleSubmit(e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
console.log('Search term: ', this.state.search)
|
|
||||||
this.setState({ search: '' })
|
this.setState({ search: '' })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +80,8 @@ class App extends React.Component {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const newTask = {
|
const newTask = {
|
||||||
desc: this.state.newTask,
|
desc: this.state.newTask,
|
||||||
projectName: this.state.selectedProject,
|
projectName: this.state.projects.find(p => p.id === this.state.selectedProjectId)['name'],
|
||||||
|
// TODO
|
||||||
// the backend expects projectName because it creates the project on the fly if none exists with that name
|
// the backend expects projectName because it creates the project on the fly if none exists with that name
|
||||||
// this feature comes at the price that there can't be two independent projects with the same name
|
// this feature comes at the price that there can't be two independent projects with the same name
|
||||||
// which could be handy if users want to have private projects
|
// which could be handy if users want to have private projects
|
||||||
@ -105,7 +105,7 @@ class App extends React.Component {
|
|||||||
console.log('Received malformed data for added task: ', data)
|
console.log('Received malformed data for added task: ', data)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert('Failed to add task: ', e)
|
alert(`Failed to add task: ${e}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async deleteTask(id) {
|
async deleteTask(id) {
|
||||||
@ -122,23 +122,48 @@ class App extends React.Component {
|
|||||||
alert('Failed to delete task: ', e)
|
alert('Failed to delete task: ', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
completeTask(id) {
|
async completeTask(id) {
|
||||||
const otherTasks = this.state.tasks.filter(t => t.id !== id)
|
const task = this.state.tasks.find(t => t.id === id)
|
||||||
const completedTask = this.state.tasks.find(t => t.id === id)
|
if (!task.id) {
|
||||||
completedTask.completed = !completedTask.completed
|
alert(`Couldn't find task with id ${id}`)
|
||||||
console.log(completedTask)
|
return
|
||||||
this.setState({ tasks: otherTasks.concat(completedTask) })
|
}
|
||||||
|
try {
|
||||||
|
task.completed = !task.completed
|
||||||
|
const { data, error } = await axios.put(api + `/api/tasks/${task.id}`, task)
|
||||||
|
if (error) {
|
||||||
|
alert(`Received error when completing task ${task.desc}: ${error}`)
|
||||||
|
} else if (data.id) {
|
||||||
|
const otherTasks = this.state.tasks.filter(t => t.id !== id)
|
||||||
|
this.setState({ tasks: otherTasks.concat(data) })
|
||||||
|
console.log(`Completed task:`, data)
|
||||||
|
} else {
|
||||||
|
alert(`Failed to complete task with id ${id}`)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
alert(`Failed to complete task ${task.desc}: ${e}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createProject(e) {
|
async createProject(e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.setState({
|
const project = { name: this.state.newProject }
|
||||||
projects: this.state.projects.concat({
|
try {
|
||||||
id: this.state.projects.length,
|
const { data, error } = await axios.post(api + '/api/projects', project)
|
||||||
name: this.state.newProject,
|
if (error) {
|
||||||
}),
|
alert(`Received error when creating project ${project.name}: ${error}`)
|
||||||
newProject: '',
|
} else if (data.id) {
|
||||||
})
|
this.setState({
|
||||||
|
projects: this.state.projects.concat(data),
|
||||||
|
newProject: '',
|
||||||
|
})
|
||||||
|
console.log(`Added project: `, data)
|
||||||
|
} else {
|
||||||
|
alert(`Failed to add project '${project}'.`)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
alert(`Failed to add project '${this.state.newProject}'.`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectProject(selectedProjectId) {
|
selectProject(selectedProjectId) {
|
||||||
@ -146,9 +171,34 @@ class App extends React.Component {
|
|||||||
this.navigate('project')
|
this.navigate('project')
|
||||||
}
|
}
|
||||||
async deleteProject(id) {
|
async deleteProject(id) {
|
||||||
//this.setState({ projects: this.state.projects.filter(p => p.id !== id) })
|
const project = this.state.projects.find(p => p.id === id)
|
||||||
await axios.post(`/api/projects/${id}/delete`)
|
if (!project.id) {
|
||||||
// TODO: some delete success function
|
alert(`Could not find project with id ${id}.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const tasks = this.state.tasks.filter(t => t.projectId === project.id)
|
||||||
|
if (tasks.length > 0) {
|
||||||
|
if (window.confirm(`Project ${project.name} has ${tasks.length} tasks. Are you sure?`)) {
|
||||||
|
this.setState({ tasks: this.state.tasks.filter(t => t.projectId !== project.id) })
|
||||||
|
console.log(`Removed ${tasks.length} tasks of project '${project.name}'.`)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const { data, error } = await axios.post(api + `/api/projects/${project.id}/delete`)
|
||||||
|
if (error) {
|
||||||
|
alert(`Received error when deleting project ${project.name}: ${error}`)
|
||||||
|
} else if (data.name) {
|
||||||
|
console.log('Deleted project:', data)
|
||||||
|
this.setState({ projects: this.state.projects.filter(p => p.id !== project.id) })
|
||||||
|
this.navigate('projects')
|
||||||
|
} else {
|
||||||
|
alert(`Failed to delete project '${project.name}'.`)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
alert(`Failed to delete project '${project.name}': ${e}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLoading() {
|
renderLoading() {
|
||||||
@ -182,6 +232,7 @@ class App extends React.Component {
|
|||||||
addTask={this.addTask}
|
addTask={this.addTask}
|
||||||
completeTask={this.completeTask}
|
completeTask={this.completeTask}
|
||||||
deleteTask={this.deleteTask}
|
deleteTask={this.deleteTask}
|
||||||
|
navigate={this.navigate}
|
||||||
{...this.state}
|
{...this.state}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
@ -205,13 +256,18 @@ class App extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
console.log(this.state)
|
//console.log(this.state)
|
||||||
const completed = this.state.tasks.filter(task => task.completed === true)
|
// TODO refactor task filtering
|
||||||
const filtered = this.state.tasks.filter(
|
const completed =
|
||||||
task =>
|
(this.state.tasks && this.state.tasks.filter(task => task.completed === true)) || []
|
||||||
task.completed !== true &&
|
const filtered =
|
||||||
this.state.search === task.desc.slice(0, this.state.search.length),
|
(this.state.tasks &&
|
||||||
)
|
this.state.tasks.filter(
|
||||||
|
task =>
|
||||||
|
task.completed !== true &&
|
||||||
|
this.state.search === task.desc.slice(0, this.state.search.length),
|
||||||
|
)) ||
|
||||||
|
[]
|
||||||
|
|
||||||
const renderComponent = () =>
|
const renderComponent = () =>
|
||||||
this.state.loading
|
this.state.loading
|
||||||
|
@ -11,22 +11,29 @@ function FilterTask(props) {
|
|||||||
value={props.newTask}
|
value={props.newTask}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
/>
|
/>
|
||||||
{props.component === 'project' ? null : (
|
{props.component === 'project' ? (
|
||||||
|
''
|
||||||
|
) : (
|
||||||
<select
|
<select
|
||||||
className="form-control custom-select col"
|
className="form-control custom-select col"
|
||||||
name="selectedProject"
|
name="selectedProjectId"
|
||||||
value={props.project.name}
|
value={props.selectedProjectId}
|
||||||
onChange={props.handleChange}
|
onChange={props.handleChange}
|
||||||
>
|
>
|
||||||
<option value='' defaultValue>select project</option>
|
<option value="" defaultValue>
|
||||||
{props.projects.map(p => (
|
select project
|
||||||
<option key={p.id} value={p.name}>
|
</option>
|
||||||
{p.name}
|
{props.projects &&
|
||||||
</option>
|
props.projects.map(p => (
|
||||||
))}
|
<option key={p.id} value={p.id}>
|
||||||
|
{p.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
</select>
|
</select>
|
||||||
)}
|
)}
|
||||||
<button className="form-control col-sm-1 btn" type="submit" onClick={props.addTask}>Add</button>
|
<button className="form-control col-sm-1 btn" type="submit" onClick={props.addTask}>
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
|
@ -2,20 +2,23 @@ import React from 'react'
|
|||||||
import Tasks from './tasks'
|
import Tasks from './tasks'
|
||||||
|
|
||||||
function Project(props) {
|
function Project(props) {
|
||||||
|
if (!props.selectedProjectId) {
|
||||||
|
props.navigate('projects')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
// TODO re-fetch project list if no project name is found instead of setting 'Default'
|
||||||
const projectName =
|
const projectName =
|
||||||
props.projects.find(p => p.id === props.selectedProjectId).name || 'Default'
|
props.projects.find(p => p.id === props.selectedProjectId)['name'] || 'Default'
|
||||||
const filtered = props.tasks.filter(
|
|
||||||
t => t.projectId === props.selectedProjectId && !t.completed
|
const filtered = props.tasks.filter(t => t.projectId === props.selectedProjectId && !t.completed)
|
||||||
)
|
|
||||||
const completed = props.tasks.filter(
|
const completed = props.tasks.filter(
|
||||||
t =>
|
t => (t.projectId === props.selectedProjectId && t.completed === true) || null,
|
||||||
(t.projectId === props.selectedProjectId && t.completed === true) || null
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>{projectName}</h2>
|
<h2>{projectName}</h2>
|
||||||
<Tasks {...props} filtered={filtered} completed={completed} />
|
<Tasks filtered={filtered} completed={completed} {...props} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
function Projects(props) {
|
function Projects(props) {
|
||||||
console.log('PROJECTS PROPS', props)
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mt-4">Projects</h3>
|
<h3 className="mt-4">Projects</h3>
|
||||||
<ul className="list-group">
|
<ul className="list-group">
|
||||||
{props.projects.map(project => (
|
{props.projects &&
|
||||||
<li className="list-group-item" key={project.id}>
|
props.projects.map(project => (
|
||||||
<button
|
<li className="list-group-item" key={project.id}>
|
||||||
className="btn btn-outline-danger mr-1"
|
<button
|
||||||
onClick={() => props.deleteProject(project.id)}
|
className="btn btn-outline-danger mr-1"
|
||||||
>
|
onClick={() => props.deleteProject(project.id)}
|
||||||
X
|
>
|
||||||
</button>
|
X
|
||||||
{props.selectedProjectId ? null : (
|
</button>
|
||||||
<span onClick={() => props.selectProject(project.id)}>
|
<span onClick={() => props.selectProject(project.id)}>{project.name} </span>
|
||||||
{project.name}{' '}
|
</li>
|
||||||
</span>
|
))}
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
<form className="" onSubmit={props.createProject}>
|
<form className="" onSubmit={props.createProject}>
|
||||||
<input
|
<input
|
||||||
className="form-control input-sm"
|
className="form-control input-sm"
|
||||||
|
@ -11,7 +11,7 @@ const TaskRow = props => {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<span>{task.desc}</span>
|
<span>{task.desc}</span>
|
||||||
{props.selectedProjectId ? null : (
|
{props.component === 'project' ? null : (
|
||||||
<button
|
<button
|
||||||
className="btn btn-outline-dark ml-5"
|
className="btn btn-outline-dark ml-5"
|
||||||
onClick={() => props.selectProject(task.projectId)}
|
onClick={() => props.selectProject(task.projectId)}
|
||||||
|
@ -4,7 +4,7 @@ import FilterTask from './filter-task'
|
|||||||
import TaskList from './task-list'
|
import TaskList from './task-list'
|
||||||
|
|
||||||
function Tasks(props) {
|
function Tasks(props) {
|
||||||
const { tasks } = props
|
const tasks = props.tasks || []
|
||||||
const filtered = props.filtered || []
|
const filtered = props.filtered || []
|
||||||
const completed = props.completed || []
|
const completed = props.completed || []
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user