Skip to content

Commit

Permalink
Connect results to toolbar and implement select-all
Browse files Browse the repository at this point in the history
  • Loading branch information
eyeseast committed Mar 29, 2024
1 parent 0577b6f commit 83b535e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
36 changes: 25 additions & 11 deletions src/lib/components/documents/ResultsList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
import { writable, type Writable } from "svelte/store";
import Button from "../common/Button.svelte";
export const selected: Writable<(number | string)[]> = writable([]);
// IDs might be strings or numbers, depending on the API endpoint
// enforce type consistency here to avoid comparison bugs later
export const selected: Writable<string[]> = writable([]);
export let visible: Writable<Set<string>> = writable(new Set());
export let total: Writable<number> = writable(0);
</script>

<script lang="ts">
Expand All @@ -25,6 +30,9 @@
let end: HTMLElement;
let observer: IntersectionObserver;
// track what's visible so we can compare to $selected
$: $visible = new Set(results.map((d) => String(d.id)));
// load the next set of results
async function load(url: URL) {
loading = true;
Expand All @@ -39,37 +47,39 @@
const r: DocumentResults = await res.json();
results = [...results, ...r.results];
count = r.count;
$total = r.count;
next = r.next;
loading = false;
if (auto) watch();
if (auto) watch(end);
}
function watch() {
function watch(el: HTMLElement) {
const io = new IntersectionObserver((entries, observer) => {
entries.forEach(async (entry) => {
if (entry.isIntersecting && next) {
await load(new URL(next));
observer.unobserve(end);
observer.unobserve(el);
}
});
});
io.observe(end);
io.observe(el);
return io;
}
function unwatch(io: IntersectionObserver) {
io.unobserve(end);
function unwatch(io: IntersectionObserver, el: HTMLElement) {
io.unobserve(el);
}
onMount(() => {
// set initial total, update later
$total = count;
if (auto) {
observer = watch();
observer = watch(end);
}
return () => {
unwatch(observer);
unwatch(observer, end);
};
});
</script>
Expand All @@ -79,7 +89,11 @@
<Flex gap={0.625} align="center">
<label>
<span class="sr-only">Select</span>
<input type="checkbox" bind:group={$selected} value={document.id} />
<input
type="checkbox"
bind:group={$selected}
value={String(document.id)}
/>
</label>
<DocumentListItem {document} />
</Flex>
Expand Down
34 changes: 31 additions & 3 deletions src/routes/app/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<script lang="ts">
import { _ } from "svelte-i18n";
import { Hourglass24 } from "svelte-octicons";
import ResultsList from "$lib/components/documents/ResultsList.svelte";
import ResultsList, {
selected,
total,
visible,
} from "$lib/components/documents/ResultsList.svelte";
import ContentLayout from "$lib/components/ContentLayout.svelte";
import PageToolbar from "$lib/components/common/PageToolbar.svelte";
import Search from "$lib/components/Search.svelte";
Expand All @@ -11,6 +15,14 @@
$: searchResults = data.searchResults;
$: query = data.query;
function selectAll(e) {
if (e.target.checked) {
$selected = [...$visible];
} else {
$selected = [];
}
}
</script>

<ContentLayout>
Expand All @@ -30,8 +42,24 @@

<PageToolbar slot="footer">
<label slot="left">
<input type="checkbox" name="select_all" />
Select all
<input
type="checkbox"
name="select_all"
checked={$selected.length === $visible.size}
indeterminate={$selected.length > 0 && $selected.length < $visible.size}
on:change={selectAll}
/>
{#if $selected.length > 0}
{$selected.length} selected
{:else}
Select all
{/if}
</label>

<svelte:fragment slot="center">
{#if $visible && $total}
Showing {$visible.size} of {$total} results
{/if}
</svelte:fragment>
</PageToolbar>
</ContentLayout>

0 comments on commit 83b535e

Please sign in to comment.