Convert tasks list and task view to Remote Function queries.

This commit is contained in:
themodrnhakr 2025-10-04 01:31:42 -05:00
parent 5c8ef1fde5
commit 9883e643e6
6 changed files with 133 additions and 101 deletions

View File

@ -0,0 +1,57 @@
import { query } from "$app/server";
import TasksService from "$lib/server/services/TasksService";
import { error } from "@sveltejs/kit";
import * as z from "zod";
const service = new TasksService("internal");
export const getAllTasks = query(async () => {
const tasksResponse = await service.getAll();
if (tasksResponse.status === "failure") {
const errorMessage = tasksResponse.error instanceof Error
? tasksResponse.error.message
: tasksResponse.error ?? "Internal error.";
throw new Error(errorMessage);
}
if (!tasksResponse.data) {
throw new Error("Internal error");
}
return tasksResponse.data;
});
export const getOneTask = query(z.union([z.string(), z.number()]), async (lookup_field: string | number) => {
const tasksResponse = typeof lookup_field === "string"
? await service.getByTaskId([lookup_field])
: await service.getByDbId([lookup_field]);
if (tasksResponse.status === "failure") {
const errorMessage = tasksResponse.error instanceof Error
? tasksResponse.error.message
: tasksResponse.error ?? "Internal error";
throw new Error(errorMessage);
}
if (!tasksResponse.data) {
error(500, "Internal error. (check the logs)");
}
const task = tasksResponse.data[0];
const parentResponse = task.parent ? await service.getByDbId([task.parent]) : null;
const parent = (!parentResponse || parentResponse.status === "failure" || !parentResponse.data
|| parentResponse.data[0].type.prefix)
? null
: parentResponse.data[0];
const childrenResponse = await service.getByParent(task.id);
const children = (!childrenResponse || childrenResponse.status === "failure" || !childrenResponse.data)
? []
: childrenResponse.data;
return {
task,
parent,
children,
};
});

View File

