diff --git a/src/components/home/features/index.tsx b/src/components/home/features/index.tsx index ae75c357..b3afaf34 100644 --- a/src/components/home/features/index.tsx +++ b/src/components/home/features/index.tsx @@ -20,7 +20,7 @@ const FEATURES = [ title: "Managed Postgres, colocated with your Lakehouse.", description: "Provision with the CLI, connect like any Postgres. Instant branching, scales to zero, and change data feed to Unity Catalog.", - href: "/product/data-lakehouse", + href: "/product/lakebase", visual: "lakebase", }, { diff --git a/src/components/theme/mobile-nav.tsx b/src/components/theme/mobile-nav.tsx index 79658429..859559c2 100644 --- a/src/components/theme/mobile-nav.tsx +++ b/src/components/theme/mobile-nav.tsx @@ -5,7 +5,9 @@ import { useLocation } from "@docusaurus/router"; import { DocsSidebarSearch } from "@/components/docs/sidebar-search"; import { + getActiveProductHref, isHeaderNavItemActive, + PRODUCT_LINKS, type HeaderNavItem, } from "@/lib/header-navigation"; import { cn } from "@/lib/utils"; @@ -126,7 +128,10 @@ function MobileTreeText({ export function MobileNav({ items, open, onOpenChange }: MobileNavProps) { const menuId = useId(); const { pathname } = useLocation(); + const activeProductHref = getActiveProductHref(pathname); const isHomeActive = pathname === "/"; + const productItem = items.find(({ label }) => label === "Product"); + const sectionItems = items.filter(({ label }) => label !== "Product"); useEffect(() => { onOpenChange(false); @@ -218,7 +223,7 @@ export function MobileNav({ items, open, onOpenChange }: MobileNavProps) { }; }, [onOpenChange, open]); - if (items.length === 0) { + if (!productItem || items.length === 0) { return null; } @@ -245,17 +250,15 @@ export function MobileNav({ items, open, onOpenChange }: MobileNavProps) { className="relative w-full h-full flex justify-between font-mono text-[20px] leading-none font-normal tracking-[-0.4px]" aria-label="Main navigation" > - {/* - Product nav section temporarily removed while product pages are - unpublished. This menu was reflowed (tree-line positions retuned) - for the shorter HOME + Solutions/Templates/Docs list. To restore - Product, revert this file to its pre-PR-114 version and uncomment - the Product entry in header-navigation.ts. - */} - - - - + + + + + + + + + - {items.map((item, index) => { + + {productItem.label.toLowerCase()} + + + {PRODUCT_LINKS.map((product, index) => { + const isActive = product.href === activeProductHref; + + return ( + + {product.label.toLowerCase()} + + ); + })} + + {sectionItems.map((item, index) => { const isActive = isHeaderNavItemActive(item, pathname); return ( @@ -278,9 +311,9 @@ export function MobileNav({ items, open, onOpenChange }: MobileNavProps) { aria-current={isActive ? "page" : undefined} className={cn( "left-[61px] right-5 md:left-[63px] md:right-[22px]", - index === 0 && "top-[58px]", - index === 1 && "top-[92px]", - index === 2 && "top-[126px]", + index === 0 && "top-[180px]", + index === 1 && "top-[214px]", + index === 2 && "top-[248px]", )} data-mobile-menu-section-link="true" key={item.href} diff --git a/src/components/theme/nav.tsx b/src/components/theme/nav.tsx index 96bff856..98ffe239 100644 --- a/src/components/theme/nav.tsx +++ b/src/components/theme/nav.tsx @@ -268,10 +268,7 @@ function Nav({ className, items }: HeaderNavProps) { {items.map((item) => { const { href, label } = item; - // The "Product" entry is temporarily commented out of HEADER_LINKS, - // so this branch never renders. Kept (with a widened comparison) so - // re-enabling Product is a one-line revert in header-navigation.ts. - if ((label as string) === "Product") { + if (label === "Product") { const isActive = Boolean(activeProductHref); return ( diff --git a/src/lib/header-navigation.ts b/src/lib/header-navigation.ts index 62dd1f98..1bbf0856 100644 --- a/src/lib/header-navigation.ts +++ b/src/lib/header-navigation.ts @@ -1,6 +1,5 @@ export const HEADER_LINKS = [ - // Temporarily hidden while product pages are unpublished. - // { label: "Product", href: "/product/data-lakehouse" }, + { label: "Product", href: "/product/lakebase" }, { label: "Solutions", href: "/solutions" }, { label: "Templates", href: "/templates" }, { label: "Docs", href: "/docs/start-here", activePath: "/docs" }, @@ -9,7 +8,7 @@ export const HEADER_LINKS = [ export type HeaderNavItem = (typeof HEADER_LINKS)[number]; export const PRODUCT_LINKS = [ - { label: "Lakebase", href: "/product/data-lakehouse" }, + { label: "Lakebase", href: "/product/lakebase" }, { label: "Agent Bricks", href: "/product/agent-bricks" }, { label: "Databricks Apps", href: "/product/databricks-apps" }, ] as const; diff --git a/src/lib/products/lakebase.ts b/src/lib/products/lakebase.ts index 58062c76..7f9017b4 100644 --- a/src/lib/products/lakebase.ts +++ b/src/lib/products/lakebase.ts @@ -5,7 +5,7 @@ export const lakebaseProduct: ProductPageContent = { title: "Lakebase", description: "Managed Postgres with branching, autoscaling, and Lakehouse sync for modern operational workloads.", - canonicalPath: "/product/data-lakehouse", + canonicalPath: "/product/lakebase", hero: { eyebrow: "Lakebase", title: "Managed Postgres, built for modern operational workloads.", diff --git a/src/pages/index.tsx b/src/pages/index.tsx index ec40363c..27440a74 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -56,7 +56,7 @@ export default function Home(): ReactNode {
- {/* */} +
+ + + + + + + + ); +} diff --git a/src/pages/product/_databricks-apps.tsx b/src/pages/product/databricks-apps.tsx similarity index 100% rename from src/pages/product/_databricks-apps.tsx rename to src/pages/product/databricks-apps.tsx diff --git a/src/pages/product/_data-lakehouse.tsx b/src/pages/product/lakebase.tsx similarity index 100% rename from src/pages/product/_data-lakehouse.tsx rename to src/pages/product/lakebase.tsx diff --git a/tests/e2e/navigation.spec.ts b/tests/e2e/navigation.spec.ts index bfa4fddc..f31bbf4b 100644 --- a/tests/e2e/navigation.spec.ts +++ b/tests/e2e/navigation.spec.ts @@ -65,12 +65,11 @@ test.describe("navbar navigation", () => { }); } - // Skipped while the Product nav dropdown is hidden. - test.skip("product dropdown hover state is visible in production CSS", async ({ + test("product dropdown hover state is visible in production CSS", async ({ page, }) => { await page.setViewportSize({ width: 1440, height: 900 }); - await page.goto("/product/data-lakehouse"); + await page.goto("/product/lakebase"); await page.getByRole("button", { name: "[Product]" }).hover(); const productMenu = page.locator('[data-slot="navigation-menu-content"]'); @@ -184,7 +183,7 @@ test.describe.skip("mobile navigation", () => { width: viewport.width, height: viewport.height, }); - await page.goto("/product/data-lakehouse"); + await page.goto("/product/lakebase"); await page.getByRole("button", { name: "Open menu" }).click(); @@ -538,19 +537,18 @@ test.describe("home page link navigation", () => { expect(finalCopiedText).toContain("llms.txt"); }); - // Skipped while the home Features pillar cards and product pages are hidden. - test.skip("pillar card Lakebase navigates to /product/data-lakehouse", async ({ + test("pillar card Lakebase navigates to /product/lakebase", async ({ page, }) => { await page.goto("/"); - const link = page.locator('a[href="/product/data-lakehouse"]').first(); + const link = page.locator('a[href="/product/lakebase"]').first(); await link.waitFor({ state: "visible" }); await link.click(); - await page.waitForURL("**/product/data-lakehouse"); - expect(new URL(page.url()).pathname).toBe("/product/data-lakehouse"); + await page.waitForURL("**/product/lakebase"); + expect(new URL(page.url()).pathname).toBe("/product/lakebase"); }); - test.skip("pillar card Agent Bricks navigates to /product/agent-bricks", async ({ + test("pillar card Agent Bricks navigates to /product/agent-bricks", async ({ page, }) => { await page.goto("/"); @@ -559,7 +557,7 @@ test.describe("home page link navigation", () => { expect(new URL(page.url()).pathname).toBe("/product/agent-bricks"); }); - test.skip("pillar card Databricks Apps navigates to /product/databricks-apps", async ({ + test("pillar card Databricks Apps navigates to /product/databricks-apps", async ({ page, }) => { await page.goto("/"); diff --git a/tests/e2e/pages.spec.ts b/tests/e2e/pages.spec.ts index f83a4fb3..a1fb7642 100644 --- a/tests/e2e/pages.spec.ts +++ b/tests/e2e/pages.spec.ts @@ -2,10 +2,9 @@ import { test, expect } from "@playwright/test"; const PAGES = [ { path: "/", title: "Databricks Developer" }, - // Product pages temporarily unpublished (hidden via `_` prefix). - // { path: "/product/data-lakehouse", title: "Lakebase" }, - // { path: "/product/agent-bricks", title: "Agent Bricks" }, - // { path: "/product/databricks-apps", title: "Databricks Apps" }, + { path: "/product/lakebase", title: "Lakebase" }, + { path: "/product/agent-bricks", title: "Agent Bricks" }, + { path: "/product/databricks-apps", title: "Databricks Apps" }, { path: "/solutions", title: "Solutions" }, { path: "/solutions/devhub-launch", @@ -121,6 +120,17 @@ test.describe("static assets load correctly", () => { }); }); +test.describe("legacy redirects", () => { + test("/product/data-lakehouse redirects to /product/lakebase", async ({ + page, + }) => { + await page.goto("/product/data-lakehouse"); + await page.waitForURL("**/product/lakebase"); + expect(new URL(page.url()).pathname).toBe("/product/lakebase"); + await expect(page).toHaveTitle(/Lakebase/); + }); +}); + test.describe("solutions RSS", () => { test("RSS action links to the generated feed", async ({ page }) => { await page.goto("/solutions");