Add optional enrichment of relationship fields when determining datasource schema and update block filters to properly reference relationship fields
This commit is contained in:
parent
aae2dc86d3
commit
0502e62e1c
|
@ -2958,7 +2958,7 @@
|
||||||
"key": "dataSource"
|
"key": "dataSource"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "multifield",
|
"type": "searchfield",
|
||||||
"label": "Search Columns",
|
"label": "Search Columns",
|
||||||
"key": "searchColumns",
|
"key": "searchColumns",
|
||||||
"placeholder": "Choose search columns"
|
"placeholder": "Choose search columns"
|
||||||
|
|
|
@ -71,12 +71,13 @@
|
||||||
const enrichFilter = (filter, columns, formId) => {
|
const enrichFilter = (filter, columns, formId) => {
|
||||||
let enrichedFilter = [...(filter || [])]
|
let enrichedFilter = [...(filter || [])]
|
||||||
columns?.forEach(column => {
|
columns?.forEach(column => {
|
||||||
|
const safePath = column.name.split(".").map(safe).join(".")
|
||||||
enrichedFilter.push({
|
enrichedFilter.push({
|
||||||
field: column.name,
|
field: column.name,
|
||||||
operator: column.type === "string" ? "string" : "equal",
|
operator: column.type === "string" ? "string" : "equal",
|
||||||
type: column.type === "string" ? "string" : "number",
|
type: column.type === "string" ? "string" : "number",
|
||||||
valueType: "Binding",
|
valueType: "Binding",
|
||||||
value: `{{ [${formId}].[${column.name}] }}`,
|
value: `{{ ${safe(formId)}.${safePath} }}`,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
return enrichedFilter
|
return enrichedFilter
|
||||||
|
@ -112,7 +113,9 @@
|
||||||
// Load the datasource schema so we can determine column types
|
// Load the datasource schema so we can determine column types
|
||||||
const fetchSchema = async dataSource => {
|
const fetchSchema = async dataSource => {
|
||||||
if (dataSource) {
|
if (dataSource) {
|
||||||
schema = await fetchDatasourceSchema(dataSource)
|
schema = await fetchDatasourceSchema(dataSource, {
|
||||||
|
enrichRelationships: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
schemaLoaded = true
|
schemaLoaded = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,11 +41,9 @@
|
||||||
let dataProviderId
|
let dataProviderId
|
||||||
let schema
|
let schema
|
||||||
let schemaLoaded = false
|
let schemaLoaded = false
|
||||||
let enrichedSearchColumns
|
|
||||||
let enrichedSearchColumnsLoaded = false
|
|
||||||
|
|
||||||
$: fetchSchema(dataSource)
|
$: fetchSchema(dataSource)
|
||||||
$: enrichSearchColumns(searchColumns, schema)
|
$: enrichedSearchColumns = enrichSearchColumns(searchColumns, schema)
|
||||||
$: enrichedFilter = enrichFilter(filter, enrichedSearchColumns, formId)
|
$: enrichedFilter = enrichFilter(filter, enrichedSearchColumns, formId)
|
||||||
$: titleButtonAction = [
|
$: titleButtonAction = [
|
||||||
{
|
{
|
||||||
|
@ -61,21 +59,22 @@
|
||||||
const enrichFilter = (filter, columns, formId) => {
|
const enrichFilter = (filter, columns, formId) => {
|
||||||
let enrichedFilter = [...(filter || [])]
|
let enrichedFilter = [...(filter || [])]
|
||||||
columns?.forEach(column => {
|
columns?.forEach(column => {
|
||||||
|
const safePath = column.name.split(".").map(safe).join(".")
|
||||||
enrichedFilter.push({
|
enrichedFilter.push({
|
||||||
field: column.name,
|
field: column.name,
|
||||||
operator: column.type === "string" ? "string" : "equal",
|
operator: column.type === "string" ? "string" : "equal",
|
||||||
type: column.type === "string" ? "string" : "number",
|
type: column.type === "string" ? "string" : "number",
|
||||||
valueType: "Binding",
|
valueType: "Binding",
|
||||||
value: `{{ ${safe(formId)}.${safe(column.name)} }}`,
|
value: `{{ ${safe(formId)}.${safePath} }}`,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
return enrichedFilter
|
return enrichedFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine data types for search fields and only use those that are valid
|
// Determine data types for search fields and only use those that are valid
|
||||||
const enrichSearchColumns = async (searchColumns, schema) => {
|
const enrichSearchColumns = (searchColumns, schema) => {
|
||||||
let enrichedColumns = []
|
let enrichedColumns = []
|
||||||
const addType = column => {
|
searchColumns?.forEach(column => {
|
||||||
const schemaType = schema?.[column]?.type
|
const schemaType = schema?.[column]?.type
|
||||||
const componentType = schemaComponentMap[schemaType]
|
const componentType = schemaComponentMap[schemaType]
|
||||||
if (componentType) {
|
if (componentType) {
|
||||||
|
@ -84,51 +83,23 @@
|
||||||
componentType,
|
componentType,
|
||||||
type: schemaType,
|
type: schemaType,
|
||||||
})
|
})
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
})
|
||||||
}
|
return enrichedColumns.slice(0, 3)
|
||||||
for (let column of searchColumns || []) {
|
|
||||||
// if addType returns false, it didn't find one, look for SQL relationships
|
|
||||||
if (!addType(column) && column.includes(".")) {
|
|
||||||
const [tableName, linkColumn] = column.split(".")
|
|
||||||
for (let colSchema of Object.values(schema || {})) {
|
|
||||||
// found the related table
|
|
||||||
if (
|
|
||||||
colSchema.type === "link" &&
|
|
||||||
colSchema.tableId &&
|
|
||||||
colSchema.tableId.endsWith(tableName)
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const linkSchema = await fetchDatasourceSchema({
|
|
||||||
...dataSource,
|
|
||||||
tableId: colSchema.tableId,
|
|
||||||
})
|
|
||||||
if (linkSchema) {
|
|
||||||
schema[column] = linkSchema[linkColumn]
|
|
||||||
addType(column)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
// ignore the error, couldn't get table
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enrichedSearchColumns = enrichedColumns.slice(0, 3)
|
|
||||||
enrichedSearchColumnsLoaded = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the datasource schema so we can determine column types
|
// Load the datasource schema so we can determine column types
|
||||||
const fetchSchema = async dataSource => {
|
const fetchSchema = async dataSource => {
|
||||||
if (dataSource) {
|
if (dataSource) {
|
||||||
schema = await fetchDatasourceSchema(dataSource)
|
schema = await fetchDatasourceSchema(dataSource, {
|
||||||
|
enrichRelationships: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
schemaLoaded = true
|
schemaLoaded = true
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if schemaLoaded && enrichedSearchColumnsLoaded}
|
{#if schemaLoaded}
|
||||||
<Block>
|
<Block>
|
||||||
<div class={size} use:styleable={$component.styles}>
|
<div class={size} use:styleable={$component.styles}>
|
||||||
<BlockComponent type="form" bind:id={formId} props={{ dataSource }}>
|
<BlockComponent type="form" bind:id={formId} props={{ dataSource }}>
|
||||||
|
|
|
@ -67,7 +67,6 @@ export default class DataFetch {
|
||||||
this.getPage = this.getPage.bind(this)
|
this.getPage = this.getPage.bind(this)
|
||||||
this.getInitialData = this.getInitialData.bind(this)
|
this.getInitialData = this.getInitialData.bind(this)
|
||||||
this.determineFeatureFlags = this.determineFeatureFlags.bind(this)
|
this.determineFeatureFlags = this.determineFeatureFlags.bind(this)
|
||||||
this.enrichSchema = this.enrichSchema.bind(this)
|
|
||||||
this.refresh = this.refresh.bind(this)
|
this.refresh = this.refresh.bind(this)
|
||||||
this.update = this.update.bind(this)
|
this.update = this.update.bind(this)
|
||||||
this.hasNextPage = this.hasNextPage.bind(this)
|
this.hasNextPage = this.hasNextPage.bind(this)
|
||||||
|
@ -129,7 +128,7 @@ export default class DataFetch {
|
||||||
|
|
||||||
// Fetch and enrich schema
|
// Fetch and enrich schema
|
||||||
let schema = this.constructor.getSchema(datasource, definition)
|
let schema = this.constructor.getSchema(datasource, definition)
|
||||||
schema = this.enrichSchema(schema)
|
schema = DataFetch.enrichSchema(schema)
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -248,7 +247,7 @@ export default class DataFetch {
|
||||||
* @param schema the datasource schema
|
* @param schema the datasource schema
|
||||||
* @return {object} the enriched datasource schema
|
* @return {object} the enriched datasource schema
|
||||||
*/
|
*/
|
||||||
enrichSchema(schema) {
|
static enrichSchema(schema) {
|
||||||
if (schema == null) {
|
if (schema == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,19 @@ import RelationshipFetch from "./fetch/RelationshipFetch.js"
|
||||||
import NestedProviderFetch from "./fetch/NestedProviderFetch.js"
|
import NestedProviderFetch from "./fetch/NestedProviderFetch.js"
|
||||||
import FieldFetch from "./fetch/FieldFetch.js"
|
import FieldFetch from "./fetch/FieldFetch.js"
|
||||||
import JSONArrayFetch from "./fetch/JSONArrayFetch.js"
|
import JSONArrayFetch from "./fetch/JSONArrayFetch.js"
|
||||||
|
import DataFetch from "./fetch/DataFetch.js"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the schema of any kind of datasource.
|
* Fetches the schema of any kind of datasource.
|
||||||
* All datasource fetch classes implement their own functionality to get the
|
* All datasource fetch classes implement their own functionality to get the
|
||||||
* schema of a datasource of their respective types.
|
* schema of a datasource of their respective types.
|
||||||
|
* @param datasource the datasource to fetch the schema for
|
||||||
|
* @param options options for enriching the schema
|
||||||
*/
|
*/
|
||||||
export const fetchDatasourceSchema = async datasource => {
|
export const fetchDatasourceSchema = async (
|
||||||
|
datasource,
|
||||||
|
options = { enrichRelationships: false }
|
||||||
|
) => {
|
||||||
const handler = {
|
const handler = {
|
||||||
table: TableFetch,
|
table: TableFetch,
|
||||||
view: ViewFetch,
|
view: ViewFetch,
|
||||||
|
@ -28,7 +34,7 @@ export const fetchDatasourceSchema = async datasource => {
|
||||||
|
|
||||||
// Get the datasource definition and then schema
|
// Get the datasource definition and then schema
|
||||||
const definition = await handler.getDefinition(datasource)
|
const definition = await handler.getDefinition(datasource)
|
||||||
const schema = handler.getSchema(datasource, definition)
|
let schema = handler.getSchema(datasource, definition)
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -49,5 +55,28 @@ export const fetchDatasourceSchema = async datasource => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return { ...schema, ...jsonAdditions }
|
schema = { ...schema, ...jsonAdditions }
|
||||||
|
|
||||||
|
// Check for any relationship fields if required
|
||||||
|
if (options?.enrichRelationships) {
|
||||||
|
let relationshipAdditions = {}
|
||||||
|
for (let fieldKey of Object.keys(schema)) {
|
||||||
|
const fieldSchema = schema[fieldKey]
|
||||||
|
if (fieldSchema?.type === "link") {
|
||||||
|
const linkSchema = await fetchDatasourceSchema({
|
||||||
|
type: "table",
|
||||||
|
tableId: fieldSchema?.tableId,
|
||||||
|
})
|
||||||
|
Object.keys(linkSchema || {}).forEach(linkKey => {
|
||||||
|
relationshipAdditions[`${fieldKey}.${linkKey}`] = {
|
||||||
|
type: linkSchema[linkKey].type,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
schema = { ...schema, ...relationshipAdditions }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure schema structure is correct
|
||||||
|
return DataFetch.enrichSchema(schema)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue