refactor validation
This commit is contained in:
parent
01b5c5d69a
commit
dc903a43f2
|
@ -7,20 +7,15 @@
|
||||||
import InfoWord from './InfoWord.svelte'
|
import InfoWord from './InfoWord.svelte'
|
||||||
import DocumentationLink from './DocumentationLink.svelte'
|
import DocumentationLink from './DocumentationLink.svelte'
|
||||||
import ExplanationModal from './ExplanationModal/index.svelte'
|
import ExplanationModal from './ExplanationModal/index.svelte'
|
||||||
|
import { warnings, errors } from "../../fieldValidator";
|
||||||
|
|
||||||
export let supportLevelClass = ''
|
export let support = {}
|
||||||
export let supportLevelIconColor = ""
|
|
||||||
export let supportLevelIcon = ""
|
|
||||||
export let supportLevelIconTooltip = ""
|
|
||||||
export let supportLevelText = ""
|
|
||||||
|
|
||||||
export let columnIcon
|
export let columnIcon
|
||||||
export let columnType
|
export let columnType
|
||||||
export let columnName
|
export let columnName
|
||||||
export let explanationModal = false
|
export let explanationModal = false
|
||||||
|
|
||||||
export let errors = []
|
|
||||||
export let warnings = []
|
|
||||||
export let tableHref = () => {}
|
export let tableHref = () => {}
|
||||||
|
|
||||||
export let schema
|
export let schema
|
||||||
|
@ -57,12 +52,12 @@
|
||||||
|
|
||||||
let explanationModalSubject = null
|
let explanationModalSubject = null
|
||||||
|
|
||||||
const handleMouseenter = (option, idx) => {
|
const handleMouseenter = (option) => {
|
||||||
explanationModalSubject = option;
|
explanationModalSubject = option;
|
||||||
root = root
|
root = root
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMouseleave = (option) => {
|
const handleMouseleave = () => {
|
||||||
explanationModalSubject = null;
|
explanationModalSubject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +65,7 @@
|
||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={root}
|
bind:this={root}
|
||||||
class={`tooltipContents ${supportLevelClass}`}
|
class="tooltipContents"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="line">
|
<div class="line">
|
||||||
|
@ -91,14 +86,14 @@
|
||||||
/>
|
/>
|
||||||
<span class="period">.</span>
|
<span class="period">.</span>
|
||||||
</div>
|
</div>
|
||||||
<div class={`line ${supportLevelClass}`}>
|
<div class="line">
|
||||||
<span class="bullet">•</span>
|
<span class="bullet">•</span>
|
||||||
<InfoWord
|
<InfoWord
|
||||||
on:mouseenter={() => handleMouseenter("support")}
|
on:mouseenter={() => handleMouseenter("support")}
|
||||||
on:mouseleave={() => handleMouseleave("support")}
|
on:mouseleave={() => handleMouseleave("support")}
|
||||||
icon={supportLevelIcon}
|
icon={support.icon}
|
||||||
color={supportLevelIconColor}
|
color={support.iconColor}
|
||||||
text={supportLevelText}
|
text={support.text}
|
||||||
/>
|
/>
|
||||||
<span class="space" />
|
<span class="space" />
|
||||||
<span class="text">with</span>
|
<span class="text">with</span>
|
||||||
|
@ -110,7 +105,7 @@
|
||||||
/>
|
/>
|
||||||
<span class="period">.</span>
|
<span class="period">.</span>
|
||||||
</div>
|
</div>
|
||||||
{#if warnings.includes("string number warning")}
|
{#if support?.warnings?.includes(warnings.stringAsNumber)}
|
||||||
<div class={`line`}>
|
<div class={`line`}>
|
||||||
<span class="bullet">•</span>
|
<span class="bullet">•</span>
|
||||||
<span class="text">Any</span>
|
<span class="text">Any</span>
|
||||||
|
@ -118,7 +113,7 @@
|
||||||
<InfoWord
|
<InfoWord
|
||||||
on:mouseenter={() => handleMouseenter("stringsAndNumbers")}
|
on:mouseenter={() => handleMouseenter("stringsAndNumbers")}
|
||||||
on:mouseleave={() => handleMouseleave("stringsAndNumbers")}
|
on:mouseleave={() => handleMouseleave("stringsAndNumbers")}
|
||||||
text="non-number-values"
|
text="non-number values"
|
||||||
/>
|
/>
|
||||||
<span class="space" />
|
<span class="space" />
|
||||||
<span class="text">
|
<span class="text">
|
||||||
|
@ -127,7 +122,7 @@
|
||||||
<span class="period">.</span>
|
<span class="period">.</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if warnings.includes("optional warning")}
|
{#if support?.warnings?.includes(warnings.notRequired)}
|
||||||
<div class={`line`}>
|
<div class={`line`}>
|
||||||
<span class="bullet">•</span>
|
<span class="bullet">•</span>
|
||||||
<span class="text">No</span>
|
<span class="text">No</span>
|
||||||
|
@ -152,11 +147,14 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ExplanationModal
|
|
||||||
anchor={root}
|
{#if explanationModal}
|
||||||
{schema}
|
<ExplanationModal
|
||||||
subject={explanationModalSubject}
|
anchor={root}
|
||||||
/>
|
{schema}
|
||||||
|
subject={explanationModalSubject}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.text {
|
.text {
|
||||||
|
|
|
@ -14,11 +14,6 @@
|
||||||
export let placeholder
|
export let placeholder
|
||||||
export let fieldValidator
|
export let fieldValidator
|
||||||
|
|
||||||
$: {
|
|
||||||
console.log($params)
|
|
||||||
}
|
|
||||||
|
|
||||||
let contextTooltipId = 0;
|
|
||||||
let contextTooltipAnchor = null
|
let contextTooltipAnchor = null
|
||||||
let currentOption = null
|
let currentOption = null
|
||||||
let previousOption = null
|
let previousOption = null
|
||||||
|
@ -127,51 +122,6 @@
|
||||||
return true
|
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) => {
|
const updateTooltip = debounce((e, option) => {
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
contextTooltipVisible = false;
|
contextTooltipVisible = false;
|
||||||
|
@ -180,8 +130,6 @@
|
||||||
previousOption = currentOption;
|
previousOption = currentOption;
|
||||||
currentOption = option;
|
currentOption = option;
|
||||||
contextTooltipVisible = true;
|
contextTooltipVisible = true;
|
||||||
currentOptionSupport = getSupportLevel(currentOption)
|
|
||||||
previousOptionSupport = getSupportLevel(previousOption)
|
|
||||||
}
|
}
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
|
@ -211,114 +159,23 @@
|
||||||
offset={20}
|
offset={20}
|
||||||
>
|
>
|
||||||
<ChartFieldContext
|
<ChartFieldContext
|
||||||
sidecar
|
explanationModal
|
||||||
tableHref={`/builder/app/${$params.application}/data/table/${datasource.tableId}`}
|
tableHref={`/builder/app/${$params.application}/data/table/${datasource?.tableId}`}
|
||||||
schema={schema[currentOption]}
|
schema={schema[currentOption]}
|
||||||
support={fieldSupport[currentOption]}
|
support={fieldSupport[currentOption]}
|
||||||
supportLevelClass={currentOptionSupport.class}
|
|
||||||
supportLevelIcon={currentOptionSupport.icon}
|
|
||||||
supportLevelIconColor={currentOptionSupport.iconColor}
|
|
||||||
supportLevelIconTooltip={currentOptionSupport.iconTooltip}
|
|
||||||
supportLevelText={currentOptionSupport.text}
|
|
||||||
columnIcon={getOptionIcon(currentOption)}
|
columnIcon={getOptionIcon(currentOption)}
|
||||||
columnName={currentOption}
|
columnName={currentOption}
|
||||||
columnType={getOptionIconTooltip(currentOption)}
|
columnType={getOptionIconTooltip(currentOption)}
|
||||||
errors={fieldSupport[currentOption]?.errors}
|
|
||||||
warnings={fieldSupport[currentOption]?.warnings}
|
|
||||||
/>
|
/>
|
||||||
<ChartFieldContext
|
<ChartFieldContext
|
||||||
slot="previous"
|
slot="previous"
|
||||||
|
schema={schema[previousOption]}
|
||||||
support={fieldSupport[previousOption]}
|
support={fieldSupport[previousOption]}
|
||||||
supportLevelClass={previousOptionSupport.class}
|
|
||||||
supportLevelIcon={previousOptionSupport.icon}
|
|
||||||
supportLevelIconColor={previousOptionSupport.iconColor}
|
|
||||||
supportLevelIconTooltip={previousOptionSupport.iconTooltip}
|
|
||||||
supportLevelText={previousOptionSupport.text}
|
|
||||||
columnIcon={getOptionIcon(previousOption)}
|
columnIcon={getOptionIcon(previousOption)}
|
||||||
columnName={previousOption}
|
columnName={previousOption}
|
||||||
columnType={getOptionIconTooltip(previousOption)}
|
columnType={getOptionIconTooltip(previousOption)}
|
||||||
errors={fieldSupport[previousOption]?.errors}
|
|
||||||
warnings={fieldSupport[previousOption]?.warnings}
|
|
||||||
/>
|
/>
|
||||||
</ContextTooltip>
|
</ContextTooltip>
|
||||||
|
|
||||||
<style>
|
<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>
|
</style>
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
import { capitalize } from 'lodash';
|
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 = {
|
export const constants = {
|
||||||
warning: Symbol("values-validator-warning"),
|
|
||||||
error: Symbol("values-validator-error"),
|
|
||||||
unsupported: Symbol("values-validator-unsupported"),
|
unsupported: Symbol("values-validator-unsupported"),
|
||||||
partialSupport: Symbol("values-validator-partialSupport"),
|
partialSupport: Symbol("values-validator-partialSupport"),
|
||||||
supported: Symbol("values-validator-supported")
|
supported: Symbol("values-validator-supported")
|
||||||
|
@ -13,54 +23,60 @@ export const validators = {
|
||||||
try {
|
try {
|
||||||
const response = {
|
const response = {
|
||||||
level: null,
|
level: null,
|
||||||
message: null,
|
|
||||||
warnings: [],
|
warnings: [],
|
||||||
errors: []
|
errors: [],
|
||||||
|
text: "",
|
||||||
|
icon: "",
|
||||||
|
iconColor: ""
|
||||||
}
|
}
|
||||||
const generalUnsupportedFields = ["array", "attachment", "barcodeqr", "link", "bb_reference"]
|
const generalUnsupportedFields = ["array", "attachment", "barcodeqr", "link", "bb_reference"]
|
||||||
if (generalUnsupportedFields.includes(fieldSchema.type)) {
|
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") {
|
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") {
|
if (fieldSchema.type === "string") {
|
||||||
|
response.warnings.push(warnings.stringAsNumber)
|
||||||
response.warnings.push(
|
|
||||||
"string number warning")
|
|
||||||
}
|
}
|
||||||
if (fieldSchema.type === "datetime") {
|
if (fieldSchema.type === "datetime") {
|
||||||
response.warnings.push(
|
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.")
|
//"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
|
const isRequired = fieldSchema?.constraints?.presence?.allowEmpty === false
|
||||||
if (!isRequired) {
|
if (!isRequired) {
|
||||||
response.warnings.push(
|
response.warnings.push(warnings.notRequired);
|
||||||
"optional warning")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.errors.length > 0) {
|
if (response.errors.length > 0) {
|
||||||
response.level = constants.unsupported
|
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) {
|
} else if (response.warnings.length > 0) {
|
||||||
response.level = constants.partialSupport
|
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 {
|
} else {
|
||||||
response.level = constants.supported
|
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
|
return response
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
|
||||||
return {
|
return {
|
||||||
level: constants.partialSupport,
|
level: constants.partialSupport,
|
||||||
message: "There was an issue validating this field, it may not be fully supported for use with charts.",
|
|
||||||
warnings: [],
|
warnings: [],
|
||||||
errors: []
|
errors: [],
|
||||||
|
text: "Partially compatible",
|
||||||
|
icon: "AlertCheck",
|
||||||
|
iconColor: "var(--yellow)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue