"""UI manager for web dashboard with audit trail display.""" import json from typing import Optional, List class UIManager: """Manages UI data and updates with audit trail display.""" def __init__(self, project_id: str): """Initialize UI manager.""" self.project_id = project_id self.ui_data = { "project_id": project_id, "status": "initialized", "progress": 0, "message": "Ready", "snapshots": [], "features": [] } def update_status(self, status: str, progress: int, message: str) -> None: """Update UI status.""" self.ui_data["status"] = status self.ui_data["progress"] = progress self.ui_data["message"] = message def add_snapshot(self, data: str, created_at: Optional[str] = None) -> None: """Add a snapshot of UI data.""" snapshot = { "data": data, "created_at": created_at or self._get_current_timestamp() } self.ui_data.setdefault("snapshots", []).append(snapshot) def add_feature(self, feature: str) -> None: """Add a feature tag.""" self.ui_data.setdefault("features", []).append(feature) def _get_current_timestamp(self) -> str: """Get current timestamp in ISO format.""" from datetime import datetime return datetime.now().isoformat() def get_ui_data(self) -> dict: """Get current UI data.""" return self.ui_data def _escape_html(self, text: str) -> str: """Escape HTML special characters for safe display.""" if text is None: return "" safe_chars = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' } return ''.join(safe_chars.get(c, c) for c in str(text)) def render_dashboard(self, audit_trail: Optional[List[dict]] = None, actions: Optional[List[dict]] = None, logs: Optional[List[dict]] = None) -> str: """Render dashboard HTML with audit trail and history display.""" # Format logs for display logs_html = "" if logs: for log in logs: level = log.get("level", "INFO") message = self._escape_html(log.get("message", "")) timestamp = self._escape_html(log.get("timestamp", "")) if level == "ERROR": level_class = "error" else: level_class = "info" logs_html += f"""
{timestamp} [{level}] {message}
""" # Format audit trail for display audit_html = "" if audit_trail: for audit in audit_trail: action = audit.get("action", "") actor = self._escape_html(audit.get("actor", "")) timestamp = self._escape_html(audit.get("timestamp", "")) details = self._escape_html(audit.get("details", "")) metadata = audit.get("metadata", {}) action_type = audit.get("action_type", "") # Color classes for action types action_color = action_type.lower() if action_type else "neutral" audit_html += f"""
{self._escape_html(action)} {actor} {timestamp}
{details}
{f'
{json.dumps(metadata)}
' if metadata else ''}
""" # Format actions for display actions_html = "" if actions: for action in actions: action_type = action.get("action_type", "") description = self._escape_html(action.get("description", "")) actor_name = self._escape_html(action.get("actor_name", "")) actor_type = action.get("actor_type", "") timestamp = self._escape_html(action.get("timestamp", "")) actions_html += f"""
{self._escape_html(action_type)}
{description}
{actor_type}: {actor_name}
{timestamp}
""" # Format snapshots for display snapshots_html = "" snapshots = self.ui_data.get("snapshots", []) if snapshots: for snapshot in snapshots: data = snapshot.get("data", "") created_at = snapshot.get("created_at", "") snapshots_html += f"""
{created_at}
{data}
""" # Build features HTML features_html = "" features = self.ui_data.get("features", []) if features: feature_tags = [] for feat in features: feature_tags.append(f'{self._escape_html(feat)}') features_html = f'
{"".join(feature_tags)}
' # Build project header HTML project_id_escaped = self._escape_html(self.ui_data.get('project_id', 'Project')) status = self.ui_data.get('status', 'initialized') # Determine empty state message empty_state_message = "" if not audit_trail and not actions and not snapshots_html: empty_state_message = 'No audit trail entries available' return f""" AI Software Factory Dashboard

AI Software Factory Dashboard

{project_id_escaped} {status.upper()}
{self._escape_html(self.ui_data.get('message', 'No message'))}
{f'
{logs_html}
' if logs else '
No logs available
'} {features_html}
{f'

Audit Trail

{audit_html}
' if audit_html else ''} {f'

User Actions

{actions_html}
' if actions_html else ''} {f'

UI Snapshots

{snapshots_html}
' if snapshots_html else ''} {empty_state_message}
"""