Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 64 additions & 12 deletions report/base_components/base_component.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,69 @@
class BaseComponent:
"""
Base Component Module

def build_component(self, entity_id, model):
raise NotImplementedError

def outer_div(self, component):
return component

Abstract base class for all dashboard components.
Provides common interface and methods for component creation and rendering.
"""

def component_data(self, entity_id, model):
raise NotImplemented
from abc import ABC, abstractmethod
from typing import Any, Dict, Optional

def __call__(self, entity_id, model):

component = self.build_component(entity_id, model)
class BaseComponent(ABC):
"""Base class for single dashboard components.

return self.outer_div(component)
Subclasses must implement `build_component(entity_id, model)` and may
implement `component_data(entity_id, model)` when SQL-backed data is needed.
"""

def __init__(
self,
component_id: str,
title: str = "",
css_class: str = "",
attrs: Optional[Dict[str, Any]] = None,
) -> None:
self.component_id = component_id
self.title = title
self.css_class = css_class
self.attrs = attrs or {}

@abstractmethod
def build_component(self, entity_id: Any, model: Any) -> Any:
"""Build and return a single HTML/FastHTML component."""
raise NotImplementedError

def component_data(self, entity_id: Any, model: Any) -> Any:
"""Fetch data needed by `build_component`.

Override this method in subclasses that need SQL-backed data.
"""
raise NotImplementedError

def __call__(self, entity_id: Any, model: Any) -> Any:
"""Allow instances to be called like functions by CombinedComponent."""
return self.build_component(entity_id, model)

def get_id(self) -> str:
return self.component_id

def set_title(self, title: str) -> "BaseComponent":
self.title = title
return self

def add_css_class(self, css_class: str) -> "BaseComponent":
if not css_class:
return self

if not self.css_class:
self.css_class = css_class
return self

current = set(self.css_class.split())
for cls in css_class.split():
if cls not in current:
self.css_class += f" {cls}"
return self

def to_html(self, entity_id: Any, model: Any) -> str:
return str(self.build_component(entity_id, model))