From 95136a54f2731d800102f02340e8195a56e6ae53 Mon Sep 17 00:00:00 2001 From: mike12345567 <me@michaeldrury.co.uk> Date: Thu, 29 Sep 2022 19:30:53 +0100 Subject: [PATCH] Adding ability for datasource plugins to have a custom icon svg. --- .../backend-core/src/objectStore/index.ts | 5 +++ .../DatasourceNavigator.svelte | 10 ++--- .../IntegrationIcon.svelte | 40 +++++++++++++++++++ .../_components/DatasourceCard.svelte | 8 +--- .../DatasourceNavigator/icons/index.js | 11 +++-- .../src/components/common/CustomSVG.svelte | 23 +++++++++++ packages/server/src/integrations/index.ts | 3 ++ packages/types/src/documents/global/plugin.ts | 1 + packages/types/src/sdk/datasources.ts | 1 + 9 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 packages/builder/src/components/backend/DatasourceNavigator/IntegrationIcon.svelte create mode 100644 packages/builder/src/components/common/CustomSVG.svelte diff --git a/packages/backend-core/src/objectStore/index.ts b/packages/backend-core/src/objectStore/index.ts index a97aa8f65d..17e002cc49 100644 --- a/packages/backend-core/src/objectStore/index.ts +++ b/packages/backend-core/src/objectStore/index.ts @@ -182,6 +182,11 @@ export const streamUpload = async ( ...extra, ContentType: "application/javascript", } + } else if (filename?.endsWith(".svg")) { + extra = { + ...extra, + ContentType: "image", + } } const params = { diff --git a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte index 19946a2386..a3531513fb 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte @@ -13,7 +13,7 @@ customQueryIconColor, customQueryText, } from "helpers/data/utils" - import { getIcon } from "./icons" + import IntegrationIcon from "./IntegrationIcon.svelte" import { notifications } from "@budibase/bbui" let openDataSources = [] @@ -123,10 +123,10 @@ on:iconClick={() => toggleNode(datasource)} > <div class="datasource-icon" slot="icon"> - <svelte:component - this={getIcon(datasource.source, datasource.schema)} - height="18" - width="18" + <IntegrationIcon + integrationType={datasource.source} + schema={datasource.schema} + size="18" /> </div> {#if datasource._id !== BUDIBASE_INTERNAL_DB} diff --git a/packages/builder/src/components/backend/DatasourceNavigator/IntegrationIcon.svelte b/packages/builder/src/components/backend/DatasourceNavigator/IntegrationIcon.svelte new file mode 100644 index 0000000000..54afa35e74 --- /dev/null +++ b/packages/builder/src/components/backend/DatasourceNavigator/IntegrationIcon.svelte @@ -0,0 +1,40 @@ +<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", + }, + }) + let text = await resp.text() + // explicitly only want to replace the first instance + if (text.includes("height=")) { + text = text.replace(/height="\d*"/, `height="${size}"`) + } + if (text.includes("width=")) { + text = text.replace(/width="\d*"/, `width="${size}"`) + } + return 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} diff --git a/packages/builder/src/components/backend/DatasourceNavigator/_components/DatasourceCard.svelte b/packages/builder/src/components/backend/DatasourceNavigator/_components/DatasourceCard.svelte index 6dffc70a63..1e966ebb2b 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/_components/DatasourceCard.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/_components/DatasourceCard.svelte @@ -1,7 +1,7 @@ <script> import { createEventDispatcher } from "svelte" import { Heading, Detail } from "@budibase/bbui" - import { getIcon } from "../icons" + import IntegrationIcon from "../IntegrationIcon.svelte" export let integration export let integrationType @@ -16,11 +16,7 @@ class="item hoverable" > <div class="item-body" class:with-type={!!schema.type}> - <svelte:component - this={getIcon(integrationType, schema)} - height="20" - width="20" - /> + <IntegrationIcon {integrationType} {schema} size="25" /> <div class="text"> <Heading size="XXS">{schema.friendlyName}</Heading> {#if schema.type} diff --git a/packages/builder/src/components/backend/DatasourceNavigator/icons/index.js b/packages/builder/src/components/backend/DatasourceNavigator/icons/index.js index 6d43258f45..18aa361570 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/icons/index.js +++ b/packages/builder/src/components/backend/DatasourceNavigator/icons/index.js @@ -16,6 +16,8 @@ import Firebase from "./Firebase.svelte" import Redis from "./Redis.svelte" import Snowflake from "./Snowflake.svelte" import Custom from "./Custom.svelte" +import { integrations } from "stores/backend" +import { get } from "svelte/store" const ICONS = { BUDIBASE: Budibase, @@ -41,9 +43,12 @@ const ICONS = { export default ICONS export function getIcon(integrationType, schema) { - if (schema?.custom || !ICONS[integrationType]) { - return ICONS.CUSTOM + const integrationList = get(integrations) + if (integrationList[integrationType]?.iconUrl) { + return { url: integrationList[integrationType].iconUrl } + } else if (schema?.custom || !ICONS[integrationType]) { + return { icon: ICONS.CUSTOM } } else { - return ICONS[integrationType] + return { icon: ICONS[integrationType] } } } diff --git a/packages/builder/src/components/common/CustomSVG.svelte b/packages/builder/src/components/common/CustomSVG.svelte new file mode 100644 index 0000000000..5ae428c12d --- /dev/null +++ b/packages/builder/src/components/common/CustomSVG.svelte @@ -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="\d*"/, `height="${size}"`) + } + if (svg.includes("width=")) { + svg = svg.replace(/width="\d*"/, `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)} diff --git a/packages/server/src/integrations/index.ts b/packages/server/src/integrations/index.ts index 000ab65a33..a542ff8455 100644 --- a/packages/server/src/integrations/index.ts +++ b/packages/server/src/integrations/index.ts @@ -78,6 +78,9 @@ module.exports = { ...plugin.schema["schema"], custom: true, } + if (plugin.iconUrl) { + pluginSchemas[sourceId].iconUrl = plugin.iconUrl + } } } return { diff --git a/packages/types/src/documents/global/plugin.ts b/packages/types/src/documents/global/plugin.ts index a374d5496c..7f6d4f4995 100644 --- a/packages/types/src/documents/global/plugin.ts +++ b/packages/types/src/documents/global/plugin.ts @@ -21,6 +21,7 @@ export interface Plugin extends Document { name: string version: string jsUrl?: string + iconUrl?: string source: PluginSource package: { [key: string]: any } hash: string diff --git a/packages/types/src/sdk/datasources.ts b/packages/types/src/sdk/datasources.ts index 970613b322..d01d636b86 100644 --- a/packages/types/src/sdk/datasources.ts +++ b/packages/types/src/sdk/datasources.ts @@ -96,6 +96,7 @@ export interface Integration { description: string friendlyName: string type?: string + iconUrl?: string datasource: {} query: { [key: string]: QueryDefinition