1
0
Fork 0
mirror of synced 2024-07-04 22:11:23 +12:00

Merge branch 'form-builder' into relationship-one-to-many

This commit is contained in:
Keviin Åberg Kultalahti 2021-02-09 16:26:42 +01:00
commit 1a474b54ef
8 changed files with 76 additions and 50 deletions

View file

@ -9,6 +9,7 @@ import {
makeSaveButton, makeSaveButton,
makeTableFormComponents, makeTableFormComponents,
makeMainForm, makeMainForm,
spectrumColor,
} from "./utils/commonComponents" } from "./utils/commonComponents"
export default function(tables) { export default function(tables) {
@ -52,6 +53,7 @@ function generateTitleContainer(table, title, formId) {
background: "transparent", background: "transparent",
color: "#4285f4", color: "#4285f4",
}) })
.customStyle(spectrumColor(700))
.text("Delete") .text("Delete")
.customProps({ .customProps({
className: "", className: "",

View file

@ -29,6 +29,11 @@ export class Component extends BaseStructure {
return this return this
} }
customStyle(styling) {
this._json._styles.custom = styling
return this
}
instanceName(name) { instanceName(name) {
this._json._instanceName = name this._json._instanceName = name
return this return this

View file

@ -3,6 +3,15 @@ import { Component } from "./Component"
import { rowListUrl } from "../rowListScreen" import { rowListUrl } from "../rowListScreen"
import { backendUiStore } from "builderStore" import { backendUiStore } from "builderStore"
export function spectrumColor(number) {
// Acorn throws a parsing error in this file if the word g-l-o-b-a-l is found
// (without dashes - I can't even type it in a comment).
// God knows why. It seems to think optional chaining further down the
// file is invalid if the word g-l-o-b-a-l is found - hence the reason this
// statement is split into parts.
return "color: var(--spectrum-glo" + `bal-color-gray-${number});`
}
export function makeLinkComponent(tableName) { export function makeLinkComponent(tableName) {
return new Component("@budibase/standard-components/link") return new Component("@budibase/standard-components/link")
.normalStyle({ .normalStyle({
@ -12,6 +21,7 @@ export function makeLinkComponent(tableName) {
.hoverStyle({ .hoverStyle({
color: "#4285f4", color: "#4285f4",
}) })
.customStyle(spectrumColor(700))
.text(tableName) .text(tableName)
.customProps({ .customProps({
url: `/${tableName.toLowerCase()}`, url: `/${tableName.toLowerCase()}`,
@ -52,6 +62,7 @@ export function makeBreadcrumbContainer(tableName, text, capitalise = false) {
"margin-right": "4px", "margin-right": "4px",
"margin-left": "4px", "margin-left": "4px",
}) })
.customStyle(spectrumColor(700))
.text(">") .text(">")
.instanceName("Arrow") .instanceName("Arrow")
@ -64,6 +75,7 @@ export function makeBreadcrumbContainer(tableName, text, capitalise = false) {
const identifierText = new Component("@budibase/standard-components/text") const identifierText = new Component("@budibase/standard-components/text")
.type("none") .type("none")
.normalStyle(textStyling) .normalStyle(textStyling)
.customStyle(spectrumColor(700))
.text(text) .text(text)
.instanceName("Identifier") .instanceName("Identifier")
@ -132,6 +144,7 @@ export function makeTitleContainer(title) {
"margin-left": "0px", "margin-left": "0px",
flex: "1 1 auto", flex: "1 1 auto",
}) })
.customStyle(spectrumColor(900))
.type("h3") .type("h3")
.instanceName("Title") .instanceName("Title")
.text(title) .text(title)

View file

@ -36,7 +36,9 @@
{:else if type === 'boolean'} {:else if type === 'boolean'}
<Toggle text={label} bind:checked={value} data-cy="{meta.name}-input" /> <Toggle text={label} bind:checked={value} data-cy="{meta.name}-input" />
{:else if type === 'link'} {:else if type === 'link'}
<LinkedRowSelector bind:linkedRows={value} schema={meta} /> <div>
<LinkedRowSelector bind:linkedRows={value} schema={meta} />
</div>
{:else if type === 'longform'} {:else if type === 'longform'}
<div> <div>
<Label extraSmall grey>{label}</Label> <Label extraSmall grey>{label}</Label>

View file

@ -25,7 +25,7 @@
<DetailSummary name={`${name}${changed ? ' *' : ''}`} on:open show={open} thin> <DetailSummary name={`${name}${changed ? ' *' : ''}`} on:open show={open} thin>
{#if open} {#if open}
<div> <div>
{#each properties as prop (`${componentInstance._id}-${prop.key}`)} {#each properties as prop (`${componentInstance._id}-${prop.key}-${prop.label}`)}
<PropertyControl <PropertyControl
bindable={false} bindable={false}
label={`${prop.label}${hasPropChanged(style, prop) ? ' *' : ''}`} label={`${prop.label}${hasPropChanged(style, prop) ? ' *' : ''}`}

View file

@ -1,10 +1,10 @@
const { const {
supertest, supertest,
createApplication, createApplication,
defaultHeaders, defaultHeaders,
builderEndpointShouldBlockNormalUsers, builderEndpointShouldBlockNormalUsers,
getDocument, getDocument,
insertDocument insertDocument,
} = require("./couchTestUtils") } = require("./couchTestUtils")
let { generateDatasourceID, generateQueryID } = require("../../../db/utils") let { generateDatasourceID, generateQueryID } = require("../../../db/utils")
@ -21,11 +21,11 @@ const TEST_DATASOURCE = {
const TEST_QUERY = { const TEST_QUERY = {
_id: generateQueryID(DATASOURCE_ID), _id: generateQueryID(DATASOURCE_ID),
datasourceId: DATASOURCE_ID, datasourceId: DATASOURCE_ID,
name:"New Query", name: "New Query",
parameters:[], parameters: [],
fields:{}, fields: {},
schema:{}, schema: {},
queryVerb:"read", queryVerb: "read",
} }
describe("/queries", () => { describe("/queries", () => {
@ -37,8 +37,8 @@ describe("/queries", () => {
let query let query
beforeAll(async () => { beforeAll(async () => {
({ request, server } = await supertest()) ;({ request, server } = await supertest())
}); })
afterAll(() => { afterAll(() => {
server.close() server.close()
@ -47,7 +47,7 @@ describe("/queries", () => {
beforeEach(async () => { beforeEach(async () => {
app = await createApplication(request) app = await createApplication(request)
appId = app.instance._id appId = app.instance._id
}); })
async function createDatasource() { async function createDatasource() {
return await insertDocument(appId, TEST_DATASOURCE) return await insertDocument(appId, TEST_DATASOURCE)
@ -63,65 +63,68 @@ describe("/queries", () => {
.post(`/api/queries`) .post(`/api/queries`)
.send(TEST_QUERY) .send(TEST_QUERY)
.set(defaultHeaders(appId)) .set(defaultHeaders(appId))
.expect('Content-Type', /json/) .expect("Content-Type", /json/)
.expect(200) .expect(200)
expect(res.res.statusMessage).toEqual(`Query ${TEST_QUERY.name} saved successfully.`); expect(res.res.statusMessage).toEqual(
expect(res.body).toEqual({ `Query ${TEST_QUERY.name} saved successfully.`
_rev: res.body._rev, )
...TEST_QUERY, expect(res.body).toEqual({
}); _rev: res.body._rev,
...TEST_QUERY,
}) })
}); })
})
describe("fetch", () => { describe("fetch", () => {
let datasource let datasource
beforeEach(async () => { beforeEach(async () => {
datasource = await createDatasource() datasource = await createDatasource()
}); })
afterEach(() => { afterEach(() => {
delete datasource._rev delete datasource._rev
}); })
it("returns all the queries from the server", async () => { it("returns all the queries from the server", async () => {
const query = await createQuery() const query = await createQuery()
const res = await request const res = await request
.get(`/api/queries`) .get(`/api/queries`)
.set(defaultHeaders(appId)) .set(defaultHeaders(appId))
.expect('Content-Type', /json/) .expect("Content-Type", /json/)
.expect(200) .expect(200)
const queries = res.body; const queries = res.body
expect(queries).toEqual([ expect(queries).toEqual([
{ {
"_rev": query.rev, _rev: query.rev,
...TEST_QUERY ...TEST_QUERY,
} readable: true,
]); },
])
}) })
it("should apply authorization to endpoint", async () => { it("should apply authorization to endpoint", async () => {
await builderEndpointShouldBlockNormalUsers({ await builderEndpointShouldBlockNormalUsers({
request, request,
method: "GET", method: "GET",
url: `/api/datasources`, url: `/api/datasources`,
appId: appId, appId: appId,
})
}) })
}); })
})
describe("destroy", () => { describe("destroy", () => {
let datasource; let datasource
beforeEach(async () => { beforeEach(async () => {
datasource = await createDatasource() datasource = await createDatasource()
}); })
afterEach(() => { afterEach(() => {
delete datasource._rev delete datasource._rev
}); })
it("deletes a query and returns a success message", async () => { it("deletes a query and returns a success message", async () => {
const query = await createQuery() const query = await createQuery()
@ -134,10 +137,10 @@ describe("/queries", () => {
const res = await request const res = await request
.get(`/api/queries`) .get(`/api/queries`)
.set(defaultHeaders(appId)) .set(defaultHeaders(appId))
.expect('Content-Type', /json/) .expect("Content-Type", /json/)
.expect(200) .expect(200)
expect(res.body).toEqual([]) expect(res.body).toEqual([])
}) })
it("should apply authorization to endpoint", async () => { it("should apply authorization to endpoint", async () => {
@ -148,5 +151,5 @@ describe("/queries", () => {
appId: appId, appId: appId,
}) })
}) })
}); })
}); })

View file

@ -138,6 +138,13 @@ class LinkController {
// iterate through the link IDs in the row field, see if any don't exist already // iterate through the link IDs in the row field, see if any don't exist already
for (let linkId of rowField) { for (let linkId of rowField) {
if (linkId && linkId !== "" && linkDocIds.indexOf(linkId) === -1) { if (linkId && linkId !== "" && linkDocIds.indexOf(linkId) === -1) {
// first check the doc we're linking to exists
try {
await this._db.get(linkId)
} catch (err) {
// skip links that don't exist
continue
}
operations.push( operations.push(
new LinkDocument( new LinkDocument(
table._id, table._id,

View file

@ -1294,12 +1294,6 @@
"type": "text", "type": "text",
"label": "Label", "label": "Label",
"key": "label" "key": "label"
},
{
"type": "text",
"label": "Placeholder",
"key": "placeholder",
"placeholder": "Choose an option"
} }
] ]
} }