wip
This commit is contained in:
parent
ab40e3babd
commit
7eed50707e
|
@ -9,8 +9,10 @@
|
|||
export let options = []
|
||||
export let getOptionLabel = option => option
|
||||
export let getOptionValue = option => option
|
||||
export let getOptionsIcon = () => null
|
||||
export let getOptionsIconToolip = () => null
|
||||
export let getOptionIcon = () => null
|
||||
export let getOptionIconTooltip = () => null
|
||||
export let getOptionTooltip = () => null
|
||||
export let isOptionEnabled = () => true
|
||||
export let readonly = false
|
||||
export let autocomplete = false
|
||||
export let sort = false
|
||||
|
@ -19,6 +21,7 @@
|
|||
export let customPopoverHeight
|
||||
export let open = false
|
||||
export let loading
|
||||
export let align
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
|
@ -82,8 +85,10 @@
|
|||
|
||||
<Picker
|
||||
on:loadMore
|
||||
{getOptionsIcon}
|
||||
{getOptionsIconTooltip}
|
||||
{isOptionEnabled}
|
||||
{getOptionIcon}
|
||||
{getOptionIconTooltip}
|
||||
{getOptionTooltip}
|
||||
{id}
|
||||
{disabled}
|
||||
{readonly}
|
||||
|
@ -101,4 +106,5 @@
|
|||
{autoWidth}
|
||||
{customPopoverHeight}
|
||||
{loading}
|
||||
{align}
|
||||
/>
|
||||
|
|
|
@ -11,6 +11,13 @@
|
|||
import Tags from "../../Tags/Tags.svelte"
|
||||
import Tag from "../../Tags/Tag.svelte"
|
||||
import ProgressCircle from "../../ProgressCircle/ProgressCircle.svelte"
|
||||
import {
|
||||
default as AbsTooltip,
|
||||
TooltipPosition,
|
||||
TooltipType,
|
||||
} from "../../Tooltip/AbsTooltip.svelte"
|
||||
import ContextTooltip from "../../Tooltip/Context.svelte"
|
||||
|
||||
|
||||
export let id = null
|
||||
export let disabled = false
|
||||
|
@ -27,6 +34,7 @@
|
|||
export let getOptionValue = option => option
|
||||
export let getOptionIcon = () => null
|
||||
export let getOptionIconTooltip = () => null
|
||||
export let getOptionTooltip = () => null
|
||||
export let useOptionIconImage = false
|
||||
export let getOptionColour = () => null
|
||||
export let getOptionSubtitle = () => null
|
||||
|
@ -48,6 +56,11 @@
|
|||
let button
|
||||
let component
|
||||
|
||||
let contextTooltipId = 0;
|
||||
let contextTooltipAnchor = null
|
||||
let contextTooltipOption = null
|
||||
let contextTooltipVisible = false
|
||||
|
||||
$: sortedOptions = getSortedOptions(options, getOptionLabel, sort)
|
||||
$: filteredOptions = getFilteredOptions(
|
||||
sortedOptions,
|
||||
|
@ -103,6 +116,29 @@
|
|||
onDestroy(() => {
|
||||
component?.removeEventListener("scroll", null)
|
||||
})
|
||||
|
||||
const handleMouseenter = (e, option) => {
|
||||
contextTooltipId += 1;
|
||||
const invokedContextTooltipId = contextTooltipId
|
||||
|
||||
setTimeout(() => {
|
||||
if (contextTooltipId === invokedContextTooltipId) {
|
||||
contextTooltipAnchor = e.target;
|
||||
contextTooltipOption = option;
|
||||
contextTooltipVisible = true;
|
||||
} else {
|
||||
console.log("not long enough");
|
||||
}
|
||||
}, 400)
|
||||
}
|
||||
|
||||
const handleMouseleave = (e, option) => {
|
||||
setTimeout(() => {
|
||||
if (option === contextTooltipOption) {
|
||||
contextTooltipVisible = false;
|
||||
}
|
||||
}, 600)
|
||||
}
|
||||
</script>
|
||||
|
||||
<button
|
||||
|
@ -158,83 +194,29 @@
|
|||
customHeight={customPopoverHeight}
|
||||
>
|
||||
<div
|
||||
class="popover-content"
|
||||
class:auto-width={autoWidth}
|
||||
use:clickOutside={() => (open = false)}
|
||||
>
|
||||
{#if autocomplete}
|
||||
<Search
|
||||
value={searchTerm}
|
||||
on:change={event => (searchTerm = event.detail)}
|
||||
{disabled}
|
||||
placeholder="Search"
|
||||
/>
|
||||
{/if}
|
||||
<ul class="spectrum-Menu" role="listbox" bind:this={component}>
|
||||
{#if placeholderOption}
|
||||
<li
|
||||
class="spectrum-Menu-item placeholder"
|
||||
class:is-selected={isPlaceholder}
|
||||
role="option"
|
||||
aria-selected="true"
|
||||
tabindex="0"
|
||||
on:click={() => onSelectOption(null)}
|
||||
>
|
||||
<span class="spectrum-Menu-itemLabel">{placeholderOption}</span>
|
||||
<svg
|
||||
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||
</svg>
|
||||
</li>
|
||||
class="popover-content"
|
||||
class:auto-width={autoWidth}
|
||||
use:clickOutside={() => (open = false)}
|
||||
>
|
||||
{#if autocomplete}
|
||||
<Search
|
||||
value={searchTerm}
|
||||
on:change={event => (searchTerm = event.detail)}
|
||||
{disabled}
|
||||
placeholder="Search"
|
||||
/>
|
||||
{/if}
|
||||
{#if filteredOptions.length}
|
||||
{#each filteredOptions as option, idx}
|
||||
<ul class="spectrum-Menu" role="listbox" bind:this={component}>
|
||||
{#if placeholderOption}
|
||||
<li
|
||||
class="spectrum-Menu-item"
|
||||
class:is-selected={isOptionSelected(getOptionValue(option, idx))}
|
||||
class="spectrum-Menu-item placeholder"
|
||||
class:is-selected={isPlaceholder}
|
||||
role="option"
|
||||
aria-selected="true"
|
||||
tabindex="0"
|
||||
on:click={() => onSelectOption(getOptionValue(option, idx))}
|
||||
class:is-disabled={!isOptionEnabled(option)}
|
||||
on:click={() => onSelectOption(null)}
|
||||
>
|
||||
{#if getOptionIcon(option, idx)}
|
||||
<span class="option-extra icon">
|
||||
{#if useoptioniconimage}
|
||||
<img
|
||||
src={getOptionIcon(option, idx)}
|
||||
alt="icon"
|
||||
width="15"
|
||||
height="15"
|
||||
/>
|
||||
{:else}
|
||||
<Icon size="S" name={getOptionIcon(option, idx)} />
|
||||
{/if}
|
||||
</span>
|
||||
{/if}
|
||||
{#if getOptionColour(option, idx)}
|
||||
<span class="option-extra">
|
||||
<StatusLight square color={getOptionColour(option, idx)} />
|
||||
</span>
|
||||
{/if}
|
||||
<span class="spectrum-Menu-itemLabel">
|
||||
{getOptionLabel(option, idx)}
|
||||
{#if getOptionSubtitle(option, idx)}
|
||||
<span class="subtitle-text">
|
||||
{getOptionSubtitle(option, idx)}
|
||||
</span>
|
||||
{/if}
|
||||
</span>
|
||||
{#if option.tag}
|
||||
<span class="option-tag">
|
||||
<Tags>
|
||||
<Tag icon="LockClosed">{option.tag}</Tag>
|
||||
</Tags>
|
||||
</span>
|
||||
{/if}
|
||||
<span class="spectrum-Menu-itemLabel">{placeholderOption}</span>
|
||||
<svg
|
||||
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
||||
focusable="false"
|
||||
|
@ -243,25 +225,104 @@
|
|||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||
</svg>
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if filteredOptions.length}
|
||||
{#each filteredOptions as option, idx}
|
||||
<li
|
||||
on:mouseenter={(e) => handleMouseenter(e, option)}
|
||||
on:mouseleave={(e) => handleMouseleave(e, option)}
|
||||
class="spectrum-Menu-item"
|
||||
class:is-selected={isOptionSelected(getOptionValue(option, idx))}
|
||||
role="option"
|
||||
aria-selected="true"
|
||||
tabindex="0"
|
||||
on:click={() => onSelectOption(getOptionValue(option, idx))}
|
||||
class:is-disabled={!isOptionEnabled(option)}
|
||||
>
|
||||
{#if getOptionIcon(option, idx)}
|
||||
<span class="option-extra icon">
|
||||
{#if useOptionIconImage}
|
||||
<img
|
||||
src={getOptionIcon(option, idx)}
|
||||
alt="icon"
|
||||
width="15"
|
||||
height="15"
|
||||
/>
|
||||
{:else}
|
||||
<Icon tooltip={getOptionIconTooltip(option)} size="S" name={getOptionIcon(option, idx)} />
|
||||
{/if}
|
||||
</span>
|
||||
{/if}
|
||||
{#if getOptionColour(option, idx)}
|
||||
<span class="option-extra">
|
||||
<StatusLight square color={getOptionColour(option, idx)} />
|
||||
</span>
|
||||
{/if}
|
||||
<span class="spectrum-Menu-itemLabel">
|
||||
{getOptionLabel(option, idx)}
|
||||
{#if getOptionSubtitle(option, idx)}
|
||||
<span class="subtitle-text">
|
||||
{getOptionSubtitle(option, idx)}
|
||||
</span>
|
||||
{/if}
|
||||
</span>
|
||||
{#if option.tag}
|
||||
<span class="option-tag">
|
||||
<Tags>
|
||||
<Tag icon="LockClosed">{option.tag}</Tag>
|
||||
</Tags>
|
||||
</span>
|
||||
{/if}
|
||||
<svg
|
||||
class="selectedIcon spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||
</svg>
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
|
||||
{#if loading}
|
||||
<div class="loading" class:loading--withAutocomplete={autocomplete}>
|
||||
<ProgressCircle size="S" />
|
||||
</div>
|
||||
{/if}
|
||||
</ul>
|
||||
|
||||
{#if loading}
|
||||
<div class="loading" class:loading--withAutocomplete={autocomplete}>
|
||||
<ProgressCircle size="S" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if footer}
|
||||
<div class="footer">
|
||||
{footer}
|
||||
</div>
|
||||
{/if}
|
||||
{#if footer}
|
||||
<div class="footer">
|
||||
{footer}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Popover>
|
||||
<ContextTooltip
|
||||
visible={contextTooltipVisible}
|
||||
anchor={contextTooltipAnchor}
|
||||
>
|
||||
<div
|
||||
class="tooltipContents"
|
||||
>
|
||||
{contextTooltipOption}
|
||||
</div>
|
||||
</Popover>
|
||||
</ContextTooltip>
|
||||
|
||||
<style>
|
||||
.tooltipContents {
|
||||
width: 300px;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.spectrum-Menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.spectrum-Menu:hover .context {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.spectrum-Picker {
|
||||
width: 100%;
|
||||
box-shadow: none;
|
||||
|
@ -332,7 +393,7 @@
|
|||
right: 2px;
|
||||
top: 2px;
|
||||
}
|
||||
.popover-content :global(.spectrum-Search .spectrum-Textfield-icon) {
|
||||
.popover-content :global(.spectrum-Search .spectrum-Textfield-icon) {
|
||||
top: 9px;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,17 @@
|
|||
export let options = []
|
||||
export let getOptionLabel = option => option
|
||||
export let getOptionValue = option => option
|
||||
export let getOptionIcon = () => null
|
||||
export let getOptionIconTooltip = () => null
|
||||
export let getOptionTooltip = () => null
|
||||
export let isOptionEnabled = () => true
|
||||
export let sort = false
|
||||
export let autoWidth = false
|
||||
export let autocomplete = false
|
||||
export let searchTerm = null
|
||||
export let customPopoverHeight
|
||||
export let helpText = null
|
||||
export let align
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const onChange = e => {
|
||||
|
@ -29,6 +34,10 @@
|
|||
|
||||
<Field {helpText} {label} {labelPosition} {error}>
|
||||
<Multiselect
|
||||
{isOptionEnabled}
|
||||
{getOptionIcon}
|
||||
{getOptionIconTooltip}
|
||||
{getOptionTooltip}
|
||||
{error}
|
||||
{disabled}
|
||||
{readonly}
|
||||
|
@ -41,6 +50,7 @@
|
|||
{autoWidth}
|
||||
{autocomplete}
|
||||
{customPopoverHeight}
|
||||
{align}
|
||||
bind:searchTerm
|
||||
on:change={onChange}
|
||||
on:click
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
<script>
|
||||
import Portal from "svelte-portal"
|
||||
|
||||
export let tooltip
|
||||
export let anchor
|
||||
export let visible = false
|
||||
export let hovering = false
|
||||
|
||||
let targetX = 0
|
||||
let targetY = 0
|
||||
|
||||
let animationId = 0;
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
|
||||
const updatePositionOnVisibilityChange = (visible, hovering) => {
|
||||
if (!visible && !hovering) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const updatePosition = (anchor, tooltip) => {
|
||||
if (anchor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = anchor.getBoundingClientRect();
|
||||
const tooltipWidth = tooltip?.getBoundingClientRect()?.width ?? 0;
|
||||
|
||||
targetX = rect.x - tooltipWidth
|
||||
targetY = rect.y
|
||||
animationId += 1
|
||||
|
||||
if (x === 0 && y === 0) {
|
||||
x = targetX
|
||||
y = targetY
|
||||
}
|
||||
}
|
||||
|
||||
const animate = (invokedAnimationId, xRate = null, yRate = null) => {
|
||||
if (invokedAnimationId !== animationId) {
|
||||
console.log("CANCEL ANIMATION ", invokedAnimationId, " ", animationId);
|
||||
return;
|
||||
}
|
||||
console.log("animating");
|
||||
|
||||
const animationDurationInFrames = 10;
|
||||
|
||||
const xDelta = targetX - x
|
||||
const yDelta = targetY - y
|
||||
|
||||
if (xRate === null) {
|
||||
xRate = Math.abs(xDelta) / animationDurationInFrames
|
||||
}
|
||||
|
||||
if (yRate === null) {
|
||||
yRate = Math.abs(yDelta) / animationDurationInFrames
|
||||
}
|
||||
|
||||
|
||||
if (xDelta === 0 && yDelta === 0) return;
|
||||
|
||||
if (
|
||||
(xDelta > 0 && xDelta <= xRate) ||
|
||||
(xDelta < 0 && xDelta >= -xRate)
|
||||
) {
|
||||
x = targetX;
|
||||
} else if (xDelta > 0) {
|
||||
x = x + xRate;
|
||||
} else if (xDelta < 0) {
|
||||
x = x - xRate;
|
||||
}
|
||||
|
||||
if (
|
||||
(yDelta > 0 && yDelta <= yRate) ||
|
||||
(yDelta < 0 && yDelta >= -yRate)
|
||||
) {
|
||||
y = targetY;
|
||||
} else if (yDelta > 0) {
|
||||
y = y + yRate;
|
||||
} else if (yDelta < 0) {
|
||||
y = y - yRate;
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => animate(invokedAnimationId, xRate, yRate))
|
||||
}
|
||||
|
||||
$: updatePosition(anchor, tooltip)
|
||||
$: updatePositionOnVisibilityChange(visible, hovering)
|
||||
$: requestAnimationFrame(() => animate(animationId))
|
||||
|
||||
const handleMouseenter = (e) => {
|
||||
hovering = true;
|
||||
}
|
||||
|
||||
const handleMouseleave = (e) => {
|
||||
hovering = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Portal target=".spectrum">
|
||||
<div
|
||||
bind:this={tooltip}
|
||||
on:mouseenter={handleMouseenter}
|
||||
on:mouseleave={handleMouseleave}
|
||||
style:top={`${y}px`}
|
||||
style:left={`${x}px`}
|
||||
class="tooltip"
|
||||
class:visible={visible || hovering}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</Portal>
|
||||
|
||||
<style>
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
</style>
|
|
@ -3,14 +3,36 @@
|
|||
import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding"
|
||||
import { selectedScreen } from "stores/builder"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { validators, supported, partialSupport, unsupported } from "../fieldValidator";
|
||||
|
||||
export let componentInstance = {}
|
||||
export let value = ""
|
||||
export let placeholder
|
||||
export let fieldValidator
|
||||
|
||||
$: {
|
||||
console.log(fieldValidator);
|
||||
}
|
||||
|
||||
const getFieldSupport = (schema, fieldValidator) => {
|
||||
if (fieldValidator == null) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const validator = validators[fieldValidator];
|
||||
|
||||
const fieldSupport = {}
|
||||
Object.entries(schema || {}).forEach(([key, value]) => {
|
||||
fieldSupport[key] = validator(value)
|
||||
})
|
||||
|
||||
return fieldSupport
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
||||
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
||||
$: fieldSupport = getFieldSupport(schema, fieldValidator);
|
||||
$: options = Object.keys(schema || {})
|
||||
$: boundValue = getValidValue(value, options)
|
||||
|
||||
|
@ -32,6 +54,32 @@
|
|||
boundValue = getValidValue(value.detail, options)
|
||||
dispatch("change", boundValue)
|
||||
}
|
||||
|
||||
const getOptionIcon = option => {
|
||||
const support = fieldSupport[option]?.support;
|
||||
|
||||
if (support == null) return null;
|
||||
if (support === supported) return null
|
||||
|
||||
if (support === partialSupport) return "Warning"
|
||||
if (support === unsupported) return "Error"
|
||||
}
|
||||
|
||||
const getOptionIconTooltip = option => {
|
||||
}
|
||||
|
||||
const isOptionEnabled = option => {
|
||||
const support = fieldSupport[option]?.support;
|
||||
|
||||
if (support == null) return true
|
||||
if (support == unsupported) return false
|
||||
|
||||
return true
|
||||
}
|
||||
</script>
|
||||
|
||||
<Select {placeholder} value={boundValue} on:change={onChange} {options} />
|
||||
<Select
|
||||
{isOptionEnabled}
|
||||
{getOptionIcon}
|
||||
{getOptionIconTooltip}
|
||||
{placeholder} value={boundValue} on:change={onChange} {options} />
|
||||
|
|
|
@ -3,17 +3,60 @@
|
|||
import { getDatasourceForProvider, getSchemaForDatasource } from "dataBinding"
|
||||
import { selectedScreen } from "stores/builder"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { validators, supported, partialSupport, unsupported } from "../fieldValidator";
|
||||
|
||||
export let componentInstance = {}
|
||||
export let value = ""
|
||||
export let placeholder
|
||||
export let fieldValidator
|
||||
|
||||
const TypeIconMap = {
|
||||
text: "Text",
|
||||
options: "Dropdown",
|
||||
datetime: "Date",
|
||||
barcodeqr: "Camera",
|
||||
longform: "TextAlignLeft",
|
||||
array: "Dropdown",
|
||||
number: "123",
|
||||
boolean: "Boolean",
|
||||
attachment: "AppleFiles",
|
||||
link: "DataCorrelated",
|
||||
formula: "Calculator",
|
||||
json: "Brackets",
|
||||
bigint: "TagBold",
|
||||
bb_reference: {
|
||||
user: "User",
|
||||
users: "UserGroup",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
const getFieldSupport = (schema, fieldValidator) => {
|
||||
if (fieldValidator == null) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const validator = validators[fieldValidator];
|
||||
|
||||
const fieldSupport = {}
|
||||
Object.entries(schema || {}).forEach(([key, value]) => {
|
||||
fieldSupport[key] = validator(value)
|
||||
})
|
||||
|
||||
return fieldSupport
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
$: datasource = getDatasourceForProvider($selectedScreen, componentInstance)
|
||||
$: schema = getSchemaForDatasource($selectedScreen, datasource).schema
|
||||
$: options = Object.keys(schema || {})
|
||||
$: fieldSupport = getFieldSupport(schema, fieldValidator);
|
||||
$: boundValue = getValidOptions(value, options)
|
||||
|
||||
$: {
|
||||
console.log(schema)
|
||||
}
|
||||
|
||||
const getValidOptions = (selectedOptions, allOptions) => {
|
||||
// Fix the hardcoded default string value
|
||||
if (!Array.isArray(selectedOptions)) {
|
||||
|
@ -26,6 +69,69 @@
|
|||
boundValue = getValidOptions(value.detail, options)
|
||||
dispatch("change", boundValue)
|
||||
}
|
||||
|
||||
const foo = () => {
|
||||
const support = fieldSupport[option]?.support;
|
||||
|
||||
if (support == null) return null;
|
||||
if (support === supported) return null
|
||||
|
||||
if (support === partialSupport) return "AlertCircleFilled"
|
||||
if (support === unsupported) return "AlertCircleFilled"
|
||||
}
|
||||
|
||||
const getOptionIcon = optionKey => {
|
||||
const option = schema[optionKey]
|
||||
if (option.autocolumn) {
|
||||
return "MagicWand"
|
||||
}
|
||||
const { type, subtype } = option
|
||||
|
||||
const result =
|
||||
typeof TypeIconMap[type] === "object" && subtype
|
||||
? TypeIconMap[type][subtype]
|
||||
: TypeIconMap[type]
|
||||
|
||||
return result || "Text"
|
||||
}
|
||||
|
||||
const getOptionIconTooltip = optionKey => {
|
||||
const option = schema[optionKey]
|
||||
|
||||
return option.type;
|
||||
}
|
||||
|
||||
const getOptionTooltip = optionKey => {
|
||||
console.log(optionKey)
|
||||
const support = fieldSupport[optionKey]?.support;
|
||||
const message = fieldSupport[optionKey]?.message;
|
||||
|
||||
if (support === unsupported) return message
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const isOptionEnabled = optionKey => {
|
||||
// Remain enabled if already selected, so it can be deselected
|
||||
if (value?.includes(optionKey)) return true
|
||||
const support = fieldSupport[optionKey]?.support;
|
||||
|
||||
if (support == null) return true
|
||||
if (support === unsupported) return false
|
||||
|
||||
return true
|
||||
}
|
||||
</script>
|
||||
|
||||
<Multiselect {placeholder} value={boundValue} on:change={setValue} {options} />
|
||||
<Multiselect
|
||||
iconPosition="right"
|
||||
{isOptionEnabled}
|
||||
{getOptionIcon}
|
||||
{getOptionIconTooltip}
|
||||
{getOptionTooltip}
|
||||
{placeholder}
|
||||
value={boundValue}
|
||||
on:change={setValue}
|
||||
{options}
|
||||
align="right"
|
||||
/>
|
||||
|
|
|
@ -2,7 +2,7 @@ export const unsupported = Symbol("values-validator-unsupported")
|
|||
export const partialSupport = Symbol("values-validator-partial-support")
|
||||
export const supported = Symbol("values-validator-supported")
|
||||
|
||||
const validatorMap = {
|
||||
export const validators = {
|
||||
chart: (fieldSchema) => {
|
||||
if (
|
||||
fieldSchema.type === "json" ||
|
||||
|
@ -14,7 +14,7 @@ const validatorMap = {
|
|||
) {
|
||||
return {
|
||||
support: unsupported,
|
||||
message: "This field cannot be used as a chart value"
|
||||
message: `"${fieldSchema.type}" columns cannot be used as a chart value long long long long long long long long long`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,5 +38,3 @@ const validatorMap = {
|
|||
}
|
||||
}
|
||||
};
|
||||
export default validatorMap;
|
||||
|
||||
|
|
|
@ -1629,7 +1629,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartmultifield",
|
||||
"type": "multifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -1788,7 +1788,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartmultifield",
|
||||
"type": "multifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -1941,7 +1941,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartmultifield",
|
||||
"type": "multifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -2106,7 +2106,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -2235,7 +2235,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -2364,28 +2364,28 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Open column",
|
||||
"key": "openColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Close column",
|
||||
"key": "closeColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "High column",
|
||||
"key": "highColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Low column",
|
||||
"key": "lowColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -2449,7 +2449,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataProvider",
|
||||
|
@ -5266,7 +5266,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5291,7 +5291,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Data column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5316,7 +5316,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartmultifield",
|
||||
"type": "multifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5363,7 +5363,7 @@
|
|||
},
|
||||
"settings": [
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Value column",
|
||||
"key": "valueColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5411,7 +5411,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartmultifield",
|
||||
"type": "multifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5460,7 +5460,7 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartmultifield",
|
||||
"type": "multifield",
|
||||
"label": "Data columns",
|
||||
"key": "valueColumns",
|
||||
"dependsOn": "dataSource",
|
||||
|
@ -5521,28 +5521,28 @@
|
|||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Open column",
|
||||
"key": "openColumn",
|
||||
"dependsOn": "dataSource",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Close column",
|
||||
"key": "closeColumn",
|
||||
"dependsOn": "dataSource",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "High column",
|
||||
"key": "highColumn",
|
||||
"dependsOn": "dataSource",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "chartfield",
|
||||
"type": "field",
|
||||
"label": "Low column",
|
||||
"key": "lowColumn",
|
||||
"dependsOn": "dataSource",
|
||||
|
|
Loading…
Reference in New Issue