Merge pull request #8058 from Budibase/feature/plugin-icons

Custom datasource icons
This commit is contained in:
Michael Drury 2022-09-30 15:08:10 +01:00 committed by GitHub
commit 64d90280a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 80 additions and 14 deletions

View File

@ -182,6 +182,11 @@ export const streamUpload = async (
...extra, ...extra,
ContentType: "application/javascript", ContentType: "application/javascript",
} }
} else if (filename?.endsWith(".svg")) {
extra = {
...extra,
ContentType: "image",
}
} }
const params = { const params = {

View File

@ -13,7 +13,7 @@
customQueryIconColor, customQueryIconColor,
customQueryText, customQueryText,
} from "helpers/data/utils" } from "helpers/data/utils"
import { getIcon } from "./icons" import IntegrationIcon from "./IntegrationIcon.svelte"
import { notifications } from "@budibase/bbui" import { notifications } from "@budibase/bbui"
let openDataSources = [] let openDataSources = []
@ -123,10 +123,10 @@
on:iconClick={() => toggleNode(datasource)} on:iconClick={() => toggleNode(datasource)}
> >
<div class="datasource-icon" slot="icon"> <div class="datasource-icon" slot="icon">
<svelte:component <IntegrationIcon
this={getIcon(datasource.source, datasource.schema)} integrationType={datasource.source}
height="18" schema={datasource.schema}
width="18" size="18"
/> />
</div> </div>
{#if datasource._id !== BUDIBASE_INTERNAL_DB} {#if datasource._id !== BUDIBASE_INTERNAL_DB}

View File

@ -0,0 +1,32 @@
<script>
import { getIcon } from "./icons"
import CustomSVG from "components/common/CustomSVG.svelte"
import { admin } from "stores/portal"
export let integrationType
export let schema
export let size = "18"
$: objectStoreUrl = $admin.cloud ? "https://cdn.budi.live" : ""
$: pluginsUrl = `${objectStoreUrl}/plugins`
$: iconInfo = getIcon(integrationType, schema)
async function getSvgFromUrl(info) {
const url = `${pluginsUrl}/${info.url}`
const resp = await fetch(url, {
headers: {
["pragma"]: "no-cache",
["cache-control"]: "no-cache",
},
})
return resp.text()
}
</script>
{#if iconInfo.icon}
<svelte:component this={iconInfo.icon} height={size} width={size} />
{:else if iconInfo.url}
{#await getSvgFromUrl(iconInfo) then retrievedSvg}
<CustomSVG {size} svgHtml={retrievedSvg} />
{/await}
{/if}

View File

@ -1,7 +1,7 @@
<script> <script>
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import { Heading, Detail } from "@budibase/bbui" import { Heading, Detail } from "@budibase/bbui"
import { getIcon } from "../icons" import IntegrationIcon from "../IntegrationIcon.svelte"
export let integration export let integration
export let integrationType export let integrationType
@ -16,11 +16,7 @@
class="item hoverable" class="item hoverable"
> >
<div class="item-body" class:with-type={!!schema.type}> <div class="item-body" class:with-type={!!schema.type}>
<svelte:component <IntegrationIcon {integrationType} {schema} size="25" />
this={getIcon(integrationType, schema)}
height="20"
width="20"
/>
<div class="text"> <div class="text">
<Heading size="XXS">{schema.friendlyName}</Heading> <Heading size="XXS">{schema.friendlyName}</Heading>
{#if schema.type} {#if schema.type}

View File

@ -16,6 +16,8 @@ import Firebase from "./Firebase.svelte"
import Redis from "./Redis.svelte" import Redis from "./Redis.svelte"
import Snowflake from "./Snowflake.svelte" import Snowflake from "./Snowflake.svelte"
import Custom from "./Custom.svelte" import Custom from "./Custom.svelte"
import { integrations } from "stores/backend"
import { get } from "svelte/store"
const ICONS = { const ICONS = {
BUDIBASE: Budibase, BUDIBASE: Budibase,
@ -41,9 +43,12 @@ const ICONS = {
export default ICONS export default ICONS
export function getIcon(integrationType, schema) { export function getIcon(integrationType, schema) {
if (schema?.custom || !ICONS[integrationType]) { const integrationList = get(integrations)
return ICONS.CUSTOM if (integrationList[integrationType]?.iconUrl) {
return { url: integrationList[integrationType].iconUrl }
} else if (schema?.custom || !ICONS[integrationType]) {
return { icon: ICONS.CUSTOM }
} else { } else {
return ICONS[integrationType] return { icon: ICONS[integrationType] }
} }
} }

View File

@ -0,0 +1,23 @@
<script>
import { Helpers } from "@budibase/bbui"
export let size
export let svgHtml
function substituteSize(svg) {
if (svg.includes("height=")) {
svg = svg.replace(/height="[^"]+"/, `height="${size}"`)
}
if (svg.includes("width=")) {
svg = svg.replace(/width="[^"]+"/, `width="${size}"`)
}
if (svg.includes("id=")) {
const matches = svg.match(/id="([^"]+)"/g)
for (let match of matches) {
svg = svg.replace(new RegExp(match, "g"), Helpers.uuid())
}
}
return svg
}
</script>
{@html substituteSize(svgHtml)}

View File

@ -78,6 +78,9 @@ module.exports = {
...plugin.schema["schema"], ...plugin.schema["schema"],
custom: true, custom: true,
} }
if (plugin.iconUrl) {
pluginSchemas[sourceId].iconUrl = plugin.iconUrl
}
} }
} }
return { return {

View File

@ -21,6 +21,7 @@ export interface Plugin extends Document {
name: string name: string
version: string version: string
jsUrl?: string jsUrl?: string
iconUrl?: string
source: PluginSource source: PluginSource
package: { [key: string]: any } package: { [key: string]: any }
hash: string hash: string

View File

@ -96,6 +96,7 @@ export interface Integration {
description: string description: string
friendlyName: string friendlyName: string
type?: string type?: string
iconUrl?: string
datasource: {} datasource: {}
query: { query: {
[key: string]: QueryDefinition [key: string]: QueryDefinition