Add filtering to relationship picker

This commit is contained in:
Andrew Kingston 2023-07-18 09:36:20 +01:00
parent 7c7d909d81
commit ae8ed1a1e5
5 changed files with 66 additions and 31 deletions

View File

@ -23,6 +23,7 @@ import BasicColumnEditor from "./controls/ColumnEditor/BasicColumnEditor.svelte"
import GridColumnEditor from "./controls/ColumnEditor/GridColumnEditor.svelte"
import BarButtonList from "./controls/BarButtonList.svelte"
import FieldConfiguration from "./controls/FieldConfiguration/FieldConfiguration.svelte"
import RelationshipFilterEditor from "./controls/RelationshipFilterEditor.svelte"
const componentMap = {
text: DrawerBindableInput,
@ -44,6 +45,7 @@ const componentMap = {
schema: SchemaSelect,
section: SectionSelect,
filter: FilterEditor,
"filter/relationship": RelationshipFilterEditor,
url: URLSelect,
fieldConfiguration: FieldConfiguration,
columns: ColumnEditor,

View File

@ -13,13 +13,14 @@
export let value = []
export let componentInstance
export let bindings = []
export let schema = null
let drawer
$: tempValue = value
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
$: schema = getSchemaForDatasource($currentAsset, datasource)?.schema
$: schemaFields = Object.values(schema || {})
$: dsSchema = getSchemaForDatasource($currentAsset, datasource)?.schema
$: schemaFields = Object.values(schema || dsSchema || {})
$: text = getText(value?.filter(filter => filter.field))
async function saveFilter() {

View File

@ -0,0 +1,35 @@
<script>
import { currentAsset } from "builderStore"
import { findClosestMatchingComponent } from "builderStore/componentUtils"
import {
getDatasourceForProvider,
getSchemaForDatasource,
} from "builderStore/dataBinding"
import { tables } from "stores/backend"
import FilterEditor from "./FilterEditor/FilterEditor.svelte"
export let componentInstance
// Extract which relationship column we're using
$: column = componentInstance.field
// Find the closest parent form
$: form = findClosestMatchingComponent(
$currentAsset.props,
componentInstance._id,
component => component._component.endsWith("/form")
)
// Get that form's schema
$: datasource = getDatasourceForProvider($currentAsset, form)
$: formSchema = getSchemaForDatasource($currentAsset, datasource)?.schema
// Get the schema for the relationship field that this picker is using
$: columnSchema = formSchema?.[column]
// Get the schema for the table on the other side of this relationship
$: linkedTable = $tables.list.find(x => x._id === columnSchema?.tableId)
$: schema = linkedTable?.schema
</script>
<FilterEditor on:change {...$$props} {schema} />

View File

@ -3489,6 +3489,16 @@
}
]
},
{
"type": "validation/link",
"label": "Validation",
"key": "validation"
},
{
"type": "filter/relationship",
"label": "Filtering",
"key": "filter"
},
{
"type": "boolean",
"label": "Autocomplete",
@ -3500,11 +3510,6 @@
"label": "Disabled",
"key": "disabled",
"defaultValue": false
},
{
"type": "validation/link",
"label": "Validation",
"key": "validation"
}
]
},

View File

@ -1,5 +1,6 @@
<script>
import { CoreSelect, CoreMultiselect } from "@budibase/bbui"
import { fetchData } from "@budibase/frontend-core"
import { getContext } from "svelte"
import Field from "./Field.svelte"
import { FieldTypes } from "../../../constants"
@ -14,43 +15,34 @@
export let autocomplete = false
export let defaultValue
export let onChange
export let filter
let fieldState
let fieldApi
let fieldSchema
let options = []
let tableDefinition
$: multiselect = fieldSchema?.relationshipType !== "one-to-many"
$: linkedTableId = fieldSchema?.tableId
$: fetchRows(linkedTableId)
$: fetchTable(linkedTableId)
$: fetch = fetchData({
API,
datasource: {
type: "table",
tableId: linkedTableId,
},
options: {
filter,
limit: 100,
},
})
$: fetch.update({ filter })
$: options = $fetch.rows
$: tableDefinition = $fetch.definition
$: singleValue = flatten(fieldState?.value)?.[0]
$: multiValue = flatten(fieldState?.value) ?? []
$: component = multiselect ? CoreMultiselect : CoreSelect
$: expandedDefaultValue = expand(defaultValue)
const fetchTable = async id => {
if (id) {
try {
tableDefinition = await API.fetchTableDefinition(id)
} catch (error) {
tableDefinition = null
}
}
}
const fetchRows = async id => {
if (id) {
try {
options = await API.fetchTableData(id)
} catch (error) {
options = []
}
}
}
const flatten = values => {
if (!values) {
return []