feat: añade paginación y búsqueda con ESCAPE en tareas

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
webui
borja 2 weeks ago
parent 1bd28380b8
commit d2cd2aff00

@ -19,10 +19,11 @@ export const GET: RequestHandler = async (event) => {
const limit = clamp(parseInt(url.searchParams.get('limit') || '20', 10) || 20, 1, 100);
const dueBeforeParam = (url.searchParams.get('dueBefore') || '').trim();
const soonDaysParam = parseInt(url.searchParams.get('soonDays') || '', 10);
const soonDays = Number.isFinite(soonDaysParam) && soonDaysParam >= 0 ? Math.min(soonDaysParam, 365) : null;
let dueCutoff: string | null = dueBeforeParam || null;
if (!dueCutoff && Number.isFinite(soonDaysParam) && soonDaysParam >= 0) {
if (!dueCutoff && soonDays != null) {
const d = new Date();
d.setUTCDate(d.getUTCDate() + soonDaysParam);
d.setUTCDate(d.getUTCDate() + soonDays);
dueCutoff = d.toISOString().slice(0, 10);
}
@ -48,7 +49,7 @@ export const GET: RequestHandler = async (event) => {
params.push(userId);
if (search) {
whereParts.push(`t.description LIKE ?`);
whereParts.push(`t.description LIKE ? ESCAPE '\\'`);
params.push(`%${search.replace(/%/g, '\\%').replace(/_/g, '\\_')}%`);
}

@ -17,24 +17,29 @@ export const load: PageServerLoad = async (event) => {
display_code: number | null;
assignees: string[];
}> = [];
let hasMore: boolean = false;
// Filtros desde la query (?q=&soonDays=)
const q = (event.url.searchParams.get('q') || '').trim();
const soonDaysStr = (event.url.searchParams.get('soonDays') || '').trim();
const pageStr = (event.url.searchParams.get('page') || '1').trim();
const page = Math.max(1, parseInt(pageStr, 10) || 1);
try {
let fetchUrl = '/api/me/tasks?limit=20';
if (q) fetchUrl += `&search=${encodeURIComponent(q)}`;
if (soonDaysStr) fetchUrl += `&soonDays=${encodeURIComponent(soonDaysStr)}`;
fetchUrl += `&page=${encodeURIComponent(String(page))}`;
const res = await event.fetch(fetchUrl);
if (res.ok) {
const json = await res.json();
tasks = Array.isArray(json?.items) ? json.items : [];
hasMore = Boolean(json?.hasMore);
}
} catch {
// Ignorar errores y dejar lista vacía
}
return { userId, tasks, q, soonDays: soonDaysStr ? Number(soonDaysStr) : null };
return { userId, tasks, q, soonDays: soonDaysStr ? Number(soonDaysStr) : null, page, hasMore };
};

@ -11,6 +11,8 @@
}>;
q?: string | null;
soonDays?: number | null;
page?: number | null;
hasMore?: boolean | null;
};
</script>
@ -54,4 +56,23 @@
</ul>
{/if}
{#if (data.page ?? 1) > 1 || data.hasMore}
<nav style="margin-top: 1rem;">
{#if (data.page ?? 1) > 1}
<a href={`/app?${new URLSearchParams({
q: data.q ?? '',
soonDays: data.soonDays != null ? String(data.soonDays) : '',
page: String((data.page ?? 1) - 1)
}).toString()}`}>Anterior</a>
{/if}
{#if data.hasMore}
<a style="margin-left:8px" href={`/app?${new URLSearchParams({
q: data.q ?? '',
soonDays: data.soonDays != null ? String(data.soonDays) : '',
page: String((data.page ?? 1) + 1)
}).toString()}`}>Siguiente</a>
{/if}
</nav>
{/if}
<p style="margin-top:1rem;">La cookie de sesión se renueva con cada visita (idle timeout).</p>

Loading…
Cancel
Save