1
0
Fork 0
mirror of synced 2024-06-14 00:14:39 +12:00
budibase/packages/builder/src/components/database/DataTable/popovers/Filter.svelte

201 lines
4.6 KiB
Svelte
Raw Normal View History

<script>
import {
Popover,
TextButton,
Button,
Icon,
Input,
Select,
2020-10-02 05:07:53 +13:00
DatePicker,
} from "@budibase/bbui"
import { backendUiStore } from "builderStore"
import { notifier } from "builderStore/store/notifications"
import CreateEditRecord from "../modals/CreateEditRecord.svelte"
import analytics from "analytics"
const CONDITIONS = [
{
name: "Equals",
key: "EQUALS",
},
{
name: "Less Than",
key: "LT",
},
{
name: "Less Than Or Equal",
key: "LTE",
},
{
name: "More Than",
key: "MT",
},
{
name: "More Than Or Equal",
key: "MTE",
},
{
name: "Contains",
key: "CONTAINS",
},
]
const CONJUNCTIONS = [
{
name: "Or",
key: "OR",
},
{
name: "And",
key: "AND",
},
]
export let view = {}
let anchor
let dropdown
$: viewModel = $backendUiStore.models.find(
({ _id }) => _id === $backendUiStore.selectedView.modelId
)
$: fields = viewModel && Object.keys(viewModel.schema)
function saveView() {
backendUiStore.actions.views.save(view)
notifier.success(`View ${view.name} saved.`)
dropdown.hide()
analytics.captureEvent("Added View Filter", {
filters: JSON.stringify(view.filters),
})
}
function removeFilter(idx) {
2020-08-26 02:39:49 +12:00
view.filters.splice(idx, 1)
view.filters = view.filters
}
function addFilter() {
2020-09-14 22:03:27 +12:00
view.filters.push({})
view.filters = view.filters
}
function isMultipleChoice(field) {
return (
(viewModel.schema[field].constraints &&
viewModel.schema[field].constraints.inclusion &&
viewModel.schema[field].constraints.inclusion.length) ||
viewModel.schema[field].type === "boolean"
2020-09-14 22:03:27 +12:00
)
}
function fieldOptions(field) {
return viewModel.schema[field].type === "string"
? viewModel.schema[field].constraints.inclusion
: [true, false]
}
2020-10-02 05:07:53 +13:00
function isDate(field) {
return viewModel.schema[field].type === "datetime"
}
</script>
<div bind:this={anchor}>
<TextButton
text
small
on:click={dropdown.show}
2020-08-26 02:39:49 +12:00
active={view.filters && view.filters.length}>
<Icon name="filter" />
Filter
</TextButton>
</div>
<Popover bind:this={dropdown} {anchor} align="left">
<h5>Filter</h5>
<div class="input-group-row">
2020-08-26 02:39:49 +12:00
{#each view.filters as filter, idx}
{#if idx === 0}
<p>Where</p>
{:else}
<Select secondary thin bind:value={filter.conjunction}>
2020-09-30 23:57:42 +13:00
<option value="">Choose an option</option>
{#each CONJUNCTIONS as conjunction}
<option value={conjunction.key}>{conjunction.name}</option>
{/each}
</Select>
{/if}
<Select secondary thin bind:value={filter.key}>
2020-09-30 23:57:42 +13:00
<option value="">Choose an option</option>
{#each fields as field}
<option value={field}>{field}</option>
{/each}
</Select>
<Select secondary thin bind:value={filter.condition}>
2020-09-30 23:57:42 +13:00
<option value="">Choose an option</option>
{#each CONDITIONS as condition}
<option value={condition.key}>{condition.name}</option>
{/each}
</Select>
2020-09-14 22:03:27 +12:00
{#if filter.key && isMultipleChoice(filter.key)}
<Select secondary thin bind:value={filter.value}>
{#each fieldOptions(filter.key) as option}
<option value={option}>{option.toString()}</option>
2020-09-14 22:03:27 +12:00
{/each}
</Select>
2020-10-02 05:07:53 +13:00
{:else if filter.key && isDate(filter.key)}
<DatePicker
bind:value={filter.value}
placeholder={filter.key || fields[0]} />
2020-09-14 22:03:27 +12:00
{:else}
<Input
thin
placeholder={filter.key || fields[0]}
bind:value={filter.value} />
{/if}
<i class="ri-close-circle-fill" on:click={() => removeFilter(idx)} />
{/each}
</div>
<div class="button-group">
<Button text on:click={addFilter}>Add Filter</Button>
<div>
<Button secondary on:click={dropdown.hide}>Cancel</Button>
<Button primary on:click={saveView}>Save</Button>
</div>
</div>
</Popover>
<style>
h5 {
margin-bottom: var(--spacing-l);
font-weight: 500;
}
.button-group {
margin-top: var(--spacing-l);
display: flex;
justify-content: space-between;
align-items: center;
}
:global(.button-group > div > button) {
margin-left: var(--spacing-m);
}
.ri-close-circle-fill {
cursor: pointer;
}
.input-group-row {
display: grid;
grid-template-columns: minmax(50px, auto) 1fr 1fr 1fr 15px;
gap: var(--spacing-s);
margin-bottom: var(--spacing-l);
align-items: center;
}
p {
margin: 0;
font-size: var(--font-size-xs);
}
</style>