diff --git a/common/router.ts b/common/router.ts index e3bc2c8f..9b49537a 100644 --- a/common/router.ts +++ b/common/router.ts @@ -32,7 +32,7 @@ export const ROUTES: RouteConfig[] = [ path: routerPaths.registerModel, label: 'Register Model', Component: RegisterModelForm, - nav: true, + nav: false, }, { path: routerPaths.modelList, diff --git a/public/components/__tests__/nav_panel.test.tsx b/public/components/__tests__/nav_panel.test.tsx new file mode 100644 index 00000000..8fdbf4a6 --- /dev/null +++ b/public/components/__tests__/nav_panel.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; + +import { NavPanel } from '../nav_panel'; +import { render, screen } from '../../../test/test_utils'; + +describe('', () => { + it('should render "Overview" with selected status', () => { + render(, { route: '/overview' }); + + expect(screen.getByText('Overview')).toBeInTheDocument(); + expect(screen.getByText('Overview').closest('a[class*=isSelected]')).toBeInTheDocument(); + }); + it('should render "Model Registry" with selected status', () => { + render(, { route: '/model-registry/model-list' }); + + expect(screen.getByText('Model Registry')).toBeInTheDocument(); + expect(screen.getByText('Model Registry').closest('a[class*=isSelected]')).toBeInTheDocument(); + }); + it('should render nothing if nav item not exists', () => { + const { container } = render(, { route: '/model-registry/model/123' }); + + expect(container).toBeEmptyDOMElement(); + }); +}); diff --git a/public/components/app.tsx b/public/components/app.tsx index 147c860b..bbd73b7c 100644 --- a/public/components/app.tsx +++ b/public/components/app.tsx @@ -46,9 +46,7 @@ export const MlCommonsPluginApp = ({ <> - - - + {ROUTES.map(({ path, Component, exact }) => ( diff --git a/public/components/nav_panel.tsx b/public/components/nav_panel.tsx index db799cb6..8f8e89e3 100644 --- a/public/components/nav_panel.tsx +++ b/public/components/nav_panel.tsx @@ -4,7 +4,7 @@ */ import React, { useCallback, useMemo } from 'react'; -import { EuiSideNav } from '@elastic/eui'; +import { EuiSideNav, EuiPageSideBar, htmlIdGenerator, OuiSideNav } from '@elastic/eui'; import { generatePath, Link, matchPath, useLocation } from 'react-router-dom'; import { ROUTES } from '../../common/router'; @@ -12,21 +12,39 @@ import { ROUTES } from '../../common/router'; export function NavPanel() { const location = useLocation(); const items = useMemo( - () => - ROUTES.filter((item) => !!item.label && item.nav).map((item) => { - const href = generatePath(item.path); - return { - id: href, - name: item.label, - href, - isSelected: matchPath(location.pathname, { path: item.path, exact: item.exact }) !== null, - }; - }), + () => [ + { + name: 'Machine Learning', + id: htmlIdGenerator('machine-learning')(), + items: ROUTES.filter((item) => !!item.label && item.nav).map((item) => { + const href = generatePath(item.path); + return { + id: href, + name: item.label, + href, + isSelected: + matchPath(location.pathname, { path: item.path, exact: item.exact }) !== null, + }; + }), + }, + ], [location.pathname] ); - const renderItem = useCallback( - ({ href, ...restProps }) => , - [] + const renderItem = useCallback((item) => { + if (!item.href) { + return item.children; + } + const { href, ...restProps } = item; + return ; + }, []); + + if (items[0].items.every((item) => !item.isSelected)) { + return null; + } + + return ( + + + ); - return ; }