EU-Utility/core/dashboard_enhanced.py

286 lines
9.3 KiB
Python

"""
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