diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/FilterDrawer.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/FilterDrawer.svelte
index d9425c961d..8d7f50a527 100644
--- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/FilterDrawer.svelte
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FilterEditor/FilterDrawer.svelte
@@ -14,6 +14,7 @@
import ClientBindingPanel from "components/common/bindings/ClientBindingPanel.svelte"
import { generate } from "shortid"
import { getValidOperatorsForType, OperatorOptions } from "constants/lucene"
+ import { getFields } from "helpers/searchFields"
export let schemaFields
export let filters = []
@@ -21,11 +22,8 @@
export let panel = ClientBindingPanel
export let allowBindings = true
- const BannedTypes = ["link", "attachment", "formula", "json", "jsonarray"]
-
- $: fieldOptions = (schemaFields ?? [])
- .filter(field => !BannedTypes.includes(field.type))
- .map(field => field.name)
+ $: enrichedSchemaFields = getFields(schemaFields || [])
+ $: fieldOptions = enrichedSchemaFields.map(field => field.name) || []
$: valueTypeOptions = allowBindings ? ["Value", "Binding"] : ["Value"]
const addFilter = () => {
@@ -53,7 +51,7 @@
const onFieldChange = (expression, field) => {
// Update the field type
- expression.type = schemaFields.find(x => x.name === field)?.type
+ expression.type = enrichedSchemaFields.find(x => x.name === field)?.type
// Ensure a valid operator is set
const validOperators = getValidOperatorsForType(expression.type).map(
@@ -85,7 +83,7 @@
}
const getFieldOptions = field => {
- const schema = schemaFields.find(x => x.name === field)
+ const schema = enrichedSchemaFields.find(x => x.name === field)
return schema?.constraints?.inclusion || []
}
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/SearchFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/SearchFieldSelect.svelte
new file mode 100644
index 0000000000..474fbc676c
--- /dev/null
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/SearchFieldSelect.svelte
@@ -0,0 +1,47 @@
+
+
+
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js
index e752240302..5e27cdce28 100644
--- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js
+++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/componentSettings.js
@@ -7,6 +7,7 @@ import ColorPicker from "./ColorPicker.svelte"
import { IconSelect } from "./IconSelect"
import FieldSelect from "./FieldSelect.svelte"
import MultiFieldSelect from "./MultiFieldSelect.svelte"
+import SearchFieldSelect from "./SearchFieldSelect.svelte"
import SchemaSelect from "./SchemaSelect.svelte"
import SectionSelect from "./SectionSelect.svelte"
import NavigationEditor from "./NavigationEditor/NavigationEditor.svelte"
@@ -30,6 +31,7 @@ const componentMap = {
icon: IconSelect,
field: FieldSelect,
multifield: MultiFieldSelect,
+ searchfield: SearchFieldSelect,
options: OptionsEditor,
schema: SchemaSelect,
section: SectionSelect,
diff --git a/packages/builder/src/constants/backend/index.js b/packages/builder/src/constants/backend/index.js
index c5fb294f80..c1eea5b0ef 100644
--- a/packages/builder/src/constants/backend/index.js
+++ b/packages/builder/src/constants/backend/index.js
@@ -229,3 +229,11 @@ export const PaginationLocations = [
{ label: "Query parameters", value: "query" },
{ label: "Request body", value: "body" },
]
+
+export const BannedSearchTypes = [
+ "link",
+ "attachment",
+ "formula",
+ "json",
+ "jsonarray",
+]
diff --git a/packages/builder/src/helpers/searchFields.js b/packages/builder/src/helpers/searchFields.js
new file mode 100644
index 0000000000..650e04a680
--- /dev/null
+++ b/packages/builder/src/helpers/searchFields.js
@@ -0,0 +1,31 @@
+import { tables } from "../stores/backend"
+import { BannedSearchTypes } from "../constants/backend"
+import { get } from "svelte/store"
+
+export function getTableFields(linkField) {
+ const table = get(tables).list.find(table => table._id === linkField.tableId)
+ if (!table || !table.sql) {
+ return []
+ }
+ const linkFields = getFields(Object.values(table.schema), {
+ allowLinks: false,
+ })
+ return linkFields.map(field => ({
+ ...field,
+ name: `${table.name}.${field.name}`,
+ }))
+}
+
+export function getFields(fields, { allowLinks } = { allowLinks: true }) {
+ let filteredFields = fields.filter(
+ field => !BannedSearchTypes.includes(field.type)
+ )
+ if (allowLinks) {
+ const linkFields = fields.filter(field => field.type === "link")
+ for (let linkField of linkFields) {
+ // only allow one depth of SQL relationship filtering
+ filteredFields = filteredFields.concat(getTableFields(linkField))
+ }
+ }
+ return filteredFields
+}
diff --git a/packages/client/manifest.json b/packages/client/manifest.json
index dfe9ae5a91..9431129fa0 100644
--- a/packages/client/manifest.json
+++ b/packages/client/manifest.json
@@ -2811,7 +2811,7 @@
"key": "dataSource"
},
{
- "type": "multifield",
+ "type": "searchfield",
"label": "Search Columns",
"key": "searchColumns",
"placeholder": "Choose search columns"
@@ -2958,7 +2958,7 @@
"key": "dataSource"
},
{
- "type": "multifield",
+ "type": "searchfield",
"label": "Search Columns",
"key": "searchColumns",
"placeholder": "Choose search columns"
diff --git a/packages/client/src/components/app/DataProvider.svelte b/packages/client/src/components/app/DataProvider.svelte
index 71c54db4da..2341eef3b2 100644
--- a/packages/client/src/components/app/DataProvider.svelte
+++ b/packages/client/src/components/app/DataProvider.svelte
@@ -67,6 +67,7 @@
$: dataContext = {
rows: $fetch.rows,
info: $fetch.info,
+ datasource: dataSource || {},
schema: $fetch.schema,
rowsLength: $fetch.rows.length,
diff --git a/packages/client/src/components/app/blocks/CardsBlock.svelte b/packages/client/src/components/app/blocks/CardsBlock.svelte
index 301b440ab3..f0892ca447 100644
--- a/packages/client/src/components/app/blocks/CardsBlock.svelte
+++ b/packages/client/src/components/app/blocks/CardsBlock.svelte
@@ -71,12 +71,13 @@
const enrichFilter = (filter, columns, formId) => {
let enrichedFilter = [...(filter || [])]
columns?.forEach(column => {
+ const safePath = column.name.split(".").map(safe).join(".")
enrichedFilter.push({
field: column.name,
operator: column.type === "string" ? "string" : "equal",
type: column.type === "string" ? "string" : "number",
valueType: "Binding",
- value: `{{ [${formId}].[${column.name}] }}`,
+ value: `{{ ${safe(formId)}.${safePath} }}`,
})
})
return enrichedFilter
@@ -112,7 +113,9 @@
// Load the datasource schema so we can determine column types
const fetchSchema = async dataSource => {
if (dataSource) {
- schema = await fetchDatasourceSchema(dataSource)
+ schema = await fetchDatasourceSchema(dataSource, {
+ enrichRelationships: true,
+ })
}
schemaLoaded = true
}
diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte
index 936a8d1734..3de4497731 100644
--- a/packages/client/src/components/app/blocks/TableBlock.svelte
+++ b/packages/client/src/components/app/blocks/TableBlock.svelte
@@ -59,12 +59,13 @@
const enrichFilter = (filter, columns, formId) => {
let enrichedFilter = [...(filter || [])]
columns?.forEach(column => {
+ const safePath = column.name.split(".").map(safe).join(".")
enrichedFilter.push({
field: column.name,
operator: column.type === "string" ? "string" : "equal",
type: column.type === "string" ? "string" : "number",
valueType: "Binding",
- value: `{{ ${safe(formId)}.${safe(column.name)} }}`,
+ value: `{{ ${safe(formId)}.${safePath} }}`,
})
})
return enrichedFilter
@@ -90,7 +91,9 @@
// Load the datasource schema so we can determine column types
const fetchSchema = async dataSource => {
if (dataSource) {
- schema = await fetchDatasourceSchema(dataSource)
+ schema = await fetchDatasourceSchema(dataSource, {
+ enrichRelationships: true,
+ })
}
schemaLoaded = true
}
diff --git a/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte b/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte
index 20909d011c..6a114afe3e 100644
--- a/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte
+++ b/packages/client/src/components/app/dynamic-filter/DynamicFilter.svelte
@@ -11,11 +11,14 @@
export let size = "M"
const component = getContext("component")
- const { builderStore, ActionTypes, getAction } = getContext("sdk")
+ const { builderStore, ActionTypes, getAction, fetchDatasourceSchema } =
+ getContext("sdk")
let modal
let tmpFilters = []
let filters = []
+ let schemaLoaded = false,
+ schema
$: dataProviderId = dataProvider?.id
$: addExtension = getAction(
@@ -26,7 +29,7 @@
dataProviderId,
ActionTypes.RemoveDataProviderQueryExtension
)
- $: schema = dataProvider?.schema
+ $: fetchSchema(dataProvider || {})
$: schemaFields = getSchemaFields(schema, allowedFields)
// Add query extension to data provider
@@ -39,7 +42,20 @@
}
}
- const getSchemaFields = (schema, allowedFields) => {
+ async function fetchSchema(dataProvider) {
+ const datasource = dataProvider?.datasource
+ if (datasource) {
+ schema = await fetchDatasourceSchema(datasource, {
+ enrichRelationships: true,
+ })
+ }
+ schemaLoaded = true
+ }
+
+ function getSchemaFields(schema, allowedFields) {
+ if (!schemaLoaded) {
+ return {}
+ }
let clonedSchema = {}
if (!allowedFields?.length) {
clonedSchema = schema
@@ -68,18 +84,20 @@
})
-