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:
76
frontend/src/pages/Dashboard.svelte
Normal file → Executable file
76
frontend/src/pages/Dashboard.svelte
Normal file → Executable file
@@ -1,28 +1,48 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { plugins, fetchPlugins, selectedPlugin } from '../lib/stores.js';
|
||||
|
||||
onMount(async () => {
|
||||
await fetchPlugins();
|
||||
});
|
||||
|
||||
function selectPlugin(plugin) {
|
||||
selectedPlugin.set(plugin);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold mb-4">Available Tools</h1>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{#each $plugins as plugin}
|
||||
<div
|
||||
class="border rounded-lg p-4 cursor-pointer hover:bg-gray-100"
|
||||
on:click={() => selectPlugin(plugin)}
|
||||
>
|
||||
<h2 class="text-xl font-semibold">{plugin.name}</h2>
|
||||
<p class="text-gray-600">{plugin.description}</p>
|
||||
<span class="text-sm text-gray-400">v{plugin.version}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
[DEF:Dashboard:Component]
|
||||
@SEMANTICS: dashboard, plugins, tools, list
|
||||
@PURPOSE: Displays the list of available plugins and allows selecting one.
|
||||
@LAYER: UI
|
||||
@RELATION: DEPENDS_ON -> frontend/src/lib/stores.js
|
||||
|
||||
@PROPS: None
|
||||
@EVENTS: None
|
||||
-->
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { plugins, fetchPlugins, selectedPlugin } from '../lib/stores.js';
|
||||
|
||||
// [DEF:onMount:Function]
|
||||
// @PURPOSE: Fetch plugins when the component mounts.
|
||||
onMount(async () => {
|
||||
console.log("[Dashboard][Entry] Component mounted, fetching plugins.");
|
||||
await fetchPlugins();
|
||||
});
|
||||
// [/DEF:onMount]
|
||||
|
||||
// [DEF:selectPlugin:Function]
|
||||
// @PURPOSE: Selects a plugin to display its form.
|
||||
// @PARAM: plugin (Object) - The plugin object to select.
|
||||
function selectPlugin(plugin) {
|
||||
console.log(`[Dashboard][Action] Selecting plugin: ${plugin.id}`);
|
||||
selectedPlugin.set(plugin);
|
||||
}
|
||||
// [/DEF:selectPlugin]
|
||||
</script>
|
||||
|
||||
<div class="container mx-auto p-4">
|
||||
<h1 class="text-2xl font-bold mb-4">Available Tools</h1>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{#each $plugins as plugin}
|
||||
<div
|
||||
class="border rounded-lg p-4 cursor-pointer hover:bg-gray-100"
|
||||
on:click={() => selectPlugin(plugin)}
|
||||
>
|
||||
<h2 class="text-xl font-semibold">{plugin.name}</h2>
|
||||
<p class="text-gray-600">{plugin.description}</p>
|
||||
<span class="text-sm text-gray-400">v{plugin.version}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<!-- [/DEF:Dashboard] -->
|
||||
Reference in New Issue
Block a user