WIP: Staged all changes
This commit is contained in:
56
frontend/src/components/DynamicForm.svelte
Normal file
56
frontend/src/components/DynamicForm.svelte
Normal file
@@ -0,0 +1,56 @@
|
||||
<script>
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let schema;
|
||||
let formData = {};
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function handleSubmit() {
|
||||
dispatch('submit', formData);
|
||||
}
|
||||
|
||||
// Initialize form data with default values from the schema
|
||||
if (schema && schema.properties) {
|
||||
for (const key in schema.properties) {
|
||||
formData[key] = schema.properties[key].default || '';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<form on:submit|preventDefault={handleSubmit} class="space-y-4">
|
||||
{#if schema && schema.properties}
|
||||
{#each Object.entries(schema.properties) as [key, prop]}
|
||||
<div class="flex flex-col">
|
||||
<label for={key} class="mb-1 font-semibold text-gray-700">{prop.title || key}</label>
|
||||
{#if prop.type === 'string'}
|
||||
<input
|
||||
type="text"
|
||||
id={key}
|
||||
bind:value={formData[key]}
|
||||
placeholder={prop.description || ''}
|
||||
class="p-2 border rounded-md"
|
||||
/>
|
||||
{:else if prop.type === 'number' || prop.type === 'integer'}
|
||||
<input
|
||||
type="number"
|
||||
id={key}
|
||||
bind:value={formData[key]}
|
||||
placeholder={prop.description || ''}
|
||||
class="p-2 border rounded-md"
|
||||
/>
|
||||
{:else if prop.type === 'boolean'}
|
||||
<input
|
||||
type="checkbox"
|
||||
id={key}
|
||||
bind:checked={formData[key]}
|
||||
class="h-5 w-5"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
<button type="submit" class="w-full bg-green-500 text-white p-2 rounded-md hover:bg-green-600">
|
||||
Run Task
|
||||
</button>
|
||||
{/if}
|
||||
</form>
|
||||
54
frontend/src/components/TaskRunner.svelte
Normal file
54
frontend/src/components/TaskRunner.svelte
Normal file
@@ -0,0 +1,54 @@
|
||||
<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>
|
||||
15
frontend/src/components/Toast.svelte
Normal file
15
frontend/src/components/Toast.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script>
|
||||
import { toasts } from '../lib/toasts.js';
|
||||
</script>
|
||||
|
||||
<div class="fixed bottom-0 right-0 p-4 space-y-2">
|
||||
{#each $toasts as toast (toast.id)}
|
||||
<div class="p-4 rounded-md shadow-lg text-white
|
||||
{toast.type === 'info' && 'bg-blue-500'}
|
||||
{toast.type === 'success' && 'bg-green-500'}
|
||||
{toast.type === 'error' && 'bg-red-500'}
|
||||
">
|
||||
{toast.message}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
Reference in New Issue
Block a user