Add batch delete

This commit is contained in:
DavidWells 2018-06-20 20:25:39 -07:00
parent 7ceec6e7d0
commit 56590ba57a
5 changed files with 92 additions and 5 deletions

View file

@ -0,0 +1,32 @@
import faunadb from 'faunadb'
import getId from './utils/getId'
const q = faunadb.query
const client = new faunadb.Client({
secret: process.env.FAUNADB_SECRET
})
exports.handler = (event, context, callback) => {
const data = JSON.parse(event.body)
console.log('data', data)
console.log("Function `todo-delete-batch` invoked", data.ids)
// construct batch query from IDs
const deleteAllCompletedTodoQuery = data.ids.map((id) => {
return q.Delete(q.Ref(`classes/todos/${id}`))
})
// Hit fauna with the query to delete the completed items
return client.query(deleteAllCompletedTodoQuery)
.then((response) => {
console.log("success", response)
return callback(null, {
statusCode: 200,
body: JSON.stringify(response)
})
}).catch((error) => {
console.log("error", error)
return callback(null, {
statusCode: 400,
body: JSON.stringify(error)
})
})
}

View file

@ -158,13 +158,49 @@ export default class App extends Component {
})
}
}
clearCompleted = () => {
const { todos } = this.state
// Optimistically remove todos from UI
const data = todos.reduce((acc, current) => {
if (current.data.completed) {
// save item being removed for rollback
acc.completedTodoIds = acc.completedTodoIds.concat(getTodoId(current))
return acc
}
// filter deleted todo out of the todos list
acc.optimisticState = acc.optimisticState.concat(current)
return acc
}, {
completedTodoIds: [],
optimisticState: []
})
// only set state if completed todos exist
if (!data.completedTodoIds.length) {
alert('Please check off some todos to batch remove them')
this.closeModal()
return false
}
this.setState({
todos: data.optimisticState
}, () => {
api.batchDelete(data.completedTodoIds).then(() => {
console.log(`Batch removal complete`, data.completedTodoIds)
this.closeModal()
}).catch((e) => {
console.log('An API error occurred', e)
})
})
}
closeModal = (e) => {
this.setState({
showMenu: false
})
}
openModal = () => {
console.log('settings')
this.setState({
showMenu: true
})
@ -254,7 +290,11 @@ export default class App extends Component {
{this.renderTodos()}
</div>
<SettingsMenu showMenu={this.state.showMenu} handleModalClose={this.closeModal} />
<SettingsMenu
showMenu={this.state.showMenu}
handleModalClose={this.closeModal}
handleClearCompleted={this.clearCompleted}
/>
</div>
)
}

View file

@ -4,7 +4,7 @@ import styles from './SettingIcon.css' // eslint-disable-line
const SettingIcon = (props) => {
const className = props.className || ''
return (
<span onClick={props.onClick} class={`setting-toggle-wrapper ${className}`}>
<span onClick={props.onClick} className={`setting-toggle-wrapper ${className}`}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125" className="settings-toggle">
<use xlinkHref="#settings" className="settings-gear"></use>
</svg>

View file

@ -20,6 +20,7 @@ export default class Menu extends Component {
const deleteConfirm = window.confirm("Are you sure you want to clear all completed todos?");
if (deleteConfirm) {
console.log('delete')
this.props.handleClearCompleted()
}
}
render() {
@ -28,7 +29,9 @@ export default class Menu extends Component {
return (
<div className='settings-wrapper' style={{display: showOrHide}}>
<div className='settings-content'>
<span className='settings-close' onClick={this.props.handleModalClose}></span>
<span className='settings-close' onClick={this.props.handleModalClose} role="img" aria-label='close'>
</span>
<h2>Settings</h2>
<div className='settings-section' onClick={this.handleDelete}>
<button className='btn-danger'>

View file

@ -34,9 +34,21 @@ const deleteTodo = (todoId) => {
})
}
const batchDeleteTodo = (todoIds) => {
return fetch(`/.netlify/functions/todos-delete-batch`, {
body: JSON.stringify({
ids: todoIds
}),
method: 'POST'
}).then(response => {
return response.json()
})
}
export default {
create: create,
readAll: readAll,
update: update,
delete: deleteTodo
delete: deleteTodo,
batchDelete: batchDeleteTodo
}