Add all CRUD ops to airtable integration
This commit is contained in:
parent
19f6139a1a
commit
33d63607e2
|
@ -139,13 +139,13 @@ export const getBackendUiStore = () => {
|
||||||
state.selectedQueryId = queryId
|
state.selectedQueryId = queryId
|
||||||
return state
|
return state
|
||||||
}),
|
}),
|
||||||
delete: async queryId => {
|
delete: async query => {
|
||||||
await api.delete(`/api/queries/${queryId}`)
|
await api.delete(`/api/queries/${query._id}/${query._rev}`)
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.queries = state.queries.filter(
|
state.queries = state.queries.filter(
|
||||||
existing => existing._id !== queryId
|
existing => existing._id !== query._id
|
||||||
)
|
)
|
||||||
if (state.selectedQueryId === queryId) {
|
if (state.selectedQueryId === query._id) {
|
||||||
state.selectedQueryId = null
|
state.selectedQueryId = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteDatasource() {
|
async function deleteDatasource() {
|
||||||
// TODO: update the store correctly
|
|
||||||
await backendUiStore.actions.datasources.delete(datasource)
|
await backendUiStore.actions.datasources.delete(datasource)
|
||||||
// await backendUiStore.actions.datasources.fetch()
|
|
||||||
notifier.success("Datasource deleted")
|
notifier.success("Datasource deleted")
|
||||||
hideEditor()
|
hideEditor()
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteQuery() {
|
async function deleteQuery() {
|
||||||
await backendUiStore.actions.queries.delete(query._id)
|
await backendUiStore.actions.queries.delete(query)
|
||||||
notifier.success("Query deleted")
|
notifier.success("Query deleted")
|
||||||
hideEditor()
|
hideEditor()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
<script>
|
|
||||||
import BottomDrawer from "components/common/BottomDrawer.svelte"
|
|
||||||
import { Button } from "@budibase/bbui"
|
|
||||||
import { store, backendUiStore, currentAsset } from "builderStore"
|
|
||||||
import { slide } from "svelte/transition"
|
|
||||||
import fetchBindableProperties from "builderStore/fetchBindableProperties"
|
|
||||||
import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte"
|
|
||||||
|
|
||||||
export let query
|
|
||||||
export let parameters = {}
|
|
||||||
|
|
||||||
$: console.log("CUSTOM PARAMS", parameters)
|
|
||||||
|
|
||||||
$: bindableProperties = fetchBindableProperties({
|
|
||||||
componentInstanceId: $store.selectedComponentId,
|
|
||||||
components: $store.components,
|
|
||||||
screen: $currentAsset,
|
|
||||||
tables: $backendUiStore.tables,
|
|
||||||
}).map(property => ({
|
|
||||||
...property,
|
|
||||||
category: property.type === "instance" ? "Component" : "Table",
|
|
||||||
label: property.readableBinding,
|
|
||||||
path: property.readableBinding,
|
|
||||||
}))
|
|
||||||
|
|
||||||
function closeDatabindingDrawer() {
|
|
||||||
store.update(state => {
|
|
||||||
state.bottomDrawerVisible = false
|
|
||||||
return state
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveComponentQuery() {
|
|
||||||
// save the parameters to the datasource of the component
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if query}
|
|
||||||
<BottomDrawer title={'Query'} onClose={closeDatabindingDrawer}>
|
|
||||||
<div slot="buttons">
|
|
||||||
<Button blue thin on:click={saveComponentQuery}>Save</Button>
|
|
||||||
</div>
|
|
||||||
<div class="drawer-contents" slot="body">
|
|
||||||
<pre>{query.queryString}</pre>
|
|
||||||
<ParameterBuilder
|
|
||||||
bind:customParams={parameters}
|
|
||||||
parameters={query.parameters}
|
|
||||||
bindings={bindableProperties} />
|
|
||||||
</div>
|
|
||||||
</BottomDrawer>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.drawer-contents {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-flow: column;
|
|
||||||
grid-template-columns: 20% 1fr;
|
|
||||||
grid-gap: var(--spacing-m);
|
|
||||||
height: 100%;
|
|
||||||
padding: var(--spacing-xl);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -6,6 +6,17 @@
|
||||||
|
|
||||||
let query
|
let query
|
||||||
|
|
||||||
|
async function fetchQueryConfig() {
|
||||||
|
try {
|
||||||
|
const response = await api.get(`/api/integrations/${datasource.source}`)
|
||||||
|
const json = await response.json()
|
||||||
|
config = json.query
|
||||||
|
} catch (err) {
|
||||||
|
notifier.danger("Error fetching datasource configuration options.")
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($params.query !== "new") {
|
if ($params.query !== "new") {
|
||||||
query = $backendUiStore.queries.find(query => query._id === $params.query)
|
query = $backendUiStore.queries.find(query => query._id === $params.query)
|
||||||
|
@ -15,7 +26,6 @@
|
||||||
datasourceId: $params.selectedDatasource,
|
datasourceId: $params.selectedDatasource,
|
||||||
name: "New Query",
|
name: "New Query",
|
||||||
parameters: [],
|
parameters: [],
|
||||||
// TODO: set dynamically
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ exports.destroy = async function(ctx) {
|
||||||
await db.bulkDocs(rows.rows.map(row => ({ ...row.doc, _deleted: true })))
|
await db.bulkDocs(rows.rows.map(row => ({ ...row.doc, _deleted: true })))
|
||||||
|
|
||||||
// delete the datasource
|
// delete the datasource
|
||||||
await db.remove(ctx.params.datasourceId)
|
await db.remove(ctx.params.datasourceId, ctx.params.revId)
|
||||||
|
|
||||||
ctx.message = `Datasource deleted.`
|
ctx.message = `Datasource deleted.`
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
|
|
|
@ -79,7 +79,7 @@ exports.execute = async function(ctx) {
|
||||||
|
|
||||||
exports.destroy = async function(ctx) {
|
exports.destroy = async function(ctx) {
|
||||||
const db = new CouchDB(ctx.user.appId)
|
const db = new CouchDB(ctx.user.appId)
|
||||||
await db.remove(ctx.params.queryId)
|
await db.remove(ctx.params.queryId, ctx.params.revId)
|
||||||
ctx.message = `Query deleted.`
|
ctx.message = `Query deleted.`
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,10 @@ router
|
||||||
authorized(PermissionTypes.QUERY, PermissionLevels.WRITE),
|
authorized(PermissionTypes.QUERY, PermissionLevels.WRITE),
|
||||||
queryController.execute
|
queryController.execute
|
||||||
)
|
)
|
||||||
.delete("/api/queries/:queryId", authorized(BUILDER), queryController.destroy)
|
.delete(
|
||||||
|
"/api/queries/:queryId/:revId",
|
||||||
|
authorized(BUILDER),
|
||||||
|
queryController.destroy
|
||||||
|
)
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
|
@ -18,7 +18,15 @@ const SCHEMA = {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
query: {},
|
query: {
|
||||||
|
Custom: {
|
||||||
|
type: "fields",
|
||||||
|
custom: true,
|
||||||
|
},
|
||||||
|
"Airtable Ids": {
|
||||||
|
type: "list",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
class AirtableIntegration {
|
class AirtableIntegration {
|
||||||
|
@ -27,17 +35,19 @@ class AirtableIntegration {
|
||||||
this.client = new Airtable(config).base(config.base)
|
this.client = new Airtable(config).base(config.base)
|
||||||
}
|
}
|
||||||
|
|
||||||
// async create() {
|
async create(record) {
|
||||||
|
try {
|
||||||
// }
|
const records = await this.client(this.config.table).create([
|
||||||
|
{
|
||||||
// async update() {
|
fields: record,
|
||||||
|
},
|
||||||
// }
|
])
|
||||||
|
return records
|
||||||
// async delete() {
|
} catch (err) {
|
||||||
|
console.error("Error writing to airtable", err)
|
||||||
// }
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async read() {
|
async read() {
|
||||||
const records = await this.client(this.config.table)
|
const records = await this.client(this.config.table)
|
||||||
|
@ -45,6 +55,33 @@ class AirtableIntegration {
|
||||||
.firstPage()
|
.firstPage()
|
||||||
return records.map(({ fields }) => fields)
|
return records.map(({ fields }) => fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async update(document) {
|
||||||
|
const { id, ...rest } = document
|
||||||
|
|
||||||
|
try {
|
||||||
|
const records = await this.client(this.config.table).update([
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
fields: rest,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
return records
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to airtable", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(id) {
|
||||||
|
try {
|
||||||
|
const records = await this.client(this.config.table).destroy([id])
|
||||||
|
return records
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to airtable", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -26,11 +26,26 @@ class ElasticSearchIntegration {
|
||||||
this.client = new Client({ node: config.url })
|
this.client = new Client({ node: config.url })
|
||||||
}
|
}
|
||||||
|
|
||||||
async read() {
|
async create(document) {
|
||||||
|
try {
|
||||||
|
const result = await this.client.index({
|
||||||
|
index: this.config.index,
|
||||||
|
body: JSON.parse(document),
|
||||||
|
})
|
||||||
|
return [result]
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to elasticsearch", err)
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
await this.client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async read(query) {
|
||||||
try {
|
try {
|
||||||
const result = await this.client.search({
|
const result = await this.client.search({
|
||||||
index: this.config.index,
|
index: this.config.index,
|
||||||
body: JSON.parse(this.config.query),
|
body: JSON.parse(query),
|
||||||
})
|
})
|
||||||
return result.body.hits.hits.map(({ _source }) => _source)
|
return result.body.hits.hits.map(({ _source }) => _source)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -32,41 +32,6 @@ const SCHEMA = {
|
||||||
SQL: {
|
SQL: {
|
||||||
type: "sql",
|
type: "sql",
|
||||||
},
|
},
|
||||||
"Simple Query": {
|
|
||||||
type: "fields",
|
|
||||||
fields: {
|
|
||||||
table: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
column: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
condition: {
|
|
||||||
type: "options",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
name: "Equals",
|
|
||||||
value: "=",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Not Equals",
|
|
||||||
value: "!=",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Greater Than",
|
|
||||||
value: ">",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Less Than",
|
|
||||||
value: "<",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,27 +52,25 @@ class PostgresIntegration {
|
||||||
return this.client.connect()
|
return this.client.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// async create() {
|
async create() {
|
||||||
|
const response = await this.client.query(this.queryString)
|
||||||
// }
|
return response.rows
|
||||||
|
}
|
||||||
|
|
||||||
async read() {
|
async read() {
|
||||||
const response = await this.client.query(this.queryString)
|
const response = await this.client.query(this.queryString)
|
||||||
return response.rows
|
return response.rows
|
||||||
}
|
}
|
||||||
|
|
||||||
// async update() {
|
async update() {
|
||||||
|
const response = await this.client.query(this.queryString)
|
||||||
|
return response.rows
|
||||||
|
}
|
||||||
|
|
||||||
// }
|
async delete() {
|
||||||
|
const response = await this.client.query(this.queryString)
|
||||||
// async delete() {
|
return response.rows
|
||||||
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// async query() {
|
|
||||||
// const response = await this.client.query(this.queryString)
|
|
||||||
// return response.rows
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
Loading…
Reference in New Issue