Support autosaving existing Tasks and explicit saving new ones

This commit is contained in:
Matte Noble
2025-06-27 10:39:13 -07:00
parent 310156c91c
commit 65abe9c2c1
7 changed files with 38 additions and 21 deletions

View File

@@ -28,13 +28,14 @@
filterProp,
}: Props = $props();
let filteredItems = $state(items);
let filterTerm = $state('');
let css = borderless ? '' : 'border-b-light border-b';
function filter() {
if (filterable && filterProp) {
filteredItems = items.filter(item => (item[filterProp] as string).includes(filterTerm));
return items.filter(item => (item[filterProp] as string).includes(filterTerm));
} else {
return items;
}
}
</script>
@@ -60,7 +61,7 @@
</Flex>
{/if}
{#each filteredItems as item, i (i)}
{#each filter() as item, i (i)}
<div class={twMerge('w-full', css)}>
{@render itemView(item)}
</div>

View File

@@ -1,4 +1,6 @@
<script lang="ts">
import { goto } from '$app/navigation';
import Button from './Button.svelte';
import Flex from '$components/Flex.svelte';
@@ -11,11 +13,12 @@
interface Props {
task: Task;
onsave?: () => void | Promise<void>;
onsave?: () => Task | Promise<Task>;
}
const { task, onsave }: Props = $props();
const isEdit = task.id !== undefined;
const isEdit = $derived(task.id !== undefined);
let mcpServers: McpServer[] = $state([]);
async function addMcpServer(mcpServer: McpServer) {
@@ -47,6 +50,15 @@
await onsave?.();
}
}
async function save() {
const task = await onsave?.();
if (task) {
mcpServers.forEach(server => task.addMcpServer(server));
goto(`/tasks/${task.id}`);
}
}
</script>
{#snippet McpServerView(mcpServer: McpServer)}
@@ -101,6 +113,6 @@
/>
{#if !isEdit}
<Button onclick={onsave} class="border-purple text-purple mt-8">Save</Button>
<Button onclick={save} class="border-purple text-purple mt-8">Save</Button>
{/if}
</Flex>

View File

@@ -44,6 +44,10 @@ export default class Task extends Base<Row>('tasks') {
return TaskMcpServer.exists({ taskId: this.id, mcpServerId: mcpServer.id });
}
should_run(): boolean {
return this.next_run <= new Date();
}
async start(force: boolean = false): Promise<void> {
if (this.should_run() || force) {
this.next_run = await this.calculate_next_run();
@@ -52,13 +56,9 @@ export default class Task extends Base<Row>('tasks') {
}
}
should_run(): boolean {
return this.next_run <= new Date();
}
async calculate_next_run(): Promise<Date> {
const interval = CronExpressionParser.parse(this.period);
return new Date(interval.next().toString());
async delete() {
TaskMcpServer.where({ taskId: this.id }).forEach(r => r.delete());
return super.delete();
}
protected async beforeSave(row: ToSqlRow<Row>): Promise<ToSqlRow<Row>> {
@@ -68,6 +68,11 @@ export default class Task extends Base<Row>('tasks') {
};
}
async calculate_next_run(): Promise<Date> {
const interval = CronExpressionParser.parse(this.period);
return new Date(interval.next().toString());
}
protected static async fromSql(row: Row): Promise<Task> {
return Task.new({
id: row.id,

View File

@@ -11,9 +11,8 @@
import Titlebar from '$components/Titlebar.svelte';
import Task from '$lib/models/task.svelte';
let allTasks: Task[] = $derived(Task.all());
const { children } = $props();
const tasks: Task[] = $derived(Task.all());
function items(task: Task): MenuItem[] {
return [
@@ -35,7 +34,7 @@
async function destroy(task: Task) {
await task.delete();
goto(`/tasks`);
await goto(`/tasks`);
}
async function edit(task: Task) {
@@ -80,7 +79,7 @@
<Layout {titlebar}>
<Flex class="h-full items-start">
<Flex class="border-r-light h-full w-[300px] flex-col items-start border-r">
<List items={allTasks} itemView={TaskView} />
<List items={tasks} itemView={TaskView} />
</Flex>
<Flex class="h-full w-[calc(100%-300px)] items-start">

View File

@@ -7,8 +7,8 @@
const taskId = Number(page.params.task_id);
const task: Task = $derived(Task.find(taskId));
async function save(): Promise<void> {
await task.save();
async function save(): Promise<Task> {
return await task.save();
}
</script>

View File

@@ -41,7 +41,7 @@
<Flex class="border-t-light h-2/5 w-full flex-col items-start border-t py-4">
<h3 class="mb-4 ml-8 uppercase">History</h3>
<List items={task.runs} itemView={RunView} class="border-t-light border-t" />
<List items={task?.runs} itemView={RunView} class="border-t-light border-t" />
</Flex>
</Flex>
{/key}

View File

@@ -5,7 +5,7 @@
const task: Task = $state(Task.new());
async function save() {
await task.save();
return await task.save();
}
</script>