feat(ui): màn quản lý project — chế độ chỉ-xem, chặn trùng tên, menu chuột phải

Bốn thay đổi trên cùng một khối, gom vào presentation/workspace/project_editing.py:

- Project đã có mở ra ở dạng CHỈ ĐỌC; phải bấm "Sửa project" (nút vàng) mới gõ
  được, và nút Lưu chuyển xanh lá. Trước đây form luôn mở nên chỉ cần lỡ tay là
  sửa mất nội dung của một project đang dùng mà không có gì cảnh báo.
- Chặn TRÙNG TÊN khi tạo và khi lưu (không phân biệt hoa thường, bỏ khoảng
  trắng hai đầu). Danh sách bên trái chỉ hiện tên, nên trùng tên là không phân
  biệt được nữa. Chặn TRƯỚC khi ghi đĩa.
- Chuột phải một project: Mở / Sửa / Xoá. Trước đây bấm phải không làm gì cả.
- workspace.counts được format một lần lúc dựng dòng nên đổi ngôn ngữ xong nó
  vẫn nằm ở ngôn ngữ cũ, kể cả khi chọn tiếng Anh. ProjectRow giờ giữ SỐ và tự
  format lại — KHÔNG gọi refresh(), vì refresh() kết thúc bằng _load_current()
  và sẽ xoá mất nội dung người dùng đang gõ dở.

Ba nút về chung một hàng với "Project mới", và cùng theo một luật hiện/ẩn: chỉ
hiện trên sub-tab Project và khi có project đang mở. Hàng tiêu đề vắt ngang cả
màn Workspace nên thứ gì đặt lên đó cũng lọt sang Cowork/Co4E/Thư mục/GraphRAG
nếu không tự ẩn.

Màu vàng/xanh lá đi qua token warning/success. Hai nút dùng nền *_soft với chữ
và viền là token, KHÔNG phải nền đặc: hai token đó được chỉnh làm màu CHỮ (cùng
lý do accent và accent_solid là hai token riêng) — chữ trắng trên warning dark
#CCA700 chỉ đạt ~2.3:1, trượt AA.

ui/workspace_tab.py đang ở đúng trần bánh cóc nên phần mã mới bắt buộc ra module
riêng; chuyển _ProjectRow và CRUD sang đó làm file co từ 566 xuống 523 dòng mã,
và bánh cóc được siết theo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 19:55:02 +09:00
co-authored by Claude Opus 5
parent aecdb15ed3
commit 5fb0f3a82d
7 changed files with 636 additions and 78 deletions
+11 -1
View File
@@ -46,7 +46,17 @@ STRINGS: Dict[str, Dict[str, str]] = {
"vi": "Project của hội thoại này không còn tồn tại — không thể mở."},
"workspace.name": {"en": "Name", "ja": "名前", "vi": "Tên"},
"workspace.description": {"en": "Description", "ja": "説明", "vi": "Mô tả"},
"workspace.instructions": {"en": "Instructions", "ja": "Instructions", "vi": "Instructions"},
"workspace.instructions": {"en": "Instructions", "ja": "指示", "vi": "Hướng dẫn"},
"workspace.edit_project": {"en": "Edit project", "ja": "プロジェクトを編集", "vi": "Sửa project"},
"workspace.menu_open": {"en": "Open", "ja": "開く", "vi": "Mở"},
"workspace.menu_edit": {"en": "Edit", "ja": "編集", "vi": "Sửa"},
"workspace.menu_delete": {"en": "Delete", "ja": "削除", "vi": "Xóa"},
"workspace.name_taken_title": {
"en": "Name already used", "ja": "名前が重複しています", "vi": "Tên đã được dùng"},
"workspace.name_taken_body": {
"en": "Another project is already called \"{name}\". Project names must be unique — the list shows nothing but the name, so two of them cannot be told apart.",
"ja": "「{name}」という名前のプロジェクトが既にあります。一覧には名前しか出ないため、同じ名前が二つあると区別できません。",
"vi": "Đã có project khác tên \"{name}\". Tên project phải khác nhau — danh sách chỉ hiện tên, trùng tên là không phân biệt được."},
"workspace.instructions_placeholder": {
"en": "e.g. \"All answers in Vietnamese. We are building the X reporting tool; always follow the naming rules …\"",
"ja": "例:「回答はすべて日本語で。X レポートツールを開発中。命名規則に従うこと …」",