refactor validation

This commit is contained in:
Gerard Burns 2024-04-08 13:05:15 +01:00
parent 01b5c5d69a
commit dc903a43f2
3 changed files with 58 additions and 187 deletions

View File

@ -7,20 +7,15 @@
import InfoWord from './InfoWord.svelte'
import DocumentationLink from './DocumentationLink.svelte'
import ExplanationModal from './ExplanationModal/index.svelte'
import { warnings, errors } from "../../fieldValidator";
export let supportLevelClass = ''
export let supportLevelIconColor = ""
export let supportLevelIcon = ""
export let supportLevelIconTooltip = ""
export let supportLevelText = ""
export let support = {}
export let columnIcon
export let columnType
export let columnName
export let explanationModal = false
export let errors = []
export let warnings = []
export let tableHref = () => {}
export let schema
@ -57,12 +52,12 @@
let explanationModalSubject = null
const handleMouseenter = (option, idx) => {
const handleMouseenter = (option) => {
explanationModalSubject = option;
root = root
}
const handleMouseleave = (option) => {
const handleMouseleave = () => {
explanationModalSubject = null;
}
@ -70,7 +65,7 @@
<div
bind:this={root}
class={`tooltipContents ${supportLevelClass}`}
class="tooltipContents"
>
<div class="line">
@ -91,14 +86,14 @@
/>
<span class="period">.</span>
</div>
<div class={`line ${supportLevelClass}`}>
<div class="line">
<span class="bullet"></span>
<InfoWord
on:mouseenter={() => handleMouseenter("support")}
on:mouseleave={() => handleMouseleave("support")}
icon={supportLevelIcon}
color={supportLevelIconColor}
text={supportLevelText}
icon={support.icon}
color={support.iconColor}
text={support.text}
/>
<span class="space" />
<span class="text">with</span>
@ -110,7 +105,7 @@
/>
<span class="period">.</span>
</div>
{#if warnings.includes("string number warning")}
{#if support?.warnings?.includes(warnings.stringAsNumber)}
<div class={`line`}>
<span class="bullet"></span>
<span class="text">Any</span>
@ -118,7 +113,7 @@
<InfoWord
on:mouseenter={() => handleMouseenter("stringsAndNumbers")}
on:mouseleave={() => handleMouseleave("stringsAndNumbers")}
text="non-number-values"
text="non-number values"
/>
<span class="space" />
<span class="text">
@ -127,7 +122,7 @@
<span class="period">.</span>
</div>
{/if}
{#if warnings.includes("optional warning")}
{#if support?.warnings?.includes(warnings.notRequired)}
<div class={`line`}>
<span class="bullet"></span>
<span class="text">No</span>
@ -152,11 +147,14 @@
{/if}
</div>
<ExplanationModal
anchor={root}
{schema}
subject={explanationModalSubject}
/>
{#if explanationModal}
<ExplanationModal
anchor={root}
{schema}
subject={explanationModalSubject}
/>
{/if}
<style>
.text {

View File

@ -14,11 +14,6 @@
export let placeholder
export let fieldValidator
$: {
console.log($params)
}
let contextTooltipId = 0;
let contextTooltipAnchor = null
let currentOption = null
let previousOption = null
@ -127,51 +122,6 @@
return true
}
const getSupportLevel = (optionKey) => {
const level = fieldSupport[optionKey]?.level;
if (level === validatorConstants.unsupported) {
return {
class: "supportLevelUnsupported",
iconColor: "var(--red)",
icon: "Alert",
iconTooltip: fieldSupport[optionKey]?.message,
text: "Not compatible"
}
}
if (level === validatorConstants.partialSupport) {
return {
class: "supportLevelPartialSupport",
iconColor: "var(--yellow)",
icon: "AlertCheck",
iconTooltip: fieldSupport[optionKey]?.message,
text: "Partially compatible"
}
}
if (level === validatorConstants.supported) {
return {
class: "supportLevelSupported",
iconColor: "var(--green)",
icon: "CheckmarkCircle",
iconTooltip: fieldSupport[optionKey]?.message,
text: "Compatible"
}
}
return {
class: "supportLevelPartialSupport",
iconColor: "var(--yellow)",
icon: "AlertCheck",
iconTooltip: "",
text: "Partially Compatible"
}
}
$: currentOptionSupport = getSupportLevel(currentOption)
$: previousOptionSupport = getSupportLevel(previousOption)
const updateTooltip = debounce((e, option) => {
if (option == null) {
contextTooltipVisible = false;
@ -180,8 +130,6 @@
previousOption = currentOption;
currentOption = option;
contextTooltipVisible = true;
currentOptionSupport = getSupportLevel(currentOption)
previousOptionSupport = getSupportLevel(previousOption)
}
}, 200);
@ -211,114 +159,23 @@
offset={20}
>
<ChartFieldContext
sidecar
tableHref={`/builder/app/${$params.application}/data/table/${datasource.tableId}`}
explanationModal
tableHref={`/builder/app/${$params.application}/data/table/${datasource?.tableId}`}
schema={schema[currentOption]}
support={fieldSupport[currentOption]}
supportLevelClass={currentOptionSupport.class}
supportLevelIcon={currentOptionSupport.icon}
supportLevelIconColor={currentOptionSupport.iconColor}
supportLevelIconTooltip={currentOptionSupport.iconTooltip}
supportLevelText={currentOptionSupport.text}
columnIcon={getOptionIcon(currentOption)}
columnName={currentOption}
columnType={getOptionIconTooltip(currentOption)}
errors={fieldSupport[currentOption]?.errors}
warnings={fieldSupport[currentOption]?.warnings}
/>
<ChartFieldContext
slot="previous"
schema={schema[previousOption]}
support={fieldSupport[previousOption]}
supportLevelClass={previousOptionSupport.class}
supportLevelIcon={previousOptionSupport.icon}
supportLevelIconColor={previousOptionSupport.iconColor}
supportLevelIconTooltip={previousOptionSupport.iconTooltip}
supportLevelText={previousOptionSupport.text}
columnIcon={getOptionIcon(previousOption)}
columnName={previousOption}
columnType={getOptionIconTooltip(previousOption)}
errors={fieldSupport[previousOption]?.errors}
warnings={fieldSupport[previousOption]?.warnings}
/>
</ContextTooltip>
<style>
.tooltipContents {
max-width: 400px;
background-color: var(--spectrum-global-color-gray-200);
display: block;
padding: 0 0 12px 0 ;
border-radius: 5px;
box-sizing: border-box;
}
.tooltipContents.supportLevelUnsupported {
background-color: var(--red);
color: var(--ink)
}
.tooltipContents.supportLevelPartialSupport {
background-color: var(--yellow);
color: var(--ink)
}
.tooltipContents.supportLevelSupported {
background-color: var(--green);
color: var(--ink)
}
.contextTooltipHeader {
background-color: var(--background-alt);
color: var(--ink);
display: flex;
align-items: center;
height: var(--spectrum-alias-item-height-m);
padding: 0px var(--spectrum-alias-item-padding-m);
border-width: var(--spectrum-actionbutton-border-size);
border-radius: var(--spectrum-alias-border-radius-regular);
border: 1px solid
var(
--spectrum-actionbutton-m-border-color,
var(--spectrum-alias-border-color)
);
}
.contextTooltipContent {
padding: 0px 12px;
color: black;
}
.contextTooltipHeader :global(svg) {
margin-right: 5px;
}
.contextTooltipHeader :global(span) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.supportLevel {
display: flex;
align-items: center;
height: var(--spectrum-alias-item-height-m);
padding: 0px var(--spectrum-alias-item-padding-m);
margin-bottom: 12px;
color: black;
}
.supportLevel :global(svg) {
margin-right: 5px;
}
.supportLevel.supportLevelUnsupported {
background-color: var(--red-light)
}
.supportLevel.supportLevelPartialSupport {
background-color: var(--yellow-light)
}
.supportLevel.supportLevelSupported {
background-color: var(--green-light)
}
</style>

View File

@ -1,8 +1,18 @@
import { capitalize } from 'lodash';
export const errors = {
// fail without explanation
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 = {
warning: Symbol("values-validator-warning"),
error: Symbol("values-validator-error"),
unsupported: Symbol("values-validator-unsupported"),
partialSupport: Symbol("values-validator-partialSupport"),
supported: Symbol("values-validator-supported")
@ -13,54 +23,60 @@ export const validators = {
try {
const response = {
level: null,
message: null,
warnings: [],
errors: []
errors: [],
text: "",
icon: "",
iconColor: ""
}
const generalUnsupportedFields = ["array", "attachment", "barcodeqr", "link", "bb_reference"]
if (generalUnsupportedFields.includes(fieldSchema.type)) {
response.errors.push('This column can not be used a chart input.')
response.errors.push(errors.general)
}
if (fieldSchema.type === "json") {
response.errors.push(`This column can not be used as a chart input, but individual properties of a JSON object can be be used if supported.`)
response.errors.push(errors.jsonPrimitivesOnly)
}
if (fieldSchema.type === "string") {
response.warnings.push(
"string number warning")
response.warnings.push(warnings.stringAsNumber)
}
if (fieldSchema.type === "datetime") {
response.warnings.push(
"This column can be used as an input for a chart, but it may be parsed differently depending on which is used.")
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(
"optional warning")
response.warnings.push(warnings.notRequired);
}
if (response.errors.length > 0) {
response.level = constants.unsupported
response.message = "This column can not be used as a chart input."
response.text = "Not compatible"
response.icon = "Alert"
response.iconColor = "var(--red)"
} else if (response.warnings.length > 0) {
response.level = constants.partialSupport
response.message = "This column can be used as a chart input, but certain values may cause issues."
response.text = "Partially compatible"
response.icon = "AlertCheck"
response.iconColor = "var(--yellow)"
} else {
response.level = constants.supported
response.message = "This column can be used as a chart input."
response.text = "Compatible"
response.icon = "CheckmarkCircle"
response.iconColor = "var(--green)"
}
return response
} catch (e) {
console.log(e)
return {
level: constants.partialSupport,
message: "There was an issue validating this field, it may not be fully supported for use with charts.",
warnings: [],
errors: []
errors: [],
text: "Partially compatible",
icon: "AlertCheck",
iconColor: "var(--yellow)"
}
}
}