|
|
|
@ -9,7 +9,6 @@ |
|
|
|
Input, |
|
|
|
Layout, |
|
|
|
Select, |
|
|
|
Toggle, |
|
|
|
Label, |
|
|
|
} from "@budibase/bbui" |
|
|
|
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" |
|
|
|
@ -17,7 +16,7 @@ |
|
|
|
import { generate } from "shortid" |
|
|
|
import { LuceneUtils, Constants } from "@budibase/frontend-core" |
|
|
|
import { getFields } from "helpers/searchFields" |
|
|
|
import { createEventDispatcher } from "svelte" |
|
|
|
import { createEventDispatcher, onMount } from "svelte" |
|
|
|
|
|
|
|
const dispatch = createEventDispatcher() |
|
|
|
|
|
|
|
@ -33,6 +32,11 @@ |
|
|
|
$: fieldOptions = enrichedSchemaFields.map(field => field.name) || [] |
|
|
|
$: valueTypeOptions = allowBindings ? ["Value", "Binding"] : ["Value"] |
|
|
|
|
|
|
|
let behaviourValue |
|
|
|
const behaviourOptions = [ |
|
|
|
{ value: "and", label: "Match all of the following filters" }, |
|
|
|
{ value: "or", label: "Match any of the following filters" }, |
|
|
|
] |
|
|
|
const addFilter = () => { |
|
|
|
filters = [ |
|
|
|
...filters, |
|
|
|
@ -99,6 +103,10 @@ |
|
|
|
const schema = enrichedSchemaFields.find(x => x.name === field) |
|
|
|
return schema?.constraints?.inclusion || [] |
|
|
|
} |
|
|
|
|
|
|
|
onMount(() => { |
|
|
|
behaviourValue = allOr ? "or" : "and" |
|
|
|
}) |
|
|
|
</script> |
|
|
|
|
|
|
|
<DrawerContent> |
|
|
|
@ -114,88 +122,98 @@ |
|
|
|
</Body> |
|
|
|
{#if filters?.length} |
|
|
|
<div class="fields"> |
|
|
|
{#each filters as filter, idx} |
|
|
|
<Select |
|
|
|
bind:value={filter.field} |
|
|
|
options={fieldOptions} |
|
|
|
on:change={e => onFieldChange(filter, e.detail)} |
|
|
|
placeholder="Column" |
|
|
|
/> |
|
|
|
<Select |
|
|
|
disabled={!filter.field} |
|
|
|
options={LuceneUtils.getValidOperatorsForType(filter.type)} |
|
|
|
bind:value={filter.operator} |
|
|
|
on:change={e => onOperatorChange(filter, e.detail)} |
|
|
|
placeholder={null} |
|
|
|
/> |
|
|
|
<Select |
|
|
|
disabled={filter.noValue || !filter.field} |
|
|
|
options={valueTypeOptions} |
|
|
|
bind:value={filter.valueType} |
|
|
|
placeholder={null} |
|
|
|
/> |
|
|
|
{#if filter.valueType === "Binding"} |
|
|
|
<DrawerBindableInput |
|
|
|
disabled={filter.noValue} |
|
|
|
title={`Value for "${filter.field}"`} |
|
|
|
value={filter.value} |
|
|
|
placeholder="Value" |
|
|
|
{panel} |
|
|
|
{bindings} |
|
|
|
on:change={event => (filter.value = event.detail)} |
|
|
|
<Select |
|
|
|
label="Behaviour" |
|
|
|
value={behaviourValue} |
|
|
|
options={behaviourOptions} |
|
|
|
getOptionLabel={opt => opt.label} |
|
|
|
getOptionValue={opt => opt.value} |
|
|
|
on:change={e => (allOr = e.detail === "or")} |
|
|
|
placeholder={null} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
<div class="filter-label"> |
|
|
|
<Label>Filters</Label> |
|
|
|
</div> |
|
|
|
<div class="fields"> |
|
|
|
{#each filters as filter, idx} |
|
|
|
<Select |
|
|
|
bind:value={filter.field} |
|
|
|
options={fieldOptions} |
|
|
|
on:change={e => onFieldChange(filter, e.detail)} |
|
|
|
placeholder="Column" |
|
|
|
/> |
|
|
|
<Select |
|
|
|
disabled={!filter.field} |
|
|
|
options={LuceneUtils.getValidOperatorsForType(filter.type)} |
|
|
|
bind:value={filter.operator} |
|
|
|
on:change={e => onOperatorChange(filter, e.detail)} |
|
|
|
placeholder={null} |
|
|
|
/> |
|
|
|
{:else if ["string", "longform", "number", "formula"].includes(filter.type)} |
|
|
|
<Input disabled={filter.noValue} bind:value={filter.value} /> |
|
|
|
{:else if ["options", "array"].includes(filter.type)} |
|
|
|
<Combobox |
|
|
|
disabled={filter.noValue} |
|
|
|
options={getFieldOptions(filter.field)} |
|
|
|
bind:value={filter.value} |
|
|
|
<Select |
|
|
|
disabled={filter.noValue || !filter.field} |
|
|
|
options={valueTypeOptions} |
|
|
|
bind:value={filter.valueType} |
|
|
|
placeholder={null} |
|
|
|
/> |
|
|
|
{:else if filter.type === "boolean"} |
|
|
|
<Combobox |
|
|
|
disabled={filter.noValue} |
|
|
|
options={[ |
|
|
|
{ label: "True", value: "true" }, |
|
|
|
{ label: "False", value: "false" }, |
|
|
|
]} |
|
|
|
bind:value={filter.value} |
|
|
|
{#if filter.valueType === "Binding"} |
|
|
|
<DrawerBindableInput |
|
|
|
disabled={filter.noValue} |
|
|
|
title={`Value for "${filter.field}"`} |
|
|
|
value={filter.value} |
|
|
|
placeholder="Value" |
|
|
|
{panel} |
|
|
|
{bindings} |
|
|
|
on:change={event => (filter.value = event.detail)} |
|
|
|
/> |
|
|
|
{:else if ["string", "longform", "number", "formula"].includes(filter.type)} |
|
|
|
<Input disabled={filter.noValue} bind:value={filter.value} /> |
|
|
|
{:else if ["options", "array"].includes(filter.type)} |
|
|
|
<Combobox |
|
|
|
disabled={filter.noValue} |
|
|
|
options={getFieldOptions(filter.field)} |
|
|
|
bind:value={filter.value} |
|
|
|
/> |
|
|
|
{:else if filter.type === "boolean"} |
|
|
|
<Combobox |
|
|
|
disabled={filter.noValue} |
|
|
|
options={[ |
|
|
|
{ label: "True", value: "true" }, |
|
|
|
{ label: "False", value: "false" }, |
|
|
|
]} |
|
|
|
bind:value={filter.value} |
|
|
|
/> |
|
|
|
{:else if filter.type === "datetime"} |
|
|
|
<DatePicker |
|
|
|
disabled={filter.noValue} |
|
|
|
enableTime={!getSchema(filter).dateOnly} |
|
|
|
timeOnly={getSchema(filter).timeOnly} |
|
|
|
bind:value={filter.value} |
|
|
|
/> |
|
|
|
{:else} |
|
|
|
<DrawerBindableInput disabled /> |
|
|
|
{/if} |
|
|
|
<Icon |
|
|
|
name="Duplicate" |
|
|
|
hoverable |
|
|
|
size="S" |
|
|
|
on:click={() => duplicateFilter(filter.id)} |
|
|
|
/> |
|
|
|
{:else if filter.type === "datetime"} |
|
|
|
<DatePicker |
|
|
|
disabled={filter.noValue} |
|
|
|
enableTime={!getSchema(filter).dateOnly} |
|
|
|
timeOnly={getSchema(filter).timeOnly} |
|
|
|
bind:value={filter.value} |
|
|
|
<Icon |
|
|
|
name="Close" |
|
|
|
hoverable |
|
|
|
size="S" |
|
|
|
on:click={() => removeFilter(filter.id)} |
|
|
|
/> |
|
|
|
{:else} |
|
|
|
<DrawerBindableInput disabled /> |
|
|
|
{/if} |
|
|
|
<Icon |
|
|
|
name="Duplicate" |
|
|
|
hoverable |
|
|
|
size="S" |
|
|
|
on:click={() => duplicateFilter(filter.id)} |
|
|
|
/> |
|
|
|
<Icon |
|
|
|
name="Close" |
|
|
|
hoverable |
|
|
|
size="S" |
|
|
|
on:click={() => removeFilter(filter.id)} |
|
|
|
/> |
|
|
|
{/each} |
|
|
|
{/each} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{/if} |
|
|
|
<div class="bottom"> |
|
|
|
<Button icon="AddCircle" size="M" secondary on:click={addFilter}> |
|
|
|
Add filter |
|
|
|
</Button> |
|
|
|
<div class="toggle"> |
|
|
|
<Toggle |
|
|
|
value={allOr} |
|
|
|
on:change={event => (allOr = event.detail)} |
|
|
|
/><Label size="L">OR conditions</Label> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Layout> |
|
|
|
</div> |
|
|
|
@ -216,10 +234,8 @@ |
|
|
|
grid-template-columns: 1fr 120px 120px 1fr auto auto; |
|
|
|
} |
|
|
|
|
|
|
|
.toggle { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
padding-right: var(--spacing-s); |
|
|
|
.filter-label { |
|
|
|
margin-bottom: var(--spacing-s); |
|
|
|
} |
|
|
|
|
|
|
|
.bottom { |
|
|
|
|