Source code for corvix.config.dashboards

"""Dashboard configuration model and YAML parsing."""

from __future__ import annotations

from dataclasses import dataclass, field

from corvix.config._utils import (
    _ensure_list,
    _ensure_map,
    _get_bool,
    _get_int,
    _get_str,
)
from corvix.config.rules import MatchCriteria, _parse_match

[docs] NO_FILTERS_DASHBOARD_NAME = "no filters"
@dataclass(slots=True)
[docs] class DashboardSpec: """Dashboard configuration for sorting, grouping, and filtering."""
[docs] name: str
[docs] group_by: str = "none"
[docs] sort_by: str = "score"
[docs] descending: bool = True
[docs] include_read: bool = False
[docs] max_items: int = 100
[docs] match: MatchCriteria = field(default_factory=MatchCriteria)
[docs] ignore_rules: list[MatchCriteria] = field(default_factory=list)
[docs] def default_dashboard() -> DashboardSpec: """Return the fallback dashboard used when config defines none.""" return DashboardSpec(name="default", group_by="repository", sort_by="score")
[docs] def no_filters_dashboard() -> DashboardSpec: """Return the hardcoded dashboard that bypasses config-driven filtering.""" return DashboardSpec( name=NO_FILTERS_DASHBOARD_NAME, group_by="repository", sort_by="score", descending=True, include_read=True, max_items=0, )
[docs] def available_dashboards(dashboards: list[DashboardSpec]) -> list[DashboardSpec]: """Return configured dashboards plus the built-in rule-free dashboard.""" configured_dashboards = [dashboard for dashboard in dashboards if dashboard.name != NO_FILTERS_DASHBOARD_NAME] if configured_dashboards: return [*configured_dashboards, no_filters_dashboard()] if dashboards: return [no_filters_dashboard()] return [default_dashboard(), no_filters_dashboard()]
[docs] def is_no_filters_dashboard(dashboard: DashboardSpec) -> bool: """Return whether the dashboard is the hardcoded rule-free dashboard.""" return dashboard.name == NO_FILTERS_DASHBOARD_NAME
[docs] def _parse_dashboards(value: object) -> list[DashboardSpec]: dashboards = _ensure_list(value, "dashboards") parsed: list[DashboardSpec] = [] for raw_dashboard in dashboards: dashboard = _ensure_map(raw_dashboard, "dashboard entry") dashboard_name = _get_str(dashboard, "name", "default", "dashboards[].name") if dashboard_name == NO_FILTERS_DASHBOARD_NAME: msg = ( f"Config field 'dashboards[].name' cannot be '{NO_FILTERS_DASHBOARD_NAME}' " "because that dashboard name is reserved." ) raise ValueError(msg) parsed.append( DashboardSpec( name=dashboard_name, group_by=_get_str(dashboard, "group_by", "none", "dashboards[].group_by"), sort_by=_get_str(dashboard, "sort_by", "score", "dashboards[].sort_by"), descending=_get_bool(dashboard, "descending", True, "dashboards[].descending"), include_read=_get_bool(dashboard, "include_read", False, "dashboards[].include_read"), max_items=_get_int(dashboard, "max_items", 100, "dashboards[].max_items"), match=_parse_match(dashboard.get("match", {})), ignore_rules=_parse_dashboard_ignore_rules(dashboard.get("ignore_rules", [])), ), ) return parsed
[docs] def _parse_dashboard_ignore_rules(value: object) -> list[MatchCriteria]: rules = _ensure_list(value, "dashboards[].ignore_rules") return [_parse_match(item, section="dashboards[].ignore_rules[]") for item in rules]