2020-08-22 04:05:26 +12:00
|
|
|
<script>
|
2020-10-07 22:45:26 +13:00
|
|
|
import { Button, Input, Select, DatePicker } from "@budibase/bbui"
|
2021-03-26 21:50:37 +13:00
|
|
|
import { tables, views } from 'stores/backend/'
|
2020-08-22 04:05:26 +12:00
|
|
|
import { notifier } from "builderStore/store/notifications"
|
2020-09-30 03:26:56 +13:00
|
|
|
import analytics from "analytics"
|
2020-08-22 04:05:26 +12:00
|
|
|
|
|
|
|
const CONDITIONS = [
|
|
|
|
{
|
|
|
|
name: "Equals",
|
|
|
|
key: "EQUALS",
|
|
|
|
},
|
2020-10-15 09:43:36 +13:00
|
|
|
{
|
|
|
|
name: "Not Equals",
|
|
|
|
key: "NOT_EQUALS",
|
|
|
|
},
|
2020-08-22 04:05:26 +12:00
|
|
|
{
|
|
|
|
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 = {}
|
2020-10-03 00:00:17 +13:00
|
|
|
export let onClosed
|
2020-08-22 04:05:26 +12:00
|
|
|
|
2021-03-23 23:54:03 +13:00
|
|
|
$: viewTable = $tables.list.find(
|
2021-03-24 00:16:54 +13:00
|
|
|
({ _id }) => _id === $views.selected.tableId
|
2020-08-22 04:05:26 +12:00
|
|
|
)
|
2020-10-10 06:49:23 +13:00
|
|
|
$: fields = viewTable && Object.keys(viewTable.schema)
|
2020-08-22 04:05:26 +12:00
|
|
|
|
|
|
|
function saveView() {
|
2021-03-24 00:16:54 +13:00
|
|
|
views.save(view)
|
2020-08-22 04:05:26 +12:00
|
|
|
notifier.success(`View ${view.name} saved.`)
|
2020-10-03 00:00:17 +13:00
|
|
|
onClosed()
|
2020-09-30 04:35:47 +13:00
|
|
|
analytics.captureEvent("Added View Filter", {
|
|
|
|
filters: JSON.stringify(view.filters),
|
|
|
|
})
|
2020-08-22 04:05:26 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
function removeFilter(idx) {
|
2020-08-26 02:39:49 +12:00
|
|
|
view.filters.splice(idx, 1)
|
|
|
|
view.filters = view.filters
|
2020-08-22 04:05:26 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
function addFilter() {
|
2020-09-14 22:03:27 +12:00
|
|
|
view.filters.push({})
|
|
|
|
view.filters = view.filters
|
|
|
|
}
|
|
|
|
|
|
|
|
function isMultipleChoice(field) {
|
|
|
|
return (
|
2020-10-10 06:49:23 +13:00
|
|
|
(viewTable.schema[field].constraints &&
|
|
|
|
viewTable.schema[field].constraints.inclusion &&
|
|
|
|
viewTable.schema[field].constraints.inclusion.length) ||
|
|
|
|
viewTable.schema[field].type === "boolean"
|
2020-09-14 22:03:27 +12:00
|
|
|
)
|
2020-08-22 04:05:26 +12:00
|
|
|
}
|
2020-10-02 04:55:17 +13:00
|
|
|
|
|
|
|
function fieldOptions(field) {
|
2020-10-13 05:45:11 +13:00
|
|
|
return viewTable.schema[field].type === "options"
|
2020-10-10 06:49:23 +13:00
|
|
|
? viewTable.schema[field].constraints.inclusion
|
2020-10-02 04:55:17 +13:00
|
|
|
: [true, false]
|
|
|
|
}
|
2020-10-02 05:07:53 +13:00
|
|
|
|
|
|
|
function isDate(field) {
|
2020-10-10 06:49:23 +13:00
|
|
|
return viewTable.schema[field].type === "datetime"
|
2020-10-02 05:07:53 +13:00
|
|
|
}
|
2020-10-02 05:34:25 +13:00
|
|
|
|
|
|
|
function isNumber(field) {
|
2020-10-10 06:49:23 +13:00
|
|
|
return viewTable.schema[field].type === "number"
|
2020-10-02 05:34:25 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
const fieldChanged = filter => ev => {
|
|
|
|
// reset if type changed
|
|
|
|
if (
|
|
|
|
filter.key &&
|
|
|
|
ev.target.value &&
|
2020-10-10 06:49:23 +13:00
|
|
|
viewTable.schema[filter.key].type !==
|
|
|
|
viewTable.schema[ev.target.value].type
|
2020-10-02 05:34:25 +13:00
|
|
|
) {
|
|
|
|
filter.value = ""
|
|
|
|
}
|
|
|
|
}
|
2020-08-22 04:05:26 +12:00
|
|
|
</script>
|
|
|
|
|
2020-10-03 00:00:17 +13:00
|
|
|
<div class="actions">
|
|
|
|
<h5>Filter</h5>
|
|
|
|
{#if view.filters.length}
|
|
|
|
<div class="input-group-row">
|
|
|
|
{#each view.filters as filter, idx}
|
|
|
|
{#if idx === 0}
|
|
|
|
<p>Where</p>
|
|
|
|
{:else}
|
|
|
|
<Select secondary thin bind:value={filter.conjunction}>
|
2020-09-25 22:35:32 +12:00
|
|
|
<option value="">Choose an option</option>
|
2020-10-03 00:00:17 +13:00
|
|
|
{#each CONJUNCTIONS as conjunction}
|
|
|
|
<option value={conjunction.key}>{conjunction.name}</option>
|
2020-09-25 22:35:32 +12:00
|
|
|
{/each}
|
|
|
|
</Select>
|
2020-10-03 00:00:17 +13:00
|
|
|
{/if}
|
2020-10-07 22:45:26 +13:00
|
|
|
<Select
|
|
|
|
secondary
|
|
|
|
thin
|
|
|
|
bind:value={filter.key}
|
|
|
|
on:change={fieldChanged(filter)}>
|
2020-10-02 05:34:25 +13:00
|
|
|
<option value="">Choose an option</option>
|
2020-10-07 22:45:26 +13:00
|
|
|
{#each fields as field}
|
|
|
|
<option value={field}>{field}</option>
|
2020-09-14 22:03:27 +12:00
|
|
|
{/each}
|
|
|
|
</Select>
|
2020-10-03 00:00:17 +13:00
|
|
|
<Select secondary thin bind:value={filter.condition}>
|
|
|
|
<option value="">Choose an option</option>
|
|
|
|
{#each CONDITIONS as condition}
|
|
|
|
<option value={condition.key}>{condition.name}</option>
|
|
|
|
{/each}
|
|
|
|
</Select>
|
|
|
|
{#if filter.key && isMultipleChoice(filter.key)}
|
|
|
|
<Select secondary thin bind:value={filter.value}>
|
2020-09-25 22:35:32 +12:00
|
|
|
<option value="">Choose an option</option>
|
2020-10-07 22:45:26 +13:00
|
|
|
{#each fieldOptions(filter.key) as option}
|
|
|
|
<option value={option}>{option.toString()}</option>
|
2020-09-25 22:35:32 +12:00
|
|
|
{/each}
|
|
|
|
</Select>
|
2020-10-07 22:45:26 +13:00
|
|
|
{:else if filter.key && isDate(filter.key)}
|
|
|
|
<DatePicker
|
|
|
|
bind:value={filter.value}
|
|
|
|
placeholder={filter.key || fields[0]} />
|
|
|
|
{:else if filter.key && isNumber(filter.key)}
|
|
|
|
<Input
|
|
|
|
thin
|
|
|
|
bind:value={filter.value}
|
|
|
|
placeholder={filter.key || fields[0]}
|
|
|
|
type="number" />
|
2020-10-03 00:00:17 +13:00
|
|
|
{:else}
|
2020-10-07 22:45:26 +13:00
|
|
|
<Input
|
|
|
|
thin
|
|
|
|
placeholder={filter.key || fields[0]}
|
|
|
|
bind:value={filter.value} />
|
2020-10-03 00:00:17 +13:00
|
|
|
{/if}
|
|
|
|
<i class="ri-close-circle-fill" on:click={() => removeFilter(idx)} />
|
|
|
|
{/each}
|
|
|
|
</div>
|
|
|
|
{/if}
|
|
|
|
<div class="footer">
|
2021-02-24 05:29:50 +13:00
|
|
|
<div class="add-filter">
|
2021-02-24 05:31:33 +13:00
|
|
|
<Button text on:click={addFilter}>Add Filter</Button>
|
2021-02-24 05:29:50 +13:00
|
|
|
</div>
|
2020-10-03 00:00:17 +13:00
|
|
|
<div class="buttons">
|
|
|
|
<Button secondary on:click={onClosed}>Cancel</Button>
|
|
|
|
<Button primary on:click={saveView}>Save</Button>
|
2020-08-22 04:05:26 +12:00
|
|
|
</div>
|
|
|
|
</div>
|
2020-10-03 00:00:17 +13:00
|
|
|
</div>
|
2020-08-22 04:05:26 +12:00
|
|
|
|
|
|
|
<style>
|
2020-09-26 00:11:57 +12:00
|
|
|
.actions {
|
2020-09-25 22:35:32 +12:00
|
|
|
display: grid;
|
|
|
|
grid-gap: var(--spacing-xl);
|
|
|
|
}
|
|
|
|
|
2020-08-22 04:05:26 +12:00
|
|
|
h5 {
|
2020-09-25 22:35:32 +12:00
|
|
|
margin: 0;
|
2020-08-22 04:05:26 +12:00
|
|
|
font-weight: 500;
|
|
|
|
}
|
|
|
|
|
2020-09-25 22:35:32 +12:00
|
|
|
.footer {
|
2020-08-22 04:05:26 +12:00
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
}
|
2020-09-25 22:35:32 +12:00
|
|
|
.buttons {
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-end;
|
|
|
|
gap: var(--spacing-m);
|
2020-08-22 04:05:26 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
.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);
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
p {
|
|
|
|
margin: 0;
|
|
|
|
font-size: var(--font-size-xs);
|
|
|
|
}
|
2021-02-24 05:29:50 +13:00
|
|
|
|
|
|
|
.add-filter {
|
|
|
|
margin-right: 16px;
|
|
|
|
}
|
2020-08-22 04:05:26 +12:00
|
|
|
</style>
|