Merge branch 'plugins-dev-experience' of github.com:Budibase/budibase into plugins-dev-experience
This commit is contained in:
commit
e5881e1f24
|
@ -58,7 +58,10 @@
|
||||||
enrichedStructure.push({
|
enrichedStructure.push({
|
||||||
name: "Custom components",
|
name: "Custom components",
|
||||||
isCategory: true,
|
isCategory: true,
|
||||||
children: customComponents.map(x => definitions[x]),
|
children: customComponents.map(x => ({
|
||||||
|
...definitions[x],
|
||||||
|
name: definitions[x].friendlyName || definitions[x].name,
|
||||||
|
})),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
let data = new FormData()
|
let data = new FormData()
|
||||||
data.append("file", $values.logo)
|
data.append("file", $values.logo)
|
||||||
await API.uploadPlugin(data)
|
await API.uploadPlugin(data)
|
||||||
|
notifications.success("Plugin uploaded successfully")
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.error("Error uploading logo")
|
notifications.error("Error uploading logo")
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,17 +40,17 @@ const loadBudibase = () => {
|
||||||
devToolsStore.actions.setEnabled(enableDevTools)
|
devToolsStore.actions.setEnabled(enableDevTools)
|
||||||
|
|
||||||
// Register any custom components
|
// Register any custom components
|
||||||
window.registerCustomComponent = plugin => {
|
|
||||||
componentStore.actions.registerCustomComponent(plugin)
|
|
||||||
console.log("registered!")
|
|
||||||
loadBudibase()
|
|
||||||
}
|
|
||||||
if (window["##BUDIBASE_CUSTOM_COMPONENTS##"]) {
|
if (window["##BUDIBASE_CUSTOM_COMPONENTS##"]) {
|
||||||
window["##BUDIBASE_CUSTOM_COMPONENTS##"].forEach(component => {
|
window["##BUDIBASE_CUSTOM_COMPONENTS##"].forEach(component => {
|
||||||
componentStore.actions.registerCustomComponent(component)
|
componentStore.actions.registerCustomComponent(component)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make a callback available for custom component bundles to register
|
||||||
|
// themselves at runtime
|
||||||
|
window.registerCustomComponent =
|
||||||
|
componentStore.actions.registerCustomComponent
|
||||||
|
|
||||||
// Create app if one hasn't been created yet
|
// Create app if one hasn't been created yet
|
||||||
if (!app) {
|
if (!app) {
|
||||||
app = new ClientApp({
|
app = new ClientApp({
|
||||||
|
|
|
@ -12,7 +12,7 @@ const budibasePrefix = "@budibase/standard-components/"
|
||||||
const createComponentStore = () => {
|
const createComponentStore = () => {
|
||||||
const store = writable({
|
const store = writable({
|
||||||
customComponentManifest: {},
|
customComponentManifest: {},
|
||||||
componentsAwaitingConstructors: {},
|
customComponentMap: {},
|
||||||
mountedComponents: {},
|
mountedComponents: {},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -54,30 +54,37 @@ const createComponentStore = () => {
|
||||||
|
|
||||||
const registerInstance = (id, instance) => {
|
const registerInstance = (id, instance) => {
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
// If this is a custom component and does not have an implementation yet,
|
// If this is a custom component, flag it so we can reload this component
|
||||||
// store so we can reload this component later
|
// later if required
|
||||||
const component = instance.component
|
const component = instance.component
|
||||||
let cac = state.componentsAwaitingConstructors
|
if (component?.startsWith("plugin")) {
|
||||||
if (!getComponentConstructor(component)) {
|
if (!state.customComponentMap[component]) {
|
||||||
if (!cac[component]) {
|
state.customComponentMap[component] = [id]
|
||||||
cac[component] = []
|
} else {
|
||||||
|
state.customComponentMap[component].push(id)
|
||||||
}
|
}
|
||||||
cac[component].push(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
// Register to mounted components
|
||||||
...state,
|
state.mountedComponents[id] = instance
|
||||||
componentsAwaitingConstructors: cac,
|
return state
|
||||||
mountedComponents: {
|
|
||||||
...state.mountedComponents,
|
|
||||||
[id]: instance,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const unregisterInstance = id => {
|
const unregisterInstance = id => {
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
|
// Remove from custom component map if required
|
||||||
|
const component = state.mountedComponents[id]?.instance?.component
|
||||||
|
let customComponentMap = state.customComponentMap
|
||||||
|
if (component?.startsWith("plugin")) {
|
||||||
|
customComponentMap[component] = customComponentMap[component].filter(
|
||||||
|
x => {
|
||||||
|
return x !== id
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from mounted components
|
||||||
delete state.mountedComponents[id]
|
delete state.mountedComponents[id]
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
@ -133,34 +140,25 @@ const createComponentStore = () => {
|
||||||
return customComponentManifest?.[type]?.Component
|
return customComponentManifest?.[type]?.Component
|
||||||
}
|
}
|
||||||
|
|
||||||
const registerCustomComponent = ({ Component, schema }) => {
|
const registerCustomComponent = ({ Component, schema, version }) => {
|
||||||
if (!Component || !schema?.schema?.name) {
|
if (!Component || !schema?.schema?.name) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const componentName = `plugin/${schema.schema.name}/1.0.0`
|
const component = `plugin/${schema.schema.name}/${version}`
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
if (!state.customComponentManifest) {
|
state.customComponentManifest[component] = {
|
||||||
state.customComponentManifest = {}
|
|
||||||
}
|
|
||||||
state.customComponentManifest[componentName] = {
|
|
||||||
schema,
|
|
||||||
Component,
|
Component,
|
||||||
|
schema,
|
||||||
|
version,
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
|
||||||
// Reload any mounted components which depend on this definition
|
// Reload any mounted instances of this custom component
|
||||||
const state = get(store)
|
const state = get(store)
|
||||||
if (state.componentsAwaitingConstructors[componentName]?.length) {
|
if (state.customComponentMap[component]?.length) {
|
||||||
state.componentsAwaitingConstructors[componentName].forEach(id => {
|
state.customComponentMap[component].forEach(id => {
|
||||||
const instance = state.mountedComponents[id]
|
state.mountedComponents[id]?.reload()
|
||||||
if (instance) {
|
|
||||||
instance.reload()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
store.update(state => {
|
|
||||||
delete state.componentsAwaitingConstructors[componentName]
|
|
||||||
return state
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,19 +48,18 @@ export async function upload(ctx: any) {
|
||||||
}
|
}
|
||||||
const jsFileName = jsFile.name
|
const jsFileName = jsFile.name
|
||||||
const pluginId = generatePluginID(name, version)
|
const pluginId = generatePluginID(name, version)
|
||||||
let existing
|
|
||||||
|
// overwrite existing docs entirely if they exist
|
||||||
|
let rev
|
||||||
try {
|
try {
|
||||||
existing = await db.get(pluginId)
|
const existing = await db.get(pluginId)
|
||||||
|
rev = existing._rev
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
existing = null
|
rev = undefined
|
||||||
}
|
|
||||||
if (existing) {
|
|
||||||
throw new Error(
|
|
||||||
`Plugin already exists: name: ${name}, version: ${version}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
const doc = {
|
const doc = {
|
||||||
_id: pluginId,
|
_id: pluginId,
|
||||||
|
_rev: rev,
|
||||||
name,
|
name,
|
||||||
version,
|
version,
|
||||||
description,
|
description,
|
||||||
|
|
|
@ -2,7 +2,7 @@ const {
|
||||||
getScreenParams,
|
getScreenParams,
|
||||||
generateScreenID,
|
generateScreenID,
|
||||||
getPluginParams,
|
getPluginParams,
|
||||||
DocumentTypes,
|
DocumentType,
|
||||||
} = require("../../db/utils")
|
} = require("../../db/utils")
|
||||||
const { AccessController } = require("@budibase/backend-core/roles")
|
const { AccessController } = require("@budibase/backend-core/roles")
|
||||||
const { getAppDB } = require("@budibase/backend-core/context")
|
const { getAppDB } = require("@budibase/backend-core/context")
|
||||||
|
@ -60,7 +60,7 @@ exports.save = async ctx => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Update the app metadata
|
// Update the app metadata
|
||||||
const application = await db.get(DocumentTypes.APP_METADATA)
|
const application = await db.get(DocumentType.APP_METADATA)
|
||||||
let usedPlugins = application.usedPlugins || []
|
let usedPlugins = application.usedPlugins || []
|
||||||
|
|
||||||
requiredPlugins.forEach(plugin => {
|
requiredPlugins.forEach(plugin => {
|
||||||
|
|
Loading…
Reference in New Issue