Merge pull request #10907 from Budibase/backmerge-master

Backmerge master 2023-06-15
This commit is contained in:
Michael Drury 2023-06-15 11:52:45 +01:00 committed by GitHub
commit 407ec2cdb4
15 changed files with 91 additions and 38 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "2.7.16-alpha.2", "version": "2.7.19",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/backend-core", "packages/backend-core",

View File

@ -5,9 +5,10 @@
<meta charset='utf8'> <meta charset='utf8'>
<meta name='viewport' content='width=device-width'> <meta name='viewport' content='width=device-width'>
<title>Budibase</title> <title>Budibase</title>
<link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="/builder/fonts/source-sans-pro/400.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap" <link href="/builder/fonts/source-sans-pro/600.css" rel="stylesheet" />
rel="stylesheet" /> <link href="/builder/fonts/source-sans-pro/700.css" rel="stylesheet" />
<link href="/builder/fonts/remixicon.css" rel="stylesheet" />
</head> </head>
<body id="app"> <body id="app">

View File

@ -70,6 +70,7 @@
"@codemirror/state": "^6.2.0", "@codemirror/state": "^6.2.0",
"@codemirror/theme-one-dark": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.11.2", "@codemirror/view": "^6.11.2",
"@fontsource/source-sans-pro": "^5.0.3",
"@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/fontawesome-svg-core": "^6.2.1",
"@fortawesome/free-brands-svg-icons": "^6.2.1", "@fortawesome/free-brands-svg-icons": "^6.2.1",
"@fortawesome/free-solid-svg-icons": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1",
@ -122,6 +123,7 @@
"tsconfig-paths": "4.0.0", "tsconfig-paths": "4.0.0",
"typescript": "4.7.3", "typescript": "4.7.3",
"vite": "^3.0.8", "vite": "^3.0.8",
"vite-plugin-static-copy": "^0.16.0",
"vitest": "^0.29.2" "vitest": "^0.29.2"
}, },
"nx": { "nx": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

View File

@ -8,7 +8,7 @@
$: platformTitle = $: platformTitle =
!$auth.user && platformTitleText ? platformTitleText : "Budibase" !$auth.user && platformTitleText ? platformTitleText : "Budibase"
$: faviconUrl = $organisation.faviconUrl || "https://i.imgur.com/Xhdt1YP.png" $: faviconUrl = $organisation.faviconUrl || "/builder/bblogo.png"
onMount(async () => { onMount(async () => {
await organisation.init() await organisation.init()
@ -27,6 +27,6 @@
<link rel="icon" href={faviconUrl} /> <link rel="icon" href={faviconUrl} />
{:else} {:else}
<!-- A default must be set or the browser defaults to favicon.ico behaviour --> <!-- A default must be set or the browser defaults to favicon.ico behaviour -->
<link rel="icon" href={"https://i.imgur.com/Xhdt1YP.png"} /> <link rel="icon" href={"/builder/bblogo.png"} />
{/if} {/if}
</svelte:head> </svelte:head>

View File

@ -44,7 +44,7 @@
<div tabindex="-1" class="exampleApp"> <div tabindex="-1" class="exampleApp">
<div class="page"> <div class="page">
<div class="header"> <div class="header">
<img alt="Budibase Logo" src={"https://i.imgur.com/Xhdt1YP.png"} /> <img alt="Budibase Logo" src={"/builder/bblogo.png"} />
<h1>{name}</h1> <h1>{name}</h1>
</div> </div>
<div class="nav">Home</div> <div class="nav">Home</div>

View File

@ -1,6 +1,7 @@
import { svelte } from "@sveltejs/vite-plugin-svelte" import { svelte } from "@sveltejs/vite-plugin-svelte"
import replace from "@rollup/plugin-replace" import replace from "@rollup/plugin-replace"
import { defineConfig, loadEnv } from "vite" import { defineConfig, loadEnv } from "vite"
import { viteStaticCopy } from "vite-plugin-static-copy"
import path from "path" import path from "path"
const ignoredWarnings = [ const ignoredWarnings = [
@ -59,6 +60,18 @@ export default defineConfig(({ mode }) => {
), ),
"process.env.SENTRY_DSN": JSON.stringify(process.env.SENTRY_DSN), "process.env.SENTRY_DSN": JSON.stringify(process.env.SENTRY_DSN),
}), }),
viteStaticCopy({
targets: [
{
src: "../../node_modules/@fontsource/source-sans-pro",
dest: "fonts",
},
{
src: "../../node_modules/remixicon/fonts/*",
dest: "fonts",
},
],
}),
], ],
optimizeDeps: { optimizeDeps: {
exclude: ["@roxi/routify"], exclude: ["@roxi/routify"],

View File

@ -180,10 +180,7 @@
{/if} {/if}
<div class="logo"> <div class="logo">
{#if !hideLogo} {#if !hideLogo}
<img <img src={logoUrl || "/builder/bblogo.png"} alt={title} />
src={logoUrl || "https://i.imgur.com/Xhdt1YP.png"}
alt={title}
/>
{/if} {/if}
{#if !hideTitle && title} {#if !hideTitle && title}
<Heading size="S">{title}</Heading> <Heading size="S">{title}</Heading>

View File

@ -18,7 +18,7 @@
<img <img
class="logo" class="logo"
alt="logo" alt="logo"
src={logoUrl || "https://i.imgur.com/Xhdt1YP.png"} src={logoUrl || "/builder/bblogo.png"}
height="48" height="48"
/> />
</a> </a>

View File

@ -19,6 +19,7 @@ import {
breakRowIdField, breakRowIdField,
convertRowId, convertRowId,
generateRowIdField, generateRowIdField,
getPrimaryDisplay,
isRowId, isRowId,
isSQL, isSQL,
} from "../../../integrations/utils" } from "../../../integrations/utils"
@ -391,7 +392,10 @@ export class ExternalRequest {
} }
} }
relatedRow = processFormulas(linkedTable, relatedRow) relatedRow = processFormulas(linkedTable, relatedRow)
const relatedDisplay = display ? relatedRow[display] : undefined let relatedDisplay
if (display) {
relatedDisplay = getPrimaryDisplay(relatedRow[display])
}
row[relationship.column][key] = { row[relationship.column][key] = {
primaryDisplay: relatedDisplay || "Invalid display column", primaryDisplay: relatedDisplay || "Invalid display column",
_id: relatedRow._id, _id: relatedRow._id,

View File

@ -40,19 +40,14 @@
{#if favicon !== ""} {#if favicon !== ""}
<link rel="icon" type="image/png" href={favicon} /> <link rel="icon" type="image/png" href={favicon} />
{:else} {:else}
<link rel="icon" type="image/png" href="https://i.imgur.com/Xhdt1YP.png" /> <link rel="icon" type="image/png" href="/builder/bblogo.png" />
{/if} {/if}
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" /> <link href="/builder/fonts/source-sans-pro/400.css" rel="stylesheet" />
<link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="/builder/fonts/source-sans-pro/600.css" rel="stylesheet" />
<link <link href="/builder/fonts/source-sans-pro/700.css" rel="stylesheet" />
href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap" <link href="/builder/fonts/remixicon.css" rel="stylesheet" />
rel="stylesheet"
/>
<link
href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css"
rel="stylesheet"
/>
<style> <style>
html, html,
body { body {

View File

@ -1,16 +1,10 @@
<html lang="en"> <html lang="en">
<head> <head>
<title>Budibase Builder Preview</title> <title>Budibase Builder Preview</title>
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" /> <link href="/builder/fonts/source-sans-pro/400.css" rel="stylesheet" />
<link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="/builder/fonts/source-sans-pro/600.css" rel="stylesheet" />
<link <link href="/builder/fonts/source-sans-pro/700.css" rel="stylesheet" />
href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap" <link href="/builder/fonts/remixicon.css" rel="stylesheet" />
rel="stylesheet"
/>
<link
href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css"
rel="stylesheet"
/>
<style> <style>
html, body { html, body {
padding: 0; padding: 0;

View File

@ -91,7 +91,7 @@ const SCHEMA: Integration = {
}, },
} }
function bindingTypeCoerce(bindings: any[]) { export function bindingTypeCoerce(bindings: any[]) {
for (let i = 0; i < bindings.length; i++) { for (let i = 0; i < bindings.length; i++) {
const binding = bindings[i] const binding = bindings[i]
if (typeof binding !== "string") { if (typeof binding !== "string") {
@ -109,7 +109,12 @@ function bindingTypeCoerce(bindings: any[]) {
dayjs(binding).isValid() && dayjs(binding).isValid() &&
!binding.includes(",") !binding.includes(",")
) { ) {
bindings[i] = dayjs(binding).toDate() let value: any
value = new Date(binding)
if (isNaN(value)) {
value = binding
}
bindings[i] = value
} }
} }
return bindings return bindings

View File

@ -1,4 +1,4 @@
import { default as MySQLIntegration } from "../mysql" import { default as MySQLIntegration, bindingTypeCoerce } from "../mysql"
jest.mock("mysql2") jest.mock("mysql2")
class TestConfiguration { class TestConfiguration {
@ -131,3 +131,21 @@ describe("MySQL Integration", () => {
}) })
}) })
}) })
describe("bindingTypeCoercion", () => {
it("shouldn't coerce something that looks like a date", () => {
const response = bindingTypeCoerce(["202205-1500"])
expect(response[0]).toBe("202205-1500")
})
it("should coerce an actual date", () => {
const date = new Date("2023-06-13T14:24:22.620Z")
const response = bindingTypeCoerce(["2023-06-13T14:24:22.620Z"])
expect(response[0]).toEqual(date)
})
it("should coerce numbers", () => {
const response = bindingTypeCoerce(["0"])
expect(response[0]).toEqual(0)
})
})

View File

@ -328,3 +328,27 @@ export function finaliseExternalTables(
.reduce((r, [k, v]) => ({ ...r, [k]: v }), {}) .reduce((r, [k, v]) => ({ ...r, [k]: v }), {})
return { tables: finalTables, errors } return { tables: finalTables, errors }
} }
/**
* Checks if the provided input is an object, but specifically not a date type object.
* Used during coercion of types and relationship handling, dates are considered valid
* and can be used as a display field, but objects and arrays cannot.
* @param testValue an unknown type which this function will attempt to extract
* a valid primary display string from.
*/
export function getPrimaryDisplay(testValue: unknown): string | undefined {
if (testValue instanceof Date) {
return testValue.toISOString()
}
if (
Array.isArray(testValue) &&
testValue[0] &&
typeof testValue[0] !== "object"
) {
return testValue.join(", ")
}
if (typeof testValue === "object") {
return undefined
}
return testValue as string
}