Files
cc-backend/web/frontend/src/generic/filters/Tags.svelte
Christoph Kluge 3ca1127685 Restructure frontend svelte file src folder
- Goal: Dependency structure mirrored in file structure
2024-07-26 12:34:18 +02:00

102 lines
2.7 KiB
Svelte

<!--
@component Filter sub-component for selecting tags
Properties:
- `isModified Bool?`: Is this filter component modified [Default: false]
- `isOpen Bool?`: Is this filter component opened [Default: false]
- `tags [Number]?`: The currently selected tags (as IDs) [Default: []]
Events:
- `set-filter, {[Number]}`: Set 'tag' filter in upstream component
-->
<script>
import { createEventDispatcher, getContext } from "svelte";
import {
Button,
ListGroup,
ListGroupItem,
Input,
Modal,
ModalBody,
ModalHeader,
ModalFooter,
Icon,
} from "@sveltestrap/sveltestrap";
import { fuzzySearchTags } from "../utils.js";
import Tag from "../helper/Tag.svelte";
const allTags = getContext("tags"),
initialized = getContext("initialized"),
dispatch = createEventDispatcher();
export let isModified = false;
export let isOpen = false;
export let tags = [];
let pendingTags = [...tags];
$: isModified =
tags.length != pendingTags.length ||
!tags.every((tagId) => pendingTags.includes(tagId));
let searchTerm = "";
</script>
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
<ModalHeader>Select Tags</ModalHeader>
<ModalBody>
<Input type="text" placeholder="Search" bind:value={searchTerm} />
<br />
<ListGroup>
{#if $initialized}
{#each fuzzySearchTags(searchTerm, allTags) as tag (tag)}
<ListGroupItem>
{#if pendingTags.includes(tag.id)}
<Button
outline
color="danger"
on:click={() =>
(pendingTags = pendingTags.filter((id) => id != tag.id))}
>
<Icon name="dash-circle" />
</Button>
{:else}
<Button
outline
color="success"
on:click={() => (pendingTags = [...pendingTags, tag.id])}
>
<Icon name="plus-circle" />
</Button>
{/if}
<Tag {tag} />
</ListGroupItem>
{:else}
<ListGroupItem disabled>No Tags</ListGroupItem>
{/each}
{/if}
</ListGroup>
</ModalBody>
<ModalFooter>
<Button
color="primary"
on:click={() => {
isOpen = false;
tags = [...pendingTags];
dispatch("set-filter", { tags });
}}>Close & Apply</Button
>
<Button
color="danger"
on:click={() => {
isOpen = false;
tags = [];
pendingTags = [];
dispatch("set-filter", { tags });
}}>Reset</Button
>
<Button on:click={() => (isOpen = false)}>Close</Button>
</ModalFooter>
</Modal>