<script lang="ts"> import { deleteComics, updateComics } from '$gql/Mutations'; import { comicsQuery } from '$gql/Queries'; import { type ComicFragment } from '$gql/graphql'; import { ComicSortLabel } from '$lib/Enums'; import { ComicFilterContext } from '$lib/Filter.svelte'; import Card, { comicCard } from '$lib/components/Card.svelte'; import Empty from '$lib/components/Empty.svelte'; import Guard from '$lib/components/Guard.svelte'; import Head from '$lib/components/Head.svelte'; import Cards from '$lib/containers/Cards.svelte'; import Column from '$lib/containers/Column.svelte'; import UpdateComicsDialog from '$lib/dialogs/UpdateComics.svelte'; import ComicFilterForm from '$lib/filter/ComicFilterForm.svelte'; import Pagination from '$lib/pagination/Pagination.svelte'; import ComicPills from '$lib/pills/ComicPills.svelte'; import Selectable from '$lib/selection/Selectable.svelte'; import { initSelectionContext } from '$lib/selection/Selection.svelte'; import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; import DeleteSelection from '$lib/toolbar/DeleteSelection.svelte'; import EditSelection from '$lib/toolbar/EditSelection.svelte'; import FilterBookmarked from '$lib/toolbar/FilterBookmarked.svelte'; import FilterFavourites from '$lib/toolbar/FilterFavourites.svelte'; import FilterOrganized from '$lib/toolbar/FilterOrganized.svelte'; import MarkBookmark from '$lib/toolbar/MarkBookmark.svelte'; import MarkFavourite from '$lib/toolbar/MarkFavourite.svelte'; import MarkOrganized from '$lib/toolbar/MarkOrganized.svelte'; import MarkSelection from '$lib/toolbar/MarkSelection.svelte'; import Search from '$lib/toolbar/Search.svelte'; import SelectItems from '$lib/toolbar/SelectItems.svelte'; import SelectSort from '$lib/toolbar/SelectSort.svelte'; import SelectionControls from '$lib/toolbar/SelectionControls.svelte'; import ToggleAdvancedFilters from '$lib/toolbar/ToggleAdvancedFilters.svelte'; import Toolbar from '$lib/toolbar/Toolbar.svelte'; import { getContextClient } from '@urql/svelte'; import type { PageProps } from './$types'; let { data }: PageProps = $props(); let pagination = $derived(data.pagination); let sort = $derived(data.sort); const client = getContextClient(); let result = $derived(comicsQuery(client, { ...data })); let comics = $derived($result.data?.comics); const selection = initSelectionContext<ComicFragment>('Comic', (c) => c.title); $effect(() => { if (comics) { selection.view = comics.edges; } }); let filter = $state(new ComicFilterContext(data.filter)); let filterSize = $derived(filter.includes + filter.excludes); $effect(() => { filter = new ComicFilterContext(data.filter); }); </script> <Head section="Comics" /> <Column> <Toolbar expand={filterSize > 0}> {#snippet start()} <SelectionControls> <MarkSelection> <MarkFavourite mutation={updateComics} /> <hr class="col-span-2 border-slate-600" /> <MarkBookmark mutation={updateComics} /> <hr class="col-span-2 border-slate-600" /> <MarkOrganized mutation={updateComics} /> </MarkSelection> <EditSelection dialog={UpdateComicsDialog} /> <DeleteSelection mutation={deleteComics} /> </SelectionControls> {/snippet} {#snippet center({ expanded, toggle })} <Search name="Comics" {filter} bind:field={filter.include.title.contains} /> <ToggleAdvancedFilters {expanded} {toggle} filterSize={filter.includes + filter.excludes} /> <div class="rounded-group flex"> <FilterFavourites {filter} /> <FilterBookmarked {filter} /> <FilterOrganized {filter} /> </div> <SelectSort {sort} labels={ComicSortLabel} /> <SelectItems {pagination} /> {/snippet} {#snippet expansion()} <ComicFilterForm {filter} /> {/snippet} </Toolbar> {#if comics} <Pagination {pagination} total={comics.count} /> <main> <Cards> {#each comics.edges as comic, index (comic.id)} <Selectable {index} id={comic.id}> {#snippet children({ onclick, selected })} <Card {...comicCard(comic)} {onclick}> {#snippet overlay()} <SelectionOverlay position="left" {selected} /> {/snippet} <ComicPills {comic} /> </Card> {/snippet} </Selectable> {:else} <Empty /> {/each} </Cards> </main> <Pagination {pagination} total={comics.count} /> {:else} <Guard {result} /> {/if} </Column>