This commit is contained in:
Dean 2025-04-22 15:25:41 +01:00
parent 20d90efae7
commit d37731d5a3
8 changed files with 53 additions and 105 deletions

View File

@ -34,7 +34,7 @@ import FormStepControls from "./controls/FormStepControls.svelte"
import PaywalledSetting from "./controls/PaywalledSetting.svelte"
import TableConditionEditor from "./controls/TableConditionEditor.svelte"
import MultilineDrawerBindableInput from "@/components/common/MultilineDrawerBindableInput.svelte"
import EmbeddedDatasourceSelect from "./controls/EmbeddedDatasourceSelect.svelte"
import FilterableSelect from "./controls/FilterableSelect.svelte"
const componentMap = {
text: DrawerBindableInput,
@ -44,7 +44,7 @@ const componentMap = {
radio: RadioGroup,
dataSource: DataSourceSelect,
"dataSource/s3": S3DataSourceSelect,
"dataSource/embedded": EmbeddedDatasourceSelect,
"dataSource/filterable": FilterableSelect,
dataProvider: DataProviderSelect,
boolean: Checkbox,
number: Stepper,

View File

@ -1,62 +0,0 @@
<script lang="ts">
import { Select } from "@budibase/bbui"
import { componentStore, selectedScreen } from "@/stores/builder"
import { findAllComponents, getComponentContexts } from "@/helpers/components"
import { makePropSafe as safe } from "@budibase/string-templates"
import { createEventDispatcher } from "svelte"
import { extractLiteralHandlebarsID } from "@/dataBinding"
import { type Component } from "@budibase/types"
export let value: string | undefined = undefined
const dispatch = createEventDispatcher()
let providersComps: Component[]
let providers: { label: string; value: string; subtitle: string }[]
// Load the component for processing
$: targetId = extractLiteralHandlebarsID(value)
// Refresh datasources if the target is altered
$: if (targetId) {
providersComps = loadProviderComponents()
providers = buildProviders()
}
const handleSelected = (selected: string) => {
dispatch("change", selected)
}
// Components that surface data
const buildProviders = () => {
if (!$selectedScreen) return []
return providersComps.map(provider => ({
label: provider._instanceName,
value: `{{ literal ${safe(provider._id)} }}`,
subtitle: `${
provider?.dataSource?.label || provider?.table?.label || "-"
}`,
}))
}
const loadProviderComponents = () => {
if (!$selectedScreen) return []
return findAllComponents($selectedScreen.props).filter(component => {
if (component._id === $componentStore.selectedComponentId) return false
const contexts = getComponentContexts(component._component)
const targetContexts = contexts.filter(ctx =>
ctx.actions?.find(act => act.type === "RefreshDatasource")
)
return !!targetContexts.length
})
}
</script>
<Select
{value}
options={providers}
on:change={e => {
handleSelected(e.detail)
}}
/>

View File

@ -0,0 +1,36 @@
<script lang="ts">
import { Select } from "@budibase/bbui"
import { selectedScreen } from "@/stores/builder"
import { findAllComponents, getComponentContexts } from "@/helpers/components"
import { makePropSafe as safe } from "@budibase/string-templates"
import { type Component } from "@budibase/types"
export let value: string | undefined = undefined
$: providers = getProviders($selectedScreen?.props)
const getProviders = (rootComponent: Component | undefined) => {
if (!rootComponent) {
return []
}
return findAllComponents(rootComponent)
.filter(component => {
return getComponentContexts(component._component).some(ctx =>
ctx.actions?.find(
act =>
act.type === "AddDataProviderQueryExtension" ||
act.type === "AddDataProviderFilterExtension"
)
)
})
.map(provider => ({
label: provider._instanceName,
value: `{{ literal ${safe(provider._id)} }}`,
subtitle: `${
provider?.dataSource?.label || provider?.table?.label || "-"
}`,
}))
}
</script>
<Select {value} options={providers} on:change />

View File

@ -212,10 +212,8 @@ export class ComponentStore extends BudiStore<ComponentState> {
}
const def = this.getDefinition(enrichedComponent?._component)
const filterableTypes = def?.settings?.filter(
setting =>
setting?.type?.startsWith("filter") &&
setting?.type !== "filterConfiguration"
const filterableTypes = def?.settings?.filter(setting =>
["filter", "filter/relationship"].includes(setting?.type)
)
for (let setting of filterableTypes || []) {
const isLegacy = Array.isArray(enrichedComponent[setting.key])

View File

@ -5204,7 +5204,7 @@
"icon": "Data",
"illegalChildren": ["section"],
"hasChildren": true,
"actions": ["RefreshDatasource"],
"actions": ["RefreshDatasource", "AddDataProviderQueryExtension"],
"size": {
"width": 500,
"height": 200
@ -5534,9 +5534,10 @@
"width": 100,
"height": 35
},
"new": true,
"settings": [
{
"type": "dataSource/embedded",
"type": "dataSource/filterable",
"label": "Target component",
"required": true,
"key": "targetComponent",
@ -5552,17 +5553,15 @@
},
{
"type": "boolean",
"label": "Persist filter values when a user returns to the screen",
"label": "Persist filters",
"key": "persistFilters",
"wide": true,
"defaultValue": false
},
{
"type": "boolean",
"label": "Add a 'Clear filters' button so that user can clear multiple filters at once",
"label": "Clear filters",
"key": "showClear",
"defaultValue": false,
"wide": true
"defaultValue": false
}
]
},
@ -7873,20 +7872,9 @@
"type": "array"
}
]
},
{
"type": "static",
"scope": "local",
"values": [
{
"label": "Datasources",
"key": "datasources",
"type": "array"
}
]
}
],
"actions": ["RefreshDatasource", "AddDataProviderQueryExtension"]
"actions": ["RefreshDatasource", "AddDataProviderFilterExtension"]
},
"bbreferencefield": {
"devComment": "As bb reference is only used for user subtype for now, we are using user for icon and labels",

View File

@ -109,27 +109,16 @@
}
const extendFilter = (initialFilter, extensions) => {
if (!extensions || !Object.keys(extensions).length) {
if (!Object.keys(extensions || {}).length) {
return initialFilter
}
// Base filter
let extended = {
groups: initialFilter ? [initialFilter] : [],
return {
groups: (initialFilter ? [initialFilter] : []).concat(
Object.values(extensions)
),
logicalOperator: UILogicalOperator.ALL,
onEmptyFilter: EmptyFilterOption.RETURN_NONE,
}
// Process and aggregate all filters.
let groups = Object.entries(extensions).map(([_, entry]) => {
// Assuming there should only ever be 1
return entry
})
// Combine all groups into the base
extended.groups = [...extended.groups, ...groups]
return extended
}
// Provide additional data context for live binding eval

View File

@ -229,7 +229,7 @@
}
.spectrum-Button-label .display {
color: rgba(179, 222, 254, 1);
color: var(--spectrum-global-color-blue-600);
}
.spectrum-Button--secondary.new-styles {

View File

@ -44,7 +44,6 @@ const createComponentStore = () => {
selectedComponentPath: selectedPath?.map(component => component._id),
mountedComponentCount: Object.keys($store.mountedComponents).length,
screenslotInstance: $store.mountedComponents[ScreenslotID],
mounted: $store.mountedComponents,
}
}
)