Repository navigation
fix(ui): a calendar event and a gantt bar open the one record page in the console (#27057) - #27564
Merged
Merged
Conversation
…cord page Claude-Session: https://claude.ai/code/session_01L6bhgWNzwmuUkLM8wBbXXx Co-authored-by: Claude <noreply@anthropic.com>
…he one record page (#27057) The console-level join: the real renderers under the console object page, the record page as a sink. Also the changeset and the RecordDetailPanel docblock naming it as the fallback. Claude-Session: https://claude.ai/code/session_01L6bhgWNzwmuUkLM8wBbXXx Co-authored-by: Claude <noreply@anthropic.com>
…-rplaiu Claude-Session: https://claude.ai/code/session_01L6bhgWNzwmuUkLM8wBbXXx Co-authored-by: Claude <noreply@anthropic.com>
… read the new click owner (#27057) The 8652 row that pinned the drawer keeping the click from a parent's onRowClick now pins the reverse, with a row for onEventClick alone. Claude-Session: https://claude.ai/code/session_01L6bhgWNzwmuUkLM8wBbXXx Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6bhgWNzwmuUkLM8wBbXXx Co-authored-by: Claude <noreply@anthropic.com>
…-rplaiu Claude-Session: https://claude.ai/code/session_01L6bhgWNzwmuUkLM8wBbXXx Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#1 · os-sales · session_01L6bhgXU26UBEjd1KKHgNEx 席位核对 · ACCEPT · 2026-10-29T13:30ZHead-sha:
|
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.
Requested by Sales · project thread
Fixes #27057
Clause-②: no
Metadata-protocol: none
维护者速读
page的日历视图也真的跳整页了(以前同样弹快速查看)。ui/packages/plugin-list/src/ListView.tsx(routedByHost一段:只在宿主接点击时把路由交给日历和甘特)、ui/packages/plugin-calendar/src/ObjectCalendar.tsx(navIsOverlay那一行)、ui/packages/plugin-gantt/src/index.tsx(注册只转发函数型onRowClick)。cd ui && pnpm exec vitest run apps/console/src/__tests__/recordOpenFromEveryView-27057.test.tsx,预期 5 条全绿:日历事件、甘特条、看板卡各自在抽屉里打开嵌入的记录页,日历打开的抽屉能再下一层并出现层级轨迹,声明page的日历视图跳到记录页路由。What changes
Inside the console every view now opens a record in the one record page:
ObjectView'shandleRowClickwrites?recordId=, andRecordStackDrawermountsRecordDetailView embedded. NorenderRecordhost channel was added: the measurement found no console path from these views that cannot reach?recordId=.ObjectCalendar: a hostonRowClicktakes the click in every navigation mode. The calendar's own drawer opens only when nobody hands it one (navIsOverlay = !onRowClick && mode === 'drawer').onEventClickbeside a hostonRowClickfires as it already did in thepagemode.onEventClickalone routes nothing, so the drawer still opens.ObjectGantt: the same. TheonRowClickhanded touseNavigationOverlayis no longer dropped in the drawer mode, and thepagesink (objectui#7334) stays for a chart with no host.ObjectGanttRenderer: forwards a function-typedonRowClickfrom the node and nothing else. This is the same answer as the calendar registration's declared host callbacks (objectui#4492). An authored non-function value is dropped, and hostdatastays dropped (objectui#7210 / objectui#7222, still pinned inObjectGantt.hostDataProp-7210).ListView: hands the calendar and the gantt its click router only when its own host passesonRowClick(routedByHost). A list with no host handler routes nothing for a view that authored nonavigation(the absent key is the host's call inuseNavigationOverlay). Handing the router over there would have turned the two views' drawer into a click that opens nothing. Every other child view gets the router as before.RecordDetailPanel: docblock only. It names the panel as the fallback for a host that routes no click, and its retirement as ADR-0049's enforce-or-remove path once the fallback measures zero callers. No tombstone.Per-site verdict
ObjectCalendar)onRowClickwhenever its mode was the drawer, andListViewputs nonavigationon its node, so in the console it always was. Console test rows 1, 4 and 5.ObjectGanttandObjectGanttRenderer)ListView, router to calendar and ganttroutedByHostgate.ListView.hostRoutedRecordClick-27057.ListViewhandsonRowClickto every child view, anduseNavigationOverlaygives an externalonRowClickfull priority. The grid CONTROL row ofListView.hostRoutedRecordClick-27057reads the router on its node.externalClick = onRowClick ?? onCardClick. Pinned in the console: test row 3, the CONTROL that stays green under both ablations.baseProps.onRowClickreaches each unconditionally. Their registrations spread the node's props, and each passesonRowClicktouseNavigationOverlay(props.onRowClick ?? props.onCardClickon the gallery,onRowClick ?? onItemClickon the timeline), where it wins.ListView's own quick-lookuseNavigationOverlayis handed the host'sonRowClick, which takes the click before the overlay. The read-only panel is drawn only for a list with no host handler.PageView)PageViewmounts no record drawer host, so there is no?recordId=overlay to reach. A calendar or gantt there keeps its own drawer, and an authoredpagereaches the page through the host navigator (objectui#11293). Reaching the record page in a drawer there needs a host channel outside this card's file surface (see findings).Why letting the host click win does not reopen what objectui#7334 guarded
The suppression's rationale (the calendar's comment and the gantt branch in
ListView) was that a parent which page-navigates on a row click must not take a drawer the view authored away from it. In the console that parent isObjectView'shandleRowClick, and it no longer page-navigates by default. It reads the view'snavigation, then the object's, defaulting to the drawer, and in the drawer case writes?recordId=and opens the drawer itself. That drawer is now the full record page. So the host keeps an authored drawer, and it honours an authoredpagetoo. That part was measured: before this change a calendar view that declaredpageopened the quick-look, because the calendar never saw the view'snavigation. Where there is no host,ListViewno longer hands over its router, so a click the list cannot route never replaces the views' own drawer, or the gantt'spagesink.Tests
ObjectCalendar.hostRowClick-27057(4 rows) andObjectGantt.hostRowClick-27057(4 rows), both through the realSchemaRendererand registration.ListView.hostRoutedRecordClick-27057(6 rows). The console joinapps/console/src/__tests__/recordOpenFromEveryView-27057(5 rows) mounts the real calendar, gantt and kanban under the consoleObjectView, withRecordDetailViewas a sink.calendarNavigationMembers-8652. Its row "an OVERLAY mode keeps the click from a parent view's handlers" pinned exactly the precedence this card reverses. It now pins the reverse, and a new row pins thatonEventClickalone still leaves the drawer to the calendar.ListView.ganttNavigationForward-7334: itstypeof onRowClick === 'function'controls now mount the list under a host handler.ObjectGantt.navigationPageSink-7334: one docblock line about the renderer brought up to date.Reverse verification, each through
scripts/ablation-replace.mjs(the mutation landed by blob hash, and each restore read blob == HEAD with an emptygit diff HEAD):onRowClickin the drawer mode againObjectCalendar.hostRowClick-27057recordOpenFromEveryView-27057pagerow among them (not predicted, explained above).onRowClickObjectGantt.hostRowClick-27057recordOpenFromEveryView-27057ObjectGantt: drop the hostonRowClickin the drawer mode againObjectGantt.hostRowClick-27057pagerow is unaffected, since the old code dropped it only in the drawer mode)ListView: hand the router to calendar and gantt unconditionallyListView.hostRoutedRecordClick-27057Acceptance notes
RecordDetailView embedded, notRecordDetailPanel: console row 1, with?recordId=1in the URL and no quick-look panel.GanttView's design. Double-click on the name, Enter and the context menu's Open fire the sameonTaskClick.record-drawer-trailnames the level left.RecordDetailPanelopens) and the hostless rows ofListView.hostRoutedRecordClick-27057.when-locked field opens on a row the server's write gate admits, in a console drawer opened from these renderers): met by composition, not measured end to end. Console rows 1 and 2 show that the drawer opened from a calendar or a gantt mounts the sameRecordDetailView embeddeda grid row mounts, andrecord-blocks.recordFieldAccess-27146pins that page'srecord:details/record:highlightsreading the stored row's field access, sosummaryedits on a draft the server unlocks and stays locked on an approved row. No server with awhenlock was driven for this card.examples/app-showcase(HotCRM is not in this repository), itsshowcase_taskcalendar and gantt views, against this branch: a console dev server (ui/apps/console, sources aliased) proxied to anos dev --seed-adminbackend on its own port, driven with Playwright.ablation-replace --hold, then restored to blob == HEAD): the event "Design system" opened the quick-look panel. The URL kept norecordId, there was no expand control, and the panel showed six fields and nothing else.?recordId=VovxsPa9FWLiZTat, "Open as full page" is there, and the page draws its status path, header actions, highlights and sections.Verification
All on the final head's tree unless noted; each exit recorded before any pipe.
pnpm exec vitest run packages/plugin-calendar packages/plugin-gantt packages/plugin-list packages/plugin-detailplus the console join. 673 files, 5994 passed, 1 failed, 227 skipped. The one failure wascalendarNavigationMembers-8652's overlay row, the precedence this card reverses, rewritten above.packages/plugin-view, theapp-shellview tests that mount calendars or gantts (PageView.recordNavigator-11293,ObjectView.calendarBinding-7029,ObjectView.recordOpenPreference-26677and five more), the twoSchemaRendererdata-prop files andtimelineAxisRefusalReach-7070: 90 files, 858 passed.mainmerge: the card's seven test files, 56 passed.turbo run type-checkfor@object-ui/plugin-calendar,plugin-gantt,plugin-list,plugin-detailand@object-ui/console: 74 of 74 tasks. The first run caught an unused import in the new console test, now removed.ui/file: 0 errors (warnings are the files' existingno-explicit-any).dispatch-gates --commands: 34 commands, each run, all exit 0.--ranreconciles 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. Also run:check:changeset-fixed(its roster sits under.changeset/),check:new-line-citations(0 new),check:doc-authoring,check:nul-bytes,check:test-source-alias.mainmerged twice (no overlap with this card's files). After each:@objectstack/specrebuilt; after the second,check:generatedgreen. The delta againstmainis these 13 files only.Findings outside this card's surface
Read from the code unless marked measured; none of them is changed here.
list-viewblock on a custom page mountsListViewwith no host handler. For a view that authored nonavigation, its router answers a grid, kanban, gallery, map, timeline or tree row with nothing (not measured). The calendar and the gantt there keep their own drawer, as before.PageViewmounts no record drawer host, so their records open inRecordDetailPanel(or the page, for an authoredpage). Bringing the one record page there needs a host channel outside this card's file surface.ListViewputs nonavigationon the calendar's node (the gantt branch has since objectui#7334). Inside the console the host now reads the view'snavigation(measured, console row 5). A list with no host still drops a calendar view's authoredpage.RecordDetailPanelsurvives as the fallback, so its in-place edit outside the console still draws the row-blind lock (noRecordFieldAccessScope). If the fallback is kept, that scope is owed there.recordAction: 'none'handsListViewno handler, so its calendar and gantt still open their own drawer, as they did before this change.Generated by Claude Code