|
1 | 1 | <script lang="ts">
|
2 |
| - import type { Item } from "$/types/item"; |
3 |
| - import { Accordion, AccordionItem, Button, Input, Label, Modal, NumberInput, Select, SpeedDial, SpeedDialButton } from "flowbite-svelte"; |
4 |
| - import { CirclePlusSolid, TrashBinOutline } from "flowbite-svelte-icons"; |
| 2 | + import type { Filter, Item, ItemCategoryIndex, NullableItemCategoryIndex } from "$/types/item"; |
| 3 | + import { Accordion, AccordionItem, Button, Input, Label, Modal, NumberInput, Select, type SelectOptionType, SpeedDial, SpeedDialButton } from "flowbite-svelte"; |
| 4 | + import { CirclePlusSolid, SearchOutline, TrashBinOutline } from "flowbite-svelte-icons"; |
5 | 5 | import { saveData } from "$/store/save-data";
|
6 | 6 | import { getItemCategory, itemCategories, nonExhaustiveItemIdList } from "$/types/item";
|
7 | 7 |
|
8 |
| - const categoryOptions = itemCategories.map(itemCategory => ({ |
| 8 | + const categoryOptions: SelectOptionType<ItemCategoryIndex>[] = itemCategories.map(itemCategory => ({ |
9 | 9 | name: itemCategory.text,
|
10 | 10 | value: itemCategory.index
|
11 | 11 | }));
|
12 | 12 |
|
| 13 | + const categoryOptionsWithNone: SelectOptionType<NullableItemCategoryIndex>[] = [ |
| 14 | + { name: "Any categories", value: -1 }, |
| 15 | + ...categoryOptions |
| 16 | + ]; |
| 17 | +
|
| 18 | + const filter = $state<Filter>({ id: "", category: -1 }); |
| 19 | + const passesFiltration = (item: Item) => { |
| 20 | + if (filter.id.length > 0) { |
| 21 | + if (!item.id.toLowerCase().includes(filter.id.toLowerCase())) { |
| 22 | + return false; |
| 23 | + } |
| 24 | + } |
| 25 | +
|
| 26 | + if (filter.category >= 0) { |
| 27 | + if (filter.category !== item.category) { |
| 28 | + return false; |
| 29 | + } |
| 30 | + } |
| 31 | +
|
| 32 | + return true; |
| 33 | + } |
| 34 | +
|
13 | 35 | console.debug(JSON.stringify($saveData.myItemList.map(x => x.id).sort()));
|
14 | 36 |
|
15 | 37 | let toShowModal = $state(false);
|
|
67 | 89 | </SpeedDialButton>
|
68 | 90 | </SpeedDial>
|
69 | 91 |
|
70 |
| - <Accordion> |
| 92 | + <div class="flex justify-between space-x-20 mb-3"> |
| 93 | + <Input placeholder="ID" bind:value={filter.id} class=""> |
| 94 | + <SearchOutline slot="left"/> |
| 95 | + </Input> |
| 96 | + <Select placeholder="Category" bind:value={filter.category} items={categoryOptionsWithNone} class=""/> |
| 97 | + </div> |
| 98 | + |
| 99 | + <Accordion multiple> |
71 | 100 | {#each $saveData.myItemList as item, index (`item-${index}`)}
|
72 | 101 | {@const ordinal = index + 1}
|
73 |
| - <AccordionItem> |
74 |
| - {#snippet header()} |
75 |
| - <span >#{ordinal} {item.id} ({getItemCategory(item.category)})</span> |
76 |
| - {/snippet} |
77 |
| - <div class="my-1"> |
78 |
| - <Label>Item ID</Label> |
79 |
| - <Input bind:value={item.id} list="item-id-list"/> |
80 |
| - </div> |
81 |
| - <div class="mt-1 mb-3"> |
82 |
| - <Label>Item Count</Label> |
83 |
| - <NumberInput bind:value={item.count} step="1"/> |
84 |
| - </div> |
85 |
| - <div class="flex flex-row-reverse"> |
86 |
| - <Button on:click={() => throwAway(index)}> |
87 |
| - <TrashBinOutline/> |
88 |
| - </Button> |
89 |
| - </div> |
90 |
| - </AccordionItem> |
| 102 | + {#if passesFiltration(item)} |
| 103 | + <AccordionItem> |
| 104 | + {#snippet header()} |
| 105 | + <span >#{ordinal} {item.id} ({getItemCategory(item.category)})</span> |
| 106 | + {/snippet} |
| 107 | + <div class="my-1"> |
| 108 | + <Label>Item ID</Label> |
| 109 | + <Input bind:value={item.id} list="item-id-list"/> |
| 110 | + </div> |
| 111 | + <div class="mt-1 mb-3"> |
| 112 | + <Label>Item Count</Label> |
| 113 | + <NumberInput bind:value={item.count} step="1"/> |
| 114 | + </div> |
| 115 | + <div class="flex flex-row-reverse"> |
| 116 | + <Button on:click={() => throwAway(index)}> |
| 117 | + <TrashBinOutline/> |
| 118 | + </Button> |
| 119 | + </div> |
| 120 | + </AccordionItem> |
| 121 | + {/if} |
91 | 122 | {/each}
|
92 | 123 | </Accordion>
|
93 | 124 | {:else}
|
|
0 commit comments