changed to svelte headless table for reactive data

This commit is contained in:
John O'Keefe 2024-09-07 19:33:02 -04:00
parent cbcb07d2f1
commit 5915bb28b8
2 changed files with 99 additions and 139 deletions

View File

@ -16,6 +16,7 @@
"postcss": "^8.4.45", "postcss": "^8.4.45",
"svelte": "^4.0.0", "svelte": "^4.0.0",
"svelte-check": "^3.4.3", "svelte-check": "^3.4.3",
"svelte-headless-table": "^0.18.2",
"svelte-preprocess": "^5.0.3", "svelte-preprocess": "^5.0.3",
"svelte-spa-router": "^4.0.1", "svelte-spa-router": "^4.0.1",
"tailwind-merge": "^2.5.2", "tailwind-merge": "^2.5.2",
@ -26,7 +27,6 @@
}, },
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"@tanstack/svelte-table": "^8.20.5",
"flowbite": "^2.5.1", "flowbite": "^2.5.1",
"flowbite-svelte": "^0.46.16", "flowbite-svelte": "^0.46.16",
"moment": "^2.30.1" "moment": "^2.30.1"

View File

@ -1,151 +1,111 @@
<script lang="ts"> <script lang="ts">
import {writable} from 'svelte/store' import {createTable, Render, Subscribe} from "svelte-headless-table";
import type {ColumnDef, TableOptions} from '@tanstack/svelte-table' // @ts-ignore
import { import { addSortBy } from "svelte-headless-table/plugins";
createSvelteTable,
flexRender,
getCoreRowModel,
getSortedRowModel,
type OnChangeFn,
type SortingState,
} from '@tanstack/svelte-table'
import {tableItems} from "./GlobalVariablesAndHelperFunctions.svelte" import {tableItems} from "./GlobalVariablesAndHelperFunctions.svelte"
import type {TableItem, TableItems} from "../helperTypes/TableTypes";
let tableItemsView: TableItems //when adding sort here is code { sort: addSortBy() }
tableItems.subscribe(value => tableItemsView = value) const table = createTable(tableItems, { sort: addSortBy() })
const defaultColumns: ColumnDef<TableItem>[] = [ const columns = table.createColumns([
{ table.column({
accessorKey: 'id', header: "Service Id",
header: () => "Service Id", accessor: 'id',
cell: info => info.getValue(), }),
}, table.column({
{ header: 'Service',
accessorKey: 'service', accessor: 'service',
header: () => 'Service', }),
cell: info => info.getValue(), table.column({
}, header: 'Episode Progress',
{ accessor: 'progress',
accessorKey: 'progress', }),
header: () => 'Episode Progress', table.column({
cell: info => info.getValue(), header: 'Status',
}, accessor: 'status',
{ }),
accessorKey: 'status', table.column({
header: () => 'Status', header: 'Started At',
cell: info => info.getValue(), accessor: 'startedAt',
}, }),
{ table.column({
accessorKey: 'startedAt', header: 'Completed At',
header: () => 'Started At', accessor: 'completedAt',
cell: info => info.getValue(), }),
}, table.column({
{ header: 'Rating',
accessorKey: 'completedAt', accessor: 'score',
header: () => 'Completed At', }),
cell: info => info.getValue(), table.column({
}, header: 'Repeat',
{ accessor: 'repeat',
accessorKey: 'score', }),
header: () => 'Rating', table.column({
cell: info => info.getValue(), header: 'Notes',
}, accessor: 'notes',
{ }),
accessorKey: 'repeat', ])
header: () => 'Repeat',
cell: info => info.getValue(),
},
{
accessorKey: 'notes',
header: () => 'Notes',
cell: info => info.getValue(),
},
]
let sorting: SortingState = [] //add pluginStates when add sort back
const {
const setSorting: OnChangeFn<SortingState> = updater => { headerRows,
if (updater instanceof Function) { rows,
sorting = updater(sorting) tableAttrs,
} else { tableBodyAttrs,
sorting = updater } = table.createViewModel(columns)
}
options.update(old => ({
...old,
state: {
...old.state,
sorting,
},
}))
}
const options = writable<TableOptions<TableItem>>({
data: tableItemsView,
columns: defaultColumns,
state: {
sorting,
},
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
})
const rerender = () => {
console.log(tableItemsView)
options.update(options => ({
...options,
data: tableItemsView,
}))
}
const table = createSvelteTable(options)
</script> </script>
<div class="relative overflow-x-auto rounded-lg mb-5"> <div class="relative overflow-x-auto rounded-lg mb-5">
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400"> <table
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400"
{#each $table.getHeaderGroups() as headerGroup} {...$tableAttrs}
<tr>
{#each headerGroup.headers as header}
<th class="px-6 py-3">
{#if !header.isPlaceholder}
<button
class:cursor-pointer={header.column.getCanSort()}
class:select-none={header.column.getCanSort()}
on:click={header.column.getToggleSortingHandler()}
> >
<svelte:component <thead
this={flexRender( class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"
header.column.columnDef.header, >
header.getContext() {#each $headerRows as headerRow (headerRow.id)}
)} <Subscribe attrs={headerRow.attrs()} let:attrs>
/> <tr {...attrs}>
{#if header.column.getIsSorted().toString() === 'asc'} {#each headerRow.cells as cell (cell.id)}
🔼 <Subscribe attrs={cell.attrs()} let:attrs props={cell.props()} let:props>
{:else if header.column.getIsSorted().toString() === 'desc'} <th
🔽 {...attrs}
{/if} on:click={props.sort.toggle}
</button> class:sorted={props.sort.order !== undefined}
class="px-6 py-3"
>
<div>
<Render of={cell.render()}/>
{#if props.sort.order === 'asc'}
⬇️
{:else if props.sort.order === 'desc'}
⬆️
{/if} {/if}
</div>
</th> </th>
</Subscribe>
{/each} {/each}
</tr> </tr>
</Subscribe>
{/each} {/each}
</thead> </thead>
<tbody> <tbody {...$tableBodyAttrs}>
{#each $table.getRowModel().rows as row} {#each $rows as row (row.id)}
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"> <Subscribe attrs={row.attrs()} let:attrs>
{#each row.getVisibleCells() as cell} <tr
<td class="px-6 py-4"> {...attrs}
<svelte:component class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"
this={flexRender(cell.column.columnDef.cell, cell.getContext())} >
/> {#each row.cells as cell (cell.id)}
<Subscribe attrs={cell.attrs()} let:attrs>
<td {...attrs} class="px-6 py-4">
<Render of={cell.render()}/>
</td> </td>
</Subscribe>
{/each} {/each}
</tr> </tr>
</Subscribe>
{/each} {/each}
</tbody> </tbody>
</table> </table>
<button on:click={() => rerender()} class="border p-2 mb-3"> Rerender</button>
</div> </div>