1
0
Fork 0
mirror of synced 2024-09-14 00:08:25 +12:00

Update client library to full handle custom components

This commit is contained in:
Andrew Kingston 2022-08-10 15:34:00 +01:00
parent 8ac1a20ef7
commit eab1b93c24
5 changed files with 86 additions and 28 deletions

View file

@ -85,18 +85,8 @@
builderStore.actions.notifyLoaded()
}
})
// TODO: remove. this is a test to render the first custom component
console.log(window["##BUDIBASE_CUSTOM_COMPONENTS##"]?.[0])
const custom = window["##BUDIBASE_CUSTOM_COMPONENTS##"]?.[0]?.Component
</script>
{#if custom}
<div style="padding: 20px;">
<svelte:component this={custom} />
</div>
{/if}
{#if dataLoaded}
<div
id="spectrum-root"

View file

@ -11,8 +11,6 @@
<script>
import { getContext, setContext, onMount, onDestroy } from "svelte"
import { writable, get } from "svelte/store"
import * as AppComponents from "components/app"
import Router from "./Router.svelte"
import {
enrichProps,
propsAreSame,
@ -180,7 +178,7 @@
// Pull definition and constructor
const component = instance._component
constructor = getComponentConstructor(component)
constructor = componentStore.actions.getComponentConstructor(component)
definition = componentStore.actions.getComponentDefinition(component)
if (!definition) {
return
@ -237,16 +235,6 @@
})
}
// Gets the component constructor for the specified component
const getComponentConstructor = component => {
const split = component?.split("/")
const name = split?.[split.length - 1]
if (name === "screenslot" && !insideScreenslot) {
return Router
}
return AppComponents[name]
}
const getSettingsDefinitionMap = settingsDefinition => {
let map = {}
settingsDefinition?.forEach(setting => {

View file

@ -13,7 +13,22 @@
$: routeStore.actions.setRouteParams(params || {})
// Get the screen definition for the current route
$: screenDefinition = $screenStore.activeScreen?.props
$: screenDefinition = getScreenDefinition($screenStore.activeScreen?.props)
const getScreenDefinition = definition => {
const test = {
_component: "test",
_id: "asfdasdfefgerdgrfdg",
_styles: {
normal: {},
},
text: "This is a text prop!",
}
return {
...definition,
_children: [...definition._children, test],
}
}
onMount(() => {
// Mark the router as loaded whenever the screen mounts

View file

@ -1,5 +1,5 @@
import ClientApp from "./components/ClientApp.svelte"
import { builderStore, appStore, devToolsStore } from "./stores"
import { componentStore, builderStore, appStore, devToolsStore } from "./stores"
import loadSpectrumIcons from "@budibase/bbui/spectrum-icons-rollup.js"
import { get } from "svelte/store"
@ -38,6 +38,13 @@ const loadBudibase = () => {
const enableDevTools = !get(builderStore).inBuilder && get(appStore).isDevApp
devToolsStore.actions.setEnabled(enableDevTools)
// Register any custom components
if (window["##BUDIBASE_CUSTOM_COMPONENTS##"]) {
window["##BUDIBASE_CUSTOM_COMPONENTS##"].forEach(component => {
componentStore.actions.registerCustomComponent(component)
})
}
// Create app if one hasn't been created yet
if (!app) {
app = new ClientApp({

View file

@ -4,6 +4,10 @@ import { findComponentById, findComponentPathById } from "../utils/components"
import { devToolsStore } from "./devTools"
import { screenStore } from "./screens"
import { builderStore } from "./builder"
import Router from "../components/Router.svelte"
import * as AppComponents from "../components/app/index.js"
const budibasePrefix = "@budibase/standard-components/"
const createComponentStore = () => {
const store = writable({})
@ -34,6 +38,7 @@ const createComponentStore = () => {
findComponentPathById(asset?.props, selectedComponentId) || []
return {
customComponentManifest: $store.customComponentManifest,
selectedComponentInstance: $store[selectedComponentId],
selectedComponent: component,
selectedComponentDefinition: definition,
@ -68,9 +73,60 @@ const createComponentStore = () => {
}
const getComponentDefinition = type => {
const prefix = "@budibase/standard-components/"
type = type?.replace(prefix, "")
return type ? Manifest[type] : null
if (!type) {
return null
}
// Screenslot is an edge case
if (type === "screenslot") {
type = `${budibasePrefix}${type}`
}
// Handle built-in components
if (type.startsWith(budibasePrefix)) {
type = type.replace(budibasePrefix, "")
return type ? Manifest[type] : null
}
// Handle custom components
const { customComponentManifest } = get(store)
return customComponentManifest?.[type]?.schema?.schema
}
const getComponentConstructor = type => {
if (!type) {
return null
}
if (type === "screenslot") {
return Router
}
// Handle budibase components
if (type.startsWith(budibasePrefix)) {
const split = type.split("/")
const name = split[split.length - 1]
return AppComponents[name]
}
// Handle custom components
const { customComponentManifest } = get(store)
return customComponentManifest?.[type]?.Component
}
const registerCustomComponent = ({ Component, schema }) => {
if (!Component || !schema?.schema?.name) {
return
}
store.update(state => {
if (!state.customComponentManifest) {
state.customComponentManifest = {}
}
state.customComponentManifest[schema.schema.name] = {
schema,
Component,
}
return state
})
}
return {
@ -81,6 +137,8 @@ const createComponentStore = () => {
isComponentRegistered,
getComponentById,
getComponentDefinition,
getComponentConstructor,
registerCustomComponent,
},
}
}