Standardise cell condition operators
This commit is contained in:
parent
42162e711a
commit
feffd80d11
|
@ -134,8 +134,8 @@ a {
|
||||||
.spectrum--light,
|
.spectrum--light,
|
||||||
.spectrum--lightest {
|
.spectrum--lightest {
|
||||||
--drop-shadow: rgba(0, 0, 0, 0.075);
|
--drop-shadow: rgba(0, 0, 0, 0.075);
|
||||||
--spectrum-global-color-red-100: #ffebe7;
|
--spectrum-global-color-red-100: #ffddd6;
|
||||||
--spectrum-global-color-orange-100: #ffeccc;
|
--spectrum-global-color-orange-100: #ffdfad;
|
||||||
--spectrum-global-color-yellow-100: #fbf198;
|
--spectrum-global-color-yellow-100: #fbf198;
|
||||||
--spectrum-global-color-green-100: #cef8e0;
|
--spectrum-global-color-green-100: #cef8e0;
|
||||||
--spectrum-global-color-seafoam-100: #cef7f3;
|
--spectrum-global-color-seafoam-100: #cef7f3;
|
||||||
|
|
|
@ -15,21 +15,36 @@
|
||||||
import { QueryUtils, Constants } from "@budibase/frontend-core"
|
import { QueryUtils, Constants } from "@budibase/frontend-core"
|
||||||
import { generate } from "shortid"
|
import { generate } from "shortid"
|
||||||
import { FieldType } from "@budibase/types"
|
import { FieldType } from "@budibase/types"
|
||||||
|
import { dndzone } from "svelte-dnd-action"
|
||||||
|
import { flip } from "svelte/animate"
|
||||||
|
|
||||||
export let componentInstance
|
export let componentInstance
|
||||||
export let bindings
|
export let bindings
|
||||||
export let value
|
export let value
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
const flipDuration = 130
|
||||||
|
|
||||||
let tempValue = []
|
let tempValue = []
|
||||||
let drawer
|
let drawer
|
||||||
|
let dragDisabled = true
|
||||||
|
|
||||||
$: conditionCount = value?.length
|
$: conditionCount = value?.length
|
||||||
$: conditionText = `${conditionCount || "No"} condition${
|
$: conditionText = `${conditionCount || "No"} condition${
|
||||||
conditionCount !== 1 ? "s" : ""
|
conditionCount !== 1 ? "s" : ""
|
||||||
} set`
|
} set`
|
||||||
$: valueTypeOptions = getValueTypeOptions(componentInstance.columnType)
|
$: type = componentInstance.columnType
|
||||||
|
$: valueTypeOptions = [
|
||||||
|
{
|
||||||
|
label: "Binding",
|
||||||
|
value: FieldType.STRING,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Value",
|
||||||
|
value: type,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
$: operatorOptions = QueryUtils.getValidOperatorsForType({ type })
|
||||||
|
|
||||||
const openDrawer = () => {
|
const openDrawer = () => {
|
||||||
tempValue = cloneDeep(value || [])
|
tempValue = cloneDeep(value || [])
|
||||||
|
@ -41,23 +56,6 @@
|
||||||
drawer.hide()
|
drawer.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getValueTypeOptions = type => {
|
|
||||||
let options = [
|
|
||||||
{
|
|
||||||
label: "Binding",
|
|
||||||
value: FieldType.STRING,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const operatorOptions = QueryUtils.getValidOperatorsForType({ type })
|
|
||||||
if (operatorOptions.length) {
|
|
||||||
options.push({
|
|
||||||
label: "Value",
|
|
||||||
value: type,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
||||||
const addCondition = () => {
|
const addCondition = () => {
|
||||||
const condition = {
|
const condition = {
|
||||||
id: generate(),
|
id: generate(),
|
||||||
|
@ -76,10 +74,6 @@
|
||||||
tempValue = tempValue.filter(c => c.id !== condition.id)
|
tempValue = tempValue.filter(c => c.id !== condition.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOperatorOptions = condition => {
|
|
||||||
return QueryUtils.getValidOperatorsForType({ type: condition.valueType })
|
|
||||||
}
|
|
||||||
|
|
||||||
const onOperatorChange = (condition, newOperator) => {
|
const onOperatorChange = (condition, newOperator) => {
|
||||||
const noValueOptions = [
|
const noValueOptions = [
|
||||||
Constants.OperatorOptions.Empty.value,
|
Constants.OperatorOptions.Empty.value,
|
||||||
|
@ -92,68 +86,93 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onValueTypeChange = (condition, newType) => {
|
const onValueTypeChange = condition => {
|
||||||
condition.referenceValue = null
|
condition.referenceValue = null
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure a valid operator is set
|
const updateConditions = e => {
|
||||||
const validOperators = QueryUtils.getValidOperatorsForType({
|
tempValue = e.detail.items
|
||||||
type: newType,
|
}
|
||||||
}).map(x => x.value)
|
|
||||||
if (!validOperators.includes(condition.operator)) {
|
const handleFinalize = e => {
|
||||||
condition.operator =
|
updateConditions(e)
|
||||||
validOperators[0] ?? Constants.OperatorOptions.Equals.value
|
dragDisabled = true
|
||||||
onOperatorChange(condition, condition.operator)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ActionButton on:click={openDrawer}>{conditionText}</ActionButton>
|
<ActionButton on:click={openDrawer}>{conditionText}</ActionButton>
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
<Drawer bind:this={drawer} title="Conditions" on:drawerShow on:drawerHide>
|
<Drawer bind:this={drawer} title="Conditions" on:drawerShow on:drawerHide>
|
||||||
<Button cta slot="buttons" on:click={save}>Save</Button>
|
<Button cta slot="buttons" on:click={save}>Save</Button>
|
||||||
<DrawerContent slot="body">
|
<DrawerContent slot="body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<Layout noPadding>
|
<Layout noPadding>
|
||||||
{#if tempValue.length}
|
{#if tempValue.length}
|
||||||
<div class="conditions">
|
<div
|
||||||
{#each tempValue as condition}
|
class="conditions"
|
||||||
<span>Set background color to</span>
|
use:dndzone={{
|
||||||
<ColorPicker
|
items: tempValue,
|
||||||
value={condition.color}
|
flipDurationMs: flipDuration,
|
||||||
on:change={e => (condition.color = e.detail)}
|
dropTargetStyle: { outline: "none" },
|
||||||
/>
|
dragDisabled,
|
||||||
<span>if value</span>
|
}}
|
||||||
<Select
|
on:consider={updateConditions}
|
||||||
placeholder={null}
|
on:finalize={handleFinalize}
|
||||||
options={getOperatorOptions(condition)}
|
>
|
||||||
bind:value={condition.operator}
|
{#each tempValue as condition (condition.id)}
|
||||||
on:change={e => onOperatorChange(condition, e.detail)}
|
<div
|
||||||
/>
|
class="condition"
|
||||||
<Select
|
class:update={condition.action === "update"}
|
||||||
disabled={condition.noValue || condition.operator === "oneOf"}
|
animate:flip={{ duration: flipDuration }}
|
||||||
options={valueTypeOptions}
|
>
|
||||||
bind:value={condition.valueType}
|
<div
|
||||||
placeholder={null}
|
class="handle"
|
||||||
on:change={e => onValueTypeChange(condition, e.detail)}
|
aria-label="drag-handle"
|
||||||
/>
|
style={dragDisabled ? "cursor: grab" : "cursor: grabbing"}
|
||||||
<DrawerBindableInput
|
on:mousedown={() => (dragDisabled = false)}
|
||||||
{bindings}
|
>
|
||||||
placeholder="Value"
|
<Icon name="DragHandle" size="XL" />
|
||||||
value={condition.referenceValue}
|
</div>
|
||||||
on:change={e => (condition.referenceValue = e.detail)}
|
<span>Set background color to</span>
|
||||||
/>
|
<ColorPicker
|
||||||
<Icon
|
value={condition.color}
|
||||||
name="Duplicate"
|
on:change={e => (condition.color = e.detail)}
|
||||||
hoverable
|
/>
|
||||||
size="S"
|
<span>if value</span>
|
||||||
on:click={() => duplicateCondition(condition)}
|
<Select
|
||||||
/>
|
placeholder={null}
|
||||||
<Icon
|
options={operatorOptions}
|
||||||
name="Close"
|
bind:value={condition.operator}
|
||||||
hoverable
|
on:change={e => onOperatorChange(condition, e.detail)}
|
||||||
size="S"
|
/>
|
||||||
on:click={() => removeCondition(condition)}
|
<Select
|
||||||
/>
|
disabled={condition.noValue || condition.operator === "oneOf"}
|
||||||
|
options={valueTypeOptions}
|
||||||
|
bind:value={condition.valueType}
|
||||||
|
placeholder={null}
|
||||||
|
on:change={() => onValueTypeChange(condition)}
|
||||||
|
/>
|
||||||
|
<DrawerBindableInput
|
||||||
|
{bindings}
|
||||||
|
disabled={condition.noValue}
|
||||||
|
placeholder="Value"
|
||||||
|
value={condition.referenceValue}
|
||||||
|
on:change={e => (condition.referenceValue = e.detail)}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
name="Duplicate"
|
||||||
|
hoverable
|
||||||
|
size="S"
|
||||||
|
on:click={() => duplicateCondition(condition)}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
name="Close"
|
||||||
|
hoverable
|
||||||
|
size="S"
|
||||||
|
on:click={() => removeCondition(condition)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -174,10 +193,14 @@
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
.conditions {
|
.conditions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--spacing-l);
|
||||||
|
}
|
||||||
|
.condition {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto auto auto 1fr 1fr 1fr auto auto;
|
grid-template-columns: auto auto auto auto 1fr 1fr 1fr auto auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-column-gap: var(--spacing-l);
|
grid-column-gap: var(--spacing-l);
|
||||||
grid-row-gap: var(--spacing-l);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue