Merge Bug Report and Update System into main #1

Merged
lyzcoote merged 14 commits from bug-report into main 2026-02-17 11:23:10 +01:00
3 changed files with 57 additions and 36 deletions
Showing only changes of commit c2052595cb - Show all commits

View File

@@ -1,7 +1,7 @@
import type { PageServerLoad } from './$types';
import { db } from '$lib/server/db';
import { bugReports, bugReportFiles } from '$lib/schema';
import { eq, like, or, count, sql, desc } from 'drizzle-orm';
import { eq, like, or, count, sql, desc, and } from 'drizzle-orm';
export const load: PageServerLoad = async ({ url }) => {
const page = Math.max(1, Number(url.searchParams.get('page')) || 1);
@@ -10,44 +10,31 @@ export const load: PageServerLoad = async ({ url }) => {
const search = url.searchParams.get('search') || '';
const conditions = [];
if (status && ['new', 'in_review', 'resolved', 'closed'].includes(status)) {
conditions.push(eq(bugReports.status, status as 'new' | 'in_review' | 'resolved' | 'closed'));
}
if (search) {
const pattern = `%${search}%`;
conditions.push(
or(
like(bugReports.hostname, pattern),
like(bugReports.os_user, pattern),
like(bugReports.name, pattern),
like(bugReports.email, pattern)
)!
like(bugReports.hostname, `%${search}%`),
like(bugReports.os_user, `%${search}%`),
like(bugReports.name, `%${search}%`),
like(bugReports.email, `%${search}%`)
)
);
}
const where = conditions.length > 0
? conditions.length === 1
? conditions[0]
: sql`${conditions[0]} AND ${conditions[1]}`
: undefined;
const where = conditions.length > 0 ? and(...conditions) : undefined;
const [totalResult] = await db
.select({ count: count() })
// Get total count
const [{ total }] = await db
.select({ total: count() })
.from(bugReports)
.where(where);
const total = totalResult.count;
const totalPages = Math.max(1, Math.ceil(total / pageSize));
const fileCountSubquery = db
.select({
report_id: bugReportFiles.report_id,
file_count: count().as('file_count')
})
.from(bugReportFiles)
.groupBy(bugReportFiles.report_id)
.as('fc');
// Get paginated reports with file count
const reports = await db
.select({
id: bugReports.id,
@@ -57,21 +44,27 @@ export const load: PageServerLoad = async ({ url }) => {
os_user: bugReports.os_user,
status: bugReports.status,
created_at: bugReports.created_at,
file_count: sql<number>`COALESCE(${fileCountSubquery.file_count}, 0)`.as('file_count')
file_count: count(bugReportFiles.id)
})
.from(bugReports)
.leftJoin(fileCountSubquery, eq(bugReports.id, fileCountSubquery.report_id))
.leftJoin(bugReportFiles, eq(bugReports.id, bugReportFiles.report_id))
.where(where)
.groupBy(bugReports.id)
.orderBy(desc(bugReports.created_at))
.limit(pageSize)
.offset((page - 1) * pageSize);
return {
reports: reports.map((r) => ({
...r,
created_at: r.created_at.toISOString()
})),
pagination: { page, pageSize, total, totalPages },
filters: { status, search }
reports,
pagination: {
page,
pageSize,
total,
totalPages: Math.ceil(total / pageSize)
},
filters: {
status,
search
}
};
};

View File

@@ -1,8 +1,8 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { goto, invalidateAll } from '$app/navigation';
import { page } from '$app/stores';
import { statusColors, statusLabels, formatDate } from '$lib/utils';
import { Search, ChevronLeft, ChevronRight, Filter, Paperclip } from 'lucide-svelte';
import { Search, ChevronLeft, ChevronRight, Filter, Paperclip, RefreshCcw } from 'lucide-svelte';
let { data } = $props();
@@ -33,6 +33,14 @@
statusFilter = '';
goto('/');
}
async function refreshReports() {
try {
await invalidateAll();
} catch (err) {
console.error('Failed to refresh reports:', err);
}
}
</script>
<div class="space-y-4">
@@ -66,6 +74,13 @@
<Filter class="h-4 w-4" />
Filter
</button>
<button
onclick={refreshReports}
class="inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90"
>
<RefreshCcw class="h-4 w-4" />
Filter
</button>
{#if data.filters.search || data.filters.status}
<button
onclick={clearFilters}

View File

@@ -0,0 +1,13 @@
import type { RequestHandler } from './$types';
import { json } from '@sveltejs/kit';
import { db } from '$lib/server/db';
import { bugReports } from '$lib/schema';
import { count } from 'drizzle-orm';
export const GET: RequestHandler = async () => {
const [{ total }] = await db
.select({ total: count() })
.from(bugReports);
return json({ total });
};