Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Navigation-Next] Add current nav group into chrome service #7166

Merged
merged 10 commits into from
Jul 12, 2024
Merged
2 changes: 2 additions & 0 deletions changelogs/fragments/7166.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- 1. Add current nav group into chrome service 2. Prepend current nav group into breadcrumb ([#7166](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7166))
3 changes: 3 additions & 0 deletions src/core/public/chrome/chrome_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
navGroup: {
getNavGroupsMap$: jest.fn(() => new BehaviorSubject({})),
getNavGroupEnabled: jest.fn(),
prependCurrentNavGroupToBreadcrumbs: jest.fn(),
getCurrentNavGroup$: jest.fn(() => new BehaviorSubject(undefined)),

Check warning on line 82 in src/core/public/chrome/chrome_service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/core/public/chrome/chrome_service.mock.ts#L82

Added line #L82 was not covered by tests
setCurrentNavGroup: jest.fn(),
},
setAppTitle: jest.fn(),
setIsVisible: jest.fn(),
Expand Down
5 changes: 4 additions & 1 deletion src/core/public/chrome/chrome_service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export class ChromeService {
const navLinks = this.navLinks.start({ application, http });
const recentlyAccessed = await this.recentlyAccessed.start({ http });
const docTitle = this.docTitle.start({ document: window.document });
const navGroup = await this.navGroup.start({ navLinks });
const navGroup = await this.navGroup.start({ navLinks, application });

// erase chrome fields from a previous app while switching to a next app
application.currentAppId$.subscribe(() => {
Expand Down Expand Up @@ -299,6 +299,9 @@ export class ChromeService {
survey={injectedMetadata.getSurvey()}
collapsibleNavHeaderRender={this.collapsibleNavHeaderRender}
sidecarConfig$={sidecarConfig$}
navGroupEnabled={navGroup.getNavGroupEnabled()}
currentNavgroup$={navGroup.getCurrentNavGroup$()}
prependCurrentNavgroupToBreadcrumbs={navGroup.prependCurrentNavGroupToBreadcrumbs}
/>
),

Expand Down
140 changes: 136 additions & 4 deletions src/core/public/chrome/nav_group/nav_group_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

import * as Rx from 'rxjs';
import { first } from 'rxjs/operators';
import { ChromeNavGroupService, ChromeRegistrationNavLink } from './nav_group_service';
import {
ChromeNavGroupService,
ChromeRegistrationNavLink,
CURRENT_NAV_GROUP_ID,
} from './nav_group_service';
import { uiSettingsServiceMock } from '../../ui_settings/ui_settings_service.mock';
import { NavLinksService } from '../nav_links';
import { applicationServiceMock, httpServiceMock } from '../../mocks';
Expand Down Expand Up @@ -82,6 +86,31 @@ mockedGetNavLinks.mockReturnValue(
])
);

interface LooseObject {
[key: string]: any;
}

// Mock sessionStorage
const sessionStorageMock = (() => {
let store = {} as LooseObject;
return {
getItem(key: string) {
return store[key] || null;
},
setItem(key: string, value: string) {
store[key] = value.toString();
},
removeItem(key: string) {
delete store[key];
},
clear() {
store = {};
},
};
})();

Object.defineProperty(window, 'sessionStorage', { value: sessionStorageMock });

describe('ChromeNavGroupService#setup()', () => {
it('should be able to `addNavLinksToGroup`', async () => {
const warnMock = jest.fn();
Expand All @@ -94,6 +123,7 @@ describe('ChromeNavGroupService#setup()', () => {
chromeNavGroupServiceSetup.addNavLinksToGroup(mockedGroupBar, [mockedGroupBar]);
const chromeNavGroupServiceStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});
const groupsMap = await chromeNavGroupServiceStart.getNavGroupsMap$().pipe(first()).toPromise();
expect(groupsMap[mockedGroupFoo.id].navLinks.length).toEqual(2);
Expand All @@ -116,6 +146,7 @@ describe('ChromeNavGroupService#setup()', () => {
chromeNavGroupServiceSetup.addNavLinksToGroup(mockedGroupBar, [mockedGroupBar]);
const chromeNavGroupServiceStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});
const groupsMap = await chromeNavGroupServiceStart.getNavGroupsMap$().pipe(first()).toPromise();
expect(groupsMap[mockedGroupFoo.id].navLinks.length).toEqual(1);
Expand Down Expand Up @@ -172,7 +203,10 @@ describe('ChromeNavGroupService#start()', () => {
]);
chromeNavGroupServiceSetup.addNavLinksToGroup(mockedGroupBar, [mockedNavLinkBar]);

const chromeStart = await chromeNavGroupService.start({ navLinks: mockedNavLinkService });
const chromeStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});

const groupsMap = await chromeStart.getNavGroupsMap$().pipe(first()).toPromise();

Expand All @@ -196,6 +230,7 @@ describe('ChromeNavGroupService#start()', () => {
chromeNavGroupService.setup({ uiSettings });
const chromeNavGroupServiceStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});

expect(chromeNavGroupServiceStart.getNavGroupEnabled()).toBe(true);
Expand All @@ -210,6 +245,7 @@ describe('ChromeNavGroupService#start()', () => {
chromeNavGroupService.setup({ uiSettings });
const chromeNavGroupServiceStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});

navGroupEnabled$.next(false);
Expand All @@ -219,6 +255,96 @@ describe('ChromeNavGroupService#start()', () => {
navGroupEnabled$.next(true);
expect(chromeNavGroupServiceStart.getNavGroupEnabled()).toBe(false);
});

it('should able to set current nav group', async () => {
const uiSettings = uiSettingsServiceMock.createSetupContract();
const navGroupEnabled$ = new Rx.BehaviorSubject(true);
uiSettings.get$.mockImplementation(() => navGroupEnabled$);

const chromeNavGroupService = new ChromeNavGroupService();
const chromeNavGroupServiceSetup = chromeNavGroupService.setup({ uiSettings });

chromeNavGroupServiceSetup.addNavLinksToGroup(
{
id: 'foo',
title: 'foo title',
description: 'foo description',
},
[mockedNavLinkFoo]
);

const chromeNavGroupServiceStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});

// set an existing nav group id
chromeNavGroupServiceStart.setCurrentNavGroup('foo');

expect(sessionStorageMock.getItem(CURRENT_NAV_GROUP_ID)).toEqual('foo');

let currentNavGroup = await chromeNavGroupServiceStart
.getCurrentNavGroup$()
.pipe(first())
.toPromise();

expect(currentNavGroup?.id).toEqual('foo');
expect(currentNavGroup?.title).toEqual('foo title');

// set a invalid nav group id
chromeNavGroupServiceStart.setCurrentNavGroup('bar');
currentNavGroup = await chromeNavGroupServiceStart
.getCurrentNavGroup$()
.pipe(first())
.toPromise();

expect(sessionStorageMock.getItem(CURRENT_NAV_GROUP_ID)).toBeFalsy();
expect(currentNavGroup).toBeUndefined();

// reset current nav group
chromeNavGroupServiceStart.setCurrentNavGroup(undefined);
currentNavGroup = await chromeNavGroupServiceStart
.getCurrentNavGroup$()
.pipe(first())
.toPromise();

expect(sessionStorageMock.getItem(CURRENT_NAV_GROUP_ID)).toBeFalsy();
expect(currentNavGroup).toBeUndefined();
});

it('shoud able to prepend current nav group into breadcrumbs', async () => {
const uiSettings = uiSettingsServiceMock.createSetupContract();
const navGroupEnabled$ = new Rx.BehaviorSubject(true);
uiSettings.get$.mockImplementation(() => navGroupEnabled$);

const chromeNavGroupService = new ChromeNavGroupService();
const chromeNavGroupServiceSetup = chromeNavGroupService.setup({ uiSettings });

chromeNavGroupServiceSetup.addNavLinksToGroup(
{
id: 'foo',
title: 'Foo title',
description: 'Foo description',
},
[mockedNavLinkFoo]
);

const chromeNavGroupServiceStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});

chromeNavGroupServiceStart.setCurrentNavGroup('foo');

const existingBreadcrumbs = [{ text: 'First' }];
const newBreadcrumbs = chromeNavGroupServiceStart.prependCurrentNavGroupToBreadcrumbs(
existingBreadcrumbs
);
expect(newBreadcrumbs.length).toEqual(3);
expect(newBreadcrumbs[0].text).toEqual('Home');
expect(newBreadcrumbs[1].text).toEqual('Foo title');
expect(newBreadcrumbs[2].text).toEqual('First');
});
});

describe('nav group updater', () => {
Expand All @@ -233,7 +359,10 @@ describe('nav group updater', () => {
id: 'foo',
},
]);
const navGroupStart = await navGroup.start({ navLinks: mockedNavLinkService });
const navGroupStart = await navGroup.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});

expect(await navGroupStart.getNavGroupsMap$().pipe(first()).toPromise()).toEqual({
dataAdministration: expect.not.objectContaining({
Expand Down Expand Up @@ -267,7 +396,10 @@ describe('nav group updater', () => {
status: 2,
}));
const unregister = navGroupSetup.registerNavGroupUpdater(appUpdater$);
const navGroupStart = await navGroup.start({ navLinks: mockedNavLinkService });
const navGroupStart = await navGroup.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});
expect(await navGroupStart.getNavGroupsMap$().pipe(first()).toPromise()).toEqual({
dataAdministration: expect.objectContaining({
status: 2,
Expand Down
Loading
Loading