Finishing up front-end, getting variable creation and management up and working from within the query schema/header menus.
This commit is contained in:
parent
85858ff6b1
commit
858ef084ad
|
@ -125,7 +125,7 @@
|
||||||
<Icon size="S" hoverable name="MoreSmallList" />
|
<Icon size="S" hoverable name="MoreSmallList" />
|
||||||
</div>
|
</div>
|
||||||
{#each menuItems as item}
|
{#each menuItems as item}
|
||||||
<MenuItem on:click={item.onClick}>
|
<MenuItem on:click={() => item.onClick(field)}>
|
||||||
{item.text}
|
{item.text}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -162,4 +162,7 @@
|
||||||
.readOnly-menu {
|
.readOnly-menu {
|
||||||
grid-template-columns: 1fr 1fr 20px;
|
grid-template-columns: 1fr 1fr 20px;
|
||||||
}
|
}
|
||||||
|
.control {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -119,3 +119,62 @@ export function flipHeaderState(headersActivity) {
|
||||||
})
|
})
|
||||||
return enabled
|
return enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert dynamic variables list to simple key/val object
|
||||||
|
export function variablesToObject(datasource) {
|
||||||
|
const variablesList = datasource?.config?.dynamicVariables
|
||||||
|
if (variablesList && variablesList.length > 0) {
|
||||||
|
return variablesList.reduce(
|
||||||
|
(acc, next) => ({ ...acc, [next.name]: next.value }),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert dynamic variables object back to a list, enrich with query id
|
||||||
|
export function rebuildVariables(queryId, variables) {
|
||||||
|
let vars = []
|
||||||
|
if (variables) {
|
||||||
|
vars = Object.entries(variables).map(entry => {
|
||||||
|
return {
|
||||||
|
name: entry[0],
|
||||||
|
value: entry[1],
|
||||||
|
queryId,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return vars
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shouldShowVariables(dynamicVariables, variablesReadOnly) {
|
||||||
|
return !!(
|
||||||
|
dynamicVariables &&
|
||||||
|
// show when editable or when read only and not empty
|
||||||
|
(!variablesReadOnly || Object.keys(dynamicVariables).length > 0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildAuthConfigs(datasource) {
|
||||||
|
if (datasource?.config?.authConfigs) {
|
||||||
|
return datasource.config.authConfigs.map(c => ({
|
||||||
|
label: c.name,
|
||||||
|
value: c._id,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
breakQueryString,
|
||||||
|
buildQueryString,
|
||||||
|
fieldsToSchema,
|
||||||
|
flipHeaderState,
|
||||||
|
keyValueToQueryParameters,
|
||||||
|
queryParametersToKeyValue,
|
||||||
|
schemaToFields,
|
||||||
|
variablesToObject,
|
||||||
|
rebuildVariables,
|
||||||
|
shouldShowVariables,
|
||||||
|
buildAuthConfigs,
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<script>
|
||||||
|
import { Input, ModalContent, Modal } from "@budibase/bbui"
|
||||||
|
|
||||||
|
export let datasource
|
||||||
|
export let dynamicVariables
|
||||||
|
export let binding
|
||||||
|
|
||||||
|
let name, modal
|
||||||
|
|
||||||
|
export const show = () => {
|
||||||
|
modal.show()
|
||||||
|
}
|
||||||
|
export const hide = () => {
|
||||||
|
modal.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkValid(vars, name) {
|
||||||
|
if (!name) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const varKeys = Object.keys(vars || {})
|
||||||
|
return varKeys.find(key => key.toLowerCase() === name.toLowerCase()) == null
|
||||||
|
}
|
||||||
|
|
||||||
|
$: valid = checkValid(dynamicVariables, name)
|
||||||
|
$: error = name && !valid ? "Variable name is already in use." : null
|
||||||
|
|
||||||
|
async function saveVariable() {
|
||||||
|
const copiedName = name,
|
||||||
|
copiedBinding = binding
|
||||||
|
name = null
|
||||||
|
binding = null
|
||||||
|
dynamicVariables[copiedName] = copiedBinding
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal bind:this={modal}>
|
||||||
|
<ModalContent
|
||||||
|
title="Add dynamic variable"
|
||||||
|
confirmText="Save"
|
||||||
|
onConfirm={saveVariable}
|
||||||
|
disabled={!valid}
|
||||||
|
>
|
||||||
|
<Input label="Variable name" bind:value={name} on:input {error} />
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
|
@ -1,22 +1,22 @@
|
||||||
<script>
|
<script>
|
||||||
import { params } from "@roxi/routify"
|
import { params } from "@roxi/routify"
|
||||||
import { datasources, integrations, queries, flags } from "stores/backend"
|
import { datasources, flags, integrations, queries } from "stores/backend"
|
||||||
import {
|
import {
|
||||||
Layout,
|
|
||||||
Input,
|
|
||||||
Select,
|
|
||||||
Tabs,
|
|
||||||
Tab,
|
|
||||||
Banner,
|
Banner,
|
||||||
Divider,
|
|
||||||
Button,
|
|
||||||
Heading,
|
|
||||||
RadioGroup,
|
|
||||||
Label,
|
|
||||||
Body,
|
Body,
|
||||||
TextArea,
|
Button,
|
||||||
Table,
|
Divider,
|
||||||
|
Heading,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Layout,
|
||||||
notifications,
|
notifications,
|
||||||
|
RadioGroup,
|
||||||
|
Select,
|
||||||
|
Tab,
|
||||||
|
Table,
|
||||||
|
Tabs,
|
||||||
|
TextArea,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte"
|
import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte"
|
||||||
import EditableLabel from "components/common/inputs/EditableLabel.svelte"
|
import EditableLabel from "components/common/inputs/EditableLabel.svelte"
|
||||||
|
@ -26,33 +26,24 @@
|
||||||
import RestBodyInput from "../../_components/RestBodyInput.svelte"
|
import RestBodyInput from "../../_components/RestBodyInput.svelte"
|
||||||
import { capitalise } from "helpers"
|
import { capitalise } from "helpers"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import {
|
import restUtils from "helpers/data/utils"
|
||||||
fieldsToSchema,
|
|
||||||
schemaToFields,
|
|
||||||
breakQueryString,
|
|
||||||
buildQueryString,
|
|
||||||
keyValueToQueryParameters,
|
|
||||||
queryParametersToKeyValue,
|
|
||||||
flipHeaderState,
|
|
||||||
} from "helpers/data/utils"
|
|
||||||
import {
|
import {
|
||||||
RestBodyTypes as bodyTypes,
|
RestBodyTypes as bodyTypes,
|
||||||
SchemaTypeOptions,
|
SchemaTypeOptions,
|
||||||
} from "constants/backend"
|
} from "constants/backend"
|
||||||
import JSONPreview from "components/integration/JSONPreview.svelte"
|
import JSONPreview from "components/integration/JSONPreview.svelte"
|
||||||
import AccessLevelSelect from "components/integration/AccessLevelSelect.svelte"
|
import AccessLevelSelect from "components/integration/AccessLevelSelect.svelte"
|
||||||
|
import DynamicVariableModal from "../../_components/DynamicVariableModal.svelte"
|
||||||
import Placeholder from "assets/bb-spaceship.svg"
|
import Placeholder from "assets/bb-spaceship.svg"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
|
||||||
let query, datasource
|
let query, datasource
|
||||||
let breakQs = {},
|
let breakQs = {},
|
||||||
bindings = {}
|
bindings = {}
|
||||||
let url = ""
|
let saveId, url
|
||||||
let saveId, isGet
|
|
||||||
let response, schema, enabledHeaders
|
let response, schema, enabledHeaders
|
||||||
let datasourceType, integrationInfo, queryConfig, responseSuccess
|
|
||||||
let authConfigId
|
let authConfigId
|
||||||
let dynamicVariables
|
let dynamicVariables, addVariableModal, varBinding
|
||||||
|
|
||||||
$: datasourceType = datasource?.source
|
$: datasourceType = datasource?.source
|
||||||
$: integrationInfo = $integrations[datasourceType]
|
$: integrationInfo = $integrations[datasourceType]
|
||||||
|
@ -61,10 +52,13 @@
|
||||||
$: checkQueryName(url)
|
$: checkQueryName(url)
|
||||||
$: responseSuccess = response?.info?.code >= 200 && response?.info?.code < 400
|
$: responseSuccess = response?.info?.code >= 200 && response?.info?.code < 400
|
||||||
$: isGet = query?.queryVerb === "read"
|
$: isGet = query?.queryVerb === "read"
|
||||||
$: authConfigs = buildAuthConfigs(datasource)
|
$: authConfigs = restUtils.buildAuthConfigs(datasource)
|
||||||
$: schemaReadOnly = !responseSuccess
|
$: schemaReadOnly = !responseSuccess
|
||||||
$: variablesReadOnly = !responseSuccess
|
$: variablesReadOnly = !responseSuccess
|
||||||
$: showVariablesTab = shouldShowVariables(dynamicVariables, variablesReadOnly)
|
$: showVariablesTab = restUtils.shouldShowVariables(
|
||||||
|
dynamicVariables,
|
||||||
|
variablesReadOnly
|
||||||
|
)
|
||||||
|
|
||||||
function getSelectedQuery() {
|
function getSelectedQuery() {
|
||||||
return cloneDeep(
|
return cloneDeep(
|
||||||
|
@ -92,7 +86,7 @@
|
||||||
if (!base) {
|
if (!base) {
|
||||||
return base
|
return base
|
||||||
}
|
}
|
||||||
const qs = buildQueryString(qsObj)
|
const qs = restUtils.buildQueryString(qsObj)
|
||||||
let newUrl = base
|
let newUrl = base
|
||||||
if (base.includes("?")) {
|
if (base.includes("?")) {
|
||||||
newUrl = base.split("?")[0]
|
newUrl = base.split("?")[0]
|
||||||
|
@ -100,29 +94,15 @@
|
||||||
return qs.length > 0 ? `${newUrl}?${qs}` : newUrl
|
return qs.length > 0 ? `${newUrl}?${qs}` : newUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildAuthConfigs = datasource => {
|
|
||||||
if (datasource?.config?.authConfigs) {
|
|
||||||
return datasource.config.authConfigs.map(c => ({
|
|
||||||
label: c.name,
|
|
||||||
value: c._id,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
function learnMoreBanner() {
|
|
||||||
window.open("https://docs.budibase.com/building-apps/data/transformers")
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildQuery() {
|
function buildQuery() {
|
||||||
const newQuery = { ...query }
|
const newQuery = { ...query }
|
||||||
const queryString = buildQueryString(breakQs)
|
const queryString = restUtils.buildQueryString(breakQs)
|
||||||
newQuery.fields.path = url.split("?")[0]
|
newQuery.fields.path = url.split("?")[0]
|
||||||
newQuery.fields.queryString = queryString
|
newQuery.fields.queryString = queryString
|
||||||
newQuery.fields.authConfigId = authConfigId
|
newQuery.fields.authConfigId = authConfigId
|
||||||
newQuery.fields.disabledHeaders = flipHeaderState(enabledHeaders)
|
newQuery.fields.disabledHeaders = restUtils.flipHeaderState(enabledHeaders)
|
||||||
newQuery.schema = fieldsToSchema(schema)
|
newQuery.schema = restUtils.fieldsToSchema(schema)
|
||||||
newQuery.parameters = keyValueToQueryParameters(bindings)
|
newQuery.parameters = restUtils.keyValueToQueryParameters(bindings)
|
||||||
return newQuery
|
return newQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,8 +115,10 @@
|
||||||
notifications.success(`Request saved successfully.`)
|
notifications.success(`Request saved successfully.`)
|
||||||
|
|
||||||
if (dynamicVariables) {
|
if (dynamicVariables) {
|
||||||
const dynamicVars = rebuildVariables(saveId)
|
datasource.config.dynamicVariables = restUtils.rebuildVariables(
|
||||||
datasource.config.dynamicVariables = dynamicVars
|
saveId,
|
||||||
|
dynamicVariables
|
||||||
|
)
|
||||||
await datasources.save(datasource)
|
await datasources.save(datasource)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -175,57 +157,21 @@
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert dynamic variables list to simple key/val object
|
|
||||||
const variablesToObject = datasource => {
|
|
||||||
const variablesList = datasource?.config?.dynamicVariables
|
|
||||||
if (variablesList && variablesList.length > 0) {
|
|
||||||
return variablesList.reduce(
|
|
||||||
(acc, next) => ({ ...acc, [next.name]: next.value }),
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert dynamic variables object back to a list, enrich with query id
|
|
||||||
const rebuildVariables = queryId => {
|
|
||||||
let variables = []
|
|
||||||
if (dynamicVariables) {
|
|
||||||
variables = Object.entries(dynamicVariables).map(entry => {
|
|
||||||
return {
|
|
||||||
name: entry[0],
|
|
||||||
value: entry[1],
|
|
||||||
queryId,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return variables
|
|
||||||
}
|
|
||||||
|
|
||||||
const shouldShowVariables = (dynamicVariables, variablesReadOnly) => {
|
|
||||||
if (
|
|
||||||
dynamicVariables &&
|
|
||||||
// show when editable or when read only and not empty
|
|
||||||
(!variablesReadOnly || Object.keys(dynamicVariables).length > 0)
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const schemaMenuItems = [
|
const schemaMenuItems = [
|
||||||
{
|
{
|
||||||
text: "Create dynamic variable",
|
text: "Create dynamic variable",
|
||||||
onClick: () => {
|
onClick: input => {
|
||||||
console.log("create variable")
|
varBinding = `{{ data.0.[${input.name}] }}`
|
||||||
|
addVariableModal.show()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
const responseHeadersMenuItems = [
|
const responseHeadersMenuItems = [
|
||||||
{
|
{
|
||||||
text: "Create dynamic variable",
|
text: "Create dynamic variable",
|
||||||
onClick: () => {
|
onClick: input => {
|
||||||
console.log("create variable")
|
varBinding = `{{ info.headers.[${input.name}] }}`
|
||||||
|
addVariableModal.show()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -237,14 +183,14 @@
|
||||||
datasource = $datasources.list.find(ds => ds._id === query?.datasourceId)
|
datasource = $datasources.list.find(ds => ds._id === query?.datasourceId)
|
||||||
const datasourceUrl = datasource?.config.url
|
const datasourceUrl = datasource?.config.url
|
||||||
const qs = query?.fields.queryString
|
const qs = query?.fields.queryString
|
||||||
breakQs = breakQueryString(qs)
|
breakQs = restUtils.breakQueryString(qs)
|
||||||
if (datasourceUrl && !query.fields.path?.startsWith(datasourceUrl)) {
|
if (datasourceUrl && !query.fields.path?.startsWith(datasourceUrl)) {
|
||||||
const path = query.fields.path
|
const path = query.fields.path
|
||||||
query.fields.path = `${datasource.config.url}/${path ? path : ""}`
|
query.fields.path = `${datasource.config.url}/${path ? path : ""}`
|
||||||
}
|
}
|
||||||
url = buildUrl(query.fields.path, breakQs)
|
url = buildUrl(query.fields.path, breakQs)
|
||||||
schema = schemaToFields(query.schema)
|
schema = restUtils.schemaToFields(query.schema)
|
||||||
bindings = queryParametersToKeyValue(query.parameters)
|
bindings = restUtils.queryParametersToKeyValue(query.parameters)
|
||||||
authConfigId = getAuthConfigId()
|
authConfigId = getAuthConfigId()
|
||||||
if (!query.fields.disabledHeaders) {
|
if (!query.fields.disabledHeaders) {
|
||||||
query.fields.disabledHeaders = {}
|
query.fields.disabledHeaders = {}
|
||||||
|
@ -255,7 +201,7 @@
|
||||||
query.fields.disabledHeaders[header] = false
|
query.fields.disabledHeaders[header] = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enabledHeaders = flipHeaderState(query.fields.disabledHeaders)
|
enabledHeaders = restUtils.flipHeaderState(query.fields.disabledHeaders)
|
||||||
if (query && !query.transformer) {
|
if (query && !query.transformer) {
|
||||||
query.transformer = "return data"
|
query.transformer = "return data"
|
||||||
}
|
}
|
||||||
|
@ -267,10 +213,16 @@
|
||||||
if (query && !query.fields.bodyType) {
|
if (query && !query.fields.bodyType) {
|
||||||
query.fields.bodyType = "none"
|
query.fields.bodyType = "none"
|
||||||
}
|
}
|
||||||
dynamicVariables = variablesToObject(datasource)
|
dynamicVariables = restUtils.variablesToObject(datasource)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<DynamicVariableModal
|
||||||
|
{datasource}
|
||||||
|
{dynamicVariables}
|
||||||
|
bind:binding={varBinding}
|
||||||
|
bind:this={addVariableModal}
|
||||||
|
/>
|
||||||
{#if query && queryConfig}
|
{#if query && queryConfig}
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
|
@ -340,7 +292,10 @@
|
||||||
{#if !$flags.queryTransformerBanner}
|
{#if !$flags.queryTransformerBanner}
|
||||||
<Banner
|
<Banner
|
||||||
extraButtonText="Learn more"
|
extraButtonText="Learn more"
|
||||||
extraButtonAction={learnMoreBanner}
|
extraButtonAction={() =>
|
||||||
|
window.open(
|
||||||
|
"https://docs.budibase.com/building-apps/data/transformers"
|
||||||
|
)}
|
||||||
on:change={() =>
|
on:change={() =>
|
||||||
flags.updateFlag("queryTransformerBanner", true)}
|
flags.updateFlag("queryTransformerBanner", true)}
|
||||||
>
|
>
|
||||||
|
@ -449,9 +404,9 @@
|
||||||
name="Variable"
|
name="Variable"
|
||||||
headings
|
headings
|
||||||
keyHeading="Name"
|
keyHeading="Name"
|
||||||
keyPlaceholder="e.g. cookie"
|
keyPlaceholder="Variable name"
|
||||||
valueHeading={`Value`}
|
valueHeading={`Value`}
|
||||||
valuePlaceholder={`e.g. {{ headers.set-cookie }}`}
|
valuePlaceholder={`{{ value }}`}
|
||||||
readOnly={variablesReadOnly}
|
readOnly={variablesReadOnly}
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -2457,6 +2457,10 @@
|
||||||
"label": "Rows",
|
"label": "Rows",
|
||||||
"key": "rows"
|
"key": "rows"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "Extra Info",
|
||||||
|
"key": "info"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Rows Length",
|
"label": "Rows Length",
|
||||||
"key": "rowsLength"
|
"key": "rowsLength"
|
||||||
|
@ -3178,6 +3182,10 @@
|
||||||
"label": "Rows",
|
"label": "Rows",
|
||||||
"key": "rows"
|
"key": "rows"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "Extra Info",
|
||||||
|
"key": "info"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Rows Length",
|
"label": "Rows Length",
|
||||||
"key": "rowsLength"
|
"key": "rowsLength"
|
||||||
|
|
|
@ -15,7 +15,8 @@ export const fetchDatasource = async dataSource => {
|
||||||
|
|
||||||
// Fetch all rows in data source
|
// Fetch all rows in data source
|
||||||
const { type, tableId, fieldName } = dataSource
|
const { type, tableId, fieldName } = dataSource
|
||||||
let rows = []
|
let rows = [],
|
||||||
|
info = {}
|
||||||
if (type === "table") {
|
if (type === "table") {
|
||||||
rows = await fetchTableData(tableId)
|
rows = await fetchTableData(tableId)
|
||||||
} else if (type === "view") {
|
} else if (type === "view") {
|
||||||
|
@ -28,7 +29,12 @@ export const fetchDatasource = async dataSource => {
|
||||||
parameters[param.name] = param.default
|
parameters[param.name] = param.default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rows = await executeQuery({ queryId: dataSource._id, parameters })
|
const { data, ...rest } = await executeQuery({
|
||||||
|
queryId: dataSource._id,
|
||||||
|
parameters,
|
||||||
|
})
|
||||||
|
info = rest
|
||||||
|
rows = data
|
||||||
} else if (type === FieldTypes.LINK) {
|
} else if (type === FieldTypes.LINK) {
|
||||||
rows = await fetchRelationshipData({
|
rows = await fetchRelationshipData({
|
||||||
rowId: dataSource.rowId,
|
rowId: dataSource.rowId,
|
||||||
|
@ -38,7 +44,7 @@ export const fetchDatasource = async dataSource => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enrich the result is always an array
|
// Enrich the result is always an array
|
||||||
return Array.isArray(rows) ? rows : []
|
return { rows: Array.isArray(rows) ? rows : [], info }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
// Provider state
|
// Provider state
|
||||||
let rows = []
|
let rows = []
|
||||||
let allRows = []
|
let allRows = []
|
||||||
|
let info = {}
|
||||||
let schema = {}
|
let schema = {}
|
||||||
let bookmarks = [null]
|
let bookmarks = [null]
|
||||||
let pageNumber = 0
|
let pageNumber = 0
|
||||||
|
@ -120,6 +121,7 @@
|
||||||
// Build our data context
|
// Build our data context
|
||||||
$: dataContext = {
|
$: dataContext = {
|
||||||
rows,
|
rows,
|
||||||
|
info,
|
||||||
schema,
|
schema,
|
||||||
rowsLength: rows.length,
|
rowsLength: rows.length,
|
||||||
|
|
||||||
|
@ -206,7 +208,9 @@
|
||||||
} else {
|
} else {
|
||||||
// For other data sources like queries or views, fetch all rows from the
|
// For other data sources like queries or views, fetch all rows from the
|
||||||
// server
|
// server
|
||||||
allRows = await API.fetchDatasource(dataSource)
|
const data = await API.fetchDatasource(dataSource)
|
||||||
|
allRows = data.rows
|
||||||
|
info = data.info
|
||||||
}
|
}
|
||||||
loading = false
|
loading = false
|
||||||
loaded = true
|
loaded = true
|
||||||
|
|
|
@ -182,13 +182,13 @@ exports.execute = async function (ctx) {
|
||||||
|
|
||||||
// call the relevant CRUD method on the integration class
|
// call the relevant CRUD method on the integration class
|
||||||
try {
|
try {
|
||||||
const { rows } = await Runner.run({
|
const { rows, extra } = await Runner.run({
|
||||||
datasource,
|
datasource,
|
||||||
queryVerb: query.queryVerb,
|
queryVerb: query.queryVerb,
|
||||||
query: enrichedQuery,
|
query: enrichedQuery,
|
||||||
transformer: query.transformer,
|
transformer: query.transformer,
|
||||||
})
|
})
|
||||||
ctx.body = rows
|
ctx.body = { data: rows, ...extra }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ctx.throw(400, err)
|
ctx.throw(400, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,11 @@ exports.definition = {
|
||||||
type: "object",
|
type: "object",
|
||||||
description: "The response from the datasource execution",
|
description: "The response from the datasource execution",
|
||||||
},
|
},
|
||||||
|
info: {
|
||||||
|
type: "object",
|
||||||
|
description:
|
||||||
|
"Some query types may return extra data, like headers from a REST query",
|
||||||
|
},
|
||||||
success: {
|
success: {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
description: "Whether the action was successful",
|
description: "Whether the action was successful",
|
||||||
|
@ -68,13 +73,16 @@ exports.run = async function ({ inputs, appId, emitter }) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await queryController.execute(ctx)
|
await queryController.execute(ctx)
|
||||||
|
const { data, ...rest } = ctx.body
|
||||||
return {
|
return {
|
||||||
response: ctx.body,
|
response: data,
|
||||||
|
info: rest,
|
||||||
success: true,
|
success: true,
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
info: {},
|
||||||
response: automationUtils.getError(err),
|
response: automationUtils.getError(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue