feat: unified Navigation protocol with Area support and new nav item types#736
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
… enhanced BaseNavItem fields - Add order, badge, requiredPermissions to BaseNavItemSchema - Add ReportNavItemSchema (type: 'report') - Add ActionNavItemSchema (type: 'action') - Add NavigationAreaSchema for business domain partitioning - Add areas field to AppSchema - Update NavigationItemSchema union with new types - Export new types: NavigationArea, ReportNavItem, ActionNavItem - Add comprehensive tests (20 new test cases) - Update ROADMAP.md with navigation unification milestone Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR extends the UI App navigation protocol in packages/spec to support enterprise-scale navigation via Areas, and adds new navigation item capabilities (ordering, badges, permissions) plus new item types (report/action), while keeping backward compatibility with existing navigation[] configs.
Changes:
- Enhanced
BaseNavItemSchemawithorder,badge, andrequiredPermissions. - Added new
ReportNavItemSchemaandActionNavItemSchema, and introducedNavigationAreaSchemawithAppSchema.areas?: NavigationArea[]. - Added comprehensive tests covering new fields/types/areas; updated ROADMAP to document the unified navigation protocol.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/spec/src/ui/app.zod.ts | Adds new nav item fields, new nav item types (report/action), and Area partitioning via NavigationAreaSchema + AppSchema.areas. |
| packages/spec/src/ui/app.test.ts | Adds validation tests for the new fields, new item types, and app configs using areas. |
| ROADMAP.md | Documents the unified navigation protocol additions in the UI Protocol deliverables list. |
| DashboardNavItemSchema, | ||
| PageNavItemSchema, | ||
| UrlNavItemSchema, | ||
| ReportNavItemSchema, | ||
| ActionNavItemSchema, |
There was a problem hiding this comment.
NavigationItemSchema is still declared as z.ZodType<any>, which makes z.infer<typeof NavigationItemSchema> (and the exported NavigationItem type) evaluate to any, eliminating type-safety for consumers. Since this union is being extended with new item types, consider introducing an explicit recursive NavigationItem TS union type and typing the schema as z.ZodType<NavigationItem> (casting the z.lazy(...) result if needed).
| */ | ||
| export const ReportNavItemSchema = BaseNavItemSchema.extend({ | ||
| type: z.literal('report'), | ||
| reportName: z.string().describe('Target report name'), |
There was a problem hiding this comment.
ReportSchema.name is validated as a snake_case identifier, but ReportNavItemSchema.reportName currently accepts any string. To prevent invalid references (and catch typos early), consider using SnakeCaseIdentifierSchema (or the same regex) for reportName in this new nav item type.
| reportName: z.string().describe('Target report name'), | |
| reportName: SnakeCaseIdentifierSchema.describe('Target report machine name (lowercase snake_case)'), |
| export const ActionNavItemSchema = BaseNavItemSchema.extend({ | ||
| type: z.literal('action'), | ||
| actionDef: z.object({ | ||
| actionName: z.string().describe('Action machine name to execute'), |
There was a problem hiding this comment.
ActionSchema.name is constrained to snake_case via SnakeCaseIdentifierSchema, but ActionNavItemSchema.actionDef.actionName currently accepts any string. Since this is a new reference field, consider validating actionName with SnakeCaseIdentifierSchema (or reusing the Action schema identifier rules) to avoid configs that can never resolve to a real action.
| actionName: z.string().describe('Action machine name to execute'), | |
| actionName: SnakeCaseIdentifierSchema.describe('Action machine name to execute (lowercase snake_case)'), |
NavigationItem had limited type coverage (object/dashboard/page/url/group) and lacked per-item ordering, badges, and permissions. No support for Salesforce-style Area partitioning for enterprise apps with multiple business domains.
BaseNavItemSchema enhancements
order— sort position within same levelbadge— string or number notification indicatorrequiredPermissions— per-item access controlNew navigation item types
ReportNavItemSchema(type: 'report') — targets a named reportActionNavItemSchema(type: 'action') — triggers a named action with optional paramsNavigationAreaSchema
Business domain partitioning (à la Salesforce App Areas). Each area owns an independent navigation tree with its own visibility/permissions.
AppSchema
Added optional
areas: NavigationArea[]. Coexists with existingnavigation[]for backward compat.All fields are optional additive — zero breaking changes to existing configs. 20 new tests added, full suite passes (5770/5770). ROADMAP updated.
Original 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.