adds multiple selection delete functionality
This commit is contained in:
parent
0a398c43c3
commit
d94a9b193b
|
@ -18,16 +18,16 @@ function emitEvent(eventType, ctx, record) {
|
||||||
}
|
}
|
||||||
|
|
||||||
validateJs.extend(validateJs.validators.datetime, {
|
validateJs.extend(validateJs.validators.datetime, {
|
||||||
parse: function(value) {
|
parse: function (value) {
|
||||||
return new Date(value).getTime()
|
return new Date(value).getTime()
|
||||||
},
|
},
|
||||||
// Input is a unix timestamp
|
// Input is a unix timestamp
|
||||||
format: function(value) {
|
format: function (value) {
|
||||||
return new Date(value).toISOString()
|
return new Date(value).toISOString()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
exports.patch = async function(ctx) {
|
exports.patch = async function (ctx) {
|
||||||
const db = new CouchDB(ctx.user.instanceId)
|
const db = new CouchDB(ctx.user.instanceId)
|
||||||
const record = await db.get(ctx.params.id)
|
const record = await db.get(ctx.params.id)
|
||||||
const model = await db.get(record.modelId)
|
const model = await db.get(record.modelId)
|
||||||
|
@ -60,7 +60,126 @@ exports.patch = async function(ctx) {
|
||||||
ctx.message = `${model.name} updated successfully.`
|
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 db = new CouchDB(ctx.user.instanceId)
|
||||||
const record = ctx.request.body
|
const record = ctx.request.body
|
||||||
record.modelId = ctx.params.modelId
|
record.modelId = ctx.params.modelId
|
||||||
|
@ -128,93 +247,4 @@ exports.save = async function(ctx) {
|
||||||
ctx.body = record
|
ctx.body = record
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
ctx.message = `${model.name} created successfully`
|
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 }
|
|
||||||
}
|
|
|
@ -29,7 +29,7 @@ router
|
||||||
)
|
)
|
||||||
.post(
|
.post(
|
||||||
"/api/:modelId/records/validate",
|
"/api/:modelId/records/validate",
|
||||||
authorized(WRITE_MODEL, ctx => ctx.params.modelId),
|
authorized(WRITE_MODEL),
|
||||||
recordController.validate
|
recordController.validate
|
||||||
)
|
)
|
||||||
.delete(
|
.delete(
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@beyonk/svelte-googlemaps": "^2.2.0",
|
"@beyonk/svelte-googlemaps": "^2.2.0",
|
||||||
"@budibase/bbui": "^1.34.6",
|
"@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",
|
"@fortawesome/fontawesome-free": "^5.14.0",
|
||||||
"@svelteschool/svelte-forms": "^0.7.0",
|
"@svelteschool/svelte-forms": "^0.7.0",
|
||||||
"britecharts": "^2.16.1",
|
"britecharts": "^2.16.1",
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
let dataLoaded = false
|
let dataLoaded = false
|
||||||
let data
|
let data
|
||||||
let columnDefs
|
let columnDefs
|
||||||
|
let selectedRows = []
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const jsonModel = await _bb.api.get(`/api/models/${datasource.modelId}`)
|
const jsonModel = await _bb.api.get(`/api/models/${datasource.modelId}`)
|
||||||
|
@ -72,11 +73,33 @@
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
console.log(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>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<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}
|
{#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} />
|
<InputForm fields={columnDefs} on:submit={handleSubmit} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,4 +113,8 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2);
|
grid-template-columns: repeat(2);
|
||||||
}
|
}
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue