diff --git a/CHANGELOG.md b/CHANGELOG.md index 8736f265..8bf81a46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ > 开发中的用户文案可先写入 `## Unreleased`;该区不会被前端解析,正式发布时再替换为数字版本和日期。 > 工程口径的完整记录见 `PROGRESS.md` / git log。 +## Unreleased + +- 项目管理集中到左侧:支持直接创建、重命名、查看文件和安全移除空项目;右侧入口改为“当前项目 / 全部文件”,专注项目内及跨项目文件浏览。 + ## 0.72.1 — 2026-09-04 - 左侧导航改为“项目→对话”分组,并保留最近对话和筛选结果;右侧文件范围改用“当前项目 / 全部项目”表达,更容易看清同一项目下的多个对话和共享资料。 diff --git a/tests/frontend_files.test.mjs b/tests/frontend_files.test.mjs index bca3449c..8cc88d32 100644 --- a/tests/frontend_files.test.mjs +++ b/tests/frontend_files.test.mjs @@ -6,6 +6,7 @@ const filesJs = fs.readFileSync("web/static/js/files.js", "utf8"); const layoutJs = fs.readFileSync("web/static/js/layout.js", "utf8"); const jobsJs = fs.readFileSync("web/static/js/software_jobs.js", "utf8"); const previewJs = fs.readFileSync("web/static/js/preview.js", "utf8"); +const newTaskJs = fs.readFileSync("web/static/js/newtask.js", "utf8"); const pageHtml = fs.readFileSync("web/static/dev.html", "utf8"); test("file menu exposes an explicit confirmed replacement action", () => { @@ -24,7 +25,7 @@ test("ordinary uploads default to rename conflict policy", () => { test("file workspace exposes explicit task and all-files contexts", () => { assert.match(pageHtml, /id="files-scope-task"[^>]*>当前项目); - assert.match(pageHtml, /id="files-scope-all"[^>]*>全部项目); + assert.match(pageHtml, /id="files-scope-all"[^>]*>全部文件); assert.match(filesJs, /state\.filesScope = "task"/); assert.match(filesJs, /state\.filesScope = "all"/); }); @@ -39,6 +40,17 @@ test("task navigation groups chats by project with restrained icon sizes", () => assert.match(chatJs, /working_dir: projectName/); assert.match(chatJs, /state\.taskHasMore = filtered &&/); assert.match(chatJs, /task-project-more/); + assert.match(chatJs, /task-project-create/); + assert.doesNotMatch(chatJs, /if \(!folder\.n_tasks\) continue/); + assert.match(chatJs, /renameProjectFolder/); + assert.match(chatJs, /removeProjectFolder/); + assert.match(chatJs, /openProjectFiles/); + assert.match(filesJs, /function createProjectFolder/); + assert.match(filesJs, /function removeProjectFolder/); + assert.match(chatJs, /folders-refresh-requested/); + assert.match(newTaskJs, /folders-refresh-requested/); + assert.match(filesJs, /setRightPanelTab\("files"\)/); + assert.match(filesJs, /recursive: entries\.length > 0/); assert.match(pageHtml, /\.task-nav-icon \{ width: 15px; height: 15px;/); assert.match(pageHtml, /\.task-project-head \.task-nav-icon \{ width: 16px; height: 16px;/); }); diff --git a/web/static/dev.html b/web/static/dev.html index ab6a5004..4ca460ab 100644 --- a/web/static/dev.html +++ b/web/static/dev.html @@ -685,11 +685,20 @@ .task-nav-recent { padding: 8px 0 6px; border-bottom: 1px solid var(--border-soft); } .task-nav-section-title { min-height: 28px; padding: 4px 12px; display: flex; align-items: center; gap: 7px; color: var(--muted); font-size: 11px; font-weight: 600; letter-spacing: .02em; } + .task-nav-section-title .spacer { flex: 1; } + .task-project-create { width: 24px; height: 24px; padding: 0; border: 0; border-radius: 5px; + background: transparent; color: var(--muted); font-size: 17px; line-height: 1; cursor: pointer; } + .task-project-create:hover { background: var(--hover); color: var(--text); } .task-projects { padding: 6px 0 10px; } .task-project { margin: 1px 0; } - .task-project-head { width: 100%; min-height: 34px; padding: 4px 12px 4px 8px; border: 0; border-radius: 0; + .task-project-row { display: flex; align-items: center; } + .task-project-head { flex: 1; min-width: 0; min-height: 34px; padding: 4px 4px 4px 8px; border: 0; border-radius: 0; background: transparent; color: var(--text); display: flex; align-items: center; gap: 6px; cursor: pointer; text-align: left; } - .task-project-head:hover { background: var(--hover); } + .task-project-row:hover { background: var(--hover); } + .task-project-menu { width: 28px; height: 28px; margin-right: 6px; padding: 0; flex: none; border: 0; + background: transparent; color: var(--muted); opacity: 0; cursor: pointer; } + .task-project-row:hover .task-project-menu, .task-project-menu:focus-visible { opacity: 1; } + @media (hover: none) { .task-project-menu { opacity: .65; } } .task-project-chevron { width: 12px; height: 18px; display: inline-flex; align-items: center; justify-content: center; flex: none; color: var(--muted); font-size: 15px; line-height: 1; transition: transform .14s ease; } .task-project.open .task-project-chevron { transform: rotate(90deg); } @@ -2379,7 +2388,7 @@