2021-02-01 14:15:35 +01:00
|
|
|
<script>
|
|
|
|
import { getContext } from "svelte"
|
2021-02-05 11:53:25 +01:00
|
|
|
import Field from "./Field.svelte"
|
2021-02-01 14:15:35 +01:00
|
|
|
import Picker from "./Picker.svelte"
|
|
|
|
|
|
|
|
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-02-01 14:15:35 +01:00
|
|
|
|
|
|
|
let fieldState
|
|
|
|
let fieldApi
|
|
|
|
let fieldSchema
|
|
|
|
|
|
|
|
// Picker state
|
|
|
|
let options = []
|
|
|
|
let tableDefinition
|
2021-02-12 16:47:20 +01:00
|
|
|
let fieldText = ""
|
2021-02-22 12:40:24 +01:00
|
|
|
|
|
|
|
const setFieldText = value => {
|
|
|
|
if (fieldSchema?.relationshipType === "one-to-many") {
|
2021-02-15 13:31:16 +01:00
|
|
|
if (value?.length && options?.length) {
|
|
|
|
const row = options.find(row => row._id === value[0])
|
2021-02-24 20:05:17 +01:00
|
|
|
return getDisplayName(row)
|
2021-02-12 16:47:20 +01:00
|
|
|
} else {
|
2021-02-22 12:40:24 +01:00
|
|
|
return placeholder || "Choose an option"
|
|
|
|
}
|
2021-02-12 16:47:20 +01:00
|
|
|
} else {
|
|
|
|
if (value?.length) {
|
|
|
|
return `${value?.length ?? 0} selected rows`
|
|
|
|
} else {
|
2021-02-22 12:40:24 +01:00
|
|
|
return placeholder || "Choose some options"
|
|
|
|
}
|
2021-02-12 16:47:20 +01:00
|
|
|
}
|
|
|
|
}
|
2021-02-01 14:15:35 +01:00
|
|
|
|
2021-02-22 12:40:24 +01:00
|
|
|
$: options, (fieldText = setFieldText($fieldState?.value))
|
2021-02-01 14:15:35 +01:00
|
|
|
$: valueLookupMap = getValueLookupMap($fieldState?.value)
|
|
|
|
$: isOptionSelected = option => valueLookupMap[option] === true
|
|
|
|
$: linkedTableId = fieldSchema?.tableId
|
|
|
|
$: fetchRows(linkedTableId)
|
|
|
|
$: fetchTable(linkedTableId)
|
|
|
|
|
|
|
|
const fetchTable = async id => {
|
2021-02-12 12:17:13 +01:00
|
|
|
if (id) {
|
2021-02-01 14:23:18 +01:00
|
|
|
const result = await API.fetchTableDefinition(id)
|
|
|
|
if (!result.error) {
|
|
|
|
tableDefinition = result
|
|
|
|
}
|
2021-02-01 14:15:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const fetchRows = async id => {
|
2021-02-12 12:17:13 +01:00
|
|
|
if (id) {
|
2021-02-01 14:23:18 +01:00
|
|
|
const rows = await API.fetchTableData(id)
|
|
|
|
options = rows && !rows.error ? rows : []
|
2021-02-01 14:15:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const getDisplayName = row => {
|
|
|
|
return row[tableDefinition?.primaryDisplay || "_id"]
|
|
|
|
}
|
|
|
|
|
|
|
|
const getValueLookupMap = value => {
|
|
|
|
let map = {}
|
|
|
|
if (value?.length) {
|
|
|
|
value.forEach(option => {
|
|
|
|
map[option] = true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return map
|
|
|
|
}
|
|
|
|
|
|
|
|
const toggleOption = option => {
|
2021-02-22 12:40:24 +01:00
|
|
|
if (fieldSchema.type === "one-to-many") {
|
2021-02-12 16:47:20 +01:00
|
|
|
fieldApi.setValue([option])
|
|
|
|
} else {
|
|
|
|
if ($fieldState.value.includes(option)) {
|
2021-02-22 12:40:24 +01:00
|
|
|
fieldApi.setValue($fieldState.value.filter(x => x !== option))
|
|
|
|
} else {
|
|
|
|
fieldApi.setValue([...$fieldState.value, option])
|
|
|
|
}
|
2021-02-12 16:47:20 +01:00
|
|
|
}
|
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-02-05 11:53:25 +01:00
|
|
|
type="link"
|
2021-02-01 14:15:35 +01:00
|
|
|
bind:fieldState
|
|
|
|
bind:fieldApi
|
|
|
|
bind:fieldSchema
|
|
|
|
defaultValue={[]}>
|
|
|
|
<Picker
|
|
|
|
{fieldState}
|
|
|
|
{fieldText}
|
|
|
|
{options}
|
|
|
|
{isOptionSelected}
|
|
|
|
onSelectOption={toggleOption}
|
|
|
|
getOptionLabel={getDisplayName}
|
|
|
|
getOptionValue={option => option._id} />
|
2021-02-05 11:53:25 +01:00
|
|
|
</Field>
|