This commit is contained in:
Gerard Burns 2024-04-11 10:56:08 +01:00
parent cd36056124
commit 293a969f5f
9 changed files with 160 additions and 116 deletions

View File

@ -1,6 +1,6 @@
<script>
import ExplanationModal from './ExplanationModal/index.svelte'
import { warnings, errors } from "./validator";
import { messages } from "./columnInfo";
import { Column, Support, NotRequired, StringNumber } from "./lines"
import subjects from './subjects';
@ -30,23 +30,23 @@
class="tooltipContents"
>
<Column
<Column
{columnName}
{columnIcon}
{columnType}
{tableHref}
{setExplanationSubject}
/>
<Support
{support}
/>
<Support
support={support.support}
{setExplanationSubject}
/>
{#if support?.warnings?.includes(warnings.stringAsNumber)}
/>
{#if support?.messages?.includes(messages.stringAsNumber)}
<StringNumber
{setExplanationSubject}
/>
{/if}
{#if support?.warnings?.includes(warnings.notRequired)}
{#if support?.messages?.includes(messages.notRequired)}
<NotRequired
{setExplanationSubject}
/>

View File

@ -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]
}
}
}

View File

@ -1,2 +1,2 @@
export { default as FieldContext } from "./FieldContext.svelte"
export * from "./validator"
export * from "./columnInfo"

View File

@ -1,18 +1,53 @@
<script>
import { Line, InfoWord, DocumentationLink, Space, Text, Period } from "../typography"
import subjects from '../subjects'
import * as columnInfo from '../columnInfo'
export let setExplanationSubject
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>
<Line>
<InfoWord
on:mouseenter={() => setExplanationSubject(subjects.support)}
on:mouseleave={() => setExplanationSubject(subjects.none)}
icon={support.icon}
color={support.iconColor}
text={support.text}
{icon}
{color}
{text}
/>
<Space />
<Text>with</Text>

View File

@ -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)"
}
}
}

View File

@ -3,7 +3,7 @@
import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding"
import { selectedScreen } from "stores/builder"
import { createEventDispatcher } from "svelte"
import { FieldContext, validate } from './FieldContext'
import { FieldContext, getColumnInfoMessagesAndSupport } from './FieldContext'
import { debounce } from "lodash"
import { goto, params } from "@roxi/routify"
import { Constants } from "@budibase/frontend-core"
@ -12,21 +12,21 @@
export let componentInstance = {}
export let value = ""
export let placeholder
export let columnContext
export let columnInfo
let contextTooltipAnchor = null
let currentOption = null
let previousOption = null
let contextTooltipVisible = false
const getFieldSupport = (schema, columnContext) => {
if (!columnContext) {
const getFieldSupport = (schema, columnInfo) => {
if (columnInfo == null) {
return {}
}
const fieldSupport = {}
Object.entries(schema || {}).forEach(([key, value]) => {
fieldSupport[key] = validate(value)
fieldSupport[key] = getColumnInfoMessagesAndSupport(value)
})
return fieldSupport
@ -35,7 +35,7 @@
const dispatch = createEventDispatcher()
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
$: fieldSupport = getFieldSupport(schema, columnContext);
$: fieldSupport = getFieldSupport(schema, columnInfo);
$: options = Object.keys(schema || {})
$: boundValue = getValidValue(value, options)
@ -117,7 +117,7 @@
{onOptionMouseleave}
/>
{#if columnContext}
{#if columnInfo}
<ContextTooltip
visible={contextTooltipVisible}
anchor={contextTooltipAnchor}

View File

@ -5,7 +5,7 @@
componentStore,
} from "stores/builder"
import { createEventDispatcher } from "svelte"
import { FieldContext, validate } from './FieldContext'
import { FieldContext, getColumnInfoMessagesAndSupport } from './FieldContext'
import { FIELDS } from 'constants/backend'
import { goto, params } from "@roxi/routify"
import { debounce } from "lodash"
@ -14,8 +14,7 @@
export let componentInstance = {}
export let value = ""
export let placeholder
export let columnContext
export let valueTypes
export let columnInfo
let contextTooltipAnchor = null
let currentOption = null
@ -26,14 +25,15 @@
componentInstance?._component
)
const getFieldSupport = (schema, columnContext) => {
if (!columnContext) {
const getFieldSupport = (schema, columnInfo) => {
if (columnInfo == null) {
return {}
}
const fieldSupport = {}
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
@ -43,9 +43,11 @@
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
$: options = Object.keys(schema || {})
$: fieldSupport = getFieldSupport(schema, columnContext);
$: fieldSupport = getFieldSupport(schema, columnInfo);
$: boundValue = getValidOptions(value, options)
$: console.log(fieldSupport)
const getValidOptions = (selectedOptions, allOptions) => {
// Fix the hardcoded default string value
@ -133,7 +135,7 @@
{onOptionMouseleave}
/>
{#if columnContext}
{#if columnInfo}
<ContextTooltip
visible={contextTooltipVisible}
anchor={contextTooltipAnchor}

View File

@ -193,7 +193,7 @@
max: setting.max ?? null,
// Field select settings
columnContext: setting.columnContext,
columnInfo: setting.columnInfo,
valueTypes: setting.valueTypes
}}
{bindings}

View File

@ -1634,8 +1634,18 @@
"label": "Data columns",
"key": "valueColumns",
"dependsOn": "dataProvider",
"valueTypes": ["number"],
"columnContext": true,
"columnInfo": {
"typeSupport": {
"supported": ["number", "boolean"],
"partialSupport": [
{ "type": "string", "message": "stringAsNumber" },
{ "type": "datetime", "message": "datetimeChart"}
],
"unsupported": [
{ "type": "json", "message": "jsonPrimitivesOnly" }
]
}
},
"required": true
},
{