Skip to content

Commit

Permalink
Merge pull request #15497 from Budibase/grid-new-component-dnd
Browse files Browse the repository at this point in the history
New component drag-and-drop improvements
  • Loading branch information
aptkingston authored Feb 13, 2025
2 parents a19acce + b6185c3 commit 6500de7
Show file tree
Hide file tree
Showing 86 changed files with 989 additions and 784 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
import { fly } from "svelte/transition"
import { findComponentPath } from "@/helpers/components"
// Smallest possible 1x1 transparent GIF
const ghost = new Image(1, 1)
ghost.src =
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
let searchString
let searchRef
let selectedIndex
Expand Down Expand Up @@ -217,7 +222,8 @@
}
})
const onDragStart = component => {
const onDragStart = (e, component) => {
e.dataTransfer.setDragImage(ghost, 0, 0)
previewStore.startDrag(component)
}
Expand Down Expand Up @@ -250,13 +256,12 @@
{#each category.children as component}
<div
draggable="true"
on:dragstart={() => onDragStart(component.component)}
on:dragstart={e => onDragStart(e, component.component)}
on:dragend={onDragEnd}
class="component"
class:selected={selectedIndex === orderMap[component.component]}
on:click={() => addComponent(component.component)}
on:mouseover={() => (selectedIndex = null)}
on:focus
on:mouseenter={() => (selectedIndex = null)}
>
<Icon name={component.icon} />
<Body size="XS">{component.name}</Body>
Expand Down Expand Up @@ -308,7 +313,6 @@
}
.component:hover {
background: var(--spectrum-global-color-gray-300);
cursor: pointer;
}
.component :global(.spectrum-Body) {
line-height: 1.2 !important;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@
} else if (type === "reload-plugin") {
await componentStore.refreshDefinitions()
} else if (type === "drop-new-component") {
const { component, parent, index } = data
await componentStore.create(component, null, parent, index)
const { component, parent, index, props } = data
await componentStore.create(component, props, parent, index)
} else if (type === "add-parent-component") {
const { componentId, parentType } = data
await componentStore.addParent(componentId, parentType)
Expand Down
6 changes: 3 additions & 3 deletions packages/builder/src/stores/builder/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ interface AppMetaState {
appInstance: { _id: string } | null
initialised: boolean
hasAppPackage: boolean
usedPlugins: Plugin[] | null
usedPlugins: Plugin[]
automations: AutomationSettings
routes: { [key: string]: any }
version?: string
Expand Down Expand Up @@ -76,7 +76,7 @@ export const INITIAL_APP_META_STATE: AppMetaState = {
appInstance: null,
initialised: false,
hasAppPackage: false,
usedPlugins: null,
usedPlugins: [],
automations: {},
routes: {},
}
Expand Down Expand Up @@ -109,7 +109,7 @@ export class AppMetaStore extends BudiStore<AppMetaState> {
appInstance: app.instance,
revertableVersion: app.revertableVersion,
upgradableVersion: app.upgradableVersion,
usedPlugins: app.usedPlugins || null,
usedPlugins: app.usedPlugins || [],
icon: app.icon,
features: {
...INITIAL_APP_META_STATE.features,
Expand Down
104 changes: 27 additions & 77 deletions packages/builder/src/stores/builder/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
findComponentParent,
findAllMatchingComponents,
makeComponentUnique,
findComponentType,
} from "@/helpers/components"
import { getComponentFieldOptions } from "@/helpers/formFields"
import { selectedScreen } from "./screens"
Expand Down Expand Up @@ -139,10 +140,6 @@ export class ComponentStore extends BudiStore<ComponentState> {

/**
* Retrieve the component definition object
* @param {string} componentType
* @example
* '@budibase/standard-components/container'
* @returns {object}
*/
getDefinition(componentType: string) {
if (!componentType) {
Expand All @@ -151,10 +148,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
return get(this.store).components[componentType]
}

/**
*
* @returns {object}
*/
getDefaultDatasource() {
// Ignore users table
const validTables = get(tables).list.filter(x => x._id !== "ta_users")
Expand Down Expand Up @@ -188,8 +181,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
/**
* Takes an enriched component instance and applies any required migration
* logic
* @param {object} enrichedComponent
* @returns {object} migrated Component
*/
migrateSettings(enrichedComponent: Component) {
const componentPrefix = "@budibase/standard-components"
Expand Down Expand Up @@ -230,22 +221,15 @@ export class ComponentStore extends BudiStore<ComponentState> {
for (let setting of filterableTypes || []) {
const isLegacy = Array.isArray(enrichedComponent[setting.key])
if (isLegacy) {
const processedSetting = utils.processSearchFilters(
enrichedComponent[setting.key] = utils.processSearchFilters(
enrichedComponent[setting.key]
)
enrichedComponent[setting.key] = processedSetting
migrated = true
}
}
return migrated
}

/**
*
* @param {object} component
* @param {object} opts
* @returns
*/
enrichEmptySettings(
component: Component,
opts: { screen?: Screen; parent?: Component; useDefaultValues?: boolean }
Expand Down Expand Up @@ -280,14 +264,25 @@ export class ComponentStore extends BudiStore<ComponentState> {
type: "table",
}
} else if (setting.type === "dataProvider") {
// Pick closest data provider where required
let providerId

// Pick closest parent data provider if one exists
const path = findComponentPath(screen.props, treeId)
const providers = path.filter((component: Component) =>
component._component?.endsWith("/dataprovider")
)
if (providers.length) {
const id = providers[providers.length - 1]?._id
component[setting.key] = `{{ literal ${safe(id)} }}`
providerId = providers[providers.length - 1]?._id

// If none in our direct path, select the first one the screen
if (!providerId) {
providerId = findComponentType(
screen.props,
"@budibase/standard-components/dataprovider"
)?._id
}

if (providerId) {
component[setting.key] = `{{ literal ${safe(providerId)} }}`
}
} else if (setting.type.startsWith("field/")) {
// Autofill form field names
Expand Down Expand Up @@ -316,6 +311,8 @@ export class ComponentStore extends BudiStore<ComponentState> {
component[setting.key] = fieldOptions[0]
component.label = fieldOptions[0]
}
} else if (setting.type === "icon") {
component[setting.key] = "ri-star-fill"
} else if (useDefaultValues && setting.defaultValue !== undefined) {
// Use default value where required
component[setting.key] = setting.defaultValue
Expand Down Expand Up @@ -427,17 +424,10 @@ export class ComponentStore extends BudiStore<ComponentState> {
}
}

/**
*
* @param {string} componentName
* @param {object} presetProps
* @param {object} parent
* @returns
*/
createInstance(
componentType: string,
presetProps: any,
parent: any
presetProps?: Record<string, any>,
parent?: Component
): Component | null {
const screen = get(selectedScreen)
if (!screen) {
Expand All @@ -463,7 +453,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
_id: Helpers.uuid(),
_component: definition.component,
_styles: {
normal: {},
normal: { ...presetProps?._styles?.normal },
hover: {},
active: {},
},
Expand Down Expand Up @@ -512,19 +502,11 @@ export class ComponentStore extends BudiStore<ComponentState> {
}
}

/**
*
* @param {string} componentName
* @param {object} presetProps
* @param {object} parent
* @param {number} index
* @returns
*/
async create(
componentType: string,
presetProps: any,
parent: Component,
index: number
presetProps?: Record<string, any>,
parent?: Component,
index?: number
) {
const state = get(this.store)
const componentInstance = this.createInstance(
Expand Down Expand Up @@ -611,13 +593,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
return componentInstance
}

/**
*
* @param {function} patchFn
* @param {string} componentId
* @param {string} screenId
* @returns
*/
async patch(
patchFn: (component: Component, screen: Screen) => any,
componentId?: string,
Expand Down Expand Up @@ -652,11 +627,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
await screenStore.patch(patchScreen, screenId)
}

/**
*
* @param {object} component
* @returns
*/
async delete(component: Component) {
if (!component) {
return
Expand Down Expand Up @@ -737,13 +707,6 @@ export class ComponentStore extends BudiStore<ComponentState> {
})
}

/**
*
* @param {object} targetComponent
* @param {string} mode
* @param {object} targetScreen
* @returns
*/
async paste(
targetComponent: Component,
mode: string,
Expand Down Expand Up @@ -1101,6 +1064,7 @@ export class ComponentStore extends BudiStore<ComponentState> {

async updateStyles(styles: Record<string, string>, id: string) {
const patchFn = (component: Component) => {
delete component._placeholder
component._styles.normal = {
...component._styles.normal,
...styles,
Expand Down Expand Up @@ -1231,7 +1195,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
}

// Create new parent instance
const newParentDefinition = this.createInstance(parentType, null, parent)
const newParentDefinition = this.createInstance(parentType)
if (!newParentDefinition) {
return
}
Expand Down Expand Up @@ -1267,10 +1231,6 @@ export class ComponentStore extends BudiStore<ComponentState> {

/**
* Check if the components settings have been cached
* @param {string} componentType
* @example
* '@budibase/standard-components/container'
* @returns {boolean}
*/
isCached(componentType: string) {
const settings = get(this.store).settingsCache
Expand All @@ -1279,11 +1239,6 @@ export class ComponentStore extends BudiStore<ComponentState> {

/**
* Cache component settings
* @param {string} componentType
* @param {object} definition
* @example
* '@budibase/standard-components/container'
* @returns {array} the settings
*/
cacheSettings(componentType: string, definition: ComponentDefinition | null) {
let settings: ComponentSetting[] = []
Expand Down Expand Up @@ -1313,12 +1268,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
/**
* Retrieve an array of the component settings.
* These settings are cached because they cannot change at run time.
*
* Searches a component's definition for a setting matching a certain predicate.
* @param {string} componentType
* @example
* '@budibase/standard-components/container'
* @returns {Array<object>}
*/
getComponentSettings(componentType: string) {
if (!componentType) {
Expand Down
4 changes: 1 addition & 3 deletions packages/builder/src/stores/builder/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import { appStore } from "@/stores/builder"
import { BudiStore } from "../BudiStore"
import { AppNavigation, AppNavigationLink, UIObject } from "@budibase/types"

interface BuilderNavigationStore extends AppNavigation {}

export const INITIAL_NAVIGATION_STATE = {
navigation: "Top",
links: [],
textAlign: "Left",
}

export class NavigationStore extends BudiStore<BuilderNavigationStore> {
export class NavigationStore extends BudiStore<AppNavigation> {
constructor() {
super(INITIAL_NAVIGATION_STATE)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/builder/src/stores/builder/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class PreviewStore extends BudiStore<PreviewState> {
}))
}

startDrag(component: any) {
async startDrag(component: string) {
this.sendEvent("dragging-new-component", {
dragging: true,
component,
Expand Down
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"module": "dist/budibase-client.js",
"main": "dist/budibase-client.js",
"type": "module",
"svelte": "src/index.js",
"svelte": "src/index.ts",
"exports": {
".": {
"import": "./dist/budibase-client.js",
Expand Down
6 changes: 1 addition & 5 deletions packages/client/src/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { createAPIClient } from "@budibase/frontend-core"
import { authStore } from "../stores/auth"
import {
notificationStore,
devToolsEnabled,
devToolsStore,
} from "../stores/index"
import { notificationStore, devToolsEnabled, devToolsStore } from "../stores"
import { get } from "svelte/store"

export const API = createAPIClient({
Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/components/Block.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { getContext, onDestroy, onMount, setContext } from "svelte"
import { builderStore } from "stores/builder.js"
import { blockStore } from "stores/blocks"
import { builderStore } from "@/stores/builder.js"
import { blockStore } from "@/stores/blocks"
const component = getContext("component")
const { styleable } = getContext("sdk")
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/components/BlockComponent.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { getContext, onDestroy } from "svelte"
import { generate } from "shortid"
import { builderStore } from "../stores/builder.js"
import Component from "components/Component.svelte"
import Component from "@/components/Component.svelte"
export let type
export let props
Expand Down
Loading

0 comments on commit 6500de7

Please sign in to comment.