feat: implement plugin architecture and application settings with Svelte UI
- Added plugin base and loader for backend extensibility - Implemented application settings management with config persistence - Created Svelte-based frontend with Dashboard and Settings pages - Added API routes for plugins, tasks, and settings - Updated documentation and specifications - Improved project structure and developer tools
This commit is contained in:
127
frontend/src/components/TaskRunner.svelte
Normal file → Executable file
127
frontend/src/components/TaskRunner.svelte
Normal file → Executable file
@@ -1,54 +1,73 @@
|
||||
<script>
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { selectedTask, taskLogs } from '../lib/stores.js';
|
||||
|
||||
let ws;
|
||||
|
||||
onMount(() => {
|
||||
if ($selectedTask) {
|
||||
taskLogs.set([]); // Clear previous logs
|
||||
const wsUrl = `ws://localhost:8000/ws/logs/${$selectedTask.id}`;
|
||||
ws = new WebSocket(wsUrl);
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log('WebSocket connection established');
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
const logEntry = JSON.parse(event.data);
|
||||
taskLogs.update(logs => [...logs, logEntry]);
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log('WebSocket connection closed');
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (ws) {
|
||||
ws.close();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-white shadow-md">
|
||||
{#if $selectedTask}
|
||||
<h2 class="text-xl font-semibold mb-2">Task: {$selectedTask.plugin_id}</h2>
|
||||
<div class="bg-gray-900 text-white font-mono text-sm p-4 rounded-md h-96 overflow-y-auto">
|
||||
{#each $taskLogs as log}
|
||||
<div>
|
||||
<span class="text-gray-400">{new Date(log.timestamp).toLocaleTimeString()}</span>
|
||||
<span class="{log.level === 'ERROR' ? 'text-red-500' : 'text-green-400'}">[{log.level}]</span>
|
||||
<span>{log.message}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<p>No task selected.</p>
|
||||
{/if}
|
||||
</div>
|
||||
<!--
|
||||
[DEF:TaskRunner:Component]
|
||||
@SEMANTICS: task, runner, logs, websocket
|
||||
@PURPOSE: Connects to a WebSocket to display real-time logs for a running task.
|
||||
@LAYER: UI
|
||||
@RELATION: DEPENDS_ON -> frontend/src/lib/stores.js
|
||||
|
||||
@PROPS: None
|
||||
@EVENTS: None
|
||||
-->
|
||||
<script>
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { selectedTask, taskLogs } from '../lib/stores.js';
|
||||
|
||||
let ws;
|
||||
|
||||
// [DEF:onMount:Function]
|
||||
// @PURPOSE: Initialize WebSocket connection for task logs.
|
||||
onMount(() => {
|
||||
if ($selectedTask) {
|
||||
console.log(`[TaskRunner][Entry] Connecting to logs for task: ${$selectedTask.id}`);
|
||||
taskLogs.set([]); // Clear previous logs
|
||||
const wsUrl = `ws://localhost:8000/ws/logs/${$selectedTask.id}`;
|
||||
ws = new WebSocket(wsUrl);
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log('[TaskRunner][Coherence:OK] WebSocket connection established');
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
const logEntry = JSON.parse(event.data);
|
||||
taskLogs.update(logs => [...logs, logEntry]);
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error('[TaskRunner][Coherence:Failed] WebSocket error:', error);
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log('[TaskRunner][Exit] WebSocket connection closed');
|
||||
};
|
||||
}
|
||||
});
|
||||
// [/DEF:onMount]
|
||||
|
||||
// [DEF:onDestroy:Function]
|
||||
// @PURPOSE: Close WebSocket connection when the component is destroyed.
|
||||
onDestroy(() => {
|
||||
if (ws) {
|
||||
console.log("[TaskRunner][Action] Closing WebSocket connection.");
|
||||
ws.close();
|
||||
}
|
||||
});
|
||||
// [/DEF:onDestroy]
|
||||
</script>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-white shadow-md">
|
||||
{#if $selectedTask}
|
||||
<h2 class="text-xl font-semibold mb-2">Task: {$selectedTask.plugin_id}</h2>
|
||||
<div class="bg-gray-900 text-white font-mono text-sm p-4 rounded-md h-96 overflow-y-auto">
|
||||
{#each $taskLogs as log}
|
||||
<div>
|
||||
<span class="text-gray-400">{new Date(log.timestamp).toLocaleTimeString()}</span>
|
||||
<span class="{log.level === 'ERROR' ? 'text-red-500' : 'text-green-400'}">[{log.level}]</span>
|
||||
<span>{log.message}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<p>No task selected.</p>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- [/DEF:TaskRunner] -->
|
||||
Reference in New Issue
Block a user