|
8 | 8 | InputSelectCheckbox,
|
9 | 9 | InputDateTime
|
10 | 10 | } from '$lib/elements/forms';
|
11 |
| - import { createEventDispatcher, onMount } from 'svelte'; |
12 |
| - import { operators, addFilter, queries, type TagValue } from './store'; |
| 11 | + import { onMount, createEventDispatcher } from 'svelte'; |
| 12 | + import { operators, addFilter, queries, tags } from './store'; |
13 | 13 | import type { Column } from '$lib/helpers/types';
|
14 | 14 | import type { Writable } from 'svelte/store';
|
15 | 15 | import { TagList } from '.';
|
16 | 16 | import { Icon, Layout } from '@appwrite.io/pink-svelte';
|
17 | 17 | import { IconPlus } from '@appwrite.io/pink-icons-svelte';
|
18 | 18 |
|
19 |
| - // We cast to any to not cause type errors in the input components |
20 |
| - /* eslint @typescript-eslint/no-explicit-any: 'off' */ |
21 |
| - export let value: any = null; |
22 |
| - export let columns: Writable<Column[]>; |
23 |
| - export let columnId: string | null = null; |
24 |
| - export let arrayValues: string[] = []; |
25 |
| - export let operatorKey: string | null = null; |
26 |
| - export let singleCondition = false; |
| 19 | + let { |
| 20 | + value = $bindable(null), |
| 21 | + columns, |
| 22 | + columnId = $bindable(null), |
| 23 | + arrayValues = $bindable([]), |
| 24 | + operatorKey = $bindable(null), |
| 25 | + singleCondition = false |
| 26 | + }: { |
| 27 | + // We cast to any to not cause type errors in the input components |
| 28 | + /* eslint @typescript-eslint/no-explicit-any: 'off' */ |
| 29 | + value?: any; |
| 30 | + columns: Writable<Column[]>; |
| 31 | + columnId?: string | null; |
| 32 | + arrayValues?: string[]; |
| 33 | + operatorKey?: string | null; |
| 34 | + singleCondition?: boolean; |
| 35 | + } = $props(); |
27 | 36 |
|
28 |
| - $: column = $columns.find((c) => c.id === columnId) as Column; |
29 |
| -
|
30 |
| - $: operatorsForColumn = Object.entries(operators) |
31 |
| - .filter(([, v]) => v.types.includes(column?.type)) |
32 |
| - .map(([k]) => ({ |
33 |
| - label: k, |
34 |
| - value: k |
| 37 | + let columnsArray = $derived($columns); |
| 38 | + let column = $derived(columnsArray.find((c) => c.id === columnId)); |
| 39 | + let operatorsForColumn = $derived.by(() => { |
| 40 | + if (!column?.type) return []; |
| 41 | + return Object.entries(operators) |
| 42 | + .filter(([, v]) => v.types.includes(column.type)) |
| 43 | + .map(([k]) => ({ label: k, value: k })); |
| 44 | + }); |
| 45 | + let operator = $derived(operatorKey ? operators[operatorKey] : null); |
| 46 | + let isDisabled = $derived(!operator); |
| 47 | + let appliedTags = $derived($tags); |
| 48 | + let columnOptions = $derived.by(() => |
| 49 | + columnsArray.filter((c) => c.filter !== false).map((c) => ({ label: c.title, value: c.id })) |
| 50 | + ); |
| 51 | + let enumOptions = $derived.by(() => { |
| 52 | + if (!column?.elements) return []; |
| 53 | + return column.elements.map((e) => ({ label: e?.label ?? e, value: e?.value ?? e })); |
| 54 | + }); |
| 55 | + let enumOptionsWithChecked = $derived.by(() => { |
| 56 | + if (!column?.elements) return []; |
| 57 | + return column.elements.map((e) => ({ |
| 58 | + label: e?.label ?? e, |
| 59 | + value: e?.value ?? e, |
| 60 | + checked: arrayValues.includes(e?.value ?? e) |
35 | 61 | }));
|
36 |
| -
|
37 |
| - $: operator = operatorKey ? operators[operatorKey] : null; |
38 |
| - $: { |
39 |
| - columnId; |
40 |
| - operatorKey = null; |
41 |
| - } |
42 |
| -
|
43 |
| - $: isDisabled = !operator; |
44 |
| -
|
45 |
| - let localTags: TagValue[] = []; |
| 62 | + }); |
46 | 63 |
|
47 | 64 | onMount(() => {
|
48 | 65 | value = column?.array ? [] : null;
|
|
52 | 69 | }
|
53 | 70 | });
|
54 | 71 |
|
| 72 | + const dispatch = createEventDispatcher<{ clear: void; apply: { applied: number } }>(); |
| 73 | +
|
55 | 74 | function addFilterAndReset() {
|
56 |
| - addFilter($columns, columnId, operatorKey, value, arrayValues); |
| 75 | + addFilter(columnsArray, columnId, operatorKey, value, arrayValues); |
57 | 76 | columnId = null;
|
58 | 77 | operatorKey = null;
|
59 | 78 | value = null;
|
60 | 79 | arrayValues = [];
|
| 80 | + dispatch('apply', { applied: appliedTags.length }); |
61 | 81 | if (singleCondition) {
|
62 | 82 | queries.apply();
|
63 | 83 | }
|
64 | 84 | }
|
65 |
| -
|
66 |
| - const dispatch = createEventDispatcher<{ |
67 |
| - clear: void; |
68 |
| - apply: { applied: number }; |
69 |
| - }>(); |
70 |
| - dispatch('apply', { applied: localTags.length }); |
71 | 85 | </script>
|
72 | 86 |
|
73 | 87 | <div>
|
74 | 88 | <form on:submit|preventDefault={addFilterAndReset}>
|
75 | 89 | <Layout.Stack gap="s" direction="row" alignItems="flex-start">
|
76 | 90 | <InputSelect
|
77 | 91 | id="column"
|
78 |
| - options={$columns |
79 |
| - .filter((c) => c.filter !== false) |
80 |
| - .map((c) => ({ |
81 |
| - label: c.title, |
82 |
| - value: c.id |
83 |
| - }))} |
| 92 | + options={columnOptions} |
84 | 93 | placeholder="Select column"
|
85 | 94 | bind:value={columnId} />
|
86 | 95 | <InputSelect
|
|
97 | 106 | name="value"
|
98 | 107 | bind:tags={arrayValues}
|
99 | 108 | placeholder="Select value"
|
100 |
| - options={column?.elements?.map((e) => ({ |
101 |
| - label: e?.label ?? e, |
102 |
| - value: e?.value ?? e, |
103 |
| - checked: arrayValues.includes(e?.value ?? e) |
104 |
| - }))}> |
| 109 | + options={enumOptionsWithChecked}> |
105 | 110 | </InputSelectCheckbox>
|
106 | 111 | {:else}
|
107 | 112 | <InputTags
|
|
117 | 122 | id="value"
|
118 | 123 | bind:value
|
119 | 124 | placeholder="Select value"
|
120 |
| - options={column?.elements?.map((e) => ({ |
121 |
| - label: e?.label ?? e, |
122 |
| - value: e?.value ?? e |
123 |
| - }))} /> |
| 125 | + options={enumOptions} /> |
124 | 126 | {:else if column.type === 'integer' || column.type === 'double'}
|
125 | 127 | <InputNumber id="value" bind:value placeholder="Enter value" />
|
126 | 128 | {:else if column.type === 'boolean'}
|
|
131 | 133 | options={[
|
132 | 134 | { label: 'True', value: true },
|
133 | 135 | { label: 'False', value: false }
|
134 |
| - ].filter(Boolean)} |
| 136 | + ]} |
135 | 137 | bind:value />
|
136 | 138 | {:else if column.type === 'datetime'}
|
137 | 139 | {#key value}
|
|
151 | 153 | {/if}
|
152 | 154 | </form>
|
153 | 155 |
|
154 |
| - {#if !singleCondition} |
| 156 | + {#if !singleCondition && appliedTags.length > 0} |
155 | 157 | <ul class="u-flex u-flex-wrap u-cross-center u-gap-8 u-margin-block-start-16 tags">
|
156 | 158 | <TagList
|
157 |
| - tags={localTags} |
| 159 | + tags={appliedTags} |
158 | 160 | on:remove={(e) => {
|
159 | 161 | queries.removeFilter(e.detail);
|
160 | 162 | queries.apply();
|
|
0 commit comments