Convert tasks list and task view to Remote Function queries.
This commit is contained in:
parent
5c8ef1fde5
commit
9883e643e6
57
src/lib/remotes/TasksRemote.remote.ts
Normal file
57
src/lib/remotes/TasksRemote.remote.ts
Normal 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,
|
||||||
|
};
|
||||||
|
});
|
||||||
@ -1,31 +1,17 @@
|
|||||||
<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}
|
||||||
|
{@render description(task.type.prefix, task.taskId, task.description)}
|
||||||
|
{@render details(
|
||||||
task.status,
|
task.status,
|
||||||
task.priority,
|
task.priority,
|
||||||
task.openDate,
|
task.openDate,
|
||||||
@ -33,9 +19,10 @@ let { task, parent, children }: {
|
|||||||
parent,
|
parent,
|
||||||
children,
|
children,
|
||||||
)}
|
)}
|
||||||
{@render checklist(task.checklist)}
|
{@render checklist(task.checklist)}
|
||||||
{@render body(task.body, task.bodyHistory)}
|
{@render body(task.body, task.bodyHistory)}
|
||||||
{@render integrations(task.integrations)}
|
{@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)}
|
||||||
|
{#if child.type.prefix}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{child.prefix + child.taskId}</td>
|
<td>{child.type.prefix + child.taskId}</td>
|
||||||
<td>{child.description}</td>
|
<td>{child.description}</td>
|
||||||
<td>{child.status}</td>
|
<td>{child.status}</td>
|
||||||
</tr>
|
</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"])}
|
||||||
|
|||||||
@ -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",
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -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}
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ export const load: PageServerLoad = async ({ params }) => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
params,
|
||||||
task,
|
task,
|
||||||
parent,
|
parent,
|
||||||
children,
|
children,
|
||||||
|
|||||||
@ -45,16 +45,16 @@ 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;
|
||||||
@ -63,8 +63,8 @@ const children = childrenTask.map(x => ({
|
|||||||
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>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user