-
Notifications
You must be signed in to change notification settings - Fork 2
Feed/Chatter 组件:补充测试 + Console 集成 + 完成收尾工作 #727
Description
背景
#706 的 P0/P1/P2 核心组件代码已全部完成,放置在 packages/plugin-detail/src/,Roadmap P1.5 已更新标记完成。
但经评估发现三个关键收尾缺口:
- 新组件缺少专项单元测试
- Console 未集成新组件(仍使用旧版
CommentThread) - P3 增强项未实现
本 Issue 跟踪所有需要开展的细项工作。
任务清单
🔴 Task 1 — 补充新组件单元测试
现有测试覆盖的是旧版 ActivityTimeline 和 RecordComments,新的消费 @objectstack/spec Feed 协议的 6 个核心组件均无专项测试。
-
RecordActivityTimeline.test.tsx—packages/plugin-detail/src/__tests__/- 渲染基本 feed items(comment / field_change / task / event / system / email / call)
- 各 item type 显示正确的图标和颜色样式
- Actor 头像 + 名称 + 来源 + 时间戳正确渲染
-
unifiedTimeline模式:评论与字段变更混排 -
filterMode切换:all / comments_only / changes_only / tasks_only - 受控
filterMode和非受控内部 filter 两种模式 - 空列表显示 "No activity recorded"
-
showFilter可通过config.showFilterToggle控制隐藏 - CommentInput 渲染(当
onAddComment提供时) - CommentInput 不渲染(当
onAddComment未提供时或config.showCommentInput === false) - 提交评论:点击按钮 + Ctrl+Enter 快捷键
- 提交后清空输入框
- 提交期间禁用输入和按钮
- 分页:
hasMore=true时显示 "Load more" 按钮 - 加载更多时显示 loading spinner
-
edited标记显示 "(edited)" -
pinned标记显示 "📌 Pinned" -
source字段显示 "via {source}" -
SubscriptionToggle在config.showSubscriptionToggle=true且subscription存在时渲染 - Reactions 在
config.enableReactions=true时渲染 - Threading 在
config.enableThreading=true时按parentId分组
-
RecordChatterPanel.test.tsx—packages/plugin-detail/src/__tests__/- Sidebar 模式(
position='right'):正确宽度、border-l 样式 - Sidebar 模式(
position='left'):border-r 样式 - Inline 模式(
position='bottom'):无 border 样式 - 可折叠:
collapsible=true+defaultCollapsed=true初始折叠 - 折叠态显示 "Open discussion panel" 按钮(sidebar)
- 折叠态显示 "Show Discussion (N)" 按钮(inline)
- 展开后显示 "Close discussion panel" / "Hide discussion" 按钮
- 点击折叠/展开按钮切换状态
-
collapsible=false时不显示折叠按钮 - 内嵌
RecordActivityTimeline正确传递config.feed配置 - Sidebar 模式下 Timeline 有
border-0 shadow-noneclass - 所有回调 props 正确透传(onAddComment, onAddReply, onToggleReaction, onToggleSubscription)
- Sidebar 模式(
-
FieldChangeItem.test.tsx—packages/plugin-detail/src/__tests__/- 渲染字段名(自动 capitalize + 下划线替换空格)
- 使用
fieldLabel优先于自动生成 - 渲染旧值(删除线样式)和新值
- 使用
oldDisplayValue/newDisplayValue优先于原始值 - 旧值/新值为 null 时显示 "(empty)"
- 中间箭头图标渲染
-
ReactionPicker.test.tsx—packages/plugin-detail/src/__tests__/- 渲染已有 reactions:emoji + count
- 已 reacted 的 reaction 显示高亮样式(bg-primary/10)
- 未 reacted 的 reaction 显示普通样式(bg-muted)
- 点击已有 reaction 调用
onToggleReaction(emoji) - "Add reaction" 按钮(SmilePlus 图标)
- 点击 "Add reaction" 展开 emoji picker
- 选择 emoji 调用
onToggleReaction(emoji)并关闭 picker - 无
onToggleReaction时不显示 "Add reaction" 按钮 - 无
onToggleReaction时已有 reaction 按钮 disabled - 自定义
emojiOptions渲染对应 emoji - aria-label 包含 emoji + count
-
ThreadedReplies.test.tsx—packages/plugin-detail/src/__tests__/- 渲染折叠态:显示 "N replies" / "1 reply"
- 点击展开按钮显示所有回复
- 展开态每条回复:头像(avatarUrl 或首字母)+ actor + 时间戳 + body
- 收起态
aria-expanded=false,展开态aria-expanded=true - Reply 输入框渲染(当
showReplyInput=true且onAddReply存在) - 输入文本并点击 Send 按钮调用
onAddReply(parentId, text) - Ctrl+Enter 快捷键提交回复
- 提交后清空输入框
- 空输入时 Send 按钮 disabled
- 提交期间输入和按钮 disabled
-
replies=[]且showReplyInput=false时返回 null
-
SubscriptionToggle.test.tsx—packages/plugin-detail/src/__tests__/-
subscribed=true显示 Bell 图标(text-primary 样式) -
subscribed=false显示 BellOff 图标(text-muted-foreground 样式) - 点击调用
onToggle(!subscription.subscribed) - 点击后 loading 状态 disabled
- 无
onToggle时按钮 disabled - aria-label 随 subscribed 状态变化
- title 随 subscribed 状态变化
-
🔴 Task 2 — Console RecordDetailView 集成
当前 apps/console/src/components/RecordDetailView.tsx 使用旧版 CommentThread(来自 @object-ui/collaboration)。需要替换为新的 spec 协议组件。
-
替换 CommentThread → RecordChatterPanel
- 从
@object-ui/plugin-detail导入RecordChatterPanel - 移除
CommentThread导入 - 将
<CommentThread>替换为<RecordChatterPanel>并传入RecordChatterPanelProps - 配置
position: 'bottom'(保持当前内联布局)或改为position: 'right'(Airtable 风格侧边栏)
- 从
-
接入 FeedItem 数据模型
- 将现有
commentsstate 从Comment[]改为FeedItem[] - 适配
FeedItem接口字段:id,type,actor,actorAvatarUrl,body,createdAt,reactions,parentId,replyCount - 添加字段变更历史获取逻辑(调用
dataSource.find('sys_audit_log', ...)或client.feed.list()) - 合并 comments + field changes 为统一
FeedItem[]数组
- 将现有
-
接入 RecordSubscription
- 添加
subscriptionstate(RecordSubscription类型) - 获取当前用户对该 record 的订阅状态
- 实现
onToggleSubscription回调
- 添加
-
接入分页
- 添加
hasMore/onLoadMore逻辑 - 初始加载 limit 设为 20,后续分页 cursor-based
- 添加
-
接入 Reactions
- 将现有
handleReaction适配为onToggleReaction(itemId, emoji)签名 - Reactions 数据从
{ [emoji]: string[] }格式映射为Reaction[]({ emoji, count, reacted })
- 将现有
-
接入 Threading
- 将
handleAddComment的parentId适配为onAddReply(parentId, text)签名 - 设置
config.enableThreading = true
- 将
🟡 Task 3 — Console ActivityFeed 升级(头部通知)
apps/console/src/components/ActivityFeed.tsx 是 Phase 17 L1 的本地状态组件,未消费 Feed 协议。
- 评估是否将
ActivityFeed(Sheet 铃铛通知面板)替换为RecordActivityTimeline - 如需替换:将
ActivityItem数据模型迁移为FeedItem - 如需替换:接入
client.feed.list()API 获取全局 activity feed
🟡 Task 4 — RichTextCommentInput 集成
RichTextCommentInput 已开发但未被 RecordActivityTimeline 的 CommentInput 区域使用(当前 Timeline 使用普通 <textarea>)。
- 评估是否将
RecordActivityTimeline内嵌的<textarea>升级为RichTextCommentInput - 如升级:传入
mentionSuggestions(用户列表)作为MentionAutocomplete数据源 - 如升级:
onSubmit回调对接onAddComment
🟢 Task 5 — P3 增强项(可后续迭代)
- Comment 编辑功能(edit 按钮 + 内联编辑模式)
- Comment 删除功能(delete 确认对话框)
- 文件附件集成(
CommentAttachment已存在,需接入到 CommentInput 流程) - 富文本渲染(将 Markdown body 渲染为 HTML,目前仅 preview 模式可用)
🟢 Task 6 — 运行测试 & 确认无回归
- 运行
pnpm test确认所有新增测试通过 - 运行
pnpm build确认 42/42 构建通过 - 确认 Console 集成后
RecordDetailView页面功能正常 - 更新 Roadmap 中测试计数(当前 5,177+)
协议参考
| 协议文件 | 位置 | 说明 |
|---|---|---|
FeedItem / FieldChangeEntry / Reaction / RecordSubscription |
@object-ui/types |
类型定义 |
RecordActivityTimeline |
packages/plugin-detail/src/RecordActivityTimeline.tsx |
统一时间线 |
RecordChatterPanel |
packages/plugin-detail/src/RecordChatterPanel.tsx |
侧边面板 |
FieldChangeItem |
packages/plugin-detail/src/FieldChangeItem.tsx |
字段变更条目 |
ReactionPicker |
packages/plugin-detail/src/ReactionPicker.tsx |
Emoji 选择器 |
ThreadedReplies |
packages/plugin-detail/src/ThreadedReplies.tsx |
回复线程 |
SubscriptionToggle |
packages/plugin-detail/src/SubscriptionToggle.tsx |
订阅开关 |
RichTextCommentInput |
packages/plugin-detail/src/RichTextCommentInput.tsx |
富文本输入 |
Console RecordDetailView |
apps/console/src/components/RecordDetailView.tsx |
集成目标 |
Console ActivityFeed |
apps/console/src/components/ActivityFeed.tsx |
通知面板 |
关联
- 上游 Issue: #706 — UI 实现:Airtable 风格的 Comments & Activity Timeline 渲染组件
- 上游协议: objectstack-ai/spec#731 — Feed/Comment/Chatter 协议定义
建议开发流程
- Task 1 先行 — 补测试,确保现有组件实现正确
- Task 2 — Console 集成,切换到新组件
- Task 3-4 — 评估 + 可选升级
- Task 6 — 全量测试验证
- 每步完成后
pnpm test确认无回归