""" EU-Utility - Enhanced Dashboard Fully functional dashboard with all widgets, persistence, and management features. """ from typing import Dict, Optional, List from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QFrame, QScrollArea, QGridLayout, QStackedWidget, QSizePolicy, QGraphicsDropShadowEffect, QMessageBox ) from PyQt6.QtCore import Qt, pyqtSignal, QTimer from PyQt6.QtGui import QColor from core.icon_manager import get_icon_manager from core.eu_styles import get_color from core.data.sqlite_store import get_sqlite_store from core.widgets.dashboard_widgets import ( SystemStatusWidget, QuickActionsWidget, RecentActivityWidget, PluginGridWidget ) from core.widgets.widget_gallery import WidgetGallery, DashboardWidgetManager class EnhancedDashboard(QWidget): """ Enhanced Dashboard with full functionality. Features: - Widget management system - System status monitoring - Quick actions - Recent activity feed - Plugin grid - Persistence via SQLite """ action_triggered = pyqtSignal(str) plugin_selected = pyqtSignal(str) settings_requested = pyqtSignal() def __init__(self, plugin_manager=None, parent=None): super().__init__(parent) self.plugin_manager = plugin_manager self.icon_manager = get_icon_manager() self.data_store = get_sqlite_store() # Track widgets self.widgets: Dict[str, QWidget] = {} self._setup_ui() self._connect_signals() self._start_session() def _setup_ui(self): """Setup dashboard UI.""" self.setStyleSheet("background: transparent;") layout = QVBoxLayout(self) layout.setContentsMargins(20, 20, 20, 20) layout.setSpacing(15) # Header header_layout = QHBoxLayout() # Title with icon title_layout = QHBoxLayout() icon_label = QLabel() icon_pixmap = self.icon_manager.get_pixmap('layout-grid', size=28) icon_label.setPixmap(icon_pixmap) icon_label.setFixedSize(28, 28) title_layout.addWidget(icon_label) header = QLabel("Dashboard") header.setStyleSheet(f""" color: {get_color('text_primary')}; font-size: 22px; font-weight: bold; """) title_layout.addWidget(header) header_layout.addLayout(title_layout) header_layout.addStretch() # Header buttons gallery_btn = QPushButton("🎨 Widgets") gallery_btn.setStyleSheet(""" QPushButton { background-color: rgba(255, 255, 255, 10); color: white; padding: 8px 16px; border: none; border-radius: 6px; font-size: 12px; } QPushButton:hover { background-color: #4a9eff; } """) gallery_btn.clicked.connect(self._toggle_gallery) header_layout.addWidget(gallery_btn) settings_btn = QPushButton("⚙️") settings_btn.setFixedSize(36, 36) settings_btn.setStyleSheet(""" QPushButton { background-color: rgba(255, 255, 255, 10); color: white; border: none; border-radius: 6px; font-size: 14px; } QPushButton:hover { background-color: #ff8c42; } """) settings_btn.setToolTip("Settings") settings_btn.clicked.connect(self.settings_requested.emit) header_layout.addWidget(settings_btn) layout.addLayout(header_layout) # Subtitle subtitle = QLabel("Your command center for EU-Utility") subtitle.setStyleSheet("color: rgba(255, 255, 255, 150); font-size: 12px;") layout.addWidget(subtitle) # Main content - Widget Manager self.widget_manager = DashboardWidgetManager(self.plugin_manager, self) self.widget_manager.set_plugin_manager(self.plugin_manager) layout.addWidget(self.widget_manager) # Connect quick actions for widget in self.widget_manager.get_all_widgets().values(): if isinstance(widget, QuickActionsWidget): widget.action_triggered.connect(self._on_quick_action) elif isinstance(widget, PluginGridWidget): widget.plugin_clicked.connect(self.plugin_selected.emit) def _toggle_gallery(self): """Toggle widget gallery visibility.""" # The gallery is built into the widget manager if hasattr(self.widget_manager, 'gallery'): if self.widget_manager.gallery.isVisible(): self.widget_manager.gallery.hide() else: self.widget_manager.gallery.show() def _on_quick_action(self, action_id: str): """Handle quick action.""" self.action_triggered.emit(action_id) # Handle specific actions if action_id == 'settings': self.settings_requested.emit() elif action_id == 'plugins': self._toggle_gallery() # Log self.data_store.log_activity('ui', 'quick_action', f"Action: {action_id}") def _connect_signals(self): """Connect internal signals.""" pass # Signals connected in setup def _start_session(self): """Start a new session.""" session_id = self.data_store.start_session() self.data_store.log_activity('system', 'session_start', f"Session: {session_id}") def refresh(self): """Refresh dashboard data.""" # Refresh all widgets for widget in self.widget_manager.get_all_widgets().values(): if hasattr(widget, '_refresh'): widget._refresh() def set_plugin_manager(self, plugin_manager): """Set the plugin manager.""" self.plugin_manager = plugin_manager self.widget_manager.set_plugin_manager(plugin_manager) def add_custom_widget(self, widget_type: str, config: dict = None) -> Optional[QWidget]: """Add a custom widget to the dashboard.""" return self.widget_manager.add_widget(widget_type, config) def get_system_status_widget(self) -> Optional[SystemStatusWidget]: """Get the system status widget if it exists.""" for widget in self.widget_manager.get_all_widgets().values(): if isinstance(widget, SystemStatusWidget): return widget return None def set_service_status(self, service_name: str, status: bool): """Set a service status in the system status widget.""" status_widget = self.get_system_status_widget() if status_widget: status_widget.set_service(service_name, status) class DashboardContainer(QFrame): """ Container frame for the dashboard with styling. """ def __init__(self, plugin_manager=None, parent=None): super().__init__(parent) self.setStyleSheet(""" DashboardContainer { background-color: rgba(25, 30, 40, 250); border: 1px solid rgba(100, 110, 130, 80); border-radius: 16px; } """) # Shadow effect shadow = QGraphicsDropShadowEffect() shadow.setBlurRadius(30) shadow.setColor(QColor(0, 0, 0, 100)) shadow.setOffset(0, 10) self.setGraphicsEffect(shadow) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.dashboard = EnhancedDashboard(plugin_manager, self) layout.addWidget(self.dashboard) def get_dashboard(self) -> EnhancedDashboard: """Get the dashboard instance.""" return self.dashboard class DashboardManager: """ Manager for dashboard operations and persistence. """ def __init__(self): self.data_store = get_sqlite_store() self.dashboards: List[EnhancedDashboard] = [] def register_dashboard(self, dashboard: EnhancedDashboard): """Register a dashboard instance.""" self.dashboards.append(dashboard) def unregister_dashboard(self, dashboard: EnhancedDashboard): """Unregister a dashboard instance.""" if dashboard in self.dashboards: self.dashboards.remove(dashboard) def broadcast_refresh(self): """Refresh all dashboards.""" for dashboard in self.dashboards: dashboard.refresh() def save_all_configs(self): """Save all dashboard configurations.""" for dashboard in self.dashboards: # Config is saved automatically by widget manager pass def get_stats(self) -> Dict: """Get dashboard statistics.""" return { 'active_dashboards': len(self.dashboards), 'widget_configs': len(self.data_store.load_widget_configs()), } # Global manager instance _dashboard_manager = None def get_dashboard_manager() -> DashboardManager: """Get global dashboard manager.""" global _dashboard_manager if _dashboard_manager is None: _dashboard_manager = DashboardManager() return _dashboard_manager