Add batch delete
This commit is contained in:
parent
7ceec6e7d0
commit
56590ba57a
5 changed files with 92 additions and 5 deletions
32
functions/todos-delete-batch.js
Normal file
32
functions/todos-delete-batch.js
Normal 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)
|
||||
})
|
||||
})
|
||||
}
|
||||
44
src/App.js
44
src/App.js
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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'>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue