diff options
Diffstat (limited to 'frontend/src/routes/characters')
-rw-r--r-- | frontend/src/routes/characters/+page.svelte | 101 | ||||
-rw-r--r-- | frontend/src/routes/characters/+page.ts | 12 |
2 files changed, 113 insertions, 0 deletions
diff --git a/frontend/src/routes/characters/+page.svelte b/frontend/src/routes/characters/+page.svelte new file mode 100644 index 0000000..0934bab --- /dev/null +++ b/frontend/src/routes/characters/+page.svelte @@ -0,0 +1,101 @@ +<script lang="ts"> + import { deleteCharacters } from '$gql/Mutations'; + import { charactersQuery, fetchCharacter } from '$gql/Queries'; + import type { Character } from '$gql/graphql'; + import { CharacterSortLabel } from '$lib/Enums'; + import { BasicFilterContext, initFilterContext } from '$lib/Filter'; + import { initPaginationContext } from '$lib/Pagination'; + import { initSelectionContext } from '$lib/Selection'; + import { initSortContext } from '$lib/Sort'; + import { toastFinally } from '$lib/Toasts'; + import AddButton from '$lib/components/AddButton.svelte'; + import Cardlet from '$lib/components/Cardlet.svelte'; + import Empty from '$lib/components/Empty.svelte'; + import Guard from '$lib/components/Guard.svelte'; + import Head from '$lib/components/Head.svelte'; + import Cardlets from '$lib/containers/Cardlets.svelte'; + import Column from '$lib/containers/Column.svelte'; + import AddCharacter from '$lib/dialogs/AddCharacter.svelte'; + import EditCharacter from '$lib/dialogs/EditCharacter.svelte'; + import Pagination from '$lib/pagination/Pagination.svelte'; + import Selectable from '$lib/selection/Selectable.svelte'; + import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; + import DeleteSelection from '$lib/toolbar/DeleteSelection.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 Toolbar from '$lib/toolbar/Toolbar.svelte'; + import { getContextClient } from '@urql/svelte'; + import { openModal } from 'svelte-modals'; + import type { PageData } from './$types'; + + const client = getContextClient(); + export let data: PageData; + + $: result = charactersQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: characters = $result.data?.characters; + + const selection = initSelectionContext<Character>('Character', (c) => c.name); + $: if (characters) { + $selection.view = characters.edges; + $pagination.total = characters.count; + } + + const filter = initFilterContext<BasicFilterContext>(); + $: $filter = new BasicFilterContext(data.filter); + + const sort = initSortContext(data.sort, CharacterSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchCharacter(client, id) + .then((character) => openModal(EditCharacter, { character })) + .catch(toastFinally); + }; +</script> + +<Head section="characters" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <DeleteSelection mutation={deleteCharacters} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Characters" bind:field={$filter.include.controls.name.contains} /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add Character" on:click={() => openModal(AddCharacter)} /> + </svelte:fragment> + </Toolbar> + {#if characters} + <Pagination /> + <main> + <Cardlets> + {#each characters.edges as { id, name }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} on:click={handle} filter="characters" {id}> + <SelectionOverlay slot="overlay" position="right" centered {selected} /> + </Cardlet> + </Selectable> + {:else} + <Empty /> + {/each} + </Cardlets> + </main> + <Pagination /> + {:else} + <Guard {result} /> + {/if} +</Column> diff --git a/frontend/src/routes/characters/+page.ts b/frontend/src/routes/characters/+page.ts new file mode 100644 index 0000000..4f7a3cf --- /dev/null +++ b/frontend/src/routes/characters/+page.ts @@ -0,0 +1,12 @@ +import { CharacterSort, type CharacterFilterInput } from '$gql/graphql'; +import { parseFilter, parsePaginationData, parseSortData } from '$lib/Navigation'; + +export const trailingSlash = 'always'; + +export function load({ url }: { url: URL; params: Record<string, string> }) { + return { + sort: parseSortData(url.searchParams, CharacterSort.Name), + filter: parseFilter<CharacterFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} |