null;
+
const navLinks: ChromeNavLink[] = [
{
id: '1',
@@ -85,7 +91,13 @@ const navLinks: ChromeNavLink[] = [
describe('
', () => {
it('render with empty navLinks', () => {
const { container } = render(
-
+
);
expect(container).toMatchSnapshot();
});
@@ -93,10 +105,11 @@ describe('
', () => {
it('render with complex navLinks', () => {
const { container, getAllByTestId } = render(
);
expect(container).toMatchSnapshot();
@@ -107,10 +120,11 @@ describe('
', () => {
const mockedNavigateToApp = jest.fn();
const { getByTestId } = render(
);
fireEvent.click(getByTestId('landingPageFeature_1'));
diff --git a/src/plugins/management/public/components/feature_cards/feature_cards.tsx b/src/plugins/management/public/components/feature_cards/feature_cards.tsx
index 57d7e128c928..7c52e6a05fda 100644
--- a/src/plugins/management/public/components/feature_cards/feature_cards.tsx
+++ b/src/plugins/management/public/components/feature_cards/feature_cards.tsx
@@ -3,42 +3,32 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { i18n } from '@osd/i18n';
import {
EuiCard,
- EuiFlexGrid,
EuiFlexGroup,
EuiFlexItem,
EuiPageContent,
- EuiPageHeader,
- EuiPageHeaderSection,
- EuiPanel,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';
import { AppCategory, ChromeNavLink, CoreStart } from 'opensearch-dashboards/public';
import React, { useMemo } from 'react';
+import { NavigationPublicPluginStart } from '../../../../../../src/plugins/navigation/public';
export interface FeatureCardsProps {
- pageTitle: string;
+ pageDescription: string;
navLinks: ChromeNavLink[];
navigateToApp: CoreStart['application']['navigateToApp'];
- getStartedCards: Array<{
- id: string;
- title: string;
- description: string;
- }>;
+ setAppDescriptionControls: CoreStart['application']['setAppDescriptionControls'];
+ navigationUI: NavigationPublicPluginStart['ui'];
}
-const getStartedTitle = i18n.translate('management.gettingStarted.label', {
- defaultMessage: 'Get started',
-});
-
export const FeatureCards = ({
navLinks,
navigateToApp,
- pageTitle,
- getStartedCards,
+ setAppDescriptionControls,
+ pageDescription,
+ navigationUI: { HeaderControl },
}: FeatureCardsProps) => {
const itemsPerRow = 4;
const groupedCardForDisplay = useMemo(() => {
@@ -65,41 +55,14 @@ export const FeatureCards = ({
}
return (
<>
-
-
-
-
- {pageTitle}
-
-
-
- {getStartedCards.length ? (
- <>
-
-
- {getStartedTitle}
-
-
- {getStartedCards.map((card) => {
- return (
-
-
- navigateToApp(card.id)}
- titleSize="xs"
- />
-
-
- );
- })}
-
- >
- ) : null}
-
+
{groupedCardForDisplay.map((group) => (
diff --git a/src/plugins/management/public/landing_page_application.test.tsx b/src/plugins/management/public/landing_page_application.test.tsx
index 13d14ff34609..e8c6f994fff9 100644
--- a/src/plugins/management/public/landing_page_application.test.tsx
+++ b/src/plugins/management/public/landing_page_application.test.tsx
@@ -4,6 +4,8 @@
*/
import { renderApp } from './landing_page_application';
+import { navigationPluginMock } from '../../navigation/public/mocks';
+import { coreMock } from '../../../../src/core/public/mocks';
describe('Landing page application', () => {
it('renders and unmount without crashing', () => {
@@ -13,6 +15,9 @@ describe('Landing page application', () => {
props: {
navigateToApp: jest.fn(),
navLinks: [],
+ navigationUI: navigationPluginMock.createStartContract().ui,
+ setAppDescriptionControls: coreMock.createStart().application.setAppDescriptionControls,
+ pageDescription: '',
},
});
diff --git a/src/plugins/management/public/plugin.ts b/src/plugins/management/public/plugin.ts
index ef91e776a962..6242b87289a1 100644
--- a/src/plugins/management/public/plugin.ts
+++ b/src/plugins/management/public/plugin.ts
@@ -46,7 +46,6 @@ import {
AppNavLinkStatus,
DEFAULT_NAV_GROUPS,
WorkspaceAvailability,
- ChromeNavLink,
} from '../../../core/public';
import { MANAGEMENT_APP_ID } from '../common/contants';
@@ -62,13 +61,17 @@ import {
LinkItemType,
getSortedNavLinks,
} from '../../../core/public';
+import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public';
interface ManagementSetupDependencies {
home?: HomePublicPluginSetup;
managementOverview?: ManagementOverViewPluginSetup;
}
-
-export class ManagementPlugin implements Plugin
{
+interface ManagementStartDependencies {
+ navigation: NavigationPublicPluginStart;
+}
+export class ManagementPlugin
+ implements Plugin {
private readonly managementSections = new ManagementSectionsService();
private readonly appUpdater = new BehaviorSubject(() => ({}));
@@ -81,7 +84,10 @@ export class ManagementPlugin implements Plugin,
+ { home, managementOverview }: ManagementSetupDependencies
+ ) {
const opensearchDashboardsVersion = this.initializerContext.env.packageInfo.version;
core.application.register({
@@ -111,15 +117,30 @@ export class ManagementPlugin implements Plugin {
const { renderApp } = await import('./landing_page_application');
- const [coreStart] = await core.getStartServices();
+ const [coreStart, { navigation }] = await core.getStartServices();
const navLinks = (
await getNavLinksByNavGroupId(DEFAULT_NAV_GROUPS.settingsAndSetup.id)
).filter((navLink) => navLink.id !== settingsLandingPageId);
+ coreStart.chrome.setBreadcrumbs([
+ {
+ text: settingsLandingPageTitle,
+ },
+ ]);
return renderApp({
mountElement: params.element,
props: {
navigateToApp: coreStart.application.navigateToApp,
+ setAppDescriptionControls: coreStart.application.setAppDescriptionControls,
navLinks,
- pageTitle: settingsLandingPageTitle,
- getStartedCards: [],
+ pageDescription: settingsLandingPageDescription,
+ navigationUI: navigation.ui,
},
});
},
@@ -213,18 +240,25 @@ export class ManagementPlugin implements Plugin {
const { renderApp } = await import('./landing_page_application');
- const [coreStart] = await core.getStartServices();
+ const [coreStart, { navigation }] = await core.getStartServices();
const navLinks = (
await getNavLinksByNavGroupId(DEFAULT_NAV_GROUPS.dataAdministration.id)
).filter((navLink) => navLink.id !== dataAdministrationLandingPageId);
+ coreStart.chrome.setBreadcrumbs([
+ {
+ text: dataAdministrationPageTitle,
+ },
+ ]);
+
return renderApp({
mountElement: params.element,
props: {
navigateToApp: coreStart.application.navigateToApp,
navLinks,
- pageTitle: dataAdministrationPageTitle,
- getStartedCards: [],
+ pageDescription: dataAdministrationPageDescription,
+ navigationUI: navigation.ui,
+ setAppDescriptionControls: coreStart.application.setAppDescriptionControls,
},
});
},
diff --git a/src/plugins/workspace/opensearch_dashboards.json b/src/plugins/workspace/opensearch_dashboards.json
index d0b0e0b55ea8..ac24c20d712b 100644
--- a/src/plugins/workspace/opensearch_dashboards.json
+++ b/src/plugins/workspace/opensearch_dashboards.json
@@ -5,7 +5,8 @@
"ui": true,
"requiredPlugins": [
"savedObjects",
- "opensearchDashboardsReact"
+ "opensearchDashboardsReact",
+ "navigation"
],
"optionalPlugins": ["savedObjectsManagement","management","dataSourceManagement","contentManagement"],
"requiredBundles": ["opensearchDashboardsReact", "home","dataSource"]
diff --git a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx
index 24692db47229..e3463bc7d9f5 100644
--- a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx
+++ b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.test.tsx
@@ -91,6 +91,9 @@ const WorkspaceCreator = ({
},
},
dataSourceManagement: {},
+ navigationUI: {
+ HeaderControl: () => null,
+ },
},
});
const registeredUseCases$ = new BehaviorSubject([
diff --git a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx
index c46d17b701ac..26bed213d142 100644
--- a/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx
+++ b/src/plugins/workspace/public/components/workspace_creator/workspace_creator.tsx
@@ -4,13 +4,7 @@
*/
import React, { useCallback } from 'react';
-import {
- EuiPage,
- EuiPageBody,
- EuiPageHeader,
- EuiPageContent,
- euiPaletteColorBlind,
-} from '@elastic/eui';
+import { EuiPage, EuiPageBody, EuiPageContent, euiPaletteColorBlind } from '@elastic/eui';
import { i18n } from '@osd/i18n';
import { useObservable } from 'react-use';
import { BehaviorSubject } from 'rxjs';
@@ -25,6 +19,7 @@ import { DataSource } from '../../../common/types';
import { DataSourceManagementPluginSetup } from '../../../../../plugins/data_source_management/public';
import { WorkspaceUseCase } from '../../types';
import { WorkspaceFormData } from '../workspace_form/types';
+import { NavigationPublicPluginStart } from '../../../../../plugins/navigation/public';
export interface WorkspaceCreatorProps {
registeredUseCases$: BehaviorSubject;
@@ -39,10 +34,12 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => {
workspaceClient,
savedObjects,
dataSourceManagement,
+ navigationUI: { HeaderControl },
},
} = useOpenSearchDashboards<{
workspaceClient: WorkspaceClient;
dataSourceManagement?: DataSourceManagementPluginSetup;
+ navigationUI: NavigationPublicPluginStart['ui'];
}>();
const defaultWorkspaceFormValues: Partial = {
@@ -102,8 +99,17 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => {
return (
+
-
{
const {
- services: { chrome },
+ services: { chrome, application },
} = useOpenSearchDashboards();
/**
* set breadcrumbs to chrome
*/
useEffect(() => {
+ const homeBreadcrumb = {
+ text: i18n.translate('core.breadcrumbs.homeTitle', { defaultMessage: 'Home' }),
+ onClick: () => {
+ application?.navigateToApp('home');
+ },
+ };
chrome?.setBreadcrumbs([
+ homeBreadcrumb,
{
text: i18n.translate('workspace.workspaceCreateTitle', {
defaultMessage: 'Create a workspace',
}),
},
]);
- }, [chrome]);
+ }, [chrome, application]);
return (
diff --git a/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap b/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap
index 562eadabefd7..e6da2eebcf46 100644
--- a/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap
+++ b/src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap
@@ -2,39 +2,6 @@
exports[`WorkspaceDetail render workspace detail page normally 1`] = `
-
-
-
diff --git a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx
index 20f739273182..d27f0187e5b1 100644
--- a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx
+++ b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.test.tsx
@@ -95,7 +95,7 @@ describe('WorkspaceDetail', () => {
it('default selected tab is overview', async () => {
const workspaceService = createWorkspacesSetupContractMockWithValue(workspaceObject);
render(WorkspaceDetailPage({ workspacesService: workspaceService }));
- expect(screen.queryByText('foo')).not.toBeNull();
+ expect(screen.queryByTestId('workspaceTabs')).not.toBeNull();
expect(document.querySelector('#overview')).toHaveClass('euiTab-isSelected');
});
diff --git a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx
index 348414eba46d..59098a5e7219 100644
--- a/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx
+++ b/src/plugins/workspace/public/components/workspace_detail/workspace_detail.tsx
@@ -4,15 +4,7 @@
*/
import React from 'react';
-import {
- EuiPage,
- EuiPageBody,
- EuiPageHeader,
- EuiFlexItem,
- EuiTabbedContent,
- EuiFlexGroup,
- EuiPanel,
-} from '@elastic/eui';
+import { EuiPage, EuiPageBody, EuiTabbedContent } from '@elastic/eui';
import { useObservable } from 'react-use';
import { i18n } from '@osd/i18n';
@@ -40,12 +32,6 @@ export const WorkspaceDetail = (props: WorkspaceDetailProps) => {
return null;
}
- const pageTitle = (
-
- {currentWorkspace?.name}
-
- );
-
const detailTabs = [
{
id: DetailTab.Overview,
@@ -86,9 +72,6 @@ export const WorkspaceDetail = (props: WorkspaceDetailProps) => {
return (
<>
-
-
-
{
text: currentWorkspace.name,
});
breadcrumbs.push({
- text: i18n.translate('workspace.detail.breadcrumb', { defaultMessage: 'Workspace Detail' }),
+ text: i18n.translate('workspace.detail.title', {
+ defaultMessage: '{name} settings',
+ values: {
+ name: currentWorkspace.name,
+ },
+ }),
});
}
chrome?.setBreadcrumbs(breadcrumbs);
diff --git a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap
index 32283810c139..86989c4bbf25 100644
--- a/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap
+++ b/src/plugins/workspace/public/components/workspace_list/__snapshots__/index.test.tsx.snap
@@ -3,275 +3,732 @@
exports[`WorkspaceList should render title and table normally 1`] = `