Repository navigation
feat(ui): open field history on the CRM's four main objects; the timeline's Changes chip follows trackHistory - #30158
Closed
objectstack-fleet[bot] wants to merge 3 commits into
Closed
objectstack-fleet[bot] wants to merge 3 commits into
objectstack-fleet[bot] wants to merge 3 commits into
Conversation
crm_lead, crm_account, crm_contact and crm_opportunity declare enable.trackHistory, so their record pages show each field change with its before and after values. Claude-Session: https://claude.ai/code/session_01QSeKYnE9YNkSZen7sijLA3 Co-authored-by: Claude <noreply@anthropic.com>
… is shown RecordDetailView hands its trackHistory gate (historyEnabled) to the stream through RecordFieldHistoryContext; record:activity drops the changes chip while it is false and falls back to all when the chosen chip goes away. Claude-Session: https://claude.ai/code/session_01QSeKYnE9YNkSZen7sijLA3 Co-authored-by: Claude <noreply@anthropic.com>
…ory; changeset Claude-Session: https://claude.ai/code/session_01QSeKYnE9YNkSZen7sijLA3 Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Nov 4, 2026
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #30074
Clause-②: no
Metadata-protocol: none
维护者速读
enable.trackHistory,记录页的动态里能看到每次字段修改的旧值和新值;没有打开它的对象,动态页签上不再出现「变更」筛选。ui/packages/plugin-detail/src/renderers/record-activity.tsx(选中的筛选被拿掉时回到「全部」)、ui/packages/plugin-detail/src/recordTimelineStream.ts(新的上下文与筛选列表)、ui/packages/app-shell/src/views/RecordDetailView.tsx(把historyEnabled交给动态)。pnpm --dir ui exec vitest run packages/plugin-detail/src/__tests__/recordTimelineStream-27055.test.tsx,预期全部通过;或pnpm dev:crm后打开一条商机,改赢单概率,再打开动态页签:有「变更」筛选,点开能看到「赢单概率 70 → 75」。What changes
crm_lead,crm_account,crm_contactandcrm_opportunitydeclareenable: { trackHistory: true }(none of the four had anenableblock). These are the four object entries of the CRM app's Sales navigation other thancrm_activity, which is the activity log itself;crm_opportunity_line_itemis a child of the opportunity and has no navigation entry. Every other object stays opt-in.RecordDetailView.tsx: the 动态 stream's chips are rendered byRecordActivityTimelinein@object-ui/plugin-detail, with the chip state held in therecord:activityrenderer. So the fix lands there, and the host only hands over its gate:@object-ui/plugin-detail: newRecordFieldHistoryContext(boolean, defaulttrue, so a host that says nothing keeps every chip) andtimelineStreamFilters(fieldHistory). Therecord:activitystream reads the context; while it isfalseit offers All / Activity / Discussion only, and a stream left on Changes falls back to All.RecordActivityTimelinetakes the chips to draw asstreamFilters(all four when absent).@object-ui/app-shell:RecordDetailViewprovidesRecordFieldHistoryContextwith its existinghistoryEnabled(the object declaresenable.trackHistory: trueandsys_audit_logis registered), the same gate that decides whether it reads the audit log.ui/packages/plugin-detail/README.mdsays the Changes chip follows the record's field history. Root changeset.changeset/30074-crm-track-history.md(@object-ui/plugin-detailpatch;app-shelland the CRM example are private).File surface: the claim declared the four object files,
RecordDetailView.tsx, their tests and one changeset. Outside it, by necessity: fourui/packages/plugin-detail/srcfiles (the chip's real renderer, as the dispatch allowed), the plugin-detail README (ui rule: docs follow code).Tests
All runs on head
8c5b89c91(the final commit; nothing pushed after them).plugin-detail/src/__tests__/recordTimelineStream-27055.test.tsx, a top-level describe in the existing harness: history shown gives four chips; history not shown gives three and All still draws every entry; no provider gives four (control); Changes taken away while chosen leaves the stream on All.app-shell/src/views/RecordDetailView.recordPageTiers-26678.test.tsx, a top-level describe: a realRecordDetailViewmount on?related=timelinedraws all / activity / discussion / changes for atrackHistoryobject, and all / activity / discussion with zero audit reads for the same object without it.record-activity.tsx, viascripts/ablation-replace.mjs; the subject resolves tosrcthroughui/vitest.config.mtsaliases): anchor 1 to 0, blob7b5fe9176ec0to69e1bc36c51c; 3 tests red (the two plugin-detail "not shown" pins and the app-shell "without it" pin), the "shown" and control pins green; restored, blob equals HEAD andgit diff HEADempty.Test readings
vitest runof the two pin files plusRecordTimelinePanel-27524.test.tsx: Test Files 3 passed (3), Tests 27 passed (27), lock VERDICT command-exit 0.@object-ui/plugin-detailwhole package (pnpm --dir ui exec vitest run packages/plugin-detail/): Test Files 369 passed, 1 skipped (370); Tests 3264 passed, 18 skipped; VERDICT command-exit 0.@object-ui/app-shell, narrowed (declared): the 218 test files that nameRecordDetailView,RecordActivityTimeline,recordTimelineStreamorrecord-activity: Test Files 218 passed (218), Tests 1630 passed (1630); VERDICT command-exit 0. The rest of the package is left to CI's Test UI.pnpm --filter @object-ui/plugin-detail run type-checkexit 0;pnpm --filter @object-ui/app-shell run type-checkexit 0 (both runtsc --noEmitandtsc -p tsconfig.test.json).pnpm --filter @objectstack/example-crm run typecheckexit 0; its vitest suite Test Files 7 passed (7), Tests 48 passed (48).Acceptance notes
trackHistory, the stream's Changes chip is not empty:ACTIVITY_TYPE_TO_FEED_TYPEmapssys_activitycreated/updated/deleted/assigned/sharedrows to thefield_changefeed type, andfilterTimelineStream(…, 'changes')keeps them (the existing pin "the four chips" inrecordTimelineStream-27055.test.tsxholds an activitycreatedrow under Changes). So on an object without history, the "更新了 …:赢单概率 (%)" lines used to be reachable under Changes and are now reachable only under All (the Activity chip leavesfield_changeout). This PR does what the ruling says; whether such rows should also show under Activity when Changes is hidden is left to the seat and the maintainer.mainmoved 8 commits past the base55337f4cebefore the PR opened; none touches a path in this diff, so the branch was not re-merged. CI runs the merge ref.RecordDetailView).Verification
Gates were taken from
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(53 commands, derived at8c5b89c91).Gate readings
--ranreconciliation: "53 derived famil(ies) accounted for — 53 run, 0 NOT-MEASURED (a DERIVED zero — all 53 recorded an exit code and none of them is 3)".node scripts/check-sdui-manifest.mjsexit 0 (seat constraint).pnpm check:dual-build-cjs-loadsandpnpm check:i18n-coveragefirst answered exit 3 (PREREQUISITE NOT MET, builds missing); after their prerequisite builds both exit 0 ("116 published require entry point(s) across 71 package(s) load"; "OK (14 config(s), 426 baselined untranslated string(s), none new)").pnpm check:type-check-debthit a 400 s local timeout once, then exit 0 under the verify lock.pnpm --dir ui exec vitest run scripts/: Test Files 170 passed, 2 skipped (172); Tests 4985 passed, 2 skipped.Generated by Claude Code