feat: support setting default workspace/project from frontend
- Add set_default_host_workspace() and /api/host/workspaces/set-default - Add default_workspace_id persistence in UserManager and /api/projects/set-default - Add 'Set as default' button in HostWorkspaceManageDialog - Sync default badge in LeftPanel workspace list - Update all workspace/project APIs to return real default_workspace_id
This commit is contained in:
parent
2c6d208be7
commit
a212a0076c
@ -338,8 +338,43 @@ def delete_host_workspace(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def set_default_host_workspace(
|
||||||
|
workspace_id: str,
|
||||||
|
config_path: Optional[Union[str, Path]] = None,
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""设置指定工作区为默认工作区。"""
|
||||||
|
ws_id = str(workspace_id or "").strip()
|
||||||
|
if not ws_id:
|
||||||
|
raise ValueError("缺少 workspace_id")
|
||||||
|
|
||||||
|
cfg_path = _resolve_config_path(config_path)
|
||||||
|
with _HOST_WORKSPACE_LOCK:
|
||||||
|
payload = _ensure_config_file(cfg_path, strict=True)
|
||||||
|
raw_workspaces = payload.get("workspaces")
|
||||||
|
if not isinstance(raw_workspaces, list):
|
||||||
|
raw_workspaces = []
|
||||||
|
|
||||||
|
seen_ids = set()
|
||||||
|
for idx, item in enumerate(raw_workspaces):
|
||||||
|
normalized = _normalize_entry(item, idx)
|
||||||
|
if normalized:
|
||||||
|
seen_ids.add(normalized.get("workspace_id"))
|
||||||
|
|
||||||
|
if ws_id not in seen_ids:
|
||||||
|
raise ValueError("工作区不存在")
|
||||||
|
|
||||||
|
payload["default_workspace_id"] = ws_id
|
||||||
|
_atomic_write_json(cfg_path, payload)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"default_workspace_id": ws_id,
|
||||||
|
"catalog": load_host_workspace_catalog(config_path=cfg_path),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"load_host_workspace_catalog",
|
"load_host_workspace_catalog",
|
||||||
"resolve_host_workspace",
|
"resolve_host_workspace",
|
||||||
"create_host_workspace",
|
"create_host_workspace",
|
||||||
|
"set_default_host_workspace",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -36,6 +36,7 @@ class UserRecord:
|
|||||||
invite_code: Optional[str] = None
|
invite_code: Optional[str] = None
|
||||||
role: str = "user"
|
role: str = "user"
|
||||||
tutorial_completed: bool = False
|
tutorial_completed: bool = False
|
||||||
|
default_workspace_id: str = "default"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -390,6 +391,14 @@ class UserManager:
|
|||||||
workspace.workspace_id = workspace_id
|
workspace.workspace_id = workspace_id
|
||||||
return workspace
|
return workspace
|
||||||
|
|
||||||
|
def _get_user_default_workspace_id(self, username: str) -> str:
|
||||||
|
"""返回用户设置的默认项目 ID,如未设置或无效则返回 default。"""
|
||||||
|
record = self._users.get(self._normalize_username(username))
|
||||||
|
default_id = str(getattr(record, "default_workspace_id", None) or "default").strip()
|
||||||
|
if not default_id:
|
||||||
|
return "default"
|
||||||
|
return default_id
|
||||||
|
|
||||||
def list_user_workspaces(self, username: str) -> Dict[str, Dict]:
|
def list_user_workspaces(self, username: str) -> Dict[str, Dict]:
|
||||||
username = self._normalize_username(username)
|
username = self._normalize_username(username)
|
||||||
self._migrate_legacy_docker_workspace_layout(username)
|
self._migrate_legacy_docker_workspace_layout(username)
|
||||||
@ -404,15 +413,21 @@ class UserManager:
|
|||||||
if web_root.exists():
|
if web_root.exists():
|
||||||
self._collect_workspaces(result, web_root)
|
self._collect_workspaces(result, web_root)
|
||||||
|
|
||||||
|
default_workspace_id = self._get_user_default_workspace_id(username)
|
||||||
|
|
||||||
# 确保 default 始终存在
|
# 确保 default 始终存在
|
||||||
if "default" not in result:
|
if "default" not in result:
|
||||||
result["default"] = {
|
result["default"] = {
|
||||||
"workspace_id": "default",
|
"workspace_id": "default",
|
||||||
"label": "默认项目",
|
"label": "默认项目",
|
||||||
"path": "",
|
"path": "",
|
||||||
"is_default": True,
|
"is_default": default_workspace_id == "default",
|
||||||
"has_conversations": False,
|
"has_conversations": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 同步 is_default 标记
|
||||||
|
for ws_id in result:
|
||||||
|
result[ws_id]["is_default"] = ws_id == default_workspace_id
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _collect_workspaces(self, result: Dict[str, Dict], projects_root: Path) -> None:
|
def _collect_workspaces(self, result: Dict[str, Dict], projects_root: Path) -> None:
|
||||||
@ -519,6 +534,20 @@ class UserManager:
|
|||||||
raise ValueError("项目不存在")
|
raise ValueError("项目不存在")
|
||||||
shutil.rmtree(target)
|
shutil.rmtree(target)
|
||||||
|
|
||||||
|
def set_default_user_workspace(self, username: str, workspace_id: str) -> str:
|
||||||
|
"""设置指定项目为用户默认项目,返回生效的默认项目 ID。"""
|
||||||
|
username = self._normalize_username(username)
|
||||||
|
ws_id = self.normalize_workspace_id(workspace_id)
|
||||||
|
known = self.list_user_workspaces(username)
|
||||||
|
if ws_id not in known:
|
||||||
|
raise ValueError("项目不存在")
|
||||||
|
record = self._users.get(username)
|
||||||
|
if not record:
|
||||||
|
raise ValueError("用户不存在")
|
||||||
|
record.default_workspace_id = ws_id
|
||||||
|
self._save_users()
|
||||||
|
return ws_id
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _load_workspace_label(workspace_root: Path, fallback: str) -> str:
|
def _load_workspace_label(workspace_root: Path, fallback: str) -> str:
|
||||||
meta_path = workspace_root / "project.json"
|
meta_path = workspace_root / "project.json"
|
||||||
@ -652,9 +681,12 @@ class UserManager:
|
|||||||
invite_code=payload.get("invite_code"),
|
invite_code=payload.get("invite_code"),
|
||||||
role=payload.get("role", "user"),
|
role=payload.get("role", "user"),
|
||||||
tutorial_completed=bool(payload.get("tutorial_completed", False)),
|
tutorial_completed=bool(payload.get("tutorial_completed", False)),
|
||||||
|
default_workspace_id=str(payload.get("default_workspace_id") or "default").strip() or "default",
|
||||||
)
|
)
|
||||||
if "tutorial_completed" not in payload:
|
if "tutorial_completed" not in payload:
|
||||||
migrated = True
|
migrated = True
|
||||||
|
if "default_workspace_id" not in payload:
|
||||||
|
migrated = True
|
||||||
self._users[username] = record
|
self._users[username] = record
|
||||||
self._index_user(record)
|
self._index_user(record)
|
||||||
if migrated:
|
if migrated:
|
||||||
@ -672,6 +704,7 @@ class UserManager:
|
|||||||
"invite_code": record.invite_code,
|
"invite_code": record.invite_code,
|
||||||
"role": record.role,
|
"role": record.role,
|
||||||
"tutorial_completed": bool(record.tutorial_completed),
|
"tutorial_completed": bool(record.tutorial_completed),
|
||||||
|
"default_workspace_id": str(record.default_workspace_id or "default").strip() or "default",
|
||||||
}
|
}
|
||||||
for username, record in self._users.items()
|
for username, record in self._users.items()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ from modules.host_workspace_manager import (
|
|||||||
load_host_workspace_catalog,
|
load_host_workspace_catalog,
|
||||||
rename_host_workspace,
|
rename_host_workspace,
|
||||||
resolve_host_workspace,
|
resolve_host_workspace,
|
||||||
|
set_default_host_workspace,
|
||||||
)
|
)
|
||||||
from utils.host_workspace_debug import write_host_workspace_debug
|
from utils.host_workspace_debug import write_host_workspace_debug
|
||||||
from .utils_common import log_conn_diag
|
from .utils_common import log_conn_diag
|
||||||
@ -49,14 +50,15 @@ def _close_terminal_for_key(term_key: str):
|
|||||||
|
|
||||||
def _build_docker_projects_payload(username: str, current_id: str) -> list[dict]:
|
def _build_docker_projects_payload(username: str, current_id: str) -> list[dict]:
|
||||||
running_by_workspace = _active_task_counts(username)
|
running_by_workspace = _active_task_counts(username)
|
||||||
|
workspaces = user_manager.list_user_workspaces(username)
|
||||||
projects = []
|
projects = []
|
||||||
for ws_id, item in user_manager.list_user_workspaces(username).items():
|
for ws_id, item in workspaces.items():
|
||||||
projects.append({
|
projects.append({
|
||||||
"workspace_id": ws_id,
|
"workspace_id": ws_id,
|
||||||
"label": item.get("label") or ("默认项目" if ws_id == "default" else ws_id),
|
"label": item.get("label") or ("默认项目" if ws_id == "default" else ws_id),
|
||||||
"path": "",
|
"path": "",
|
||||||
"is_current": ws_id == current_id,
|
"is_current": ws_id == current_id,
|
||||||
"is_default": ws_id == "default",
|
"is_default": bool(item.get("is_default", ws_id == "default")),
|
||||||
"running_task_count": int(running_by_workspace.get(ws_id, 0)),
|
"running_task_count": int(running_by_workspace.get(ws_id, 0)),
|
||||||
})
|
})
|
||||||
return projects
|
return projects
|
||||||
@ -1051,10 +1053,11 @@ def list_docker_projects():
|
|||||||
# 默认项目用于向后兼容旧 Docker Web 文件/对话。
|
# 默认项目用于向后兼容旧 Docker Web 文件/对话。
|
||||||
user_manager.ensure_user_workspace(username, current_id)
|
user_manager.ensure_user_workspace(username, current_id)
|
||||||
projects = _build_docker_projects_payload(username, current_id)
|
projects = _build_docker_projects_payload(username, current_id)
|
||||||
|
default_workspace_id = user_manager._get_user_default_workspace_id(username)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"data": {
|
"data": {
|
||||||
"default_workspace_id": "default",
|
"default_workspace_id": default_workspace_id,
|
||||||
"current_workspace_id": current_id,
|
"current_workspace_id": current_id,
|
||||||
"workspaces": projects,
|
"workspaces": projects,
|
||||||
}
|
}
|
||||||
@ -1100,12 +1103,13 @@ def select_docker_project():
|
|||||||
attach_user_broadcast(terminal, username)
|
attach_user_broadcast(terminal, username)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
default_workspace_id = user_manager._get_user_default_workspace_id(username)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"data": {
|
"data": {
|
||||||
"current_workspace_id": session["workspace_id"],
|
"current_workspace_id": session["workspace_id"],
|
||||||
"project_path": "",
|
"project_path": "",
|
||||||
"default_workspace_id": "default",
|
"default_workspace_id": default_workspace_id,
|
||||||
"reloaded": previous_workspace_id != session["workspace_id"],
|
"reloaded": previous_workspace_id != session["workspace_id"],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1127,13 +1131,14 @@ def create_docker_project():
|
|||||||
return jsonify({"success": False, "error": str(exc)}), 400
|
return jsonify({"success": False, "error": str(exc)}), 400
|
||||||
projects = []
|
projects = []
|
||||||
current_id = session.get("workspace_id") or "default"
|
current_id = session.get("workspace_id") or "default"
|
||||||
|
default_workspace_id = user_manager._get_user_default_workspace_id(username)
|
||||||
for ws_id, item in user_manager.list_user_workspaces(username).items():
|
for ws_id, item in user_manager.list_user_workspaces(username).items():
|
||||||
projects.append({
|
projects.append({
|
||||||
"workspace_id": ws_id,
|
"workspace_id": ws_id,
|
||||||
"label": item.get("label") or ws_id,
|
"label": item.get("label") or ws_id,
|
||||||
"path": "",
|
"path": "",
|
||||||
"is_current": ws_id == current_id,
|
"is_current": ws_id == current_id,
|
||||||
"is_default": ws_id == "default",
|
"is_default": ws_id == default_workspace_id,
|
||||||
})
|
})
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
@ -1144,7 +1149,7 @@ def create_docker_project():
|
|||||||
"label": label,
|
"label": label,
|
||||||
"path": "",
|
"path": "",
|
||||||
},
|
},
|
||||||
"default_workspace_id": "default",
|
"default_workspace_id": default_workspace_id,
|
||||||
"current_workspace_id": current_id,
|
"current_workspace_id": current_id,
|
||||||
"workspaces": projects,
|
"workspaces": projects,
|
||||||
}
|
}
|
||||||
@ -1169,11 +1174,12 @@ def rename_docker_project():
|
|||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
return jsonify({"success": False, "error": str(exc)}), 400
|
return jsonify({"success": False, "error": str(exc)}), 400
|
||||||
current_id = session.get("workspace_id") or "default"
|
current_id = session.get("workspace_id") or "default"
|
||||||
|
default_workspace_id = user_manager._get_user_default_workspace_id(username)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"data": {
|
"data": {
|
||||||
"workspace": workspace,
|
"workspace": workspace,
|
||||||
"default_workspace_id": "default",
|
"default_workspace_id": default_workspace_id,
|
||||||
"current_workspace_id": current_id,
|
"current_workspace_id": current_id,
|
||||||
"workspaces": _build_docker_projects_payload(username, current_id),
|
"workspaces": _build_docker_projects_payload(username, current_id),
|
||||||
}
|
}
|
||||||
@ -1218,11 +1224,20 @@ def delete_docker_project():
|
|||||||
)
|
)
|
||||||
except RuntimeError as exc:
|
except RuntimeError as exc:
|
||||||
return jsonify({"success": False, "error": str(exc)}), 503
|
return jsonify({"success": False, "error": str(exc)}), 503
|
||||||
|
|
||||||
|
# 如果删除的是当前默认项目,重置为 default
|
||||||
|
if user_manager._get_user_default_workspace_id(username) == workspace_id:
|
||||||
|
try:
|
||||||
|
user_manager.set_default_user_workspace(username, "default")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
default_workspace_id = user_manager._get_user_default_workspace_id(username)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"data": {
|
"data": {
|
||||||
"deleted_workspace_id": workspace_id,
|
"deleted_workspace_id": workspace_id,
|
||||||
"default_workspace_id": "default",
|
"default_workspace_id": default_workspace_id,
|
||||||
"current_workspace_id": current_id,
|
"current_workspace_id": current_id,
|
||||||
"workspaces": _build_docker_projects_payload(username, current_id),
|
"workspaces": _build_docker_projects_payload(username, current_id),
|
||||||
}
|
}
|
||||||
@ -1474,6 +1489,64 @@ def delete_host_workspace_api():
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@status_bp.route('/api/host/workspaces/set-default', methods=['POST'])
|
||||||
|
@api_login_required
|
||||||
|
def set_default_host_workspace_api():
|
||||||
|
if not _is_host_mode_request():
|
||||||
|
return jsonify({"success": False, "error": "仅宿主机模式可用"}), 403
|
||||||
|
|
||||||
|
payload = request.get_json(silent=True) or {}
|
||||||
|
workspace_id = (payload.get("workspace_id") or "").strip()
|
||||||
|
if not workspace_id:
|
||||||
|
return jsonify({"success": False, "error": "缺少 workspace_id"}), 400
|
||||||
|
try:
|
||||||
|
result = set_default_host_workspace(workspace_id)
|
||||||
|
except ValueError as exc:
|
||||||
|
return jsonify({"success": False, "error": str(exc)}), 400
|
||||||
|
except Exception as exc:
|
||||||
|
return jsonify({"success": False, "error": str(exc)}), 500
|
||||||
|
|
||||||
|
catalog = result.get("catalog") or load_host_workspace_catalog()
|
||||||
|
current_id = (session.get("host_workspace_id") or "").strip()
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"data": {
|
||||||
|
"default_workspace_id": catalog.get("default_workspace_id"),
|
||||||
|
"current_workspace_id": current_id,
|
||||||
|
"workspaces": _build_host_workspaces_payload(catalog, current_id),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@status_bp.route('/api/projects/set-default', methods=['POST'])
|
||||||
|
@api_login_required
|
||||||
|
def set_default_docker_project_api():
|
||||||
|
if not _is_docker_project_request():
|
||||||
|
return jsonify({"success": False, "error": "仅 Docker Web 模式可用"}), 403
|
||||||
|
|
||||||
|
payload = request.get_json(silent=True) or {}
|
||||||
|
workspace_id = (payload.get("workspace_id") or "").strip()
|
||||||
|
if not workspace_id:
|
||||||
|
return jsonify({"success": False, "error": "缺少项目 ID"}), 400
|
||||||
|
username = session.get("username")
|
||||||
|
try:
|
||||||
|
user_manager.set_default_user_workspace(username, workspace_id)
|
||||||
|
except ValueError as exc:
|
||||||
|
return jsonify({"success": False, "error": str(exc)}), 400
|
||||||
|
except Exception as exc:
|
||||||
|
return jsonify({"success": False, "error": str(exc)}), 500
|
||||||
|
|
||||||
|
current_id = session.get("workspace_id") or "default"
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"data": {
|
||||||
|
"default_workspace_id": user_manager._get_user_default_workspace_id(username),
|
||||||
|
"current_workspace_id": current_id,
|
||||||
|
"workspaces": _build_docker_projects_payload(username, current_id),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@status_bp.route('/api/container-status')
|
@status_bp.route('/api/container-status')
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@with_terminal
|
@with_terminal
|
||||||
|
|||||||
@ -551,6 +551,7 @@
|
|||||||
@create="submitHostWorkspaceCreateFromManage"
|
@create="submitHostWorkspaceCreateFromManage"
|
||||||
@rename="renameHostWorkspace"
|
@rename="renameHostWorkspace"
|
||||||
@delete="deleteHostWorkspace"
|
@delete="deleteHostWorkspace"
|
||||||
|
@set-default="setDefaultHostWorkspace"
|
||||||
/>
|
/>
|
||||||
</transition>
|
</transition>
|
||||||
<TutorialOverlay v-if="tutorialStore.running" />
|
<TutorialOverlay v-if="tutorialStore.running" />
|
||||||
|
|||||||
@ -1474,6 +1474,52 @@ export const uiMethods = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async setDefaultHostWorkspace(payload = {}) {
|
||||||
|
if (!(this.versioningHostMode || this.dockerProjectMode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const workspaceId = String(payload?.workspace_id || '').trim();
|
||||||
|
if (!workspaceId) return;
|
||||||
|
if (workspaceId === this.defaultHostWorkspaceId) return;
|
||||||
|
|
||||||
|
this.hostWorkspaceManageSubmitting = true;
|
||||||
|
this.hostWorkspaceCreateError = '';
|
||||||
|
const kindLabel = this.versioningHostMode ? '工作区' : '项目';
|
||||||
|
try {
|
||||||
|
const endpoint = this.versioningHostMode
|
||||||
|
? '/api/host/workspaces/set-default'
|
||||||
|
: '/api/projects/set-default';
|
||||||
|
const resp = await fetch(endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
credentials: 'same-origin',
|
||||||
|
body: JSON.stringify({ workspace_id: workspaceId })
|
||||||
|
});
|
||||||
|
const result = await resp.json().catch(() => ({}));
|
||||||
|
if (!resp.ok || !result?.success) {
|
||||||
|
throw new Error(result?.error || `设置默认${kindLabel}失败`);
|
||||||
|
}
|
||||||
|
const data = result.data || {};
|
||||||
|
this.defaultHostWorkspaceId = String(data.default_workspace_id || workspaceId);
|
||||||
|
await this.fetchHostWorkspaces();
|
||||||
|
this.uiPushToast({
|
||||||
|
title: `已设为默认${kindLabel}`,
|
||||||
|
message: (this.hostWorkspaces || []).find((w: any) => w.workspace_id === workspaceId)?.label || workspaceId,
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error || `设置默认${kindLabel}失败`);
|
||||||
|
this.hostWorkspaceCreateError = message;
|
||||||
|
this.uiPushToast({
|
||||||
|
title: `设置默认${kindLabel}失败`,
|
||||||
|
message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
this.hostWorkspaceManageSubmitting = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
fetchTodoList() {
|
fetchTodoList() {
|
||||||
return this.fileFetchTodoList();
|
return this.fileFetchTodoList();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -77,12 +77,24 @@
|
|||||||
{{ item.path || '(未配置路径)' }}
|
{{ item.path || '(未配置路径)' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="workspace-manage-badges">
|
<div class="workspace-manage-badges">
|
||||||
|
<span v-if="item.workspace_id === defaultWorkspaceId" class="workspace-manage-badge default">
|
||||||
|
默认
|
||||||
|
</span>
|
||||||
<span v-if="Number(item.running_task_count || 0) > 0" class="workspace-manage-badge running">
|
<span v-if="Number(item.running_task_count || 0) > 0" class="workspace-manage-badge running">
|
||||||
运行中
|
运行中
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="workspace-manage-actions">
|
<div class="workspace-manage-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="host-workspace-dialog__btn ghost"
|
||||||
|
:class="{ active: item.workspace_id === defaultWorkspaceId }"
|
||||||
|
:disabled="busy || item.workspace_id === defaultWorkspaceId"
|
||||||
|
@click="submitSetDefault(item)"
|
||||||
|
>
|
||||||
|
{{ item.workspace_id === defaultWorkspaceId ? '已默认' : '设为默认' }}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="host-workspace-dialog__btn ghost"
|
class="host-workspace-dialog__btn ghost"
|
||||||
@ -140,6 +152,7 @@ const emits = defineEmits<{
|
|||||||
(event: 'create', payload: { path: string; label: string }): void;
|
(event: 'create', payload: { path: string; label: string }): void;
|
||||||
(event: 'rename', payload: { workspace_id: string; label: string }): void;
|
(event: 'rename', payload: { workspace_id: string; label: string }): void;
|
||||||
(event: 'delete', item: WorkspaceItem): void;
|
(event: 'delete', item: WorkspaceItem): void;
|
||||||
|
(event: 'setDefault', payload: { workspace_id: string }): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workspaceKind = props.workspaceKind || 'workspace';
|
const workspaceKind = props.workspaceKind || 'workspace';
|
||||||
@ -190,6 +203,11 @@ const submitRename = (item: WorkspaceItem) => {
|
|||||||
label: String(renameDrafts[item.workspace_id] ?? '').trim()
|
label: String(renameDrafts[item.workspace_id] ?? '').trim()
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const submitSetDefault = (item: WorkspaceItem) => {
|
||||||
|
if (item.workspace_id === props.defaultWorkspaceId) return;
|
||||||
|
emits('setDefault', { workspace_id: item.workspace_id });
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -368,6 +386,11 @@ const submitRename = (item: WorkspaceItem) => {
|
|||||||
color: var(--claude-accent);
|
color: var(--claude-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.workspace-manage-badge.default {
|
||||||
|
color: var(--state-success);
|
||||||
|
border-color: color-mix(in srgb, var(--state-success) 45%, var(--theme-control-border-strong));
|
||||||
|
}
|
||||||
|
|
||||||
.workspace-manage-empty {
|
.workspace-manage-empty {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--claude-text-secondary);
|
color: var(--claude-text-secondary);
|
||||||
|
|||||||
@ -222,6 +222,12 @@
|
|||||||
<div class="host-workspace-card-head">
|
<div class="host-workspace-card-head">
|
||||||
<span class="host-workspace-label">{{ item.label }}</span>
|
<span class="host-workspace-label">{{ item.label }}</span>
|
||||||
<span class="host-workspace-badges">
|
<span class="host-workspace-badges">
|
||||||
|
<span
|
||||||
|
v-if="item.workspace_id === hostWorkspaceDefaultId"
|
||||||
|
class="host-workspace-badge default"
|
||||||
|
>
|
||||||
|
默认
|
||||||
|
</span>
|
||||||
<span
|
<span
|
||||||
v-if="Number(item.running_task_count || 0) > 0"
|
v-if="Number(item.running_task_count || 0) > 0"
|
||||||
class="host-workspace-badge running"
|
class="host-workspace-badge running"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user