Merge branch 'develop' of github.com:Budibase/budibase into events/plugins
This commit is contained in:
commit
274e34044e
27 changed files with 68 additions and 58 deletions
|
@ -65,7 +65,7 @@ Budibase is open-source - licensed as GPL v3. This should fill you with confiden
|
|||
<br /><br />
|
||||
|
||||
### Load data or start from scratch
|
||||
Budibase pulls in data from multiple sources, including MongoDB, CouchDB, PostgreSQL, MySQL, Airtable, S3, DynamoDB, or a REST API. And unlike other platforms, with Budibase you can start from scratch and create business apps with no data sources. [Request new data sources](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas).
|
||||
Budibase pulls in data from multiple sources, including MongoDB, CouchDB, PostgreSQL, MySQL, Airtable, S3, DynamoDB, or a REST API. And unlike other platforms, with Budibase you can start from scratch and create business apps with no datasources. [Request new datasources](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas).
|
||||
|
||||
<p align="center">
|
||||
<img alt="Budibase data" src="https://res.cloudinary.com/daog6scxm/image/upload/v1636970242/Out%20of%20beta%20launch/data_n1tlhf.png">
|
||||
|
|
|
@ -348,7 +348,7 @@ export interface paths {
|
|||
}
|
||||
}
|
||||
responses: {
|
||||
/** Returns the created table, including the ID which has been generated for it. This can be internal or external data sources. */
|
||||
/** Returns the created table, including the ID which has been generated for it. This can be internal or external datasources. */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["tableOutput"]
|
||||
|
@ -959,7 +959,7 @@ export interface components {
|
|||
query: {
|
||||
/** @description The ID of the query. */
|
||||
_id: string
|
||||
/** @description The ID of the data source the query belongs to. */
|
||||
/** @description The ID of the datasource the query belongs to. */
|
||||
datasourceId?: string
|
||||
/** @description The bindings which are required to perform this query. */
|
||||
parameters?: string[]
|
||||
|
@ -983,7 +983,7 @@ export interface components {
|
|||
data: {
|
||||
/** @description The ID of the query. */
|
||||
_id: string
|
||||
/** @description The ID of the data source the query belongs to. */
|
||||
/** @description The ID of the datasource the query belongs to. */
|
||||
datasourceId?: string
|
||||
/** @description The bindings which are required to perform this query. */
|
||||
parameters?: string[]
|
||||
|
|
|
@ -82,10 +82,10 @@ filterTests(['smoke', 'all'], () => {
|
|||
})
|
||||
|
||||
if (Cypress.env("TEST_ENV")) {
|
||||
it("should generate data source screens", () => {
|
||||
// Using MySQL data source for testing this
|
||||
it("should generate datasource screens", () => {
|
||||
// Using MySQL datasource for testing this
|
||||
const datasource = "MySQL"
|
||||
// Select & configure MySQL data source
|
||||
// Select & configure MySQL datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
cy.addDatasourceConfig(datasource)
|
||||
// Create Autogenerated screens from a MySQL table - MySQL contains books table
|
||||
|
|
|
@ -11,8 +11,8 @@ filterTests(["all"], () => {
|
|||
const queryName = "Cypress Test Query"
|
||||
const queryRename = "CT Query Rename"
|
||||
|
||||
it("Should add MySQL data source without configuration", () => {
|
||||
// Select MySQL data source
|
||||
it("Should add MySQL datasource without configuration", () => {
|
||||
// Select MySQL datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
// Attempt to fetch tables without applying configuration
|
||||
cy.intercept("**/datasources").as("datasource")
|
||||
|
@ -35,8 +35,8 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Button").contains("Skip table fetch").click({ force: true })
|
||||
})
|
||||
|
||||
it("should add MySQL data source and fetch tables", () => {
|
||||
// Add & configure MySQL data source
|
||||
it("should add MySQL datasource and fetch tables", () => {
|
||||
// Add & configure MySQL datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
cy.intercept("**/datasources").as("datasource")
|
||||
cy.addDatasourceConfig(datasource)
|
||||
|
@ -52,7 +52,7 @@ filterTests(["all"], () => {
|
|||
})
|
||||
|
||||
it("should check table fetching error", () => {
|
||||
// MySQL test data source contains tables without primary keys
|
||||
// MySQL test datasource contains tables without primary keys
|
||||
cy.get(".spectrum-InLineAlert")
|
||||
.should("contain", "Error fetching tables")
|
||||
.and("contain", "No primary key constraint found")
|
||||
|
|
|
@ -11,8 +11,8 @@ filterTests(["all"], () => {
|
|||
const queryName = "Cypress Test Query"
|
||||
const queryRename = "CT Query Rename"
|
||||
|
||||
it("Should add Oracle data source and skip table fetch", () => {
|
||||
// Select Oracle data source
|
||||
it("Should add Oracle datasource and skip table fetch", () => {
|
||||
// Select Oracle datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
// Skip table fetch - no config added
|
||||
cy.get(".spectrum-Button")
|
||||
|
@ -23,7 +23,7 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Textfield-input", { timeout: 500 })
|
||||
.eq(1)
|
||||
.should("have.value", "localhost")
|
||||
// Add another Oracle data source, configure & skip table fetch
|
||||
// Add another Oracle datasource, configure & skip table fetch
|
||||
cy.selectExternalDatasource(datasource)
|
||||
cy.addDatasourceConfig(datasource, true)
|
||||
// Confirm config and no tables
|
||||
|
@ -33,8 +33,8 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Body").eq(2).should("contain", "No tables found.")
|
||||
})
|
||||
|
||||
it("Should add Oracle data source and fetch tables without configuration", () => {
|
||||
// Select Oracle data source
|
||||
it("Should add Oracle datasource and fetch tables without configuration", () => {
|
||||
// Select Oracle datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
// Attempt to fetch tables without applying configuration
|
||||
cy.intercept("**/datasources").as("datasource")
|
||||
|
@ -49,8 +49,8 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Button").contains("Skip table fetch").click({ force: true })
|
||||
})
|
||||
|
||||
xit("should add Oracle data source and fetch tables", () => {
|
||||
// Add & configure Oracle data source
|
||||
xit("should add Oracle datasource and fetch tables", () => {
|
||||
// Add & configure Oracle datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
cy.intercept("**/datasources").as("datasource")
|
||||
cy.addDatasourceConfig(datasource)
|
||||
|
|
|
@ -11,8 +11,8 @@ filterTests(["all"], () => {
|
|||
const queryName = "Cypress Test Query"
|
||||
const queryRename = "CT Query Rename"
|
||||
|
||||
xit("Should add PostgreSQL data source without configuration", () => {
|
||||
// Select PostgreSQL data source
|
||||
xit("Should add PostgreSQL datasource without configuration", () => {
|
||||
// Select PostgreSQL datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
// Attempt to fetch tables without applying configuration
|
||||
cy.intercept("**/datasources").as("datasource")
|
||||
|
@ -27,8 +27,8 @@ filterTests(["all"], () => {
|
|||
cy.get(".spectrum-Button").contains("Skip table fetch").click({ force: true })
|
||||
})
|
||||
|
||||
it("should add PostgreSQL data source and fetch tables", () => {
|
||||
// Add & configure PostgreSQL data source
|
||||
it("should add PostgreSQL datasource and fetch tables", () => {
|
||||
// Add & configure PostgreSQL datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
cy.intercept("**/datasources").as("datasource")
|
||||
cy.addDatasourceConfig(datasource)
|
||||
|
|
|
@ -10,8 +10,8 @@ filterTests(["smoke", "all"], () => {
|
|||
const datasource = "REST"
|
||||
const restUrl = "https://api.openbrewerydb.org/breweries"
|
||||
|
||||
it("Should add REST data source with incorrect API", () => {
|
||||
// Select REST data source
|
||||
it("Should add REST datasource with incorrect API", () => {
|
||||
// Select REST datasource
|
||||
cy.selectExternalDatasource(datasource)
|
||||
// Enter incorrect api & attempt to send query
|
||||
cy.get(".query-buttons", { timeout: 1000 }).contains("Add query").click({ force: true })
|
||||
|
|
|
@ -763,7 +763,7 @@ Cypress.Commands.add("navigateToDataSection", () => {
|
|||
})
|
||||
|
||||
Cypress.Commands.add("navigateToAutogeneratedModal", () => {
|
||||
// Screen name must already exist within data source
|
||||
// Screen name must already exist within datasource
|
||||
cy.contains("Design").click()
|
||||
cy.get(".spectrum-Button").contains("Add screen").click({ force: true })
|
||||
cy.get(".spectrum-Modal").within(() => {
|
||||
|
@ -779,7 +779,7 @@ Cypress.Commands.add("navigateToAutogeneratedModal", () => {
|
|||
Cypress.Commands.add("selectExternalDatasource", datasourceName => {
|
||||
// Navigates to Data Section
|
||||
cy.navigateToDataSection()
|
||||
// Open Data Source modal
|
||||
// Open Datasource modal
|
||||
cy.get(".nav").within(() => {
|
||||
cy.get(".add-button").click()
|
||||
})
|
||||
|
|
|
@ -27,7 +27,7 @@ export async function saveDatasource(config, skipFetch = false) {
|
|||
// Create datasource
|
||||
const resp = await datasources.save(datasource, !skipFetch && datasource.plus)
|
||||
|
||||
// update the tables incase data source plus
|
||||
// update the tables incase datasource plus
|
||||
await tables.fetch()
|
||||
await datasources.select(resp._id)
|
||||
return resp
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
: []
|
||||
$: openDataSource = enrichedDataSources.find(x => x.open)
|
||||
$: {
|
||||
// Ensure the open data source is always included in the list of open
|
||||
// data sources
|
||||
// Ensure the open datasource is always included in the list of open
|
||||
// datasources
|
||||
if (openDataSource) {
|
||||
openNode(openDataSource)
|
||||
}
|
||||
|
@ -79,7 +79,7 @@
|
|||
})
|
||||
|
||||
const containsActiveEntity = datasource => {
|
||||
// If we're view a query then the data source ID is in the URL
|
||||
// If we're view a query then the datasource ID is in the URL
|
||||
if ($params.selectedDatasource === datasource._id) {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
<Modal bind:this={modal}>
|
||||
<ModalContent
|
||||
disabled={!Object.keys(integration).length}
|
||||
title="Add data source"
|
||||
title="Add datasource"
|
||||
confirmText="Continue"
|
||||
showSecondaryButton={showImportButton}
|
||||
secondaryButtonText="Import"
|
||||
|
@ -155,7 +155,7 @@
|
|||
</Layout>
|
||||
|
||||
<Layout noPadding gap="XS">
|
||||
<Body size="S">Connect to an external data source</Body>
|
||||
<Body size="S">Connect to an external datasource</Body>
|
||||
<div class="item-list">
|
||||
{#each Object.entries(integrations).filter(([key, val]) => key !== IntegrationTypes.INTERNAL && !val.custom) as [integrationType, schema]}
|
||||
<DatasourceCard
|
||||
|
@ -170,7 +170,7 @@
|
|||
|
||||
{#if customIntegrations.length > 0}
|
||||
<Layout noPadding gap="XS">
|
||||
<Body size="S">Custom data source</Body>
|
||||
<Body size="S">Custom datasource</Body>
|
||||
<div class="item-list">
|
||||
{#each customIntegrations as [integrationType, schema]}
|
||||
<DatasourceCard
|
||||
|
|
|
@ -73,13 +73,13 @@
|
|||
|
||||
<div class="root">
|
||||
<Body size="S">
|
||||
Choose the data source that provides the row you would like to duplicate.
|
||||
Choose the datasource that provides the row you would like to duplicate.
|
||||
<br />
|
||||
You can always add or override fields manually.
|
||||
</Body>
|
||||
|
||||
<div class="params">
|
||||
<Label small>Data Source</Label>
|
||||
<Label small>Datasource</Label>
|
||||
<Select
|
||||
bind:value={parameters.providerId}
|
||||
options={providerOptions}
|
||||
|
|
|
@ -71,13 +71,13 @@
|
|||
|
||||
<div class="root">
|
||||
<Body size="S">
|
||||
Choosing a Data Source will automatically use the data it provides, but it's
|
||||
Choosing a Datasource will automatically use the data it provides, but it's
|
||||
optional.<br />
|
||||
You can always add or override fields manually.
|
||||
</Body>
|
||||
|
||||
<div class="params">
|
||||
<Label small>Data Source</Label>
|
||||
<Label small>Datasource</Label>
|
||||
<Select
|
||||
bind:value={parameters.providerId}
|
||||
options={providerOptions}
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
size="L"
|
||||
>
|
||||
<Body size="S">
|
||||
Select which data source you would like to use to create your screens
|
||||
Select which datasource you would like to use to create your screens
|
||||
</Body>
|
||||
<Layout noPadding gap="S">
|
||||
{#each filteredSources as datasource}
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
<Heading size="XS">Autogenerated screens</Heading>
|
||||
<Body size="S">
|
||||
Add autogenerated screens with CRUD functionality to get a working
|
||||
app quickly! (Requires a data source)
|
||||
app quickly! (Requires a datasource)
|
||||
</Body>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
? plugin.schema.schema.icon || "Book"
|
||||
: plugin.schema.schema.icon || "Beaker"
|
||||
|
||||
$: friendlyName = plugin?.schema?.schema?.friendlyName
|
||||
|
||||
function pluginDeleted() {
|
||||
if (detailsModal) {
|
||||
detailsModal.hide()
|
||||
|
@ -41,6 +43,9 @@
|
|||
>
|
||||
{plugin.name}
|
||||
</Body>
|
||||
<Body size="XS" color="var(--spectrum-global-color-gray-900)">
|
||||
{friendlyName}
|
||||
</Body>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -65,6 +70,11 @@
|
|||
<Input disabled value={plugin.name} />
|
||||
</div>
|
||||
|
||||
<div class="details-row">
|
||||
<Label size="M">Friendly name</Label>
|
||||
<Input disabled value={friendlyName} />
|
||||
</div>
|
||||
|
||||
<div class="details-row">
|
||||
<Label size="M">Type</Label>
|
||||
<Input
|
||||
|
@ -127,7 +137,7 @@
|
|||
|
||||
.details-row {
|
||||
display: grid;
|
||||
grid-template-columns: 60px 1fr;
|
||||
grid-template-columns: 70px 1fr;
|
||||
grid-gap: var(--spacing-l) var(--spacing-l);
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
if (["user", "url"].includes(context.closestComponentId)) {
|
||||
return {}
|
||||
}
|
||||
// Always inherit the closest data source
|
||||
// Always inherit the closest datasource
|
||||
const closestContext = context[`${context.closestComponentId}`] || {}
|
||||
return closestContext || {}
|
||||
}
|
||||
|
|
|
@ -372,7 +372,7 @@
|
|||
formState,
|
||||
formApi,
|
||||
|
||||
// Data source is needed by attachment fields to be able to upload files
|
||||
// Datasource is needed by attachment fields to be able to upload files
|
||||
// to the correct table ID
|
||||
dataSource,
|
||||
})
|
||||
|
|
|
@ -13,7 +13,7 @@ const schemaComponentMap = {
|
|||
/**
|
||||
* Determine data types for search fields and only use those that are valid
|
||||
* @param searchColumns the search columns to use
|
||||
* @param schema the data source schema
|
||||
* @param schema the datasource schema
|
||||
*/
|
||||
export const enrichSearchColumns = (searchColumns, schema) => {
|
||||
let enrichedColumns = []
|
||||
|
|
|
@ -1327,7 +1327,7 @@
|
|||
"type": "string"
|
||||
},
|
||||
"datasourceId": {
|
||||
"description": "The ID of the data source the query belongs to.",
|
||||
"description": "The ID of the datasource the query belongs to.",
|
||||
"type": "string"
|
||||
},
|
||||
"parameters": {
|
||||
|
@ -1386,7 +1386,7 @@
|
|||
"type": "string"
|
||||
},
|
||||
"datasourceId": {
|
||||
"description": "The ID of the data source the query belongs to.",
|
||||
"description": "The ID of the datasource the query belongs to.",
|
||||
"type": "string"
|
||||
},
|
||||
"parameters": {
|
||||
|
@ -2289,7 +2289,7 @@
|
|||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Returns the created table, including the ID which has been generated for it. This can be internal or external data sources.",
|
||||
"description": "Returns the created table, including the ID which has been generated for it. This can be internal or external datasources.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
|
|
|
@ -1004,7 +1004,7 @@ components:
|
|||
description: The ID of the query.
|
||||
type: string
|
||||
datasourceId:
|
||||
description: The ID of the data source the query belongs to.
|
||||
description: The ID of the datasource the query belongs to.
|
||||
type: string
|
||||
parameters:
|
||||
description: The bindings which are required to perform this query.
|
||||
|
@ -1051,7 +1051,7 @@ components:
|
|||
description: The ID of the query.
|
||||
type: string
|
||||
datasourceId:
|
||||
description: The ID of the data source the query belongs to.
|
||||
description: The ID of the datasource the query belongs to.
|
||||
type: string
|
||||
parameters:
|
||||
description: The bindings which are required to perform this query.
|
||||
|
@ -1665,7 +1665,7 @@ paths:
|
|||
responses:
|
||||
"200":
|
||||
description: Returns the created table, including the ID which has been
|
||||
generated for it. This can be internal or external data sources.
|
||||
generated for it. This can be internal or external datasources.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
|
|
@ -82,7 +82,7 @@ const querySchema = object(
|
|||
type: "string",
|
||||
},
|
||||
datasourceId: {
|
||||
description: "The ID of the data source the query belongs to.",
|
||||
description: "The ID of the datasource the query belongs to.",
|
||||
type: "string",
|
||||
},
|
||||
parameters: {
|
||||
|
|
|
@ -53,7 +53,7 @@ exports.save = async ctx => {
|
|||
}
|
||||
|
||||
exports.fetchView = async ctx => {
|
||||
// there are no views in external data sources, shouldn't ever be called
|
||||
// there are no views in external datasources, shouldn't ever be called
|
||||
// for now just fetch
|
||||
const split = ctx.params.viewName.split("all_")
|
||||
ctx.params.tableId = split[1] ? split[1] : split[0]
|
||||
|
|
|
@ -26,7 +26,7 @@ const read = [],
|
|||
* responses:
|
||||
* 200:
|
||||
* description: Returns the created table, including the ID which has been generated for it. This can be
|
||||
* internal or external data sources.
|
||||
* internal or external datasources.
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
|
|
|
@ -55,7 +55,7 @@ router
|
|||
* @apiParam (Body) {string} [_rev] If updating an existing internal table then the revision must also be specified.
|
||||
* @apiParam (Body) {string} type] This should either be "internal" or "external" depending on the table type -
|
||||
* this will default to internal.
|
||||
* @apiParam (Body) {string} [sourceId] If creating an external table then this should be set to the data source ID. If
|
||||
* @apiParam (Body) {string} [sourceId] If creating an external table then this should be set to the datasource ID. If
|
||||
* building an internal table this does not need to be set, although it will be returned as "bb_internal".
|
||||
* @apiParam (Body) {string} name The name of the table, this will be used in the UI. To rename the table simply
|
||||
* supply the table structure to this endpoint with the name changed.
|
||||
|
|
|
@ -344,7 +344,7 @@ export interface paths {
|
|||
};
|
||||
};
|
||||
responses: {
|
||||
/** Returns the created table, including the ID which has been generated for it. This can be internal or external data sources. */
|
||||
/** Returns the created table, including the ID which has been generated for it. This can be internal or external datasources. */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["tableOutput"];
|
||||
|
@ -965,7 +965,7 @@ export interface components {
|
|||
query: {
|
||||
/** @description The ID of the query. */
|
||||
_id: string;
|
||||
/** @description The ID of the data source the query belongs to. */
|
||||
/** @description The ID of the datasource the query belongs to. */
|
||||
datasourceId?: string;
|
||||
/** @description The bindings which are required to perform this query. */
|
||||
parameters?: string[];
|
||||
|
@ -989,7 +989,7 @@ export interface components {
|
|||
data: {
|
||||
/** @description The ID of the query. */
|
||||
_id: string;
|
||||
/** @description The ID of the data source the query belongs to. */
|
||||
/** @description The ID of the datasource the query belongs to. */
|
||||
datasourceId?: string;
|
||||
/** @description The bindings which are required to perform this query. */
|
||||
parameters?: string[];
|
||||
|
|
|
@ -560,7 +560,7 @@ class TestConfiguration {
|
|||
|
||||
async createQuery(config = null) {
|
||||
if (!this.datasource && !config) {
|
||||
throw "No data source created for query."
|
||||
throw "No datasource created for query."
|
||||
}
|
||||
config = config || basicQuery(this.datasource._id)
|
||||
return this._req(config, null, controllers.query.save)
|
||||
|
|
Loading…
Reference in a new issue