wip
This commit is contained in:
parent
cd36056124
commit
293a969f5f
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import ExplanationModal from './ExplanationModal/index.svelte'
|
import ExplanationModal from './ExplanationModal/index.svelte'
|
||||||
import { warnings, errors } from "./validator";
|
import { messages } from "./columnInfo";
|
||||||
import { Column, Support, NotRequired, StringNumber } from "./lines"
|
import { Column, Support, NotRequired, StringNumber } from "./lines"
|
||||||
import subjects from './subjects';
|
import subjects from './subjects';
|
||||||
|
|
||||||
|
@ -30,23 +30,23 @@
|
||||||
class="tooltipContents"
|
class="tooltipContents"
|
||||||
>
|
>
|
||||||
|
|
||||||
<Column
|
<Column
|
||||||
{columnName}
|
{columnName}
|
||||||
{columnIcon}
|
{columnIcon}
|
||||||
{columnType}
|
{columnType}
|
||||||
{tableHref}
|
{tableHref}
|
||||||
{setExplanationSubject}
|
{setExplanationSubject}
|
||||||
/>
|
/>
|
||||||
<Support
|
<Support
|
||||||
{support}
|
support={support.support}
|
||||||
{setExplanationSubject}
|
{setExplanationSubject}
|
||||||
/>
|
/>
|
||||||
{#if support?.warnings?.includes(warnings.stringAsNumber)}
|
{#if support?.messages?.includes(messages.stringAsNumber)}
|
||||||
<StringNumber
|
<StringNumber
|
||||||
{setExplanationSubject}
|
{setExplanationSubject}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{#if support?.warnings?.includes(warnings.notRequired)}
|
{#if support?.messages?.includes(messages.notRequired)}
|
||||||
<NotRequired
|
<NotRequired
|
||||||
{setExplanationSubject}
|
{setExplanationSubject}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
import { capitalize } from 'lodash';
|
||||||
|
|
||||||
|
export const messages = {
|
||||||
|
jsonPrimitivesOnly: Symbol("column-info-json-primitives-only"),
|
||||||
|
stringAsNumber: Symbol("column-info-string-as-number"),
|
||||||
|
chartDatetime: Symbol("column-info-chart-datetime"),
|
||||||
|
notRequired: Symbol("column-info-not-required"),
|
||||||
|
contextError: Symbol("column-info-context-error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
export const support = {
|
||||||
|
unsupported: Symbol("column-info-unsupported"),
|
||||||
|
partialSupport: Symbol("column-info-partialSupport"),
|
||||||
|
supported: Symbol("column-info-supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getSupport = (type, columnInfo) => {
|
||||||
|
if (!columnInfo?.typeSupport) {
|
||||||
|
return support.supported
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnInfo?.typeSupport?.supported?.find(mapping => mapping === type || mapping?.type === type)) {
|
||||||
|
return support.supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnInfo?.typeSupport?.partialSupport?.find(mapping => mapping === type || mapping?.type === type)) {
|
||||||
|
return support.partialSupport;
|
||||||
|
}
|
||||||
|
|
||||||
|
return support.unsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSupportMessage = (type, columnInfo) => {
|
||||||
|
if (!columnInfo?.typeSupport) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const supported = columnInfo?.typeSupport?.supported?.find(mapping => mapping?.type === type)
|
||||||
|
if (supported) {
|
||||||
|
return messages[supported?.message]
|
||||||
|
}
|
||||||
|
|
||||||
|
const partialSupport = columnInfo?.typeSupport?.partialSupport?.find(mapping => mapping?.type === type)
|
||||||
|
if (partialSupport) {
|
||||||
|
return messages[partialSupport?.message]
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsupported = columnInfo?.typeSupport?.unsupported?.find(mapping => mapping?.type === type)
|
||||||
|
if (unsupported) {
|
||||||
|
return messages[unsupported?.message]
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getColumnInfoMessagesAndSupport = (fieldSchema, columnInfo) => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
const columnInfoMessagesAndSupport = {
|
||||||
|
support: getSupport(fieldSchema.type, columnInfo),
|
||||||
|
messages: [getSupportMessage(fieldSchema.type, columnInfo)],
|
||||||
|
}
|
||||||
|
|
||||||
|
const isRequired = fieldSchema?.constraints?.presence?.allowEmpty === false
|
||||||
|
if (!isRequired) {
|
||||||
|
columnInfoMessagesAndSupport.messages.push(messages.notRequired);
|
||||||
|
}
|
||||||
|
|
||||||
|
return columnInfoMessagesAndSupport;
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
support: support.partialSupport,
|
||||||
|
messages: [messages.contextError]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,2 @@
|
||||||
export { default as FieldContext } from "./FieldContext.svelte"
|
export { default as FieldContext } from "./FieldContext.svelte"
|
||||||
export * from "./validator"
|
export * from "./columnInfo"
|
||||||
|
|
|
@ -1,18 +1,53 @@
|
||||||
<script>
|
<script>
|
||||||
import { Line, InfoWord, DocumentationLink, Space, Text, Period } from "../typography"
|
import { Line, InfoWord, DocumentationLink, Space, Text, Period } from "../typography"
|
||||||
import subjects from '../subjects'
|
import subjects from '../subjects'
|
||||||
|
import * as columnInfo from '../columnInfo'
|
||||||
|
|
||||||
export let setExplanationSubject
|
export let setExplanationSubject
|
||||||
export let support
|
export let support
|
||||||
|
|
||||||
|
const getIcon = (support) => {
|
||||||
|
if (support === columnInfo.support.unsupported) {
|
||||||
|
return "Alert"
|
||||||
|
} else if (support === columnInfo.support.supported) {
|
||||||
|
return "CheckmarkCircle"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "AlertCheck"
|
||||||
|
}
|
||||||
|
|
||||||
|
const getColor = (support) => {
|
||||||
|
if (support === columnInfo.support.unsupported) {
|
||||||
|
return "var(--red)"
|
||||||
|
} else if (support === columnInfo.support.supported) {
|
||||||
|
return "var(--green)"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "var(--yellow)"
|
||||||
|
}
|
||||||
|
|
||||||
|
const getText = (support) => {
|
||||||
|
if (support === columnInfo.support.unsupported) {
|
||||||
|
return "Not compatible"
|
||||||
|
} else if (support === columnInfo.support.supported) {
|
||||||
|
return "Compatible"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Partially compatible"
|
||||||
|
}
|
||||||
|
|
||||||
|
$: icon = getIcon(support);
|
||||||
|
$: color = getColor(support);
|
||||||
|
$: text = getText(support);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Line>
|
<Line>
|
||||||
<InfoWord
|
<InfoWord
|
||||||
on:mouseenter={() => setExplanationSubject(subjects.support)}
|
on:mouseenter={() => setExplanationSubject(subjects.support)}
|
||||||
on:mouseleave={() => setExplanationSubject(subjects.none)}
|
on:mouseleave={() => setExplanationSubject(subjects.none)}
|
||||||
icon={support.icon}
|
{icon}
|
||||||
color={support.iconColor}
|
{color}
|
||||||
text={support.text}
|
{text}
|
||||||
/>
|
/>
|
||||||
<Space />
|
<Space />
|
||||||
<Text>with</Text>
|
<Text>with</Text>
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
import { capitalize } from 'lodash';
|
|
||||||
|
|
||||||
export const errors = {
|
|
||||||
general: Symbol("values-validator-general"),
|
|
||||||
jsonPrimitivesOnly: Symbol("values-validator-json-primitives-only"),
|
|
||||||
}
|
|
||||||
|
|
||||||
export const warnings = {
|
|
||||||
stringAsNumber: Symbol("values-validator-string-as-number"),
|
|
||||||
chartDatetime: Symbol("values-validator-chart-datetime"),
|
|
||||||
notRequired: Symbol("values-validator-not-required"),
|
|
||||||
}
|
|
||||||
|
|
||||||
export const constants = {
|
|
||||||
unsupported: Symbol("values-validator-unsupported"),
|
|
||||||
partialSupport: Symbol("values-validator-partialSupport"),
|
|
||||||
supported: Symbol("values-validator-supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
export const validate = (fieldSchema) => {
|
|
||||||
try {
|
|
||||||
const response = {
|
|
||||||
level: null,
|
|
||||||
warnings: [],
|
|
||||||
errors: [],
|
|
||||||
text: "",
|
|
||||||
icon: "",
|
|
||||||
iconColor: ""
|
|
||||||
}
|
|
||||||
const generalUnsupportedFields = ["array", "attachment", "barcodeqr", "link", "bb_reference"]
|
|
||||||
if (generalUnsupportedFields.includes(fieldSchema.type)) {
|
|
||||||
response.errors.push(errors.general)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldSchema.type === "json") {
|
|
||||||
response.errors.push(errors.jsonPrimitivesOnly)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldSchema.type === "string") {
|
|
||||||
response.warnings.push(warnings.stringAsNumber)
|
|
||||||
}
|
|
||||||
if (fieldSchema.type === "datetime") {
|
|
||||||
response.warnings.push(warnings.chartDatetime);
|
|
||||||
//"This column can be used as an input for a chart, but it may be parsed differently depending on which is used.
|
|
||||||
}
|
|
||||||
|
|
||||||
const isRequired = fieldSchema?.constraints?.presence?.allowEmpty === false
|
|
||||||
if (!isRequired) {
|
|
||||||
response.warnings.push(warnings.notRequired);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.errors.length > 0) {
|
|
||||||
response.level = constants.unsupported
|
|
||||||
response.text = "Not compatible"
|
|
||||||
response.icon = "Alert"
|
|
||||||
response.iconColor = "var(--red)"
|
|
||||||
} else if (response.warnings.length > 0) {
|
|
||||||
response.level = constants.partialSupport
|
|
||||||
response.text = "Partially compatible"
|
|
||||||
response.icon = "AlertCheck"
|
|
||||||
response.iconColor = "var(--yellow)"
|
|
||||||
} else {
|
|
||||||
response.level = constants.supported
|
|
||||||
response.text = "Compatible"
|
|
||||||
response.icon = "CheckmarkCircle"
|
|
||||||
response.iconColor = "var(--green)"
|
|
||||||
}
|
|
||||||
|
|
||||||
return response
|
|
||||||
} catch (e) {
|
|
||||||
return {
|
|
||||||
level: constants.partialSupport,
|
|
||||||
warnings: [],
|
|
||||||
errors: [],
|
|
||||||
text: "Partially compatible",
|
|
||||||
icon: "AlertCheck",
|
|
||||||
iconColor: "var(--yellow)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding"
|
import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding"
|
||||||
import { selectedScreen } from "stores/builder"
|
import { selectedScreen } from "stores/builder"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { FieldContext, validate } from './FieldContext'
|
import { FieldContext, getColumnInfoMessagesAndSupport } from './FieldContext'
|
||||||
import { debounce } from "lodash"
|
import { debounce } from "lodash"
|
||||||
import { goto, params } from "@roxi/routify"
|
import { goto, params } from "@roxi/routify"
|
||||||
import { Constants } from "@budibase/frontend-core"
|
import { Constants } from "@budibase/frontend-core"
|
||||||
|
@ -12,21 +12,21 @@
|
||||||
export let componentInstance = {}
|
export let componentInstance = {}
|
||||||
export let value = ""
|
export let value = ""
|
||||||
export let placeholder
|
export let placeholder
|
||||||
export let columnContext
|
export let columnInfo
|
||||||
|
|
||||||
let contextTooltipAnchor = null
|
let contextTooltipAnchor = null
|
||||||
let currentOption = null
|
let currentOption = null
|
||||||
let previousOption = null
|
let previousOption = null
|
||||||
let contextTooltipVisible = false
|
let contextTooltipVisible = false
|
||||||
|
|
||||||
const getFieldSupport = (schema, columnContext) => {
|
const getFieldSupport = (schema, columnInfo) => {
|
||||||
if (!columnContext) {
|
if (columnInfo == null) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldSupport = {}
|
const fieldSupport = {}
|
||||||
Object.entries(schema || {}).forEach(([key, value]) => {
|
Object.entries(schema || {}).forEach(([key, value]) => {
|
||||||
fieldSupport[key] = validate(value)
|
fieldSupport[key] = getColumnInfoMessagesAndSupport(value)
|
||||||
})
|
})
|
||||||
|
|
||||||
return fieldSupport
|
return fieldSupport
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
||||||
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
||||||
$: fieldSupport = getFieldSupport(schema, columnContext);
|
$: fieldSupport = getFieldSupport(schema, columnInfo);
|
||||||
$: options = Object.keys(schema || {})
|
$: options = Object.keys(schema || {})
|
||||||
$: boundValue = getValidValue(value, options)
|
$: boundValue = getValidValue(value, options)
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
{onOptionMouseleave}
|
{onOptionMouseleave}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if columnContext}
|
{#if columnInfo}
|
||||||
<ContextTooltip
|
<ContextTooltip
|
||||||
visible={contextTooltipVisible}
|
visible={contextTooltipVisible}
|
||||||
anchor={contextTooltipAnchor}
|
anchor={contextTooltipAnchor}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
componentStore,
|
componentStore,
|
||||||
} from "stores/builder"
|
} from "stores/builder"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { FieldContext, validate } from './FieldContext'
|
import { FieldContext, getColumnInfoMessagesAndSupport } from './FieldContext'
|
||||||
import { FIELDS } from 'constants/backend'
|
import { FIELDS } from 'constants/backend'
|
||||||
import { goto, params } from "@roxi/routify"
|
import { goto, params } from "@roxi/routify"
|
||||||
import { debounce } from "lodash"
|
import { debounce } from "lodash"
|
||||||
|
@ -14,8 +14,7 @@
|
||||||
export let componentInstance = {}
|
export let componentInstance = {}
|
||||||
export let value = ""
|
export let value = ""
|
||||||
export let placeholder
|
export let placeholder
|
||||||
export let columnContext
|
export let columnInfo
|
||||||
export let valueTypes
|
|
||||||
|
|
||||||
let contextTooltipAnchor = null
|
let contextTooltipAnchor = null
|
||||||
let currentOption = null
|
let currentOption = null
|
||||||
|
@ -26,14 +25,15 @@
|
||||||
componentInstance?._component
|
componentInstance?._component
|
||||||
)
|
)
|
||||||
|
|
||||||
const getFieldSupport = (schema, columnContext) => {
|
const getFieldSupport = (schema, columnInfo) => {
|
||||||
if (!columnContext) {
|
if (columnInfo == null) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldSupport = {}
|
const fieldSupport = {}
|
||||||
Object.entries(schema || {}).forEach(([key, value]) => {
|
Object.entries(schema || {}).forEach(([key, value]) => {
|
||||||
fieldSupport[key] = validate(value)
|
// super TODO: nicer to do this at the component level jit and store each value seperately so i don't have this long ass name???
|
||||||
|
fieldSupport[key] = getColumnInfoMessagesAndSupport(value, columnInfo)
|
||||||
})
|
})
|
||||||
|
|
||||||
return fieldSupport
|
return fieldSupport
|
||||||
|
@ -43,9 +43,11 @@
|
||||||
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
||||||
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
||||||
$: options = Object.keys(schema || {})
|
$: options = Object.keys(schema || {})
|
||||||
$: fieldSupport = getFieldSupport(schema, columnContext);
|
$: fieldSupport = getFieldSupport(schema, columnInfo);
|
||||||
$: boundValue = getValidOptions(value, options)
|
$: boundValue = getValidOptions(value, options)
|
||||||
|
|
||||||
|
$: console.log(fieldSupport)
|
||||||
|
|
||||||
|
|
||||||
const getValidOptions = (selectedOptions, allOptions) => {
|
const getValidOptions = (selectedOptions, allOptions) => {
|
||||||
// Fix the hardcoded default string value
|
// Fix the hardcoded default string value
|
||||||
|
@ -133,7 +135,7 @@
|
||||||
{onOptionMouseleave}
|
{onOptionMouseleave}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if columnContext}
|
{#if columnInfo}
|
||||||
<ContextTooltip
|
<ContextTooltip
|
||||||
visible={contextTooltipVisible}
|
visible={contextTooltipVisible}
|
||||||
anchor={contextTooltipAnchor}
|
anchor={contextTooltipAnchor}
|
||||||
|
|
|
@ -193,7 +193,7 @@
|
||||||
max: setting.max ?? null,
|
max: setting.max ?? null,
|
||||||
|
|
||||||
// Field select settings
|
// Field select settings
|
||||||
columnContext: setting.columnContext,
|
columnInfo: setting.columnInfo,
|
||||||
valueTypes: setting.valueTypes
|
valueTypes: setting.valueTypes
|
||||||
}}
|
}}
|
||||||
{bindings}
|
{bindings}
|
||||||
|
|
|
@ -1634,8 +1634,18 @@
|
||||||
"label": "Data columns",
|
"label": "Data columns",
|
||||||
"key": "valueColumns",
|
"key": "valueColumns",
|
||||||
"dependsOn": "dataProvider",
|
"dependsOn": "dataProvider",
|
||||||
"valueTypes": ["number"],
|
"columnInfo": {
|
||||||
"columnContext": true,
|
"typeSupport": {
|
||||||
|
"supported": ["number", "boolean"],
|
||||||
|
"partialSupport": [
|
||||||
|
{ "type": "string", "message": "stringAsNumber" },
|
||||||
|
{ "type": "datetime", "message": "datetimeChart"}
|
||||||
|
],
|
||||||
|
"unsupported": [
|
||||||
|
{ "type": "json", "message": "jsonPrimitivesOnly" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue