From d8ff016023b4067bb8698698e1036378cd65196b Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Tue, 23 Jul 2024 17:35:37 +0800 Subject: [PATCH 01/11] feat: add scoped breadcrumbs Signed-off-by: SuZhou-Joe --- src/plugins/advanced_settings/public/plugin.ts | 4 +++- src/plugins/data_source_management/public/plugin.ts | 4 +++- .../index_pattern_management/public/plugin.ts | 4 +++- .../public/react_router_navigate/index.ts | 6 +++++- .../react_router_navigate/react_router_navigate.tsx | 13 ++++++++++++- .../saved_objects_management/public/plugin.ts | 4 +++- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/plugins/advanced_settings/public/plugin.ts b/src/plugins/advanced_settings/public/plugin.ts index f2bf05da4114..17cb7508c440 100644 --- a/src/plugins/advanced_settings/public/plugin.ts +++ b/src/plugins/advanced_settings/public/plugin.ts @@ -35,6 +35,7 @@ import { ComponentRegistry } from './component_registry'; import { AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup } from './types'; import { setupTopNavThemeButton } from './register_nav_control'; import { DEFAULT_NAV_GROUPS, AppNavLinkStatus, WorkspaceAvailability } from '../../../core/public'; +import { getScopedBreadcrumbs } from '../../opensearch_dashboards_react/public'; const component = new ComponentRegistry(); @@ -81,7 +82,8 @@ export class AdvancedSettingsPlugin { ...params, basePath: core.http.basePath.get(), - setBreadcrumbs: coreStart.chrome.setBreadcrumbs, + setBreadcrumbs: (breadCrumbs) => + coreStart.chrome.setBreadcrumbs(getScopedBreadcrumbs(breadCrumbs, params.history)), wrapInPage: true, }, component.start diff --git a/src/plugins/data_source_management/public/plugin.ts b/src/plugins/data_source_management/public/plugin.ts index c51be57e4bb2..0b8d60e67c52 100644 --- a/src/plugins/data_source_management/public/plugin.ts +++ b/src/plugins/data_source_management/public/plugin.ts @@ -50,6 +50,7 @@ import { import { AccelerationDetailsFlyout } from './components/direct_query_data_sources_components/acceleration_management/acceleration_details_flyout'; import { CreateAcceleration } from './components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration'; import { AssociatedObjectsDetailsFlyout } from './components/direct_query_data_sources_components/associated_object_management/associated_objects_details_flyout'; +import { getScopedBreadcrumbs } from '../../opensearch_dashboards_react/public'; export const [ getRenderAccelerationDetailsFlyout, @@ -166,7 +167,8 @@ export class DataSourceManagementPlugin { ...params, basePath: core.http.basePath.get(), - setBreadcrumbs: coreStart.chrome.setBreadcrumbs, + setBreadcrumbs: (breadCrumbs) => + coreStart.chrome.setBreadcrumbs(getScopedBreadcrumbs(breadCrumbs, params.history)), wrapInPage: true, }, this.authMethodsRegistry, diff --git a/src/plugins/index_pattern_management/public/plugin.ts b/src/plugins/index_pattern_management/public/plugin.ts index ef462374129e..36bc22c5d659 100644 --- a/src/plugins/index_pattern_management/public/plugin.ts +++ b/src/plugins/index_pattern_management/public/plugin.ts @@ -47,6 +47,7 @@ import { import { ManagementSetup } from '../../management/public'; import { DEFAULT_NAV_GROUPS, AppStatus, DEFAULT_APP_CATEGORIES } from '../../../core/public'; +import { getScopedBreadcrumbs } from '../../opensearch_dashboards_react/public'; export interface IndexPatternManagementSetupDependencies { management: ManagementSetup; @@ -148,7 +149,8 @@ export class IndexPatternManagementPlugin { ...params, basePath: core.http.basePath.get(), - setBreadcrumbs: coreStart.chrome.setBreadcrumbs, + setBreadcrumbs: (breadCrumbs) => + coreStart.chrome.setBreadcrumbs(getScopedBreadcrumbs(breadCrumbs, params.history)), wrapInPage: true, }, () => this.indexPatternManagementService.environmentService.getEnvironment().ml(), diff --git a/src/plugins/opensearch_dashboards_react/public/react_router_navigate/index.ts b/src/plugins/opensearch_dashboards_react/public/react_router_navigate/index.ts index 8ba6b1e2fe90..f5a3ecceac35 100644 --- a/src/plugins/opensearch_dashboards_react/public/react_router_navigate/index.ts +++ b/src/plugins/opensearch_dashboards_react/public/react_router_navigate/index.ts @@ -28,4 +28,8 @@ * under the License. */ -export { reactRouterNavigate, reactRouterOnClickHandler } from './react_router_navigate'; +export { + reactRouterNavigate, + reactRouterOnClickHandler, + getScopedBreadcrumbs, +} from './react_router_navigate'; diff --git a/src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.tsx b/src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.tsx index 5e367f8cb94b..ae249bdadea9 100644 --- a/src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.tsx +++ b/src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.tsx @@ -28,7 +28,7 @@ * under the License. */ -import { ScopedHistory } from 'opensearch-dashboards/public'; +import { ChromeBreadcrumb, ScopedHistory } from 'opensearch-dashboards/public'; import { History } from 'history'; interface LocationObject { @@ -79,3 +79,14 @@ export const reactRouterOnClickHandler = ( event.preventDefault(); history.push(toLocationObject(to)); }; + +export const getScopedBreadcrumbs = ( + crumbs: ChromeBreadcrumb[] = [], + appHistory: ScopedHistory +) => { + const wrapBreadcrumb = (item: ChromeBreadcrumb, scopedHistory: ScopedHistory) => ({ + ...item, + ...(item.href ? reactRouterNavigate(scopedHistory, item.href) : {}), + }); + return crumbs.map((item) => wrapBreadcrumb(item, appHistory)); +}; diff --git a/src/plugins/saved_objects_management/public/plugin.ts b/src/plugins/saved_objects_management/public/plugin.ts index 1247b56b5555..8529a9555681 100644 --- a/src/plugins/saved_objects_management/public/plugin.ts +++ b/src/plugins/saved_objects_management/public/plugin.ts @@ -66,6 +66,7 @@ import { bootstrap } from './ui_actions_bootstrap'; import { DEFAULT_NAV_GROUPS, DEFAULT_APP_CATEGORIES } from '../../../core/public'; import { RecentWork } from './management_section/recent_work'; import { HOME_CONTENT_AREAS } from '../../../plugins/home/public'; +import { getScopedBreadcrumbs } from '../../opensearch_dashboards_react/public'; export interface SavedObjectsManagementPluginSetup { actions: SavedObjectsManagementActionServiceSetup; @@ -173,7 +174,8 @@ export class SavedObjectsManagementPlugin mountParams: { ...params, basePath: core.http.basePath.get(), - setBreadcrumbs: coreStart.chrome.setBreadcrumbs, + setBreadcrumbs: (breadCrumbs) => + coreStart.chrome.setBreadcrumbs(getScopedBreadcrumbs(breadCrumbs, params.history)), wrapInPage: true, }, dataSourceEnabled: !!dataSource, From 92d80ebaebbaa48a4b41d287b1eefc065f7cde1b Mon Sep 17 00:00:00 2001 From: "opensearch-changeset-bot[bot]" <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:00:39 +0000 Subject: [PATCH 02/11] Changeset file for PR #7401 created/updated --- changelogs/fragments/7401.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/7401.yml diff --git a/changelogs/fragments/7401.yml b/changelogs/fragments/7401.yml new file mode 100644 index 000000000000..049af0e41e00 --- /dev/null +++ b/changelogs/fragments/7401.yml @@ -0,0 +1,2 @@ +fix: +- Breadcrumb issue in the new application. ([#7401](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7401)) \ No newline at end of file From b21c2d3e180e27fe8e52b6c6e75b595d1a17bcca Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Tue, 23 Jul 2024 18:13:29 +0800 Subject: [PATCH 03/11] feat: move data source management register logic up a little bit Signed-off-by: SuZhou-Joe --- src/plugins/data_source_management/public/plugin.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/data_source_management/public/plugin.ts b/src/plugins/data_source_management/public/plugin.ts index 0b8d60e67c52..c384e30089f3 100644 --- a/src/plugins/data_source_management/public/plugin.ts +++ b/src/plugins/data_source_management/public/plugin.ts @@ -142,11 +142,6 @@ export class DataSourceManagementPlugin }, }); - // when the feature flag is disabled, we don't need to register any of the mds components - if (!this.featureFlagStatus) { - return undefined; - } - /** * The data sources features in observability has the same name as `DSM_APP_ID` * Add a suffix to avoid duplication @@ -226,6 +221,11 @@ export class DataSourceManagementPlugin }, ]); + // when the feature flag is disabled, we don't need to register any of the mds components + if (!this.featureFlagStatus) { + return undefined; + } + const registerAuthenticationMethod = (authMethod: AuthenticationMethod) => { if (this.started) { throw new Error( From 22760ec6c89b88efb7840d44b67ffa6909c0aba7 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Tue, 23 Jul 2024 18:50:08 +0800 Subject: [PATCH 04/11] feat: add unit test Signed-off-by: SuZhou-Joe --- .../react_router_navigate.test.tsx | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.test.tsx diff --git a/src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.test.tsx b/src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.test.tsx new file mode 100644 index 000000000000..138e33906ac7 --- /dev/null +++ b/src/plugins/opensearch_dashboards_react/public/react_router_navigate/react_router_navigate.test.tsx @@ -0,0 +1,41 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { scopedHistoryMock } from '../../../../core/public/mocks'; +import { getScopedBreadcrumbs } from './react_router_navigate'; + +describe('getScopedBreadcrumbs', () => { + it('should return scoped bread crumbs when given an array', () => { + const history = scopedHistoryMock.create({ + pathname: '/base', + }); + history.createHref.mockImplementation((location) => `/base${location.pathname}`); + const scopedBreadcrumbs = getScopedBreadcrumbs( + [ + { + text: 'Home', + href: '/', + }, + { + text: 'Dashboard', + href: '/dashboard', + }, + ], + history + ); + expect(scopedBreadcrumbs[0]).toEqual( + expect.objectContaining({ + href: '/base/', + text: 'Home', + }) + ); + expect(scopedBreadcrumbs[1]).toEqual( + expect.objectContaining({ + href: '/base/dashboard', + text: 'Dashboard', + }) + ); + }); +}); From 4722476dee08b450aeb0039e74c38fd3539a7e3d Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Tue, 23 Jul 2024 23:17:38 +0800 Subject: [PATCH 05/11] feat: revert the home related change Signed-off-by: SuZhou-Joe --- .../ui/header/collapsible_nav_group_enabled.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx b/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx index c6669a6b99f8..d56f1c76d042 100644 --- a/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx +++ b/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx @@ -177,7 +177,7 @@ export function CollapsibleNavGroupEnabled({ basePath, id, isLocked, - isNavOpen: isNavOpenProps, + isNavOpen, storage = window.localStorage, onIsLockedUpdate, closeNav, @@ -263,18 +263,6 @@ export function CollapsibleNavGroupEnabled({ return fulfillRegistrationLinksToChromeNavLinks(navLinksForAll, navLinks); }, [navLinks, navGroupsMap, currentNavGroup]); - const isNavOpen = useMemo(() => { - // For now, only home page need to always collapse left navigation - // when workspace is enabled. - // If there are more pages need to collapse left navigation in the future - // need to come up with a mechanism to register. - if (capabilities.workspaces.enabled && appId === 'home') { - return false; - } - - return isNavOpenProps; - }, [isNavOpenProps, capabilities.workspaces.enabled, appId]); - const width = useMemo(() => { if (!isNavOpen) { return 50; From b416b599727dbb73b3df18bcafb31f35d113acc3 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Tue, 23 Jul 2024 23:28:26 +0800 Subject: [PATCH 06/11] fix: overview error in all use case when workspace is enabled Signed-off-by: SuZhou-Joe --- src/plugins/workspace/public/plugin.test.ts | 2 +- src/plugins/workspace/public/plugin.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/workspace/public/plugin.test.ts b/src/plugins/workspace/public/plugin.test.ts index 00f0f302ef8c..dc601137789b 100644 --- a/src/plugins/workspace/public/plugin.test.ts +++ b/src/plugins/workspace/public/plugin.test.ts @@ -186,7 +186,7 @@ describe('Workspace plugin', () => { expect(setupMock.application.register).toHaveBeenCalledWith( expect.objectContaining({ id: 'workspace_detail', - navLinkStatus: AppNavLinkStatus.visible, + navLinkStatus: AppNavLinkStatus.hidden, }) ); diff --git a/src/plugins/workspace/public/plugin.ts b/src/plugins/workspace/public/plugin.ts index 23b6224dffe3..879813acba42 100644 --- a/src/plugins/workspace/public/plugin.ts +++ b/src/plugins/workspace/public/plugin.ts @@ -114,6 +114,12 @@ export class WorkspacePlugin if (app.id === 'home' && isAllUseCase) { return { navLinkStatus: AppNavLinkStatus.hidden }; } + + // show the overview page in all use case + if (app.id === WORKSPACE_DETAIL_APP_ID && isAllUseCase) { + return { navLinkStatus: AppNavLinkStatus.visible }; + } + if (isAppAccessibleInWorkspace(app, currentWorkspace, registeredUseCases)) { return; } @@ -333,9 +339,7 @@ export class WorkspacePlugin title: i18n.translate('workspace.settings.workspaceDetail', { defaultMessage: 'Workspace Detail', }), - navLinkStatus: core.chrome.navGroup.getNavGroupEnabled() - ? AppNavLinkStatus.visible - : AppNavLinkStatus.hidden, + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const { renderDetailApp } = await import('./application'); return mountWorkspaceApp(params, renderDetailApp); From 776bec4198da1da6d331c299c055c2b536467add Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Wed, 24 Jul 2024 00:34:35 +0800 Subject: [PATCH 07/11] fix: update snapshot Signed-off-by: SuZhou-Joe --- ...ollapsible_nav_group_enabled.test.tsx.snap | 220 +++++++++++++++++- 1 file changed, 217 insertions(+), 3 deletions(-) diff --git a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap index 1bd0458ef1b5..f83e6403bcc7 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap @@ -14,15 +14,229 @@ exports[` should hide left navigation when in home class="eui-yScroll scrollable-container" >
+ > + +
+ +
+

From 8803144e844573b4b35168f788de33967e2d7d86 Mon Sep 17 00:00:00 2001 From: "opensearch-changeset-bot[bot]" <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 01:58:50 +0000 Subject: [PATCH 08/11] Changeset file for PR #7401 created/updated --- changelogs/fragments/7401.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/7401.yml b/changelogs/fragments/7401.yml index 049af0e41e00..5aebdb156692 100644 --- a/changelogs/fragments/7401.yml +++ b/changelogs/fragments/7401.yml @@ -1,2 +1,2 @@ fix: -- Breadcrumb issue in the new application. ([#7401](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7401)) \ No newline at end of file +- Make breadcrumb of 4 new added applications comply with BrowserRouter. ([#7401](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7401)) \ No newline at end of file From c710dd12d01c4eca17ca21aa51005daef71a95d5 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Wed, 24 Jul 2024 11:55:19 +0800 Subject: [PATCH 09/11] fix: hide nav groups that should be displayed Signed-off-by: SuZhou-Joe --- ...ollapsible_nav_group_enabled.test.tsx.snap | 242 +++--------------- .../collapsible_nav_group_enabled.test.tsx | 55 +++- .../header/collapsible_nav_group_enabled.tsx | 7 +- 3 files changed, 88 insertions(+), 216 deletions(-) diff --git a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap index f83e6403bcc7..4201e5146669 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav_group_enabled.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` should hide left navigation when in home page when workspace is enabled 1`] = ` +exports[` should render correctly 1`] = `
should hide left navigation when in home
`; -exports[` should render correctly 1`] = ` +exports[` should render correctly 2`] = ` +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[` should show all use case by default and able to click see all 1`] = `
should render correctly 1`] = ` class="euiSideNavItem euiSideNavItem--root nav-link-item " >
-
-
- - - - - -
-
- - -
-
-
-
- - - - - -
-
- - -
-
@@ -486,36 +345,7 @@ exports[` should render correctly 1`] = `
`; -exports[` should render correctly 2`] = ` -
-
-
-
-
-
-
-
-
-
-
-`; - -exports[` should show all use case by default and able to click see all 1`] = ` +exports[` should show all use case when current nav group is \`all\` 1`] = `
', () => { function mockProps( props?: Partial & { navGroupsMap?: Record; + currentNavGroupId?: string; + navLinks?: ChromeNavLink[]; } ): CollapsibleNavGroupEnabledProps { - const currentNavGroup$ = new BehaviorSubject(undefined); const navGroupsMap$ = new BehaviorSubject>({ [ALL_USE_CASE_ID]: { ...DEFAULT_NAV_GROUPS[ALL_USE_CASE_ID], @@ -121,6 +122,9 @@ describe('', () => { }, ...props?.navGroupsMap, }); + const currentNavGroup$ = new BehaviorSubject( + props?.currentNavGroupId ? navGroupsMap$.getValue()[props.currentNavGroupId] : undefined + ); return { appId$: new BehaviorSubject('test'), basePath: mockBasePath, @@ -146,6 +150,7 @@ describe('', () => { baseUrl: '', href: '', }, + ...(props?.navLinks || []), ]), storage: new StubBrowserStorage(), onIsLockedUpdate: () => {}, @@ -226,8 +231,9 @@ describe('', () => { expect(getAllByTestId('collapsibleNavAppLink-link-in-analytics').length).toEqual(2); }); - it('should hide left navigation when in home page when workspace is enabled', async () => { + it('should show all use case when current nav group is `all`', async () => { const props = mockProps({ + currentNavGroupId: ALL_USE_CASE_ID, navGroupsMap: { [DEFAULT_NAV_GROUPS.analytics.id]: { ...DEFAULT_NAV_GROUPS.analytics, @@ -241,12 +247,45 @@ describe('', () => { }, }, }); - props.appId$ = new BehaviorSubject('home'); - if (props.capabilities.workspaces) { - (props.capabilities.workspaces as Record) = {}; - (props.capabilities.workspaces as Record).enabled = true; - } - const { container } = render(); + const { container, getAllByTestId, getByTestId } = render( + + ); + fireEvent.click(getAllByTestId('collapsibleNavAppLink-link-in-analytics')[1]); + expect(getAllByTestId('collapsibleNavAppLink-link-in-analytics').length).toEqual(1); expect(container).toMatchSnapshot(); + fireEvent.click(getByTestId('back')); + expect(getAllByTestId('collapsibleNavAppLink-link-in-analytics').length).toEqual(2); + }); + + it('should not show group if the nav link is hidden', async () => { + const props = mockProps({ + currentNavGroupId: ALL_USE_CASE_ID, + navGroupsMap: { + [DEFAULT_NAV_GROUPS.analytics.id]: { + ...DEFAULT_NAV_GROUPS.analytics, + navLinks: [ + { + id: 'link-in-analytics-but-hidden', + title: 'link-in-analytics-but-hidden', + showInAllNavGroup: true, + }, + ], + }, + }, + navLinks: [ + { + id: 'link-in-analytics-but-hidden', + hidden: true, + title: 'link-in-analytics-but-hidden', + baseUrl: '', + href: '', + }, + ], + }); + const { queryAllByTestId } = render(); + expect(queryAllByTestId('collapsibleNavAppLink-link-in-analytics-but-hidden').length).toEqual( + 0 + ); + expect(queryAllByTestId('collapsibleNavAppLink-link-in-all').length).toEqual(1); }); }); diff --git a/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx b/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx index d56f1c76d042..ea5510ad5994 100644 --- a/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx +++ b/src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx @@ -194,7 +194,7 @@ export function CollapsibleNavGroupEnabled({ const currentNavGroup = useObservable(observables.currentNavGroup$, undefined); const navLinksForRender: ChromeNavLink[] = useMemo(() => { - if (currentNavGroup) { + if (currentNavGroup && currentNavGroup.id !== ALL_USE_CASE_ID) { return fulfillRegistrationLinksToChromeNavLinks( navGroupsMap[currentNavGroup.id].navLinks || [], navLinks @@ -241,7 +241,10 @@ export function CollapsibleNavGroupEnabled({ label: group.title, order: group.order, }; - const linksForAllUseCaseWithinNavGroup = group.navLinks + const linksForAllUseCaseWithinNavGroup = fulfillRegistrationLinksToChromeNavLinks( + group.navLinks, + navLinks + ) .filter((navLink) => navLink.showInAllNavGroup) .map((navLink) => ({ ...navLink, From 942e2aa2d006b8284fb662d7e7c7ee39070df7d5 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Wed, 24 Jul 2024 14:31:05 +0800 Subject: [PATCH 10/11] feat: hide expand icon in left navigation Signed-off-by: SuZhou-Joe --- .../header/__snapshots__/header.test.tsx.snap | 148 ++++++++++++++++++ .../public/chrome/ui/header/header.test.tsx | 18 +++ src/core/public/chrome/ui/header/header.tsx | 54 ++++--- 3 files changed, 198 insertions(+), 22 deletions(-) diff --git a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index 284d6c7f2579..9180cba86580 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap @@ -160,6 +160,43 @@ exports[`Header handles visibility and lock changes 1`] = ` "syncErrorThrown": false, "syncErrorValue": null, }, + Subscriber { + "_parentOrParents": null, + "_subscriptions": Array [ + SubjectSubscription { + "_parentOrParents": [Circular], + "_subscriptions": null, + "closed": false, + "subject": [Circular], + "subscriber": [Circular], + }, + ], + "closed": false, + "destination": SafeSubscriber { + "_complete": undefined, + "_context": [Circular], + "_error": undefined, + "_next": [Function], + "_parentOrParents": null, + "_parentSubscriber": [Circular], + "_subscriptions": null, + "closed": false, + "destination": Object { + "closed": true, + "complete": [Function], + "error": [Function], + "next": [Function], + }, + "isStopped": false, + "syncErrorThrowable": false, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + "isStopped": false, + "syncErrorThrowable": true, + "syncErrorThrown": false, + "syncErrorValue": null, + }, ], "thrownError": null, }, @@ -6135,6 +6172,43 @@ exports[`Header handles visibility and lock changes 1`] = ` "syncErrorThrown": false, "syncErrorValue": null, }, + Subscriber { + "_parentOrParents": null, + "_subscriptions": Array [ + SubjectSubscription { + "_parentOrParents": [Circular], + "_subscriptions": null, + "closed": false, + "subject": [Circular], + "subscriber": [Circular], + }, + ], + "closed": false, + "destination": SafeSubscriber { + "_complete": undefined, + "_context": [Circular], + "_error": undefined, + "_next": [Function], + "_parentOrParents": null, + "_parentSubscriber": [Circular], + "_subscriptions": null, + "closed": false, + "destination": Object { + "closed": true, + "complete": [Function], + "error": [Function], + "next": [Function], + }, + "isStopped": false, + "syncErrorThrowable": false, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + "isStopped": false, + "syncErrorThrowable": true, + "syncErrorThrown": false, + "syncErrorValue": null, + }, ], "thrownError": null, }, @@ -7124,6 +7198,43 @@ exports[`Header renders condensed header 1`] = ` "syncErrorThrown": false, "syncErrorValue": null, }, + Subscriber { + "_parentOrParents": null, + "_subscriptions": Array [ + SubjectSubscription { + "_parentOrParents": [Circular], + "_subscriptions": null, + "closed": false, + "subject": [Circular], + "subscriber": [Circular], + }, + ], + "closed": false, + "destination": SafeSubscriber { + "_complete": undefined, + "_context": [Circular], + "_error": undefined, + "_next": [Function], + "_parentOrParents": null, + "_parentSubscriber": [Circular], + "_subscriptions": null, + "closed": false, + "destination": Object { + "closed": true, + "complete": [Function], + "error": [Function], + "next": [Function], + }, + "isStopped": false, + "syncErrorThrowable": false, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + "isStopped": false, + "syncErrorThrowable": true, + "syncErrorThrown": false, + "syncErrorValue": null, + }, ], "thrownError": null, }, @@ -11870,6 +11981,43 @@ exports[`Header renders condensed header 1`] = ` "syncErrorThrown": false, "syncErrorValue": null, }, + Subscriber { + "_parentOrParents": null, + "_subscriptions": Array [ + SubjectSubscription { + "_parentOrParents": [Circular], + "_subscriptions": null, + "closed": false, + "subject": [Circular], + "subscriber": [Circular], + }, + ], + "closed": false, + "destination": SafeSubscriber { + "_complete": undefined, + "_context": [Circular], + "_error": undefined, + "_next": [Function], + "_parentOrParents": null, + "_parentSubscriber": [Circular], + "_subscriptions": null, + "closed": false, + "destination": Object { + "closed": true, + "complete": [Function], + "error": [Function], + "next": [Function], + }, + "isStopped": false, + "syncErrorThrowable": false, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + "isStopped": false, + "syncErrorThrowable": true, + "syncErrorThrown": false, + "syncErrorValue": null, + }, ], "thrownError": null, }, diff --git a/src/core/public/chrome/ui/header/header.test.tsx b/src/core/public/chrome/ui/header/header.test.tsx index 4e3539f2e53b..bef0f152c6a4 100644 --- a/src/core/public/chrome/ui/header/header.test.tsx +++ b/src/core/public/chrome/ui/header/header.test.tsx @@ -187,4 +187,22 @@ describe('Header', () => { expect(component.find('CollapsibleNavGroupEnabled').exists()).toBeTruthy(); }); + + it('show hide expand icon in top left navigation when workspace enabled + homepage + new navigation enabled', () => { + const branding = { + useExpandedHeader: false, + }; + const props = { + ...mockProps(), + branding, + }; + props.application.currentAppId$ = new BehaviorSubject('home'); + props.application.capabilities = { ...props.application.capabilities }; + (props.application.capabilities.workspaces as Record) = {}; + (props.application.capabilities.workspaces as Record).enabled = true; + + const component = mountWithIntl(
); + + expect(component.find('.header__toggleNavButtonSection').exists()).toBeFalsy(); + }); }); diff --git a/src/core/public/chrome/ui/header/header.tsx b/src/core/public/chrome/ui/header/header.tsx index dc161456ba84..adcbba00fe8c 100644 --- a/src/core/public/chrome/ui/header/header.tsx +++ b/src/core/public/chrome/ui/header/header.tsx @@ -131,9 +131,17 @@ export function Header({ }: HeaderProps) { const isVisible = useObservable(observables.isVisible$, false); const isLocked = useObservable(observables.isLocked$, false); + const appId = useObservable(application.currentAppId$, ''); const [isNavOpen, setIsNavOpen] = useState(false); const sidecarConfig = useObservable(observables.sidecarConfig$, undefined); + /** + * This is a workaround on 2.16 to hide the navigation items within left navigation + * when user is in homepage with workspace enabled + new navigation enabled + */ + const shouldHideExpandIcon = + navGroupEnabled && appId === 'home' && application.capabilities.workspaces.enabled; + const sidecarPaddingStyle = useMemo(() => { return getOsdSidecarPaddingStyle(sidecarConfig); }, [sidecarConfig]); @@ -198,29 +206,31 @@ export function Header({ - - - + setIsNavOpen(!isNavOpen)} - aria-expanded={isNavOpen} - aria-pressed={isNavOpen} - aria-controls={navId} - ref={toggleCollapsibleNavRef} + delay="long" + position="bottom" > - - - - + setIsNavOpen(!isNavOpen)} + aria-expanded={isNavOpen} + aria-pressed={isNavOpen} + aria-controls={navId} + ref={toggleCollapsibleNavRef} + > + + + + + )} @@ -293,7 +303,7 @@ export function Header({ id={navId} isLocked={isLocked} navLinks$={observables.navLinks$} - isNavOpen={isNavOpen} + isNavOpen={shouldHideExpandIcon ? false : isNavOpen} basePath={basePath} navigateToApp={application.navigateToApp} navigateToUrl={application.navigateToUrl} From f343e78a0d3417144f6e1ea2ff10e5a791c033bd Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Wed, 24 Jul 2024 14:40:20 +0800 Subject: [PATCH 11/11] feat: update Signed-off-by: SuZhou-Joe --- .../chrome/ui/header/collapsible_nav_group_enabled_top.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/public/chrome/ui/header/collapsible_nav_group_enabled_top.tsx b/src/core/public/chrome/ui/header/collapsible_nav_group_enabled_top.tsx index 9e89155a8e4e..568290da727b 100644 --- a/src/core/public/chrome/ui/header/collapsible_nav_group_enabled_top.tsx +++ b/src/core/public/chrome/ui/header/collapsible_nav_group_enabled_top.tsx @@ -18,6 +18,7 @@ import { i18n } from '@osd/i18n'; import { createEuiListItem } from './nav_link'; import { NavGroupItemInMap } from '../../nav_group'; import { ChromeNavLink } from '../../nav_links'; +import { ALL_USE_CASE_ID } from '../../../../../core/utils'; export interface CollapsibleNavTopProps { navLinks: ChromeNavLink[]; @@ -44,6 +45,7 @@ export const CollapsibleNavTop = ({ const shouldShowBackButton = useMemo( () => + currentNavGroup?.id !== ALL_USE_CASE_ID && !shouldShrinkNavigation && Object.values(navGroupsMap).filter((item) => !item.type).length > 1 && currentNavGroup,