added search to links page

pull/3/head
TZGyn 2 years ago
parent 6ad56232bc
commit 5ab9b27d85
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -1,5 +1,5 @@
import { db } from '$lib/db'
import { and, count, eq } from 'drizzle-orm'
import { and, count, eq, ilike } from 'drizzle-orm'
import { shortener } from '$lib/db/schema'
import type { PageServerLoad } from './$types'
@ -7,6 +7,7 @@ export const load = (async (event) => {
const user = event.locals.userObject
const project_uuid = event.url.searchParams.get('project')
const search = event.url.searchParams.get('search')
let page = parseInt(event.url.searchParams.get('page') ?? '1')
let perPage = parseInt(
event.url.searchParams.get('perPage') ?? '10',
@ -47,22 +48,28 @@ export const load = (async (event) => {
project: true,
},
orderBy: (shortener, { desc }) => [desc(shortener.createdAt)],
where: (shortener, { eq, and, isNull }) =>
where: (shortener, { eq, and, ilike }) =>
and(
eq(shortener.userId, user.id),
project_id ? eq(shortener.projectId, project_id) : undefined,
search
? ilike(shortener.link, `%${decodeURI(search)}%`)
: undefined,
),
offset: perPage * (page - 1),
limit: perPage,
})
const pagination = await db
const pagination = db
.select({ count: count() })
.from(shortener)
.where(
and(
eq(shortener.userId, user.id),
project_id ? eq(shortener.projectId, project_id) : undefined,
search
? ilike(shortener.link, `%${decodeURI(search)}%`)
: undefined,
),
)
@ -81,6 +88,7 @@ export const load = (async (event) => {
settings,
page,
perPage,
pagination: pagination[0],
search,
pagination,
}
}) satisfies PageServerLoad

@ -1,5 +1,9 @@
<script lang="ts">
import type { PageData } from './$types'
import { cn } from '$lib/utils'
import { goto } from '$app/navigation'
import { browser } from '$app/environment'
import { Button } from '$lib/components/ui/button'
import * as Dialog from '$lib/components/ui/dialog'
import * as Card from '$lib/components/ui/card'
@ -9,6 +13,10 @@
import * as Popover from '$lib/components/ui/popover'
import { Badge } from '$lib/components/ui/badge'
import * as Pagination from '$lib/components/ui/pagination'
import { Input } from '$lib/components/ui/input'
import ScrollArea from '$lib/components/ui/scroll-area/scroll-area.svelte'
import { Skeleton } from '$lib/components/ui/skeleton'
import {
BarChart,
ExternalLink,
@ -17,15 +25,12 @@
Check,
ChevronsUpDown,
} from 'lucide-svelte'
import { cn } from '$lib/utils'
import Qr from '$lib/components/QR.svelte'
import AddShortenerDialog from './(component)/AddShortenerDialog.svelte'
import ScrollArea from '$lib/components/ui/scroll-area/scroll-area.svelte'
import { Skeleton } from '$lib/components/ui/skeleton'
import EditShortenerDialog from './(component)/EditShortenerDialog.svelte'
import DeleteShortenerDialog from './(component)/DeleteShortenerDialog.svelte'
import { goto } from '$app/navigation'
import { browser } from '$app/environment'
import { onMount } from 'svelte'
export let data: PageData
@ -78,21 +83,26 @@
let page: number = data.page
let perPage: any = { label: data.perPage, value: data.perPage }
let selectedProjectUUID: string | null
let search: string | null = data.search
let searchUpdateTimeout: any
$: browser && updateUrl(selectedProjectUUID, page, perPage)
$: browser && updateUrl(selectedProjectUUID, page, perPage, search)
const updateUrl = (
selectedProjectUUID: string | null,
page: number,
perPage: any,
search: string | null,
) => {
let query = [`page=${page}`, `perPage=${perPage.value}`]
if (selectedProjectUUID) {
goto(
`/links?project=${selectedProjectUUID}&page=${page}&perPage=${perPage.value}`,
)
} else {
goto(`/links?page=${page}&perPage=${perPage.value}`)
query.push(`project=${selectedProjectUUID}`)
}
if (search) {
query.push(`search=${encodeURI(search)}`)
}
goto(`/links?${query.join('&')}`)
}
</script>
@ -152,6 +162,20 @@
</Command.Root>
</Popover.Content>
</Popover.Root>
<Input
type="text"
placeholder="search"
class="max-w-[250px]"
value={search}
on:keyup={({ target, key }) => {
if (key !== 'Enter') return
clearTimeout(searchUpdateTimeout)
searchUpdateTimeout = setTimeout(() => {
search = target.value
}, 500)
}} />
<Button disabled={!search} on:click={() => (search = '')}
>Clear</Button>
<AddShortenerDialog bind:dialogOpen projects={data.projects} />
</div>
@ -258,6 +282,25 @@
{/each}
</div>
</ScrollArea>
{:else}
<div class="flex h-full w-full items-center justify-center">
<div class="flex flex-col items-center gap-12">
<div class="flex flex-col items-center gap-4">
<div class="text-4xl font-bold">No Shortener Found</div>
</div>
<Button
on:click={() => {
dialogOpen = true
}}
class="w-fit">Add Shortener</Button>
</div>
</div>
{/if}
{/await}
{#await data.pagination}
<!-- promise is pending -->
{:then pagination}
<div class="flex items-center justify-between border-t p-4">
<Select.Root bind:selected={perPage}>
<Select.Trigger class="w-[180px]">
@ -267,9 +310,8 @@
<Select.Group>
<Select.Label>Page Size</Select.Label>
{#each [10, 20, 50, 100] as pageSize}
<Select.Item
value={pageSize}
label={pageSize.toString()}>{pageSize}</Select.Item>
<Select.Item value={pageSize} label={pageSize.toString()}
>{pageSize}</Select.Item>
{/each}
</Select.Group>
</Select.Content>
@ -277,7 +319,7 @@
</Select.Root>
<Pagination.Root
class="items-end "
count={data.pagination.count}
count={pagination[0].count}
bind:page
perPage={perPage.value}
let:pages
@ -307,20 +349,6 @@
</Pagination.Content>
</Pagination.Root>
</div>
{:else}
<div class="flex h-full w-full items-center justify-center">
<div class="flex flex-col items-center gap-12">
<div class="flex flex-col items-center gap-4">
<div class="text-4xl font-bold">No Shortener Found</div>
</div>
<Button
on:click={() => {
dialogOpen = true
}}
class="w-fit">Add Shortener</Button>
</div>
</div>
{/if}
{/await}
<EditShortenerDialog

Loading…
Cancel
Save