feat(ui): GraphRAG giữ project đã chọn, tự quét, và báo khi đang tải
Cùng lớp lỗi với tab Thư mục: _bind_project gọi _structure.set_project(pid) vô điều kiện, và chuỗi _goto -> refresh -> _load_current -> _bind_project chạy lại mỗi lần vào lại màn Workspace, nên bộ chọn project của chính màn GraphRAG bị kéo về giá trị của Workspace ở mỗi cú chuyển tab. set_workspace_project() bỏ qua khi project không đổi (dùng None làm giá trị khởi tạo, không phải "", để lần gọi đầu không bị bỏ qua khi chưa chọn project nào). Chọn project xong phải tự quét: _on_project_changed cố ý hoãn lượt quét sang "lần ghé tiếp", nhưng combo nằm ngay trên màn đó nên người dùng đang đứng ở đấy và không có lần ghé tiếp nào — họ phải tự bấm Scan. Giờ quét ngay khi màn đang mở; hoãn vẫn giữ cho trường hợp đổi project từ màn Workspace khi GraphRAG ẩn. Panel "đang tải": prewarm() chỉ chạy 3 giây sau khi cửa sổ hiện, nên bấm GraphRAG trong 3 giây đầu gặp _ensure_web() dựng QWebEngineView ĐỒNG BỘ trên GUI thread — đóng băng 1-2 giây mà không có gì báo. Vì GUI thread bị chặn, panel phải repaint() ngay chứ không update(): update() chỉ xếp hàng một lượt vẽ cho vòng lặp sự kiện, mà vòng lặp đó sắp bị chặn, nên panel sẽ chỉ hiện ra sau khi hết đóng băng — đúng lúc không còn cần tới nó nữa. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
"""Project chọn ở tab GraphRAG không được biến mất khi chuyển tab.
|
||||
|
||||
Cùng khuôn với ``test_folder_root_persists.py``: ``WorkspaceTab._bind_project``
|
||||
gọi ``self._structure.set_project(pid)`` vô điều kiện, và nó chạy lại mỗi lần
|
||||
người dùng vào lại màn Workspace (``_goto`` → ``refresh`` → ``_load_current`` →
|
||||
``_bind_project``). Nên bộ chọn project của chính màn GraphRAG bị kéo về giá trị
|
||||
của Workspace mỗi cú chuyển tab.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
pytest.importorskip("PySide6", reason="cần PySide6 để dựng widget thật")
|
||||
|
||||
|
||||
class _Ghi:
|
||||
"""Thay GraphRenderer — chỉ ghi lại nó bị áp project mấy lần, với giá trị gì."""
|
||||
|
||||
def __init__(self):
|
||||
self.lan_ap = []
|
||||
|
||||
def set_project(self, project_id):
|
||||
self.lan_ap.append(project_id)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def view(qapp, monkeypatch):
|
||||
"""StructureGraphView với renderer bị thay — dựng renderer thật kéo theo
|
||||
QtWebEngine, quá đắt cho một khẳng định về luồng điều khiển."""
|
||||
from cowork_local.presentation.graph.structure_graph_view import StructureGraphView
|
||||
|
||||
v = StructureGraphView.__new__(StructureGraphView)
|
||||
v._workspace_project = None
|
||||
v.renderer = _Ghi()
|
||||
return v
|
||||
|
||||
|
||||
def test_lan_dau_van_ap_du_project_la_rong(view):
|
||||
"""``None`` khởi tạo để lần gọi đầu không bị bỏ qua khi pid là chuỗi rỗng."""
|
||||
view.set_workspace_project("")
|
||||
|
||||
assert view.renderer.lan_ap == [""]
|
||||
|
||||
|
||||
def test_refresh_cung_project_khong_ap_lai(view):
|
||||
"""Đây chính là triệu chứng: chuyển tab rồi quay lại là mất lựa chọn."""
|
||||
view.set_workspace_project("p-a")
|
||||
view.set_workspace_project("p-a") # chuyển tab rồi quay lại -> refresh
|
||||
view.set_workspace_project("p-a")
|
||||
|
||||
assert view.renderer.lan_ap == ["p-a"], "áp lại là kéo bộ chọn về, xoá lựa chọn tay"
|
||||
|
||||
|
||||
def test_doi_project_o_workspace_thi_van_ap(view):
|
||||
"""Đổi project thật thì GraphRAG phải theo."""
|
||||
view.set_workspace_project("p-a")
|
||||
view.set_workspace_project("p-b")
|
||||
|
||||
assert view.renderer.lan_ap == ["p-a", "p-b"]
|
||||
|
||||
|
||||
def test_quay_lai_project_cu_thi_ap_lai(view):
|
||||
view.set_workspace_project("p-a")
|
||||
view.set_workspace_project("p-b")
|
||||
view.set_workspace_project("p-a")
|
||||
|
||||
assert view.renderer.lan_ap == ["p-a", "p-b", "p-a"]
|
||||
|
||||
|
||||
def test_bo_khoa_van_di_qua_duoc(view):
|
||||
"""Bỏ chọn project ở Workspace là một thay đổi thật, không phải refresh."""
|
||||
view.set_workspace_project("p-a")
|
||||
view.set_workspace_project("")
|
||||
|
||||
assert view.renderer.lan_ap == ["p-a", ""]
|
||||
|
||||
|
||||
# ---- chỗ gọi phải dùng hàm mới -------------------------------------------
|
||||
|
||||
def test_workspace_tab_goi_set_workspace_project():
|
||||
from pathlib import Path
|
||||
|
||||
src = (Path(__file__).resolve().parents[2] / "ui" / "workspace_tab.py").read_text(encoding="utf-8")
|
||||
|
||||
assert "_structure.set_workspace_project(pid)" in src
|
||||
assert "_structure.set_project(pid)" not in src, (
|
||||
"gọi set_project() vô điều kiện là quay lại đúng lỗi cũ")
|
||||
Reference in New Issue
Block a user