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

View File

@ -13,13 +13,14 @@
export let value = [] export let value = []
export let componentInstance export let componentInstance
export let bindings = [] export let bindings = []
export let schema = null
let drawer let drawer
$: tempValue = value $: tempValue = value
$: datasource = getDatasourceForProvider($currentAsset, componentInstance) $: datasource = getDatasourceForProvider($currentAsset, componentInstance)
$: schema = getSchemaForDatasource($currentAsset, datasource)?.schema $: dsSchema = getSchemaForDatasource($currentAsset, datasource)?.schema
$: schemaFields = Object.values(schema || {}) $: schemaFields = Object.values(schema || dsSchema || {})
$: text = getText(value?.filter(filter => filter.field)) $: text = getText(value?.filter(filter => filter.field))
async function saveFilter() { 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", "type": "boolean",
"label": "Autocomplete", "label": "Autocomplete",
@ -3500,11 +3510,6 @@
"label": "Disabled", "label": "Disabled",
"key": "disabled", "key": "disabled",
"defaultValue": false "defaultValue": false
},
{
"type": "validation/link",
"label": "Validation",
"key": "validation"
} }
] ]
}, },

View File

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