Make automated topLevelNavItems use built-in pages & nav improvements#1002
Make automated topLevelNavItems use built-in pages & nav improvements#1002
Conversation
Migration Safety CheckFound 29 potential issues: 20260325_142016_convert_auto_nav_items.ts Warning (line 13): DELETE keyword detected - review for data loss FOREIGN KEY (\`_parent_id\`) REFERENCES \`navigations\`(\`id\`) ON UPDATE no action ON DELETE cascadeWarning (line 30): DELETE keyword detected - review for data loss FOREIGN KEY (\`_parent_id\`) REFERENCES \`navigations\`(\`id\`) ON UPDATE no action ON DELETE cascadeWarning (line 48): DELETE keyword detected - review for data loss FOREIGN KEY (\`_parent_id\`) REFERENCES \`_navigations_v\`(\`id\`) ON UPDATE no action ON DELETE cascadeWarning (line 66): DELETE keyword detected - review for data loss FOREIGN KEY (\`_parent_id\`) REFERENCES \`_navigations_v\`(\`id\`) ON UPDATE no action ON DELETE cascadeWarning (line 75): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`built_in_pages\` ADD \`is_in_nav\` integer DEFAULT false;`)Warning (line 77): ALTER keyword detected - review for data loss sql`ALTER TABLE \`navigations\` ADD \`forecasts_link_type\` text DEFAULT 'internal';`,Warning (line 79): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`forecasts_link_url\` text;`)Warning (line 80): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`forecasts_link_label\` text;`)Warning (line 82): ALTER keyword detected - review for data loss sql`ALTER TABLE \`navigations\` ADD \`forecasts_link_new_tab\` integer DEFAULT true;`,Warning (line 84): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`blog_link_type\` text DEFAULT 'internal';`)Warning (line 85): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`blog_link_url\` text;`)Warning (line 86): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`blog_link_label\` text;`)Warning (line 87): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`blog_link_new_tab\` integer DEFAULT true;`)Warning (line 88): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`events_link_type\` text DEFAULT 'internal';`)Warning (line 89): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`events_link_url\` text;`)Warning (line 90): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`events_link_label\` text;`)Warning (line 91): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`navigations\` ADD \`events_link_new_tab\` integer DEFAULT true;`)Warning (line 93): ALTER keyword detected - review for data loss sql`ALTER TABLE \`_navigations_v\` ADD \`version_forecasts_link_type\` text DEFAULT 'internal';`,Warning (line 95): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`_navigations_v\` ADD \`version_forecasts_link_url\` text;`)Warning (line 96): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`_navigations_v\` ADD \`version_forecasts_link_label\` text;`)Warning (line 98): ALTER keyword detected - review for data loss sql`ALTER TABLE \`_navigations_v\` ADD \`version_forecasts_link_new_tab\` integer DEFAULT true;`,Warning (line 101): ALTER keyword detected - review for data loss sql`ALTER TABLE \`_navigations_v\` ADD \`version_blog_link_type\` text DEFAULT 'internal';`,Warning (line 103): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`_navigations_v\` ADD \`version_blog_link_url\` text;`)Warning (line 104): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`_navigations_v\` ADD \`version_blog_link_label\` text;`)Warning (line 106): ALTER keyword detected - review for data loss sql`ALTER TABLE \`_navigations_v\` ADD \`version_blog_link_new_tab\` integer DEFAULT true;`,Warning (line 109): ALTER keyword detected - review for data loss sql`ALTER TABLE \`_navigations_v\` ADD \`version_events_link_type\` text DEFAULT 'internal';`,Warning (line 111): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`_navigations_v\` ADD \`version_events_link_url\` text;`)Warning (line 112): ALTER keyword detected - review for data loss await db.run(sql`ALTER TABLE \`_navigations_v\` ADD \`version_events_link_label\` text;`)Warning (line 114): ALTER keyword detected - review for data loss sql`ALTER TABLE \`_navigations_v\` ADD \`version_events_link_new_tab\` integer DEFAULT true;`,Review these patterns and add backup/restore logic if needed. See |
|
Preview deployment: https://nav-updates.preview.avy-fx.org |
…for prod migration
…-in pages that are nav links
Description
Improves the Navigation admin UI with contextual banners for automated fields, and seeds built-in page references for the forecasts, observations, blog, and events top-level nav tabs so their links appear as proper CMS relationships rather than being hardcoded.
Related Issues
Fixes #988
Fixes #825
Key Changes
Add one time script to add and assign built-in pages for current tenants in prod
BannerDescriptioncomponent — new reusable Payload admin component that wraps@payloadcms/ui'sBannerwith an icon, used as contextual info banners on nav tabstopLevelNavTab— addshasReadOnlyLinkandhasReadOnlyNavItemsoptions; renders description as auifield (banner) instead of plain tab description text;virtuallogic updated to account for new optionsitemsField— addshasSubNavItemsoption to suppress the sub-item accordion UI for readonly tabs where sub-items aren't applicableSeed — fetches active forecast zones per tenant from NAC API; creates zone-specific built-in pages; populates forecasts, observations, blog, and events navigation entries with proper
builtInPagereferencesTo navigation tabs:
How to test
pnpm seedScreenshots / Demo video
https://www.loom.com/share/896c5419b9fb4909805422889d7a064a
Important
I updated the permission after the video to give
superAdminusers edit access to read only nav items just in case we run into issues and need to edit. I also think this is okay to leave?Migration Explanation
Adds link columns for
blog,events, andforecaststo thenavigationstable. Theforecaststab previously had no link field; blog and events links were stored as plain URLs and are now proper relationships. All existing data should be re-seeded.Migration script testing
Tested the one-time migration script (
src/scripts/migrate-nav-builtin-pages.ts) against a copy of the production database following the Run one-time script in Notion.Important
I ran the script on the preview environment so the admin panel will look like it will post script run
Deployment note: There is a brief window between deploying the code and running the migration script where forecasts will render as a single "Forecasts" link pointing to
/forecasts/avalancheinstead of the full zone dropdown. This is the default fallback atutils.ts:265-267. Once the migration script is run and the navigation cache is revalidated (Admin → Diagnostics → Revalidate Cache or republish each nav), the full dropdown appears.There are similar fallbacks for other refrences we are adding
{ label: 'Forecasts', url: '/forecasts/avalanche' }{ label: 'Blog', url: '/blog' }{ label: 'Events', url: '/events' }Future enhancements / Questions