Uh oh!
There was an error while loading. Please reload this page.
fix: deduplicate action buttons in action-bar renderer - #1003
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Actions with duplicate `name` entries are now filtered (keep-first) in the action:bar renderer (platform-level fix) and in RecordDetailView (consumer-level defense). This prevents duplicate buttons appearing inline and in overflow menus. Fixes #duplicate-action-buttons Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…ency Address code review: use the same O(n) Set-based dedup pattern as action-bar.tsx, wrapped in useMemo for React performance. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
hotlong
commented
Mar 3, 2026
@copilot 进入记录详情页报错Minified React error #310; visit https://react.dev/errors/310 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. |
The useMemo hook was placed after conditional early returns in RecordDetailView, violating React's Rules of Hooks and causing "Rendered fewer hooks than expected" (React error #310). Replaced with an IIFE to keep the same Set-based dedup logic without hooks. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Fixed in |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Pull request overview
This PR addresses duplicate action buttons by deduplicating actions (by name) at both the platform renderer level (action:bar) and at a key consumer entry point (RecordDetailView), plus adding regression tests to lock the behavior in place.
Changes:
- Deduplicate
action:barrenderer actions bynameafter location filtering. - Deduplicate
RecordDetailViewheader actions bynamebefore building the detail schema. - Add test coverage for action deduplication behavior in the action-bar test suite.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/components/src/renderers/action/action-bar.tsx | Adds Set-based deduplication by action name after location filtering. |
| packages/components/src/tests/action-bar.test.tsx | Adds two tests validating deduplication behavior (basic + post-location-filter). |
| apps/console/src/components/RecordDetailView.tsx | Switches header-action filtering to an IIFE that filters + deduplicates by name before passing to the schema. |
| const recordHeaderActions = (() => { | ||
| const seen = new Set<string>(); | ||
| return (objectDef.actions || []).filter((a: any) => { | ||
| if (!a.locations?.includes('record_header')) return false; |
There was a problem hiding this comment.
recordHeaderActions only includes actions whose locations explicitly contain record_header. In @object-ui/types the ActionSchema docs indicate locations defaults to ['record_header'], and action:bar itself treats missing/empty locations as eligible for any location. As written, actions that omit locations (relying on the default) will never render in the record header because they get filtered out before being passed to the action:bar schema. Consider including actions with no locations (or an empty array) here, or passing the full objectDef.actions to action:bar and letting it handle location filtering/deduplication consistently.
| if(!a.locations?.includes('record_header'))returnfalse; | |
| constlocations=a.locations; | |
| // If locations is a non-empty array and does not include record_header, exclude it. | |
| // Missing or empty locations are treated as eligible for any location. | |
| if(Array.isArray(locations)&&locations.length>0&&!locations.includes('record_header')){ | |
| returnfalse; | |
| } |
nameinfilteredActions(platform-level fix)recordHeaderActionsbefore passing to schema (consumer-level defense)useMemo(placed after early returns) with IIFEOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.