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:
2025-12-20 20:48:18 +03:00
parent ce703322c2
commit 2d8cae563f
98 changed files with 7894 additions and 5021 deletions

46
frontend/src/lib/toasts.js Normal file → Executable file
View File

@@ -1,13 +1,33 @@
import { writable } from 'svelte/store';
export const toasts = writable([]);
export function addToast(message, type = 'info', duration = 3000) {
const id = Math.random().toString(36).substr(2, 9);
toasts.update(all => [...all, { id, message, type }]);
setTimeout(() => removeToast(id), duration);
}
function removeToast(id) {
toasts.update(all => all.filter(t => t.id !== id));
}
// [DEF:toasts_module:Module]
// @SEMANTICS: notification, toast, feedback, state
// @PURPOSE: Manages toast notifications using a Svelte writable store.
// @LAYER: UI-State
import { writable } from 'svelte/store';
// [DEF:toasts:Data]
// @PURPOSE: Writable store containing the list of active toasts.
export const toasts = writable([]);
// [DEF:addToast:Function]
// @PURPOSE: Adds a new toast message.
// @PARAM: message (string) - The message text.
// @PARAM: type (string) - The type of toast (info, success, error).
// @PARAM: duration (number) - Duration in ms before the toast is removed.
export function addToast(message, type = 'info', duration = 3000) {
const id = Math.random().toString(36).substr(2, 9);
console.log(`[toasts.addToast][Action] Adding toast context={{'id': '${id}', 'type': '${type}', 'message': '${message}'}}`);
toasts.update(all => [...all, { id, message, type }]);
setTimeout(() => removeToast(id), duration);
}
// [/DEF:addToast]
// [DEF:removeToast:Function]
// @PURPOSE: Removes a toast message by ID.
// @PARAM: id (string) - The ID of the toast to remove.
function removeToast(id) {
console.log(`[toasts.removeToast][Action] Removing toast context={{'id': '${id}'}}`);
toasts.update(all => all.filter(t => t.id !== id));
}
// [/DEF:removeToast]
// [/DEF:toasts_module]