2021-02-01 14:15:35 +01:00
|
|
|
<script>
|
2023-09-21 11:39:02 +02:00
|
|
|
import { CoreSelect, CoreMultiselect } from "@budibase/bbui"
|
|
|
|
import { fetchData } from "@budibase/frontend-core"
|
2021-02-01 14:15:35 +01:00
|
|
|
import { getContext } from "svelte"
|
2021-02-05 11:53:25 +01:00
|
|
|
import Field from "./Field.svelte"
|
2021-11-08 18:25:05 +01:00
|
|
|
import { FieldTypes } from "../../../constants"
|
2021-02-01 14:15:35 +01:00
|
|
|
|
|
|
|
const { API } = getContext("sdk")
|
|
|
|
|
|
|
|
export let field
|
|
|
|
export let label
|
2021-02-12 16:47:20 +01:00
|
|
|
export let placeholder
|
2021-02-17 16:16:44 +01:00
|
|
|
export let disabled = false
|
2021-08-10 15:37:14 +02:00
|
|
|
export let validation
|
2023-09-06 17:38:11 +02:00
|
|
|
export let autocomplete = true
|
2022-02-04 09:50:56 +01:00
|
|
|
export let defaultValue
|
2022-04-14 11:01:14 +02:00
|
|
|
export let onChange
|
2023-07-18 10:36:20 +02:00
|
|
|
export let filter
|
2021-02-01 14:15:35 +01:00
|
|
|
|
|
|
|
let fieldState
|
|
|
|
let fieldApi
|
|
|
|
let fieldSchema
|
|
|
|
let tableDefinition
|
2023-09-21 12:29:39 +02:00
|
|
|
let fetchTerm
|
2021-02-22 12:40:24 +01:00
|
|
|
|
2021-04-15 20:43:18 +02:00
|
|
|
$: multiselect = fieldSchema?.relationshipType !== "one-to-many"
|
2021-02-01 14:15:35 +01:00
|
|
|
$: linkedTableId = fieldSchema?.tableId
|
2023-07-18 10:36:20 +02:00
|
|
|
$: fetch = fetchData({
|
|
|
|
API,
|
|
|
|
datasource: {
|
|
|
|
type: "table",
|
|
|
|
tableId: linkedTableId,
|
|
|
|
},
|
|
|
|
options: {
|
|
|
|
filter,
|
|
|
|
limit: 100,
|
|
|
|
},
|
|
|
|
})
|
2023-09-21 12:29:39 +02:00
|
|
|
|
2023-09-21 11:39:02 +02:00
|
|
|
$: options = $fetch.rows
|
2023-07-18 10:36:20 +02:00
|
|
|
$: tableDefinition = $fetch.definition
|
2021-08-19 13:53:31 +02:00
|
|
|
$: singleValue = flatten(fieldState?.value)?.[0]
|
|
|
|
$: multiValue = flatten(fieldState?.value) ?? []
|
2021-08-17 15:13:57 +02:00
|
|
|
$: component = multiselect ? CoreMultiselect : CoreSelect
|
2022-02-04 09:50:56 +01:00
|
|
|
$: expandedDefaultValue = expand(defaultValue)
|
2023-09-21 12:29:39 +02:00
|
|
|
$: primaryDisplay = tableDefinition?.primaryDisplay || "_id"
|
|
|
|
|
2023-09-21 13:15:42 +02:00
|
|
|
let lastFetchedTerm
|
2023-09-21 12:29:39 +02:00
|
|
|
$: {
|
2023-09-21 13:15:42 +02:00
|
|
|
const termChangedSinceFetch = (lastFetchedTerm || "") !== (fetchTerm || "")
|
|
|
|
|
2023-09-21 13:22:48 +02:00
|
|
|
const allRowsFetched = !lastFetchedTerm / !$fetch.hasNextPage
|
2023-09-21 13:15:42 +02:00
|
|
|
if (!allRowsFetched && termChangedSinceFetch) {
|
|
|
|
debugger
|
|
|
|
// Don't request until we have the primary display
|
|
|
|
if (primaryDisplay) {
|
|
|
|
lastFetchedTerm = fetchTerm
|
|
|
|
fetch.update({
|
|
|
|
query: { string: { [primaryDisplay]: fetchTerm } },
|
|
|
|
})
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
options = fetchTerm
|
|
|
|
? $fetch.rows.filter(row => row[primaryDisplay].includes(fetchTerm))
|
|
|
|
: $fetch.rows
|
2023-09-21 12:29:39 +02:00
|
|
|
}
|
|
|
|
}
|
2021-02-01 14:15:35 +01:00
|
|
|
|
2021-05-04 12:32:22 +02:00
|
|
|
const flatten = values => {
|
2021-04-16 12:32:41 +02:00
|
|
|
if (!values) {
|
|
|
|
return []
|
|
|
|
}
|
2022-08-05 15:53:41 +02:00
|
|
|
if (!Array.isArray(values)) {
|
|
|
|
values = [values]
|
|
|
|
}
|
2021-05-04 12:32:22 +02:00
|
|
|
return values.map(value => (typeof value === "object" ? value._id : value))
|
2021-04-16 12:32:41 +02:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:32:22 +02:00
|
|
|
const getDisplayName = row => {
|
2023-09-21 12:29:39 +02:00
|
|
|
return row?.[primaryDisplay] || "-"
|
2021-02-01 14:15:35 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:32:22 +02:00
|
|
|
const singleHandler = e => {
|
2022-04-14 11:01:14 +02:00
|
|
|
handleChange(e.detail == null ? [] : [e.detail])
|
2021-02-01 14:15:35 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:32:22 +02:00
|
|
|
const multiHandler = e => {
|
2022-04-14 11:01:14 +02:00
|
|
|
handleChange(e.detail)
|
2021-02-01 14:15:35 +01:00
|
|
|
}
|
2022-02-04 09:50:56 +01:00
|
|
|
|
|
|
|
const expand = values => {
|
|
|
|
if (!values) {
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
if (Array.isArray(values)) {
|
|
|
|
return values
|
|
|
|
}
|
|
|
|
return values.split(",").map(value => value.trim())
|
|
|
|
}
|
2022-04-14 11:01:14 +02:00
|
|
|
|
|
|
|
const handleChange = value => {
|
2022-08-31 12:39:04 +02:00
|
|
|
const changed = fieldApi.setValue(value)
|
|
|
|
if (onChange && changed) {
|
2022-04-14 11:01:14 +02:00
|
|
|
onChange({ value })
|
|
|
|
}
|
|
|
|
}
|
2021-02-01 14:15:35 +01:00
|
|
|
</script>
|
|
|
|
|
2021-02-05 11:53:25 +01:00
|
|
|
<Field
|
2021-02-01 14:15:35 +01:00
|
|
|
{label}
|
|
|
|
{field}
|
2021-02-17 16:16:44 +01:00
|
|
|
{disabled}
|
2021-08-10 15:37:14 +02:00
|
|
|
{validation}
|
2022-02-04 09:50:56 +01:00
|
|
|
defaultValue={expandedDefaultValue}
|
2021-11-08 18:25:05 +01:00
|
|
|
type={FieldTypes.LINK}
|
2021-02-01 14:15:35 +01:00
|
|
|
bind:fieldState
|
|
|
|
bind:fieldApi
|
|
|
|
bind:fieldSchema
|
2021-05-04 12:04:42 +02:00
|
|
|
>
|
2021-04-15 20:43:18 +02:00
|
|
|
{#if fieldState}
|
2023-09-21 11:39:02 +02:00
|
|
|
<svelte:component
|
|
|
|
this={component}
|
|
|
|
{options}
|
|
|
|
{autocomplete}
|
|
|
|
value={multiselect ? multiValue : singleValue}
|
|
|
|
on:change={multiselect ? multiHandler : singleHandler}
|
|
|
|
id={fieldState.fieldId}
|
|
|
|
disabled={fieldState.disabled}
|
|
|
|
error={fieldState.error}
|
|
|
|
getOptionLabel={getDisplayName}
|
|
|
|
getOptionValue={option => option._id}
|
|
|
|
{placeholder}
|
2023-09-21 12:29:39 +02:00
|
|
|
sort
|
|
|
|
useFetch
|
|
|
|
bind:fetchTerm
|
2023-09-21 11:39:02 +02:00
|
|
|
/>
|
2021-04-15 20:43:18 +02:00
|
|
|
{/if}
|
2021-02-05 11:53:25 +01:00
|
|
|
</Field>
|