Files
SystemSimulationApp/app/simulation/core/catalog.py
T

107 lines
2.7 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import Literal
PortDisplaySide = Literal["left", "right"]
ComponentCatalogRole = Literal["amesimGasMediumDefinition"]
@dataclass(frozen=True)
class ComponentCategorySpec:
"""A presentation-only category declared by one component library."""
id: str
label: str
order: int = 0
def as_catalog_dict(self) -> dict[str, object]:
return {
"id": self.id,
"label": self.label,
"order": self.order,
}
@dataclass(frozen=True)
class PortDisplaySpec:
"""Canvas placement for one port without changing its physical contract."""
name: str
side: PortDisplaySide
order: int = 0
@dataclass(frozen=True)
class ParameterGroupDisplaySpec:
"""Ordered, collapsible presentation group for component parameters."""
id: str
label: str
parameters: tuple[str, ...]
order: int = 0
default_expanded: bool = False
def as_catalog_dict(self) -> dict[str, object]:
return {
"id": self.id,
"label": self.label,
"parameters": list(self.parameters),
"order": self.order,
"defaultExpanded": self.default_expanded,
}
@dataclass(frozen=True)
class ComponentDisplaySpec:
"""Frontend metadata co-located with a component implementation."""
label: str
library_id: str
category_id: str
symbol: str
ports: tuple[PortDisplaySpec, ...]
order: int = 0
role: ComponentCatalogRole | None = None
parameter_groups: tuple[ParameterGroupDisplaySpec, ...] = ()
@property
def port_by_name(self) -> dict[str, PortDisplaySpec]:
return {port.name: port for port in self.ports}
@dataclass(frozen=True)
class ComponentLibrarySpec:
"""Manifest for one explicitly enabled component library."""
id: str
label: str
version: str
source_package: str
categories: tuple[ComponentCategorySpec, ...]
models: tuple[str, ...]
temporary: bool = False
order: int = 0
@property
def category_by_id(self) -> dict[str, ComponentCategorySpec]:
return {category.id: category for category in self.categories}
def as_catalog_dict(self) -> dict[str, object]:
return {
"id": self.id,
"label": self.label,
"version": self.version,
"sourcePackage": self.source_package,
"temporary": self.temporary,
"order": self.order,
"categories": [
category.as_catalog_dict()
for category in sorted(
self.categories,
key=lambda item: (item.order, item.id),
)
],
}