98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
"""Манифест стенда: что есть в БД и какие URL/пользователей использовать в сценариях.
|
||
|
||
Путь: perf/results/manifest-s{scale}.json.
|
||
|
||
Сегмент {direction} в URL листа: web/src/components/common/TableList/TableList.jsx
|
||
строит путь как `${table?.direction}`, поэтому при direction == null (JSON null из API)
|
||
в URL попадает литерал "null" (маршрут в web/src/app/Routes.jsx:
|
||
/table/form/:formId/form-type/:formType/:sheetName/:direction/:year).
|
||
|
||
Task 3 заполняет `svods` и `modal_pages` по маршрутам Routes.jsx
|
||
(/svod, /svod/2, /svods-navigator, /projects/summaries и т.д.) — это просто списки Page(name, url).
|
||
Лист свода выбирается вкладкой внутри страницы, не URL: у Page свода url = путь + '#' + имя листа
|
||
(`/svod#FORM_1`, `/svod/2#RF`); хеш на маршрутизацию не влияет, сценарий по нему выбирает вкладку.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
from dataclasses import dataclass, field, asdict
|
||
from pathlib import Path
|
||
|
||
from . import RESULTS_DIR
|
||
|
||
NO_DIRECTION = "null" # см. docstring модуля
|
||
USER_KEYS = ("admin", "rf", "rf_coauthor", "dfip")
|
||
|
||
|
||
@dataclass
|
||
class Sheet:
|
||
form_id: int
|
||
form_type: str
|
||
sheet: str
|
||
direction: str | None
|
||
year: int
|
||
url: str
|
||
rows: int
|
||
# чьей оргединице принадлежит форма: "rf" — РФ пользователя `rf` (ему доступна), "ssp" — ССП
|
||
# (доступна admin/dfip, но не `rf`). Поле добавлено Task 3, по умолчанию "rf".
|
||
owner: str = "rf"
|
||
|
||
@staticmethod
|
||
def build_url(form_id, form_type, sheet, direction, year) -> str:
|
||
d = NO_DIRECTION if direction is None else direction
|
||
return f"/table/form/{form_id}/form-type/{form_type}/{sheet}/{d}/{year}"
|
||
|
||
|
||
@dataclass
|
||
class ProjectReport:
|
||
project_id: int
|
||
year: int
|
||
report_type: str
|
||
url: str
|
||
rows: int
|
||
|
||
|
||
@dataclass
|
||
class Page:
|
||
name: str
|
||
url: str
|
||
|
||
|
||
@dataclass
|
||
class User:
|
||
username: str
|
||
password: str
|
||
role_id: int
|
||
|
||
|
||
@dataclass
|
||
class Manifest:
|
||
scale: int
|
||
users: dict[str, User] = field(default_factory=dict)
|
||
sheets: list[Sheet] = field(default_factory=list)
|
||
project_reports: list[ProjectReport] = field(default_factory=list)
|
||
svods: list[Page] = field(default_factory=list)
|
||
modal_pages: list[Page] = field(default_factory=list)
|
||
|
||
|
||
def manifest_path(scale: int, results_dir: Path | None = None) -> Path:
|
||
return Path(results_dir or RESULTS_DIR) / f"manifest-s{scale}.json"
|
||
|
||
|
||
def dump(m: Manifest, path) -> None:
|
||
path = Path(path)
|
||
path.parent.mkdir(parents=True, exist_ok=True)
|
||
path.write_text(json.dumps(asdict(m), ensure_ascii=False, indent=2), encoding="utf-8")
|
||
|
||
|
||
def load(path) -> Manifest:
|
||
d = json.loads(Path(path).read_text(encoding="utf-8"))
|
||
return Manifest(
|
||
scale=d["scale"],
|
||
users={k: User(**v) for k, v in d.get("users", {}).items()},
|
||
sheets=[Sheet(**x) for x in d.get("sheets", [])],
|
||
project_reports=[ProjectReport(**x) for x in d.get("project_reports", [])],
|
||
svods=[Page(**x) for x in d.get("svods", [])],
|
||
modal_pages=[Page(**x) for x in d.get("modal_pages", [])],
|
||
)
|