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:
78
frontend/src/App.svelte
Normal file → Executable file
78
frontend/src/App.svelte
Normal file → Executable file
@@ -1,28 +1,91 @@
|
||||
<!--
|
||||
[DEF:App:Component]
|
||||
@SEMANTICS: main, entrypoint, layout, navigation
|
||||
@PURPOSE: The root component of the frontend application. Manages navigation and layout.
|
||||
@LAYER: UI
|
||||
@RELATION: DEPENDS_ON -> frontend/src/pages/Dashboard.svelte
|
||||
@RELATION: DEPENDS_ON -> frontend/src/pages/Settings.svelte
|
||||
@RELATION: DEPENDS_ON -> frontend/src/lib/stores.js
|
||||
|
||||
@PROPS: None
|
||||
@EVENTS: None
|
||||
@INVARIANT: Navigation state must be persisted in the currentPage store.
|
||||
-->
|
||||
<script>
|
||||
import Dashboard from './pages/Dashboard.svelte';
|
||||
import { selectedPlugin, selectedTask } from './lib/stores.js';
|
||||
import Settings from './pages/Settings.svelte';
|
||||
import { selectedPlugin, selectedTask, currentPage } from './lib/stores.js';
|
||||
import TaskRunner from './components/TaskRunner.svelte';
|
||||
import DynamicForm from './components/DynamicForm.svelte';
|
||||
import { api } from './lib/api.js';
|
||||
import Toast from './components/Toast.svelte';
|
||||
|
||||
// [DEF:handleFormSubmit:Function]
|
||||
// @PURPOSE: Handles form submission for task creation.
|
||||
// @PARAM: event (CustomEvent) - The submit event from DynamicForm.
|
||||
async function handleFormSubmit(event) {
|
||||
console.log("[App.handleFormSubmit][Action] Handling form submission for task creation.");
|
||||
const params = event.detail;
|
||||
const task = await api.createTask($selectedPlugin.id, params);
|
||||
selectedTask.set(task);
|
||||
selectedPlugin.set(null);
|
||||
try {
|
||||
const task = await api.createTask($selectedPlugin.id, params);
|
||||
selectedTask.set(task);
|
||||
selectedPlugin.set(null);
|
||||
console.log(`[App.handleFormSubmit][Coherence:OK] Task created context={{'id': '${task.id}'}}`);
|
||||
} catch (error) {
|
||||
console.error(`[App.handleFormSubmit][Coherence:Failed] Task creation failed context={{'error': '${error}'}}`);
|
||||
}
|
||||
}
|
||||
// [/DEF:handleFormSubmit]
|
||||
|
||||
// [DEF:navigate:Function]
|
||||
// @PURPOSE: Changes the current page and resets state.
|
||||
// @PARAM: page (string) - Target page name.
|
||||
function navigate(page) {
|
||||
console.log(`[App.navigate][Action] Navigating to ${page}.`);
|
||||
// Reset selection first
|
||||
if (page !== $currentPage) {
|
||||
selectedPlugin.set(null);
|
||||
selectedTask.set(null);
|
||||
}
|
||||
// Then set page
|
||||
currentPage.set(page);
|
||||
}
|
||||
// [/DEF:navigate]
|
||||
</script>
|
||||
|
||||
<Toast />
|
||||
|
||||
<main class="bg-gray-50 min-h-screen">
|
||||
<header class="bg-white shadow-md p-4">
|
||||
<h1 class="text-3xl font-bold text-gray-800">Superset Tools</h1>
|
||||
<header class="bg-white shadow-md p-4 flex justify-between items-center">
|
||||
<button
|
||||
type="button"
|
||||
class="text-3xl font-bold text-gray-800 focus:outline-none"
|
||||
on:click={() => navigate('dashboard')}
|
||||
>
|
||||
Superset Tools
|
||||
</button>
|
||||
<nav class="space-x-4">
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => navigate('dashboard')}
|
||||
class="text-gray-600 hover:text-blue-600 font-medium {$currentPage === 'dashboard' ? 'text-blue-600 border-b-2 border-blue-600' : ''}"
|
||||
>
|
||||
Dashboard
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => navigate('settings')}
|
||||
class="text-gray-600 hover:text-blue-600 font-medium {$currentPage === 'settings' ? 'text-blue-600 border-b-2 border-blue-600' : ''}"
|
||||
>
|
||||
Settings
|
||||
</button>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="p-4">
|
||||
{#if $selectedTask}
|
||||
{#if $currentPage === 'settings'}
|
||||
<Settings />
|
||||
{:else if $selectedTask}
|
||||
<TaskRunner />
|
||||
<button on:click={() => selectedTask.set(null)} class="mt-4 bg-blue-500 text-white p-2 rounded">
|
||||
Back to Task List
|
||||
@@ -38,3 +101,4 @@
|
||||
{/if}
|
||||
</div>
|
||||
</main>
|
||||
<!-- [/DEF:App] -->
|
||||
|
||||
Reference in New Issue
Block a user