adds multiple selection delete functionality

This commit is contained in:
kevmodrome 2020-09-28 15:32:06 +02:00
parent 0a398c43c3
commit d94a9b193b
4 changed files with 154 additions and 97 deletions

View File

@ -18,16 +18,16 @@ function emitEvent(eventType, ctx, record) {
}
validateJs.extend(validateJs.validators.datetime, {
parse: function(value) {
parse: function (value) {
return new Date(value).getTime()
},
// Input is a unix timestamp
format: function(value) {
format: function (value) {
return new Date(value).toISOString()
},
})
exports.patch = async function(ctx) {
exports.patch = async function (ctx) {
const db = new CouchDB(ctx.user.instanceId)
const record = await db.get(ctx.params.id)
const model = await db.get(record.modelId)
@ -60,7 +60,126 @@ exports.patch = async function(ctx) {
ctx.message = `${model.name} updated successfully.`
}
exports.save = async function(ctx) {
exports.save = async function (ctx) {
if (ctx.request.body.type === 'delete') {
await bulkDelete(ctx)
} else {
await saveRecords(ctx)
}
}
exports.fetchView = async function (ctx) {
const db = new CouchDB(ctx.user.instanceId)
const { stats, group, field } = ctx.query
const response = await db.query(`database/${ctx.params.viewName}`, {
include_docs: !stats,
group,
})
if (stats) {
response.rows = response.rows.map(row => ({
group: row.key,
field,
...row.value,
avg: row.value.sum / row.value.count,
}))
} else {
response.rows = response.rows.map(row => row.doc)
}
ctx.body = response.rows
}
exports.fetchModelRecords = async function (ctx) {
const db = new CouchDB(ctx.user.instanceId)
const response = await db.query(`database/all_${ctx.params.modelId}`, {
include_docs: true,
})
ctx.body = response.rows.map(row => row.doc)
}
exports.search = async function (ctx) {
const db = new CouchDB(ctx.user.instanceId)
const response = await db.allDocs({
include_docs: true,
...ctx.request.body,
})
ctx.body = response.rows.map(row => row.doc)
}
exports.find = async function (ctx) {
const db = new CouchDB(ctx.user.instanceId)
const record = await db.get(ctx.params.recordId)
if (record.modelId !== ctx.params.modelId) {
ctx.throw(400, "Supplied modelId does not match the records modelId")
return
}
ctx.body = record
}
exports.destroy = async function (ctx) {
const db = new CouchDB(ctx.user.instanceId)
const record = await db.get(ctx.params.recordId)
if (record.modelId !== ctx.params.modelId) {
ctx.throw(400, "Supplied modelId doesn't match the record's modelId")
return
}
ctx.body = await db.remove(ctx.params.recordId, ctx.params.revId)
ctx.status = 200
// for automations
ctx.record = record
emitEvent(`record:delete`, ctx, record)
}
exports.validate = async function (ctx) {
const errors = await validate({
instanceId: ctx.user.instanceId,
modelId: ctx.params.modelId,
record: ctx.request.body,
})
ctx.status = 200
ctx.body = errors
}
async function validate({ instanceId, modelId, record, model }) {
if (!model) {
const db = new CouchDB(instanceId)
model = await db.get(modelId)
}
const errors = {}
for (let fieldName in model.schema) {
const res = validateJs.single(
record[fieldName],
model.schema[fieldName].constraints
)
if (res) errors[fieldName] = res
}
return { valid: Object.keys(errors).length === 0, errors }
}
async function bulkDelete(ctx) {
const { records } = ctx.request.body
console.log(records)
const db = new CouchDB(ctx.user.instanceId)
await db.bulkDocs(
records.map(record => ({ ...record, _deleted: true })), console.log)
// await db.bulkDocs(
// records.rows.map(record => ({ _id: record.id, _deleted: true }))
// )
// const record = await db.get(ctx.params.recordId)
// if (record.modelId !== ctx.params.modelId) {
// ctx.throw(400, "Supplied modelId doesn't match the record's modelId")
// return
// }
// ctx.body = await db.remove(ctx.params.recordId, ctx.params.revId)
ctx.status = 200
// // for automations
// ctx.record = record
// emitEvent(`record:delete`, ctx, record)
}
async function saveRecords(ctx) {
const db = new CouchDB(ctx.user.instanceId)
const record = ctx.request.body
record.modelId = ctx.params.modelId
@ -128,93 +247,4 @@ exports.save = async function(ctx) {
ctx.body = record
ctx.status = 200
ctx.message = `${model.name} created successfully`
}
exports.fetchView = async function(ctx) {
const db = new CouchDB(ctx.user.instanceId)
const { stats, group, field } = ctx.query
const response = await db.query(`database/${ctx.params.viewName}`, {
include_docs: !stats,
group,
})
if (stats) {
response.rows = response.rows.map(row => ({
group: row.key,
field,
...row.value,
avg: row.value.sum / row.value.count,
}))
} else {
response.rows = response.rows.map(row => row.doc)
}
ctx.body = response.rows
}
exports.fetchModelRecords = async function(ctx) {
const db = new CouchDB(ctx.user.instanceId)
const response = await db.query(`database/all_${ctx.params.modelId}`, {
include_docs: true,
})
ctx.body = response.rows.map(row => row.doc)
}
exports.search = async function(ctx) {
const db = new CouchDB(ctx.user.instanceId)
const response = await db.allDocs({
include_docs: true,
...ctx.request.body,
})
ctx.body = response.rows.map(row => row.doc)
}
exports.find = async function(ctx) {
const db = new CouchDB(ctx.user.instanceId)
const record = await db.get(ctx.params.recordId)
if (record.modelId !== ctx.params.modelId) {
ctx.throw(400, "Supplied modelId does not match the records modelId")
return
}
ctx.body = record
}
exports.destroy = async function(ctx) {
const db = new CouchDB(ctx.user.instanceId)
const record = await db.get(ctx.params.recordId)
if (record.modelId !== ctx.params.modelId) {
ctx.throw(400, "Supplied modelId doesn't match the record's modelId")
return
}
ctx.body = await db.remove(ctx.params.recordId, ctx.params.revId)
ctx.status = 200
// for automations
ctx.record = record
emitEvent(`record:delete`, ctx, record)
}
exports.validate = async function(ctx) {
const errors = await validate({
instanceId: ctx.user.instanceId,
modelId: ctx.params.modelId,
record: ctx.request.body,
})
ctx.status = 200
ctx.body = errors
}
async function validate({ instanceId, modelId, record, model }) {
if (!model) {
const db = new CouchDB(instanceId)
model = await db.get(modelId)
}
const errors = {}
for (let fieldName in model.schema) {
const res = validateJs.single(
record[fieldName],
model.schema[fieldName].constraints
)
if (res) errors[fieldName] = res
}
return { valid: Object.keys(errors).length === 0, errors }
}
}

View File

@ -29,7 +29,7 @@ router
)
.post(
"/api/:modelId/records/validate",
authorized(WRITE_MODEL, ctx => ctx.params.modelId),
authorized(WRITE_MODEL),
recordController.validate
)
.delete(

View File

@ -37,7 +37,7 @@
"dependencies": {
"@beyonk/svelte-googlemaps": "^2.2.0",
"@budibase/bbui": "^1.34.6",
"@budibase/svelte-ag-grid": "^0.0.10",
"@budibase/svelte-ag-grid": "^0.0.11",
"@fortawesome/fontawesome-free": "^5.14.0",
"@svelteschool/svelte-forms": "^0.7.0",
"britecharts": "^2.16.1",

View File

@ -20,6 +20,7 @@
let dataLoaded = false
let data
let columnDefs
let selectedRows = []
onMount(async () => {
const jsonModel = await _bb.api.get(`/api/models/${datasource.modelId}`)
@ -72,11 +73,33 @@
const json = await response.json()
console.log(json)
}
const deleteRecords = async () => {
console.log(_bb.api)
const response = await _bb.api.post(`/api/${datasource.name}/records`, {
records: selectedRows,
type: "delete",
})
data = data.filter(record => !selectedRows.includes(record))
selectedRows = []
}
</script>
<div class="container">
<div class="controls">
<button>Add Row</button>
{#if selectedRows.length > 0}
<button on:click={deleteRecords}>
Delete {selectedRows.length} row(s)
</button>
{/if}
</div>
{#if dataLoaded}
<AgGrid {data} {columnDefs} on:update={handleUpdate} />
<AgGrid
{data}
{columnDefs}
on:update={handleUpdate}
on:select={({ detail }) => (selectedRows = detail)} />
<InputForm fields={columnDefs} on:submit={handleSubmit} />
{/if}
</div>
@ -90,4 +113,8 @@
display: grid;
grid-template-columns: repeat(2);
}
.controls {
display: flex;
flex-direction: row;
}
</style>