diff options
Diffstat (limited to '')
-rw-r--r-- | frontend/src/routes/worlds/+page.svelte | 102 | ||||
-rw-r--r-- | frontend/src/routes/worlds/+page.ts | 12 |
2 files changed, 114 insertions, 0 deletions
diff --git a/frontend/src/routes/worlds/+page.svelte b/frontend/src/routes/worlds/+page.svelte new file mode 100644 index 0000000..e0366e9 --- /dev/null +++ b/frontend/src/routes/worlds/+page.svelte @@ -0,0 +1,102 @@ +<script lang="ts"> + import { deleteWorlds } from '$gql/Mutations'; + import { fetchWorld, worldsQuery } from '$gql/Queries'; + import type { World } from '$gql/graphql'; + import { WorldSortLabel } 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 AddWorld from '$lib/dialogs/AddWorld.svelte'; + import EditWorld from '$lib/dialogs/EditWorld.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 = worldsQuery(client, { + pagination: data.pagination, + filter: data.filter, + sort: data.sort + }); + + $: worlds = $result.data?.worlds; + + const selection = initSelectionContext<World>('World', (w) => w.name); + $: if (worlds) { + $selection.view = worlds.edges; + $pagination.total = worlds.count; + } + + const filter = initFilterContext<BasicFilterContext>(); + $: $filter = new BasicFilterContext(data.filter); + + const sort = initSortContext(data.sort, WorldSortLabel); + $: $sort.update = data.sort; + + const pagination = initPaginationContext(); + $: $pagination.update = data.pagination; + + const edit = (id: number) => { + fetchWorld(client, id) + .then((world) => openModal(EditWorld, { world })) + .catch(toastFinally); + }; +</script> + +<Head section="Worlds" /> + +<Column> + <Toolbar> + <SelectionControls slot="start"> + <DeleteSelection mutation={deleteWorlds} /> + </SelectionControls> + <svelte:fragment slot="center"> + <Search name="Worlds" bind:field={$filter.include.controls.name.contains} /> + <SelectSort /> + <SelectItems /> + </svelte:fragment> + <svelte:fragment slot="end"> + <AddButton title="Add World" on:click={() => openModal(AddWorld)} /> + </svelte:fragment> + </Toolbar> + {#if worlds} + <Pagination /> + <main> + <Cardlets> + {#each worlds.edges as { id, name }, index (id)} + <Selectable {index} {id} {edit} let:handle let:selected> + <Cardlet {name} on:click={handle} filter="worlds" {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/worlds/+page.ts b/frontend/src/routes/worlds/+page.ts new file mode 100644 index 0000000..3b85f4c --- /dev/null +++ b/frontend/src/routes/worlds/+page.ts @@ -0,0 +1,12 @@ +import { WorldSort, type WorldFilterInput } 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, WorldSort.Name), + filter: parseFilter<WorldFilterInput>(url.searchParams), + pagination: parsePaginationData(url.searchParams) + }; +} |