Add full type support to conditional UI

This commit is contained in:
Andrew Kingston 2021-07-26 12:52:55 +01:00
parent 9ee53f7ee8
commit 38df0b54a5
3 changed files with 107 additions and 16 deletions

View File

@ -17,8 +17,6 @@
store.actions.components.updateConditions(tempValue) store.actions.components.updateConditions(tempValue)
drawer.hide() drawer.hide()
} }
$: console.log(componentInstance?._id)
</script> </script>
<DetailSummary <DetailSummary

View File

@ -6,6 +6,8 @@
DrawerContent, DrawerContent,
Layout, Layout,
Select, Select,
Input,
DatePicker,
} from "@budibase/bbui" } from "@budibase/bbui"
import { flip } from "svelte/animate" import { flip } from "svelte/animate"
import { dndzone } from "svelte-dnd-action" import { dndzone } from "svelte-dnd-action"
@ -34,6 +36,24 @@
value: "update", value: "update",
}, },
] ]
const valueTypeOptions = [
{
value: "string",
label: "Binding",
},
{
value: "number",
label: "Number",
},
{
value: "datetime",
label: "Date",
},
{
value: "boolean",
label: "Boolean",
},
]
$: definition = store.actions.components.getDefinition( $: definition = store.actions.components.getDefinition(
$selectedComponent?._component $selectedComponent?._component
@ -44,7 +64,6 @@
value: setting.key, value: setting.key,
} }
}) })
$: operatorOptions = getValidOperatorsForType("string")
$: bindableProperties = getBindableProperties( $: bindableProperties = getBindableProperties(
$currentAsset, $currentAsset,
$store.selectedComponentId $store.selectedComponentId
@ -70,6 +89,7 @@
conditions = [ conditions = [
...conditions, ...conditions,
{ {
valueType: "string",
id: generate(), id: generate(),
action: "hide", action: "hide",
operator: OperatorOptions.Equals.value, operator: OperatorOptions.Equals.value,
@ -84,6 +104,34 @@
const updateLinks = e => { const updateLinks = e => {
conditions = e.detail.items conditions = e.detail.items
} }
const getOperatorOptions = condition => {
return getValidOperatorsForType(condition.valueType)
}
const onOperatorChange = (condition, newOperator) => {
const noValueOptions = [
OperatorOptions.Empty.value,
OperatorOptions.NotEmpty.value,
]
condition.noValue = noValueOptions.includes(newOperator)
if (condition.noValue) {
condition.referenceValue = null
condition.valueType = "string"
}
}
const onValueTypeChange = (condition, newType) => {
condition.referenceValue = null
// Ensure a valid operator is set
const validOperators = getValidOperatorsForType(newType)
if (!validOperators.includes(condition.operator)) {
condition.operator =
validOperators[0]?.value ?? OperatorOptions.Equals.value
onOperatorChange(condition, condition.operator)
}
}
</script> </script>
<DrawerContent> <DrawerContent>
@ -143,15 +191,39 @@
/> />
<Select <Select
placeholder={null} placeholder={null}
options={operatorOptions} options={getOperatorOptions(condition)}
bind:value={condition.operator} bind:value={condition.operator}
on:change={e => onOperatorChange(condition, e.detail)}
/> />
<DrawerBindableInput <Select
bindings={bindableProperties} disabled={condition.noValue}
placeholder="Value" options={valueTypeOptions}
value={condition.referenceValue} bind:value={condition.valueType}
on:change={e => (condition.referenceValue = e.detail)} placeholder={null}
on:change={e => onValueTypeChange(condition, e.detail)}
/> />
{#if ["string", "number"].includes(condition.valueType)}
<DrawerBindableInput
disabled={condition.noValue}
bindings={bindableProperties}
placeholder="Value"
value={condition.referenceValue}
on:change={e => (condition.referenceValue = e.detail)}
/>
{:else if condition.valueType === "datetime"}
<DatePicker
placeholder="Value"
disabled={condition.noValue}
bind:value={condition.referenceValue}
/>
{:else if condition.valueType === "boolean"}
<Select
placeholder="Value"
disabled={condition.noValue}
options={["True", "False"]}
bind:value={condition.referenceValue}
/>
{/if}
<Icon <Icon
name="Close" name="Close"
hoverable hoverable
@ -176,7 +248,7 @@
<style> <style>
.container { .container {
width: 100%; width: 100%;
max-width: 1200px; max-width: 1400px;
margin: 0 auto; margin: 0 auto;
} }
.conditions { .conditions {
@ -190,12 +262,12 @@
gap: var(--spacing-l); gap: var(--spacing-l);
display: grid; display: grid;
align-items: center; align-items: center;
grid-template-columns: auto 1fr auto 1fr 1fr 1fr auto; grid-template-columns: auto 1fr auto 1fr 1fr 1fr 1fr auto;
border-radius: var(--border-radius-s); border-radius: var(--border-radius-s);
transition: background-color ease-in-out 130ms; transition: background-color ease-in-out 130ms;
} }
.condition.update { .condition.update {
grid-template-columns: auto 1fr 1fr auto 1fr auto 1fr 1fr 1fr auto; grid-template-columns: auto 1fr 1fr auto 1fr auto 1fr 1fr 1fr 1fr auto;
} }
.condition:hover { .condition:hover {
background-color: var(--spectrum-global-color-gray-100); background-color: var(--spectrum-global-color-gray-100);

View File

@ -9,14 +9,35 @@ export const getActiveConditions = conditions => {
} }
return conditions.filter(condition => { return conditions.filter(condition => {
const luceneCompatibleCondition = { // Parse values into correct types
if (condition.valueType === "number") {
condition.referenceValue = parseFloat(condition.referenceValue)
condition.newValue = parseFloat(condition.newValue)
} else if (condition.valueType === "datetime") {
if (condition.referenceValue) {
condition.referenceValue = new Date(
condition.referenceValue
).toISOString()
}
if (condition.newValue) {
condition.newValue = new Date(condition.newValue).toISOString()
}
} else if (condition.valueType === "boolean") {
condition.referenceValue =
`${condition.referenceValue}`.toLowerCase() === "true"
condition.newValue = `${condition.newValue}`.toLowerCase() === "true"
}
// Build lucene compatible condition expression
const luceneCondition = {
...condition, ...condition,
type: "string", type: condition.valueType,
field: "newValue", field: "newValue",
value: condition.referenceValue, value: condition.referenceValue,
} }
const query = buildLuceneQuery([luceneCompatibleCondition])
const result = luceneQuery([luceneCompatibleCondition], query) const query = buildLuceneQuery([luceneCondition])
const result = luceneQuery([luceneCondition], query)
return result.length > 0 return result.length > 0
}) })
} }