1
0
Fork 0
mirror of synced 2024-07-09 00:06:05 +12:00

Working commit

This commit is contained in:
Dean 2023-03-16 09:07:21 +00:00
parent c7e54947a8
commit 253ee413a2
14 changed files with 296 additions and 164 deletions

View file

@ -4,73 +4,35 @@
import Icon from "../../Icon/Icon.svelte" import Icon from "../../Icon/Icon.svelte"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
export let value = null //support multi? export let value = null
export let title = "Upload file" export let title = "Upload file"
export let disabled = false export let disabled = false
export let extensions = "*" export let extensions = null
export let handleFileTooLarge = null export let handleFileTooLarge = null
export let handleTooManyFiles = null export let fileSizeLimit = BYTES_IN_MB * 20
export let fileSizeLimit = BYTES_IN_MB * 20 // Centralise
export let id = null export let id = null
export let previewUrl = null
const dispatch = createEventDispatcher()
//Is this necessary?
const fieldId = id || uuid() const fieldId = id || uuid()
// Centralise all in new file section?
const BYTES_IN_KB = 1000 const BYTES_IN_KB = 1000
const BYTES_IN_MB = 1000000 const BYTES_IN_MB = 1000000
const dispatch = createEventDispatcher()
let fileInput let fileInput
// $: file = value[0] || null
// const imageExtensions = [ $: inputAccept = Array.isArray(extensions) ? extensions.join(",") : "*"
// "png",
// "tiff",
// "gif",
// "raw",
// "jpg",
// "jpeg",
// "svg",
// "bmp",
// "jfif",
// ]
// Should support only 1 file for now. async function processFile(targetFile) {
// Files[0] if (handleFileTooLarge && targetFile?.size >= fileSizeLimit) {
handleFileTooLarge(targetFile)
//What is the limit? 50mb?
async function processFileList(fileList) {
if (
handleFileTooLarge &&
Array.from(fileList).some(file => file.size >= fileSizeLimit)
) {
handleFileTooLarge(fileSizeLimit, value)
return return
} }
dispatch("change", targetFile)
const fileCount = fileList.length + value.length
if (handleTooManyFiles && maximum && fileCount > maximum) {
handleTooManyFiles(maximum)
return
}
if (processFiles) {
const processedFiles = await processFiles(fileList)
const newValue = [...value, ...processedFiles]
dispatch("change", newValue)
selectedImageIdx = newValue.length - 1
} else {
dispatch("change", fileList)
}
} }
function handleFile(evt) { function handleFile(evt) {
console.log("Hello ", evt.target.files[0]) processFile(evt.target.files[0])
dispatch("change", evt.target.files[0])
//processFileList(evt.target.files)
} }
function clearFile() { function clearFile() {
@ -82,7 +44,7 @@
id={fieldId} id={fieldId}
{disabled} {disabled}
type="file" type="file"
accept={extensions} accept={inputAccept}
bind:this={fileInput} bind:this={fileInput}
on:change={handleFile} on:change={handleFile}
/> />
@ -90,7 +52,9 @@
<div class="field"> <div class="field">
{#if value} {#if value}
<div class="file-view"> <div class="file-view">
<!-- <img alt="" src={value.url} /> --> {#if previewUrl}
<img class="preview" alt="" src={previewUrl} />
{/if}
<div class="filename">{value.name}</div> <div class="filename">{value.name}</div>
{#if value.size} {#if value.size}
<div class="filesize"> <div class="filesize">
@ -128,6 +92,23 @@
display: none; display: none;
} }
.delete-button { .delete-button {
transition: all 0.3s;
margin-left: 10px;
display: flex;
}
.delete-button:hover {
cursor: pointer; cursor: pointer;
color: var(--red);
}
.filesize {
white-space: nowrap;
}
.filename {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.preview {
height: 1.5em;
} }
</style> </style>

View file

@ -6,6 +6,9 @@
export let label = null export let label = null
export let labelPosition = "above" export let labelPosition = "above"
export let disabled = false export let disabled = false
export let handleFileTooLarge = () => {}
export let previewUrl = null
export let extensions = null
export let error = null export let error = null
export let title = null export let title = null
export let value = null export let value = null
@ -19,5 +22,14 @@
</script> </script>
<Field {label} {labelPosition} {error} {tooltip}> <Field {label} {labelPosition} {error} {tooltip}>
<CoreFile {error} {disabled} {title} {value} on:change={onChange} /> <CoreFile
{error}
{disabled}
{title}
{value}
{previewUrl}
{handleFileTooLarge}
{extensions}
on:change={onChange}
/>
</Field> </Field>

View file

@ -0,0 +1,59 @@
<script>
import { organisation, auth, admin } from "stores/portal"
import { onMount } from "svelte"
let loaded = false
let platformTitle = null
$: platformTitleText = $organisation.platformTitle
$: platformTitleText,
(platformTitle =
!$admin.isCloud && !$auth.user ? platformTitleText : "Budibase")
onMount(async () => {
await organisation.init()
loaded = true
})
</script>
<!--
In order to update the org elements, an update will have to be made to clear them.
-->
<svelte:head>
<title>{platformTitle}</title>
{#if loaded && !$auth.user}
<link
rel="icon"
href={$organisation.faviconUrl || "https://i.imgur.com/Xhdt1YP.png"}
/>
{:else}
<!-- A default must be set or the browser defaults to favicon.ico behaviour -->
<link rel="icon" href={"https://i.imgur.com/Xhdt1YP.png"} />
{/if}
<!-- Primary Meta Tags -->
<!-- <meta name="title" content={metaTitle} /> -->
<!--
metaTitle should match the title...
should title override metaTitle, if set??
-->
<!-- <meta name="description" content={metaDescription} /> -->
<!-- Opengraph Meta Tags -->
<!-- <meta property="og:site_name" content="Budibase" />
<meta property="og:title" content="{title} - built with Budibase" />
<meta property="og:description" content={metaDescription} />
<meta property="og:type" content="website" />
<meta property="og:image" content={metaImage} /> -->
<!-- Twitter -->
<!-- <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@budibase" />
<meta name="twitter:image" content={metaImage} /> -->
<!-- Consider adding this twitter:image:alt -->
<!-- <meta name="twitter:title" content="{title} - built with Budibase" />
<meta property="twitter:description" content={metaDescription} /> -->
</svelte:head>

View file

@ -147,7 +147,7 @@
</Layout> </Layout>
{/if} {/if}
{#if cloud && $organisation.licenceAgreementEnabled} {#if cloud && $organisation.licenseAgreementEnabled}
<Body size="xs" textAlign="center"> <Body size="xs" textAlign="center">
By using Budibase Cloud By using Budibase Cloud
<br /> <br />

View file

@ -12,15 +12,34 @@
Toggle, Toggle,
Input, Input,
Label, Label,
TextArea,
} from "@budibase/bbui" } from "@budibase/bbui"
import { auth, organisation, licensing, admin } from "stores/portal" import { auth, organisation, licensing, admin } from "stores/portal"
import { API } from "api" import { API } from "api"
import { onMount } from "svelte" import { onMount } from "svelte"
const imageExtensions = [
".png",
".tiff",
".gif",
".raw",
".jpg",
".jpeg",
".svg",
".bmp",
".jfif",
]
const faviconExtensions = [".png", ".ico", ".gif"]
let loaded = false let loaded = false
let saving = false let saving = false
let logoFile = null let logoFile = null
let logoPreview = null
let faviconFile = null let faviconFile = null
let faviconPreview = null
let config = {} let config = {}
let updated = false let updated = false
@ -39,9 +58,45 @@
: null : null
$: favicon = config.faviconUrl $: favicon = config.faviconUrl
? { url: config.logoUrl, type: "image", name: "Favicon" } ? { url: config.faviconUrl, type: "image", name: "Favicon" }
: null : null
//If type of file do this IN the picker
//If string use the string
//If object?.url us that
const previewUrl = async localFile => {
if (!localFile) {
return Promise.resolve(null)
}
return new Promise(resolve => {
let reader = new FileReader()
try {
reader.onload = e => {
resolve({
result: e.target.result,
})
}
reader.readAsDataURL(localFile)
} catch (error) {
console.error(error)
resolve(null)
}
})
}
$: previewUrl(logoFile).then(response => {
if (response) {
logoPreview = response.result
}
})
$: previewUrl(faviconFile).then(response => {
if (response) {
faviconPreview = response.result
}
})
async function uploadLogo(file) { async function uploadLogo(file) {
let response = {} let response = {}
try { try {
@ -54,8 +109,6 @@
return response return response
} }
// Limit file types
// PNG, GIF, or ICO?
async function uploadFavicon(file) { async function uploadFavicon(file) {
let response = {} let response = {}
try { try {
@ -70,9 +123,7 @@
async function saveConfig() { async function saveConfig() {
saving = true saving = true
console.log("SAVING CONFIG ")
console.log("Save Config")
if (logoFile) { if (logoFile) {
const logoResp = await uploadLogo(logoFile) const logoResp = await uploadLogo(logoFile)
if (logoResp.url) { if (logoResp.url) {
@ -80,8 +131,8 @@
...config, ...config,
logoUrl: logoResp.url, logoUrl: logoResp.url,
} }
} else { logoFile = null
//would have to delete logoPreview = null
} }
} }
@ -92,6 +143,8 @@
...config, ...config,
faviconUrl: faviconResp.url, faviconUrl: faviconResp.url,
} }
faviconFile = null
faviconPreview = null
} }
} }
console.log("SAVE CONFIG ", config) console.log("SAVE CONFIG ", config)
@ -111,28 +164,19 @@
onMount(async () => { onMount(async () => {
await organisation.init() await organisation.init()
const {
faviconUrl,
logoUrl,
platformTitle,
emailBrandingEnabled,
appFooterEnabled,
loginHeading,
loginButton,
licenceAgreementEnabled,
testimonialsEnabled,
} = $organisation
config = { config = {
faviconUrl, faviconUrl: $organisation.faviconUrl,
logoUrl, logoUrl: $organisation.logoUrl,
platformTitle, platformTitle: $organisation.platformTitle,
emailBrandingEnabled, emailBrandingEnabled: $organisation.emailBrandingEnabled,
appFooterEnabled, appFooterEnabled: $organisation.appFooterEnabled,
loginHeading, loginHeading: $organisation.loginHeading,
loginButton, loginButton: $organisation.loginButton,
licenceAgreementEnabled, licenseAgreementEnabled: $organisation.licenseAgreementEnabled,
testimonialsEnabled, testimonialsEnabled: $organisation.testimonialsEnabled,
metaDescription: $organisation.metaDescription,
metaImageUrl: $organisation.metaImageUrl,
metaTitle: $organisation.metaTitle,
} }
loaded = true loaded = true
@ -158,17 +202,24 @@
<Label size="L">Logo</Label> <Label size="L">Logo</Label>
<File <File
title="Upload image" title="Upload image"
handleFileTooLarge={() => {
notifications.warn("File too large. 20mb limit")
}}
extensions={imageExtensions}
previewUrl={logoPreview || logo?.url}
on:change={e => { on:change={e => {
console.log("Updated Logo") console.log("Updated Logo")
let clone = { ...config } let clone = { ...config }
if (e.detail) { if (e.detail) {
logoFile = e.detail logoFile = e.detail
logoPreview = null
} else { } else {
logoFile = null
clone.logoUrl = "" clone.logoUrl = ""
} }
config = clone config = clone
}} }}
value={logo} value={logoFile || logo}
/> />
</div> </div>
@ -176,17 +227,22 @@
<Label size="L">Favicon</Label> <Label size="L">Favicon</Label>
<File <File
title="Upload image" title="Upload image"
handleFileTooLarge={() => {
notifications.warn("File too large. 20mb limit")
}}
extensions={faviconExtensions}
previewUrl={faviconPreview || favicon?.url}
on:change={e => { on:change={e => {
console.log("Updated Favicon")
let clone = { ...config } let clone = { ...config }
if (e.detail) { if (e.detail) {
faviconFile = e.detail faviconFile = e.detail
faviconPreview = null
} else { } else {
clone.faviconUrl = "" clone.faviconUrl = ""
} }
config = clone config = clone
}} }}
value={favicon} value={faviconFile || favicon}
/> />
</div> </div>
<div class="field"> <div class="field">
@ -197,12 +253,12 @@
clone.platformTitle = e.detail ? e.detail : "" clone.platformTitle = e.detail ? e.detail : ""
config = clone config = clone
}} }}
value={config.platformTitle || "Budibase"} value={config.platformTitle || ""}
/> />
</div> </div>
<div> <div>
<Toggle <Toggle
text={"Remove Buidbase brand from emails"} text={"Remove Budibase brand from emails"}
on:change={e => { on:change={e => {
let clone = { ...config } let clone = { ...config }
clone.emailBrandingEnabled = !e.detail clone.emailBrandingEnabled = !e.detail
@ -222,7 +278,6 @@
</div> </div>
</div> </div>
<!-- Should this be displayed? -->
{#if !$admin.cloud} {#if !$admin.cloud}
<Divider /> <Divider />
<Layout gap="XS" noPadding> <Layout gap="XS" noPadding>
@ -239,7 +294,7 @@
clone.loginHeading = e.detail ? e.detail : "" clone.loginHeading = e.detail ? e.detail : ""
config = clone config = clone
}} }}
value={config.loginHeading || "Log in to Budibase"} value={config.loginHeading || ""}
/> />
</div> </div>
@ -251,7 +306,7 @@
clone.loginButton = e.detail ? e.detail : "" clone.loginButton = e.detail ? e.detail : ""
config = clone config = clone
}} }}
value={config.loginButton || "Log in to Budibase"} value={config.loginButton || ""}
/> />
</div> </div>
<div> <div>
@ -265,13 +320,13 @@
value={!config.testimonialsEnabled} value={!config.testimonialsEnabled}
/> />
<Toggle <Toggle
text={"Remove licence agreement"} text={"Remove license agreement"}
on:change={e => { on:change={e => {
let clone = { ...config } let clone = { ...config }
clone.licenceAgreementEnabled = !e.detail clone.licenseAgreementEnabled = !e.detail
config = clone config = clone
}} }}
value={!config.licenceAgreementEnabled} value={!config.licenseAgreementEnabled}
/> />
</div> </div>
</div> </div>
@ -285,15 +340,37 @@
<div class="app-previews"> <div class="app-previews">
<div class="fields"> <div class="fields">
<div class="field"> <div class="field">
<!-- <Label size="L">Header</Label> <Label size="L">Image URL</Label>
<Input <Input
on:change={e => { on:change={e => {
let clone = { ...config } let clone = { ...config }
clone.loginHeading = e.detail ? e.detail : "" clone.metaImageUrl = e.detail ? e.detail : ""
config = clone config = clone
}} }}
value={config.loginHeading || "Log in to Budibase"} value={config.metaImageUrl}
/> --> />
</div>
<div class="field">
<Label size="L">Title</Label>
<Input
on:change={e => {
let clone = { ...config }
clone.metaTitle = e.detail ? e.detail : ""
config = clone
}}
value={config.metaTitle}
/>
</div>
<div class="field">
<Label size="L">Description</Label>
<TextArea
on:change={e => {
let clone = { ...config }
clone.metaDescription = e.detail ? e.detail : ""
config = clone
}}
value={config.metaDescription}
/>
</div> </div>
</div> </div>
</div> </div>
@ -316,7 +393,8 @@
.branding, .branding,
.login { .login {
width: 60%; width: 70%;
max-width: 70%;
} }
.fields { .fields {
display: grid; display: grid;
@ -324,7 +402,7 @@
} }
.field { .field {
display: grid; display: grid;
grid-template-columns: 80px 1fr; grid-template-columns: 80px auto;
grid-gap: var(--spacing-l); grid-gap: var(--spacing-l);
align-items: center; align-items: center;
} }

View file

@ -7,12 +7,10 @@
Divider, Divider,
Label, Label,
Input, Input,
// Dropzone,
notifications, notifications,
Toggle, Toggle,
} from "@budibase/bbui" } from "@budibase/bbui"
import { auth, organisation, admin } from "stores/portal" import { auth, organisation, admin } from "stores/portal"
import { API } from "api"
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { redirect } from "@roxi/routify" import { redirect } from "@roxi/routify"
@ -28,21 +26,9 @@
company: $organisation.company, company: $organisation.company,
platformUrl: $organisation.platformUrl, platformUrl: $organisation.platformUrl,
analyticsEnabled: $organisation.analyticsEnabled, analyticsEnabled: $organisation.analyticsEnabled,
// logo: $organisation.logoUrl
// ? { url: $organisation.logoUrl, type: "image", name: "Logo" }
// : null,
}) })
let loading = false
// async function uploadLogo(file) { let loading = false
// try {
// let data = new FormData()
// data.append("file", file)
// await API.uploadLogo(data)
// } catch (error) {
// notifications.error("Error uploading logo")
// }
// }
async function saveConfig() { async function saveConfig() {
loading = true loading = true

View file

@ -7,17 +7,20 @@ const DEFAULT_CONFIG = {
platformUrl: "", platformUrl: "",
logoUrl: undefined, logoUrl: undefined,
faviconUrl: undefined,
faviconUrl: undefined,
emailBrandingEnabled: true, emailBrandingEnabled: true,
appFooterEnabled: true, appFooterEnabled: true,
// Self host only
testimonialsEnabled: true, testimonialsEnabled: true,
licenceAgreementEnabled: true, licenseAgreementEnabled: true,
platformTitle: "Budibase", platformTitle: "Budibase",
loginHeading: undefined, loginHeading: undefined,
loginButton: undefined, loginButton: undefined,
metaDescription: undefined,
metaImageUrl: undefined,
metaTitle: undefined,
docsUrl: undefined, docsUrl: undefined,
company: "Budibase", company: "Budibase",
oidc: undefined, oidc: undefined,

View file

@ -11,10 +11,11 @@ import {
} from "../../../utilities/fileSystem" } from "../../../utilities/fileSystem"
import env from "../../../environment" import env from "../../../environment"
import { DocumentType } from "../../../db/utils" import { DocumentType } from "../../../db/utils"
import { context, objectStore, utils } from "@budibase/backend-core" import { context, objectStore, utils, configs } from "@budibase/backend-core"
import AWS from "aws-sdk" import AWS from "aws-sdk"
import fs from "fs" import fs from "fs"
import sdk from "../../../sdk" import sdk from "../../../sdk"
const send = require("koa-send") const send = require("koa-send")
async function prepareUpload({ s3Key, bucket, metadata, file }: any) { async function prepareUpload({ s3Key, bucket, metadata, file }: any) {
@ -98,6 +99,8 @@ export const deleteObjects = async function (ctx: any) {
} }
export const serveApp = async function (ctx: any) { export const serveApp = async function (ctx: any) {
const { config } = await configs.getSettingsConfigDoc()
const db = context.getAppDB({ skip_setup: true }) const db = context.getAppDB({ skip_setup: true })
const appInfo = await db.get(DocumentType.APP_METADATA) const appInfo = await db.get(DocumentType.APP_METADATA)
let appId = context.getAppId() let appId = context.getAppId()
@ -105,16 +108,19 @@ export const serveApp = async function (ctx: any) {
if (!env.isJest()) { if (!env.isJest()) {
const App = require("./templates/BudibaseApp.svelte").default const App = require("./templates/BudibaseApp.svelte").default
const plugins = objectStore.enrichPluginURLs(appInfo.usedPlugins) const plugins = objectStore.enrichPluginURLs(appInfo.usedPlugins)
console.log(appInfo)
const { head, html, css } = App.render({ const { head, html, css } = App.render({
metaImage: metaImage:
config?.metaImageUrl ||
"https://res.cloudinary.com/daog6scxm/image/upload/v1666109324/meta-images/budibase-meta-image_uukc1m.png", "https://res.cloudinary.com/daog6scxm/image/upload/v1666109324/meta-images/budibase-meta-image_uukc1m.png",
title: appInfo.name, //Replace Title here? metaDescription: config?.metaDescription || "",
metaTitle: `${appInfo.name} - built with Budibase` || config?.metaTitle,
title: appInfo.name,
production: env.isProd(), production: env.isProd(),
appId, appId,
clientLibPath: objectStore.clientLibraryUrl(appId!, appInfo.version), clientLibPath: objectStore.clientLibraryUrl(appId!, appInfo.version),
usedPlugins: plugins, usedPlugins: plugins,
favicon: objectStore.getGlobalFileUrl("settings", "faviconUrl"), favicon: objectStore.getGlobalFileUrl("settings", "faviconUrl"),
//logo: objectStore.getGlobalFileUrl("settings", "logoUrl"),
}) })
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`) const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)

View file

@ -1,7 +1,10 @@
<script> <script>
export let title = "" export let title = ""
export let favicon = "" export let favicon = ""
export let metaImage = "" export let metaImage = ""
export let metaTitle = ""
export let metaDescription = ""
export let clientLibPath export let clientLibPath
export let usedPlugins export let usedPlugins
@ -13,15 +16,31 @@
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover" content="width=device-width, initial-scale=1.0, viewport-fit=cover"
/> />
<!-- Primary Meta Tags -->
<meta name="title" content={metaTitle} />
<meta name="description" content={metaDescription} />
<!--
metaTitle should match the title...
should title override metaTitle, if set??
-->
<!-- Opengraph Meta Tags --> <!-- Opengraph Meta Tags -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@budibase" />
<meta name="twitter:image" content={metaImage} />
<meta name="twitter:title" content="{title} - built with Budibase" />
<meta property="og:site_name" content="Budibase" /> <meta property="og:site_name" content="Budibase" />
<meta property="og:title" content="{title} - built with Budibase" /> <meta property="og:title" content="{title} - built with Budibase" />
<meta property="og:description" content={metaDescription} />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:image" content={metaImage} /> <meta property="og:image" content={metaImage} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:site" content="@budibase" />
<meta property="twitter:image" content={metaImage} />
<!-- Consider adding this twitter:image:alt -->
<meta property="twitter:title" content="{title} - built with Budibase" />
<meta property="twitter:description" content={metaDescription} />
<title>{title}</title> <title>{title}</title>
<link rel="icon" type="image/png" href={favicon} /> <link rel="icon" type="image/png" href={favicon} />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" /> <link rel="stylesheet" href="https://rsms.me/inter/inter.css" />

View file

@ -32,15 +32,17 @@ export interface SettingsInnerConfig {
faviconUrlEtag?: string faviconUrlEtag?: string
emailBrandingEnabled?: boolean emailBrandingEnabled?: boolean
// Self host only
appFooterEnabled?: boolean appFooterEnabled?: boolean
testimonialsEnabled?: boolean testimonialsEnabled?: boolean
licenceAgreementEnabled?: boolean licenseAgreementEnabled?: boolean
platformTitle?: string platformTitle?: string
loginHeading?: string loginHeading?: string
loginButton?: string loginButton?: string
metaDescription?: string
metaImageUrl?: string
metaTitle?: string
uniqueTenantId?: string uniqueTenantId?: string
analyticsEnabled?: boolean analyticsEnabled?: boolean
isSSOEnforced?: boolean isSSOEnforced?: boolean

View file

@ -20,6 +20,7 @@ export enum TemplateType {
} }
export enum EmailTemplatePurpose { export enum EmailTemplatePurpose {
CORE = "core",
BASE = "base", BASE = "base",
PASSWORD_RECOVERY = "password_recovery", PASSWORD_RECOVERY = "password_recovery",
INVITATION = "invitation", INVITATION = "invitation",

View file

@ -10,18 +10,18 @@
> >
<tbody> <tbody>
<tr> <tr>
<td <td style="padding:0 35px;" cellpadding="0" cellspacing="0">
style="padding:0 35px;vertical-align: middle;"
cellpadding="0"
cellspacing="0"
>
<img <img
width="32px" width="32px"
style="margin-right: 16px;" style="margin-right:16px; vertical-align: middle;"
alt="Budibase Logo" alt="Budibase Logo"
src="https://i.imgur.com/Xhdt1YP.png" src="https://i.imgur.com/Xhdt1YP.png"
/> />
<h2 style="margin: 0px">Budibase</h2> <strong
style="color:#333333; vertical-align: middle; font-size: 1.1em"
>
Budibase
</strong>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -21,8 +21,7 @@ export const EmailTemplates = {
join(__dirname, "welcome.hbs") join(__dirname, "welcome.hbs")
), ),
[EmailTemplatePurpose.CUSTOM]: readStaticFile(join(__dirname, "custom.hbs")), [EmailTemplatePurpose.CUSTOM]: readStaticFile(join(__dirname, "custom.hbs")),
//Core wrapper [EmailTemplatePurpose.CORE]: readStaticFile(join(__dirname, "core.hbs")),
["branding"]: readStaticFile(join(__dirname, "core.hbs")),
} }
export function addBaseTemplates(templates: Template[], type?: string) { export function addBaseTemplates(templates: Template[], type?: string) {

View file

@ -108,53 +108,39 @@ async function buildEmail(
let [base, body] = await Promise.all([ let [base, body] = await Promise.all([
getTemplateByPurpose(TYPE, EmailTemplatePurpose.BASE), getTemplateByPurpose(TYPE, EmailTemplatePurpose.BASE),
getTemplateByPurpose(TYPE, purpose), getTemplateByPurpose(TYPE, purpose),
//getTemplateByPurpose(TYPE, "branding"), //should generalise to 'branding'
]) ])
let branding = EmailTemplates["branding"] // Change from branding to core
let core = EmailTemplates.core
if (!base || !body || !branding) { if (!base || !body || !core) {
throw "Unable to build email, missing base components" throw "Unable to build email, missing base components"
} }
base = base.contents base = base.contents
body = body.contents body = body.contents
//branding = branding.contents
let name = user ? user.name : undefined let name = user ? user.name : undefined
if (user && !name && user.firstName) { if (user && !name && user.firstName) {
name = user.lastName ? `${user.firstName} ${user.lastName}` : user.firstName name = user.lastName ? `${user.firstName} ${user.lastName}` : user.firstName
} }
context = { context = {
...context, //enableEmailBranding ...context,
contents, contents,
email, email,
name, name,
user: user || {}, user: user || {},
} }
const core = branding + body // Prepend the core template
const fullBody = core + body
body = await processString(core, context) body = await processString(fullBody, context)
// Conditional elements
// branding = await processString(branding, {
// ...context,
// body,
// })
// this should now be the core email HTML // this should now be the core email HTML
return processString(base, { return processString(base, {
...context, ...context,
body, //: branding, // pass as body as usual body,
}) })
// body = await processString(body, context)
// // this should now be the coree email HTML
// return processString(base, {
// ...context,
// body,
// })
} }
/** /**