@ -1,41 +1,28 @@
<script lang="ts">
import { page } from "$app/state";
import { getOneTask } from "$lib/remotes/TasksRemote.remote";
import type { Task } from "$lib/server/services/TasksService";
import { error } from "@sveltejs/kit";
type DisplayableTask = Task & {
taskId: NonNullable<Task["taskId"]>;
type: Task["type"] & {
prefix: NonNullable<Task["type"]["prefix"]>;
};
};
let { task, parent, children }: {
task: DisplayableTask;
parent: {
prefix: Task["type"]["prefix"];
taskId: Task["taskId"];
description: Task["description"];
};
children: Array<{
prefix: Task["type"]["prefix"];
taskId: Task["taskId"];
description: Task["description"];
status: Task["status"];
}>;
} = $props();
if (!page.params.task_id) error(400, "Missing the 'task_id' url param.");
const taskRemote = getOneTask(page.params.task_id);
</script>
{@render description(task.type.prefix, task.taskId, task.description)}
{@render details(
task.status,
task.priority,
task.openDate,
task.closeDate,
parent,
children,
)}
{@render checklist(task.checklist)}
{@render body(task.body, task.bodyHistory)}
{@render integrations(task.integrations)}
<svelte:boundary>
{@const { task, parent, children } = await taskRemote}
{@render description(task.type.prefix, task.taskId, task.description)}
{@render details(
task.status,
task.priority,
task.openDate,
task.closeDate,
parent,
children,
)}
{@render checklist(task.checklist)}
{@render body(task.body, task.bodyHistory)}
{@render integrations(task.integrations)}
</svelte:boundary>
<style>
.container {
@ -73,19 +60,8 @@ let { task, parent, children }: {
priority: Task["priority"],
opened: Task["openDate"],
closed: Task["closeDate"],
parent: {
prefix: Task["type"]["prefix"];
taskId: Task["taskId"];
description: Task["description"];
},
children: Array<
{
prefix: Task["type"]["prefix"];
taskId: Task["taskId"];
description: Task["description"];
status: Task["status"];
}
>,
parent: Task | null,
children: Array<Task>,
)}
<div class="details">
<div class="labeled-field">
@ -108,8 +84,8 @@ let { task, parent, children }: {
<div>
<span class="label">Parent:</span>
<span>{
!Object.values(parent).some(value => value === null)
? `${parent.prefix}${parent.taskId} | ${parent.description}`
(parent && !Object.values(parent).some(value => value === null))
? `${parent.type.prefix}${parent.taskId} | ${parent.description}`
: "--"
}</span>
</div>
@ -118,11 +94,13 @@ let { task, parent, children }: {
<table>
<tbody>
{#each children as child (child.taskId)}
<tr>
<td>{child.prefix + child.taskId}</td>
<td>{child.description}</td>
<td>{child.status}</td>
</tr>
{#if child.type.prefix}
<tr>
<td>{child.type.prefix + child.taskId}</td>
<td>{child.description}</td>
<td>{child.status}</td>
</tr>
{/if}
{/each}
</tbody>
</table>
@ -139,16 +117,6 @@ let { task, parent, children }: {
<p>{history}</p>
{/if}
</div>
<div>
<h2>Updates</h2>
<p>
{
task.updateChain
? JSON.stringify(task.updateChain)
: "--"
}
</p>
</div>
{/snippet}
{#snippet checklist(checklist: Task["checklist"])}

View File

@ -1,10 +0,0 @@
import TasksService from "$lib/server/services/TasksService";
import type { PageServerLoad } from "./$types";
export const load: PageServerLoad = async () => {
const tasks = new TasksService("internal");
return {
tasks: await tasks.getAll(),
test: "string",
};
};

View File

@ -1,11 +1,25 @@
<script lang="ts">
import type { PageProps } from "./$types";
import { resolve } from "$app/paths";
import { getAllTasks } from "$lib/remotes/TasksRemote.remote";
import { type Task } from "$lib/server/services/TasksService";
let { data }: PageProps = $props();
const tasksData = getAllTasks();
</script>
{#if data.tasks.status === "ok" && data.tasks.data !== undefined}
<p>{data.tasks.data.length} total records.</p>
<svelte:boundary>
{@render view(await tasksData)}
{#snippet pending()}
<p>Loading...</p>
{/snippet}
{#snippet failed(error)}
<p>{error}</p>
{/snippet}
</svelte:boundary>
{#snippet view(tasks: Array<Task>)}
<p>{tasks.length} total records.</p>
<table>
<thead>
<tr>
@ -15,10 +29,14 @@ let { data }: PageProps = $props();
</tr>
</thead>
<tbody>
{#each data.tasks.data as task (task.id)}
{#each tasks as task (task.id)}
<tr>
<td>
<a href={`/tasks/${task.type.prefix}${task.taskId}`}>
<a
href={resolve("/tasks/[task_id]", {
task_id: `${task.type.prefix}${task.taskId}`,
})}
>
{
task.type?.prefix
+ task.taskId
@ -31,6 +49,4 @@ let { data }: PageProps = $props();
{/each}
</tbody>
</table>
{:else}
<p>There was an error accessing the database.</p>
{/if}
{/snippet}

View File

@ -27,6 +27,7 @@ export const load: PageServerLoad = async ({ params }) => {
]);
return {
params,
task,
parent,
children,

View File

@ -45,26 +45,26 @@ const children = childrenTask.map(x => ({
{#if isEditing}
<TaskEdit {task} {form} />
{:else}
<TaskView {task} {parent} {children} />
<TaskView />
{/if}
<style>
.view-controls {
margin-bottom: 2rem;
display: flex;
justify-content: flex-end;
}
.button {
/* Basic button styling for links */
display: inline-block;
padding: 0.5rem 1rem;
border: 1px solid #ccc;
border-radius: 4px;
text-decoration: none;
color: #333;
background-color: #f0f0f0;
}
.button:hover {
background-color: #e0e0e0;
}
.view-controls {
margin-bottom: 2rem;
display: flex;
justify-content: flex-end;
}
.button {
/* Basic button styling for links */
display: inline-block;
padding: 0.5rem 1rem;
border: 1px solid #ccc;
border-radius: 4px;
text-decoration: none;
color: #333;
background-color: #f0f0f0;
}
.button:hover {
background-color: #e0e0e0;
}
</style>