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-07-18 10:36:20 +02:00
|
|
|
$: tableDefinition = $fetch.definition
|
2023-09-22 10:14:17 +02:00
|
|
|
$: selectedValue = multiselect
|
|
|
|
? flatten(fieldState?.value) ?? []
|
|
|
|
: flatten(fieldState?.value)?.[0]
|
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-22 12:16:54 +02:00
|
|
|
$: primaryDisplay = tableDefinition?.primaryDisplay
|
|
|
|
|
|
|
|
$: initialValues =
|
|
|
|
initialValues ||
|
|
|
|
(primaryDisplay &&
|
|
|
|
fieldState?.value?.map(x => ({
|
|
|
|
_id: x._id,
|
|
|
|
[primaryDisplay]: x.primaryDisplay,
|
|
|
|
})))
|
|
|
|
|
2023-09-22 12:39:49 +02:00
|
|
|
$: allOptions = {
|
|
|
|
...(allOptions || {}),
|
|
|
|
...[...($fetch.rows || []), ...(initialValues || [])]?.reduce((p, c) => {
|
|
|
|
p[c._id] = c
|
|
|
|
return p
|
|
|
|
}, {}),
|
|
|
|
}
|
|
|
|
|
|
|
|
$: options = fetchTerm
|
|
|
|
? Object.values(allOptions).filter(row =>
|
|
|
|
row[primaryDisplay].includes(fetchTerm)
|
|
|
|
)
|
|
|
|
: Object.values(allOptions)
|
2023-09-21 12:29:39 +02:00
|
|
|
|
2023-09-21 13:15:42 +02:00
|
|
|
let lastFetchedTerm
|
2023-09-22 12:39:49 +02:00
|
|
|
$: fetchRows(fetchTerm)
|
2023-09-22 12:16:54 +02:00
|
|
|
|
2023-09-22 12:39:49 +02:00
|
|
|
const fetchRows = fetchTerm => {
|
2023-09-21 13:15:42 +02:00
|
|
|
const termChangedSinceFetch = (lastFetchedTerm || "") !== (fetchTerm || "")
|
|
|
|
|
2023-09-21 13:24:29 +02:00
|
|
|
const allRowsFetched = !lastFetchedTerm && !$fetch.hasNextPage
|
2023-09-21 13:15:42 +02:00
|
|
|
if (!allRowsFetched && termChangedSinceFetch) {
|
|
|
|
// Don't request until we have the primary display
|
|
|
|
if (primaryDisplay) {
|
|
|
|
lastFetchedTerm = fetchTerm
|
|
|
|
fetch.update({
|
|
|
|
query: { string: { [primaryDisplay]: fetchTerm } },
|
|
|
|
})
|
|
|
|
}
|
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}
|
2023-09-22 11:00:56 +02:00
|
|
|
value={selectedValue}
|
2023-09-21 11:39:02 +02:00
|
|
|
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>
|