Svelte query

Svelte query

Product name
Price
Quantity
Category
Expiration date
Location
Manufacturer
Sprouts - Onion
261.51
972
furniture
7/14/2023
Apt 1819
Feedspan
Beer - True North Lager
191.32
38
furniture
7/17/2023
Suite 11
Brainlounge
Milk - Condensed
826.1
714
furniture
6/9/2022
Apt 767
Vimbo
Brandy Cherry - Mcguinness
555.07
212
electronics
2/26/2022
Suite 47
Brainlounge
Olive - Spread Tapenade
506.45
509
furniture
3/5/2022
Room 1868
Gabtune
Tea - Black Currant
750.65
848
clothing
11/1/2022
Room 1846
Skaboo
Coconut Milk - Unsweetened
658.56
149
electronics
8/5/2022
PO Box 75154
Jaloo
Nut - Walnut, Pieces
763.42
147
furniture
9/7/2023
PO Box 39137
Kimia
Apple - Northern Spy
81.35
950
clothing
12/12/2023
Room 1284
Linkbridge
Orange - Canned, Mandarin
939.59
200
furniture
7/28/2022
18th Floor
Feedbug

0 : 10 / 1000

//page.ts
import { inventoryData } from "$lib/data/inventory"
import { paginateData } from "$lib/datagrid/fns/paginate-data"

export async function load() {

	// provide initial data to datagrid with fetch	
	// in this example we will use workaround for an endpoint

    const page = 1
    const perPage = 10
    const data = paginateData(inventoryData, page, perPage)
    const count = inventoryData.length
    return {
        data,
        count,
        page,
        perPage
    }
}
<script lang="ts">
	import { setContext } from 'svelte';
	import { columns } from './columns.svelte';
	import { type InventoryDataRow } from '$lib/data/inventory';
	import { TzezarDatagrid, type ConstructorOptions } from '$lib/datagrid/tzezar-datagrid.svelte';
	import * as Datagrid from '$lib/datagrid';
	import { cn } from '$lib/utils';
	import { createQuery } from '@tanstack/svelte-query';
	import { simulateServerRequest } from './simulate-server-request';

	type InitialData = {
		data: InventoryDataRow[];
		count: number;
		perPage: number;
		page: number;
	};

	let { initialData }: { initialData: InitialData } = $props();

	const config: ConstructorOptions = {
		state: {
			pagination: {
				count: initialData.count,
				perPage: initialData.perPage,
				page: initialData.page
			}
		},
		options: {
			pagination: { display: true },
			rows: { striped: true },
			footer: { display: false },
			topbar: {
				display: true,
				displayCopyDataMenu: false,
				displayExportDataMenu: false,
				displayFullscreenToggle: true,
				displayHeadFilterToggle: true,
				settingsMenu: {
					display: true
				}
			}
		}
	};

	let datagrid = setContext(
		`datagrid`,
		new TzezarDatagrid({
			mode: 'server',
			title: 'Svelte query',
			data: initialData.data,
			columns,
			onChange: () => $query.refetch(),
			...config
		})
	);
	// this is damn buggy with svelte 5
	// query keys are not reactive, not sure if could be fixed with eg writable store as they suggest
	let query = createQuery({
		queryKey: ['inventory', datagrid.state.pagination.page],
		queryFn: async () => {
			return await simulateServerRequest({
				page: datagrid.state.pagination.page,
				perPage: datagrid.state.pagination.perPage,
				filters: datagrid.state.filters,
				sorting: datagrid.state.sortingArray
			});
		},
		initialData,
		refetchOnMount: false
	});

	// need to put everything in effect cuz svelte query does not work with $derrived or other,
	// and its not possible (or skill issue - let me know) to update values after refetch
	$effect(() => {
		datagrid.state.status.isError = $query.isError;
		datagrid.state.status.isRefetching = $query.isRefetching;
		datagrid.state.status.isFetching = $query.isFetching;
		datagrid.internal.paginatedData = $query.data?.data;
		datagrid.state.pagination.count = $query.data?.count;
		datagrid.state.pagination.page = $query.data?.page;
		datagrid.state.pagination.perPage = $query.data?.perPage;
	});
</script>

<Datagrid.Datagrid>
	{#snippet head()}
		{#each datagrid.columns as column, i (column.id)}
			<Datagrid.Header {column}>
				{#snippet filter()}
					<Datagrid.ColumnFilter {column} />
				{/snippet}
			</Datagrid.Header>
		{/each}
	{/snippet}
	{#snippet body()}
		{#each datagrid.internal.paginatedData as row, rowIndex}
			<Datagrid.Row {rowIndex}>
				{#each datagrid.columns as column, columnIndex}
					<Datagrid.Cell
						{row}
						{column}
						{columnIndex}
						{rowIndex}
						class={{
							cell: cn(row['quantity'] < 200 && 'text-red-500')
						}}
					/>
				{/each}
			</Datagrid.Row>
		{/each}
	{/snippet}
</Datagrid.Datagrid>