CI / test (push) Canceled after 0s
## Summary epic r04 - begin refactor ## Change Type - [x] Cowork feature - [ ] Bug fix - [ ] Core AI contribution - [ ] Test / hardening - [ ] Performance - [ ] Documentation ## Related Work Cowork Task: Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets Core AI Issue: Core Task: Related PR: ## Scope What is intentionally included? What is intentionally NOT included? ## Validation - [ ] Unit tests - [ ] Integration tests - [ ] Manual verification - [ ] Regression check Commands / evidence: ## Security Impact Permission / credential / network / customer data impact: ## Compatibility - [ ] No breaking change - [ ] Breaking change documented ## Reviewer Notes Anything Cowork reviewers should pay attention to. --------- Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com> Co-authored-by: Huong Le Thi Thien <huongltt35@fpt.com> Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com> Co-authored-by: Vu Dam Tuan <vudt15@fpt.com> Co-authored-by: Hiep Ha Van <hiephv3@fpt.com> Co-authored-by: Lam Hoang Van <lamhv7@fpt.com> Reviewed-on: #7 Co-authored-by: Duy Le Huu <duylh19@fpt.com>
99 lines
4.1 KiB
Python
99 lines
4.1 KiB
Python
"""StructureGraphView shell (R08-T14) — assembles
|
|
``graph_renderer.py::GraphRenderer`` and
|
|
``graph_qa_widget.py::GraphQaWidget`` behind the splitter that used to be
|
|
inline in ``ui/structure_graph_view.py::StructureGraphView.__init__`` (lines
|
|
188-343 of the original 1035-line file), and forwards the public methods
|
|
``app.py``/``ui/workspace_tab.py`` call: ``schedule_rescan``,
|
|
``auto_scan_and_fit``, ``set_project``, ``prewarm``.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from PySide6.QtCore import Qt, Signal
|
|
from PySide6.QtWidgets import QSplitter, QVBoxLayout, QWidget
|
|
|
|
from cowork_local.i18n import on_language_changed
|
|
from cowork_local.presentation.graph.graph_qa_widget import GraphQaWidget
|
|
from cowork_local.presentation.graph.graph_renderer import GraphRenderer
|
|
from cowork_local.state import AppContext
|
|
from cowork_local.ui.widgets import CollapseStrip
|
|
|
|
_COLLAPSED_SIZES_HINT = (840, 320) # matches the original single-class default
|
|
|
|
|
|
class StructureGraphView(QWidget):
|
|
"""Màn GraphRAG: ghép khung đồ thị (:class:`GraphRenderer`) và khung hỏi-đáp
|
|
(:class:`GraphQaWidget`) vào một splitter.
|
|
|
|
Vỏ này chỉ lắp ráp và chuyển tiếp bốn phương thức mà ``app.py`` và
|
|
``ui/workspace_tab.py`` gọi tới; toàn bộ phần việc thật nằm ở hai widget con.
|
|
"""
|
|
status_message = Signal(str)
|
|
|
|
def __init__(self, ctx: AppContext):
|
|
"""Ghép hai nửa của màn GraphRAG: bên trái là đồ thị, bên phải là panel Hỏi
|
|
đáp.
|
|
"""
|
|
super().__init__()
|
|
self.ctx = ctx
|
|
|
|
root = QVBoxLayout(self)
|
|
self.renderer = GraphRenderer(ctx)
|
|
self.renderer.status_message.connect(self.status_message.emit)
|
|
self.qa = GraphQaWidget(ctx, self.renderer)
|
|
self.qa.status_message.connect(self.status_message.emit)
|
|
self.qa.collapse_changed.connect(self._on_qa_collapse_changed)
|
|
|
|
self._split = QSplitter(Qt.Horizontal)
|
|
self._split.addWidget(self.renderer)
|
|
self._split.addWidget(self.qa)
|
|
self._split.setChildrenCollapsible(False)
|
|
self._split.setSizes(list(_COLLAPSED_SIZES_HINT))
|
|
root.addWidget(self._split, 1)
|
|
|
|
on_language_changed(self._retranslate)
|
|
|
|
def _retranslate(self) -> None:
|
|
"""Chuyển lệnh dịch lại xuống cho cả hai widget con."""
|
|
self.renderer._retranslate()
|
|
self.qa.retranslate()
|
|
|
|
def _on_qa_collapse_changed(self, collapsed: bool) -> None:
|
|
"""Gập/mở khung hỏi-đáp: gập thì thu về đúng bề rộng dải nắm, mở thì trả
|
|
splitter về tỉ lệ mặc định.
|
|
"""
|
|
strip_w = CollapseStrip.WIDTH + 2
|
|
if collapsed:
|
|
self.qa.setMaximumWidth(strip_w)
|
|
sizes = self._split.sizes()
|
|
if len(sizes) == 2:
|
|
self._split.setSizes([max(1, sum(sizes) - strip_w), strip_w])
|
|
else:
|
|
self.qa.setMaximumWidth(16777215)
|
|
self._split.setSizes(list(_COLLAPSED_SIZES_HINT))
|
|
|
|
# ---- public API (app.py / ui/workspace_tab.py) --------------------------- #
|
|
def schedule_rescan(self, path: str = "") -> None:
|
|
"""Hẹn quét lại đồ thị sau khi thư mục có thay đổi."""
|
|
self.renderer.schedule_rescan(path)
|
|
|
|
def auto_scan_and_fit(self) -> None:
|
|
"""Vào màn GraphRAG: hiện đồ thị, chỉ quét lại khi thật sự cần."""
|
|
self.renderer.auto_scan_and_fit()
|
|
|
|
def set_project(self, project_id: str) -> None:
|
|
"""Khoá phạm vi quét vào một project (chuỗi rỗng là bỏ khoá)."""
|
|
self.renderer.set_project(project_id)
|
|
|
|
def prewarm(self) -> None:
|
|
"""Dựng sẵn khung đồ thị trước khi người dùng bấm vào, để lần mở đầu không giật."""
|
|
self.renderer.prewarm()
|
|
|
|
def hideEvent(self, e): # noqa: N802
|
|
# Leaving the GraphRAG tab → drop the temporary extracted info.
|
|
"""Rời màn GraphRAG thì xoá phần trích xuất tạm của khung hỏi-đáp."""
|
|
self.qa.clear_extracts()
|
|
super().hideEvent(e)
|
|
|
|
|
|
__all__ = ["StructureGraphView"]
|