Add Dispatch_V0.1.1

This commit is contained in:
2026-04-29 08:18:54 +04:00
commit a7ede6ded4
404 changed files with 39167 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
# gui/components/_tree_node_building.py
"""Сервис построения узлов дерева и ленивой загрузки (композиция)."""
from __future__ import annotations
from typing import TYPE_CHECKING, Dict, Any
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QTreeWidgetItem
if TYPE_CHECKING:
from gui.components.topology_tree_widget import TopologyTreeWidget
class TreeNodeBuilder:
"""Создание элементов QTreeWidget и ленивая загрузка дочерних узлов."""
def __init__(self, host: "TopologyTreeWidget") -> None:
self._host = host
def load_root_nodes(self) -> None:
"""Загрузка корневых узлов (сайтов)."""
try:
root_nodes = self._host.data_loader('site', None)
for node_data in root_nodes:
item = self._create_tree_item(node_data)
self._host._tree.addTopLevelItem(item)
if node_data.has_children and not node_data.children_loaded:
stub = QTreeWidgetItem(["Загрузка..."])
stub.setData(0, Qt.UserRole, {"is_stub": True})
item.addChild(stub)
except Exception as e:
error_msg = f"Ошибка загрузки корневых узлов: {e}"
print(error_msg)
self._host.dataLoadError.emit(error_msg)
def _create_tree_item(self, node_data) -> QTreeWidgetItem:
"""Создание элемента дерева на основе данных узла."""
item = QTreeWidgetItem()
display_attrs = self._host.DISPLAY_ATTRIBUTES.get(node_data.node_type, [])
col_values = self._get_column_values(
node_data.display_data, display_attrs, node_data.node_type,
)
for i, value in enumerate(col_values):
if i < self._host._tree.columnCount():
item.setText(i, str(value))
item.setData(0, Qt.UserRole, {
'type': node_data.node_type,
'id': node_data.node_id,
'display_data': node_data.display_data,
'has_children': node_data.has_children,
'children_loaded': node_data.children_loaded,
'raw_data': node_data.raw_data,
})
item.setChildIndicatorPolicy(
QTreeWidgetItem.ShowIndicator if node_data.has_children
else QTreeWidgetItem.DontShowIndicator
)
return item
@staticmethod
def _get_column_values(
data: Dict[str, Any], attrs: list[str], node_type: str,
) -> list[str]:
"""Значения для колонок (только значения атрибутов, без ключей)."""
values = []
if attrs:
for attr in attrs:
if attr in data and data[attr]:
values.append(str(data[attr]))
break
else:
values.append("")
else:
values.append("")
if len(attrs) > 1:
other = [str(data[a]) for a in attrs[1:] if a in data and data[a]]
sep = " " if node_type == "shelf" else ", "
values.append(sep.join(other))
else:
values.append("")
return values
def load_children(self, parent_item: QTreeWidgetItem) -> None:
"""Ленивая загрузка дочерних элементов для узла."""
parent_data = parent_item.data(0, Qt.UserRole)
if not parent_data:
return
parent_type = parent_data['type']
parent_id = parent_data['id']
node_key = f"{parent_type}:{parent_id}"
if node_key in self._host._loading_nodes:
return
self._host._loading_nodes.add(node_key)
try:
if parent_item.childCount() == 1:
child = parent_item.child(0)
child_data = child.data(0, Qt.UserRole) if child else {}
if child_data and child_data.get('is_stub'):
parent_item.removeChild(child)
children_data = self._host.data_loader(
self._get_child_type(parent_type), parent_id,
)
for child_data in children_data:
child_item = self._create_tree_item(child_data)
parent_item.addChild(child_item)
if child_data.has_children and not child_data.children_loaded:
stub = QTreeWidgetItem(["Загрузка..."])
stub.setData(0, Qt.UserRole, {"is_stub": True})
child_item.addChild(stub)
parent_data['children_loaded'] = True
parent_item.setData(0, Qt.UserRole, parent_data)
self._host._tree.resizeColumnToContents(0)
except Exception as e:
msg = f"Ошибка загрузки дочерних элементов для {parent_type} {parent_id}: {e}"
print(msg)
self._host.dataLoadError.emit(msg)
err_item = QTreeWidgetItem(["Ошибка загрузки", str(e)[:50]])
err_item.setData(0, Qt.UserRole, {"is_error": True})
parent_item.addChild(err_item)
finally:
self._host._loading_nodes.remove(node_key)
@staticmethod
def _get_child_type(parent_type: str) -> str:
"""Тип дочерних элементов на основе типа родителя."""
hierarchy = {
'site': 'facility', 'facility': 'zone', 'zone': 'rack',
'rack': 'shelf', 'shelf': 'cell', 'cell': 'volume',
}
return hierarchy.get(parent_type, '')