feat: Bitable P0 UX Polish + Agent Parity #23
Loading…
Reference in New Issue
No description provided.
Delete Branch "feat/bitable-enhancement"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bitable P0 UX Polish + Agent Parity
Summary
实现 bitable P0 交付:统一设计 token 系统 + grid 视图 UX 补齐 + agent 对等闭合。分 3 阶段交付(R5 token 基座 → R1-R4 前端 UX → R15a 后端+agent)。
Changes by Implementation Unit
Phase 1 — Foundation
U1: R5 Design Token System + vxe-table Dependency (
e1cf073)bitable-tokens.css— 4 类 token(颜色/间距/圆角/字号/抽屉宽度)+ 条件格式 8 色 WCAG AA 预设FieldTypeIcon.vue— 9 种字段类型 Ant Design Outlined 图标映射useResponsiveBreakpoint.ts— 768/1024/1440 响应式断点 composableLoadingState.vue+ErrorState.vue— 统一加载/错误态组件package.json— 显式声明 vxe-table + vxe-pc-ui(消除幽灵依赖)Phase 2 — Frontend UX
U2: R1 Inline Field Configuration (
f0c993a)InlineFieldConfigurator.vue— 列头菜单内联编辑(不跳抽屉)fieldRenderUtils.ts— 类型转换兼容性检查(9 种字段类型矩阵)ColumnHeaderMenu.vue重构 +BitableGrid.vueheader slot 集成U3: R2 Record Detail Drawer (
5baaeb4)RecordDetailDrawer.vue— 行点击展开详情抽屉(480px/640px 自适应)recordDrawerUtils.ts— 字段值渲染 + 缩略图 + 抽屉宽度计算U4: R3 View Type Switcher (
f280627)viewSwitcherUtils.ts— 5 种视图类型元数据ViewSwitcher.vue— Dropdown + disabled items + "规划中" tooltiphandleCreateView接受 view_type 参数(不再硬编码 grid)U5: R4 Grouping + Conditional Formatting (
e931fbe)GroupingEditor.vue— 多字段分组(max 3)+ 方向 + 排序ConditionalFormatEditor.vue— 列表式规则编辑器(7 运算符 + 8 色 + bold 默认)groupingRulesUtils.ts— 分组树 + 聚合 + CF 匹配(首条 wins)view_config.py— Pydantic 校验 GroupByItem/ConditionalFormatRuleBitableGrid.vue— 分组 wrapper + 条件格式着色(组合态:分组头不染色)Phase 3 — Agent Parity
U6: R15a BitableTool 4 New Actions + DELETE /views (
229dc0b)DELETE /views/{view_id}端点(204 + 404-before-403 + 409 last-view protection)ViewSwitcher.vue视图删除入口 + popconfirmPost-Review
ce-simplify-code (
137bda0) — 5 文件行为保持简化(-22 行)Residual findings (
0f4a418) — 3 个 P2/P3 deferred itemsTest Coverage
后端: 54 pytest passed (U5) + 19 pytest passed (U6)
前端: typecheck + build:frontend 通过,hex grep 零匹配
Code Review
ce-code-review (mode:agent) — PASS WITH FINDINGS
Residual Review Findings
text()SQL calls in repository.py (line 660, 778-779) — not introduced by this branch, defer to subsequent sprint详见
docs/residual-review-findings/feat-bitable-enhancement.mdChecklist
Plan Reference
docs/plans/2026-07-03-001-feat-bitable-p0-ux-and-agent-parity-plan.mdExtend BitableTool from 6 to 10 actions (create_view, update_view, update_field, delete_view) and add the DELETE /views/{view_id} backend endpoint with 404-before-403 ownership, 409 last-view protection, and X-Internal-Token passthrough (KTD11). Backend: - repository.py: add delete_view() — DELETE row by view_id, returns rowcount > 0 - service.py: add LastViewDeletionError domain exception + delete_view() with last-view guard (siblings <= 1 → raise → route maps to 409) - routes/bitable.py: add DELETE /views/{view_id} (204 No Content), 404-before-403 ownership pattern, 409 on LastViewDeletionError, X-Internal-Token passthrough via require_bitable_auth - tools/bitable_tool.py: add 4 new actions (_create_view, _update_view, _update_field, _delete_view), register in BOTH handlers dict AND input_schema.action.enum (KTD10 — 10 actions each) Frontend: - api/bitable.ts: add deleteView(viewId): Promise<void> - stores/bitable.ts: add deleteView action — removes from local state, switches to first remaining view if active was deleted, 409 warning - ViewSwitcher.vue: add delete button (a-popconfirm "确认删除此视图?"), hidden when views.length <= 1 (preempt last-view 409) - BitableFileDetailView.vue: handle @delete event from ViewSwitcher Tests: - test_routes.py: 6 new DELETE /views tests (204, 404 missing, 404 non-owner, 409 last-view, internal-token passthrough, internal-token 404) - test_bitable_tool.py: 13 new tests (action count = 10, handlers = 10, 4 action happy paths, missing-field errors, 409 last-view, R3/R4 config parity, X-Internal-Token passthrough on all 4 new actions) - e2e/bitable-agent-parity.spec.ts: 10 scenarios (P1-P10) covering delete button visibility, popconfirm, 204/409/404 flows, tab removal, view switch after delete, create view adds tab Verification: - ruff check: all files pass - pytest: 62 passed, 12 pre-existing failures (unchanged frome931fbebaseline) - typecheck: pass (EXIT_CODE=0) - build:frontend: pass (BUILD_EXIT=0) - action count: ENUM=10, HANDLERS=10, delete_view in both - no blue hex colors in ViewSwitcher.vue Pre-existing test failures (12, unchanged frome931fbe): test_create_table_success, test_create_field_success, test_list_fields, test_create_records_batch, test_upsert_inserts_then_updates, test_upsert_preserves_user_columns, test_create_view_success, test_batch_upsert_1200_records, test_resume_from_partial_failure, test_query_records, test_query_records_with_limit, test_collect_api Constraints honored: - No emojis, no `any` type, no blue hex colors, no pyproject.toml changes - 404-before-403 for non-owned resources (Pattern 4) - X-Internal-Token transparent passthrough (KTD11) - KTD10: actions registered in both handlers dict AND enum