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

View File

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

View File

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