Merge pull request #8066 from Budibase/plugin-improvements-master
Plugin fixes and improvements
This commit is contained in:
commit
4e20c979ff
|
@ -143,7 +143,10 @@ export const getComponentSettings = componentType => {
|
|||
}
|
||||
|
||||
// Ensure whole component name is used
|
||||
if (!componentType.startsWith("@budibase")) {
|
||||
if (
|
||||
!componentType.startsWith("plugin/") &&
|
||||
!componentType.startsWith("@budibase")
|
||||
) {
|
||||
componentType = `@budibase/standard-components/${componentType}`
|
||||
}
|
||||
|
||||
|
|
|
@ -243,18 +243,18 @@ export const getDatasourceForProvider = (asset, component) => {
|
|||
return null
|
||||
}
|
||||
|
||||
// There are different types of setting which can be a datasource, for
|
||||
// example an actual datasource object, or a table ID string.
|
||||
// Convert the datasource setting into a proper datasource object so that
|
||||
// we can use it properly
|
||||
if (datasourceSetting.type === "table") {
|
||||
// For legacy compatibility, we need to be able to handle datasources that are
|
||||
// just strings. These are not generated any more, so could be removed in
|
||||
// future.
|
||||
// TODO: remove at some point
|
||||
const datasource = component[datasourceSetting?.key]
|
||||
if (typeof datasource === "string") {
|
||||
return {
|
||||
tableId: component[datasourceSetting?.key],
|
||||
tableId: datasource,
|
||||
type: "table",
|
||||
}
|
||||
} else {
|
||||
return component[datasourceSetting?.key]
|
||||
}
|
||||
return datasource
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -88,27 +88,12 @@ export const getFrontendStore = () => {
|
|||
initialise: async pkg => {
|
||||
const { layouts, screens, application, clientLibPath } = pkg
|
||||
|
||||
// Fetch component definitions.
|
||||
// Allow errors to propagate.
|
||||
const components = await API.fetchComponentLibDefinitions(
|
||||
application.appId
|
||||
)
|
||||
|
||||
// Filter out custom component keys so we can flag them
|
||||
const customComponents = Object.keys(components).filter(name =>
|
||||
name.startsWith("plugin/")
|
||||
)
|
||||
await store.actions.components.refreshDefinitions(application.appId)
|
||||
|
||||
// Reset store state
|
||||
store.update(state => ({
|
||||
...state,
|
||||
libraries: application.componentLibraries,
|
||||
components,
|
||||
customComponents,
|
||||
clientFeatures: {
|
||||
...INITIAL_FRONTEND_STATE.clientFeatures,
|
||||
...components.features,
|
||||
},
|
||||
name: application.name,
|
||||
description: application.description,
|
||||
appId: application.appId,
|
||||
|
@ -385,6 +370,29 @@ export const getFrontendStore = () => {
|
|||
},
|
||||
},
|
||||
components: {
|
||||
refreshDefinitions: async appId => {
|
||||
if (!appId) {
|
||||
appId = get(store).appId
|
||||
}
|
||||
|
||||
// Fetch definitions and filter out custom component definitions so we
|
||||
// can flag them
|
||||
const components = await API.fetchComponentLibDefinitions(appId)
|
||||
const customComponents = Object.keys(components).filter(name =>
|
||||
name.startsWith("plugin/")
|
||||
)
|
||||
|
||||
// Update store
|
||||
store.update(state => ({
|
||||
...state,
|
||||
components,
|
||||
customComponents,
|
||||
clientFeatures: {
|
||||
...INITIAL_FRONTEND_STATE.clientFeatures,
|
||||
...components.features,
|
||||
},
|
||||
}))
|
||||
},
|
||||
getDefinition: componentName => {
|
||||
if (!componentName) {
|
||||
return null
|
||||
|
@ -428,7 +436,7 @@ export const getFrontendStore = () => {
|
|||
_id: Helpers.uuid(),
|
||||
_component: definition.component,
|
||||
_styles: { normal: {}, hover: {}, active: {} },
|
||||
_instanceName: `New ${definition.name}`,
|
||||
_instanceName: `New ${definition.friendlyName || definition.name}`,
|
||||
...cloneDeep(props),
|
||||
...extras,
|
||||
}
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
<script>
|
||||
import { Select } from "@budibase/bbui"
|
||||
import { tables } from "stores/backend"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { tables as tablesStore } from "stores/backend"
|
||||
|
||||
export let value
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
$: tables = $tablesStore.list.map(m => ({
|
||||
label: m.name,
|
||||
tableId: m._id,
|
||||
type: "table",
|
||||
}))
|
||||
|
||||
const onChange = e => {
|
||||
const dataSource = tables?.find(x => x.tableId === e.detail)
|
||||
dispatch("change", dataSource)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<Select extraThin secondary wide on:change {value}>
|
||||
<option value="">Choose a table</option>
|
||||
{#each $tables.list as table}
|
||||
<option value={table._id}>{table.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
div :global(> *) {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
</style>
|
||||
<Select
|
||||
on:change={onChange}
|
||||
value={value?.tableId}
|
||||
options={tables}
|
||||
getOptionValue={x => x.tableId}
|
||||
getOptionLabel={x => x.label}
|
||||
/>
|
||||
|
|
|
@ -198,6 +198,8 @@
|
|||
block: "center",
|
||||
})
|
||||
}
|
||||
} else if (type === "reload-plugin") {
|
||||
await store.actions.components.refreshDefinitions()
|
||||
} else {
|
||||
console.warn(`Client sent unknown event type: ${type}`)
|
||||
}
|
||||
|
|
|
@ -98,6 +98,9 @@ const createBuilderStore = () => {
|
|||
return state
|
||||
})
|
||||
}
|
||||
|
||||
// Notify the builder so we can reload component definitions
|
||||
dispatchEvent("reload-plugin")
|
||||
},
|
||||
}
|
||||
return {
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
import { builderStore, environmentStore } from "./stores/index.js"
|
||||
import {
|
||||
builderStore,
|
||||
environmentStore,
|
||||
notificationStore,
|
||||
} from "./stores/index.js"
|
||||
import { get } from "svelte/store"
|
||||
import { io } from "socket.io-client"
|
||||
|
||||
let socket
|
||||
|
||||
export const initWebsocket = () => {
|
||||
const { inBuilder, location } = get(builderStore)
|
||||
const { cloud } = get(environmentStore)
|
||||
|
||||
// Only connect when we're inside the builder preview, for now
|
||||
if (!inBuilder || !location || cloud) {
|
||||
if (!inBuilder || !location || cloud || socket) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -16,20 +22,20 @@ export const initWebsocket = () => {
|
|||
const proto = tls ? "wss:" : "ws:"
|
||||
const host = location.hostname
|
||||
const port = location.port || (tls ? 443 : 80)
|
||||
const socket = io(`${proto}//${host}:${port}`, {
|
||||
socket = io(`${proto}//${host}:${port}`, {
|
||||
path: "/socket/client",
|
||||
// Cap reconnection attempts to 10 (total of 95 seconds before giving up)
|
||||
reconnectionAttempts: 10,
|
||||
// Delay initial reconnection attempt by 5 seconds
|
||||
// Cap reconnection attempts to 3 (total of 15 seconds before giving up)
|
||||
reconnectionAttempts: 3,
|
||||
// Delay reconnection attempt by 5 seconds
|
||||
reconnectionDelay: 5000,
|
||||
// Then decrease to 10 second intervals
|
||||
reconnectionDelayMax: 10000,
|
||||
// Timeout after 5 seconds so we never stack requests
|
||||
timeout: 5000,
|
||||
reconnectionDelayMax: 5000,
|
||||
// Timeout after 4 seconds so we never stack requests
|
||||
timeout: 4000,
|
||||
})
|
||||
|
||||
// Event handlers
|
||||
socket.on("plugin-update", data => {
|
||||
builderStore.actions.updateUsedPlugin(data.name, data.hash)
|
||||
notificationStore.actions.info(`"${data.name}" plugin reloaded`)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -8,10 +8,9 @@ export const buildRowEndpoints = API => ({
|
|||
if (!tableId || !rowId) {
|
||||
return null
|
||||
}
|
||||
const row = await API.get({
|
||||
return await API.get({
|
||||
url: `/api/${tableId}/rows/${rowId}`,
|
||||
})
|
||||
return (await API.enrichRows([row], tableId))[0]
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue