Skip to content

Commit

Permalink
Add registerNavGroupUpdater to nav group service
Browse files Browse the repository at this point in the history
Signed-off-by: Lin Wang <wonglam@amazon.com>
  • Loading branch information
wanglam committed Jul 2, 2024
1 parent 9ac3184 commit e57195d
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/core/public/chrome/chrome_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const createSetupContractMock = () => {
navGroup: {
addNavLinksToGroup: jest.fn(),
getNavGroupEnabled: jest.fn(),
registerNavGroupUpdater: jest.fn(),
},
};
};
Expand Down
2 changes: 1 addition & 1 deletion src/core/public/chrome/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ export { ChromeRecentlyAccessed, ChromeRecentlyAccessedHistoryItem } from './rec
export { ChromeNavControl, ChromeNavControls } from './nav_controls';
export { ChromeDocTitle } from './doc_title';
export { RightNavigationOrder } from './constants';
export { ChromeRegistrationNavLink } from './nav_group';
export { ChromeRegistrationNavLink, ChromeNavGroupUpdater } from './nav_group';
1 change: 1 addition & 0 deletions src/core/public/chrome/nav_group/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export {
ChromeNavGroupServiceStartContract,
ChromeRegistrationNavLink,
NavGroupItemInMap,
ChromeNavGroupUpdater,
} from './nav_group_service';
64 changes: 64 additions & 0 deletions src/core/public/chrome/nav_group/nav_group_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { uiSettingsServiceMock } from '../../ui_settings/ui_settings_service.moc
import { NavLinksService } from '../nav_links';
import { applicationServiceMock, httpServiceMock } from '../../mocks';
import { AppCategory } from 'opensearch-dashboards/public';
import { DEFAULT_NAV_GROUPS } from '../../';

const mockedGroupFoo = {
id: 'foo',
Expand Down Expand Up @@ -219,3 +220,66 @@ describe('ChromeNavGroupService#start()', () => {
expect(chromeNavGroupServiceStart.getNavGroupEnabled()).toBe(false);
});
});

describe('nav group updater', () => {
it('should emit updated nav group after nav group updater called', async () => {
const navGroup = new ChromeNavGroupService();
const uiSettings = uiSettingsServiceMock.createSetupContract();
uiSettings.get$.mockImplementation(() => new Rx.BehaviorSubject(true));

const navGroupSetup = navGroup.setup({ uiSettings });
navGroupSetup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.dataAdministration, [
{
id: 'foo',
},
]);
const navGroupStart = await navGroup.start({ navLinks: mockedNavLinkService });

expect(await navGroupStart.getNavGroupsMap$().pipe(first()).toPromise()).toEqual({
dataAdministration: expect.not.objectContaining({
status: expect.anything,
}),
});
navGroupSetup.registerNavGroupUpdater(
new Rx.BehaviorSubject(() => ({
status: 2,
}))
);
expect(await navGroupStart.getNavGroupsMap$().pipe(first()).toPromise()).toEqual({
dataAdministration: expect.objectContaining({
status: 2,
}),
});
});

it('should reset to original status after nav group updater unregister', async () => {
const navGroup = new ChromeNavGroupService();
const uiSettings = uiSettingsServiceMock.createSetupContract();
uiSettings.get$.mockImplementation(() => new Rx.BehaviorSubject(true));

const navGroupSetup = navGroup.setup({ uiSettings });
navGroupSetup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.dataAdministration, [
{
id: 'foo',
},
]);
const appUpdater$ = new Rx.BehaviorSubject(() => ({
status: 2,
}));
const unregister = navGroupSetup.registerNavGroupUpdater(appUpdater$);
const navGroupStart = await navGroup.start({ navLinks: mockedNavLinkService });
expect(await navGroupStart.getNavGroupsMap$().pipe(first()).toPromise()).toEqual({
dataAdministration: expect.objectContaining({
status: 2,
}),
});

unregister();

expect(await navGroupStart.getNavGroupsMap$().pipe(first()).toPromise()).toEqual({
dataAdministration: expect.not.objectContaining({
status: expect.anything,
}),
});
});
});
45 changes: 42 additions & 3 deletions src/core/public/chrome/nav_group/nav_group_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { BehaviorSubject, combineLatest, Observable, ReplaySubject, Subscription } from 'rxjs';
import { BehaviorSubject, combineLatest, Observable, of, ReplaySubject, Subscription } from 'rxjs';
import { AppCategory, ChromeNavGroup, ChromeNavLink } from 'opensearch-dashboards/public';
import { map, takeUntil } from 'rxjs/operators';
import { map, switchMap, takeUntil } from 'rxjs/operators';
import { IUiSettingsClient } from '../../ui_settings';
import {
flattenLinksOrCategories,
Expand All @@ -31,12 +31,15 @@ export type NavGroupItemInMap = ChromeNavGroup & {
navLinks: ChromeRegistrationNavLink[];
};

export type ChromeNavGroupUpdater = (navGroup: ChromeNavGroup) => Partial<ChromeNavGroup> | void;

export interface ChromeNavGroupServiceSetupContract {
addNavLinksToGroup: (navGroup: ChromeNavGroup, navLinks: ChromeRegistrationNavLink[]) => void;
/**
* Get a boolean value to indicates whether use case is enabled
*/
getNavGroupEnabled: () => boolean;
registerNavGroupUpdater: (navGroupUpdater: Observable<ChromeNavGroupUpdater>) => () => void;
}

export interface ChromeNavGroupServiceStartContract {
Expand All @@ -51,6 +54,7 @@ export class ChromeNavGroupService {
private navLinks$: Observable<Array<Readonly<ChromeNavLink>>> = new BehaviorSubject([]);
private navGroupEnabled: boolean = false;
private navGroupEnabledUiSettingsSubscription: Subscription | undefined;
private navGroupUpdaters$$ = new BehaviorSubject<Array<Observable<ChromeNavGroupUpdater>>>([]);
private addNavLinkToGroup(
currentGroupsMap: Record<string, NavGroupItemInMap>,
navGroup: ChromeNavGroup,
Expand Down Expand Up @@ -78,7 +82,7 @@ export class ChromeNavGroupService {
return currentGroupsMap;
}
private getSortedNavGroupsMap$() {
return combineLatest([this.navGroupsMap$, this.navLinks$])
return combineLatest([this.getUpdatedNavGroupsMap$(), this.navLinks$])
.pipe(takeUntil(this.stop$))
.pipe(
map(([navGroupsMap, navLinks]) => {
Expand All @@ -96,6 +100,33 @@ export class ChromeNavGroupService {
})
);
}

private getUpdatedNavGroupsMap$() {
return combineLatest([this.navGroupsMap$, this.navGroupUpdaters$$]).pipe(
switchMap(([navGroupsMap, updaters$]) => {
if (updaters$.length === 0) {
return of(navGroupsMap);
}
return combineLatest(updaters$).pipe(
map((updaters) => {
return Object.keys(navGroupsMap).reduce<Record<string, NavGroupItemInMap>>(
(previousValue, currentKey) => ({
...previousValue,
[currentKey]: updaters.reduce(
(prevNavGroup, currentUpdater) => ({
...prevNavGroup,
...currentUpdater(prevNavGroup),
}),
navGroupsMap[currentKey]
),
}),
{}
);
})
);
})
);
}
setup({ uiSettings }: { uiSettings: IUiSettingsClient }): ChromeNavGroupServiceSetupContract {
this.navGroupEnabledUiSettingsSubscription = uiSettings
.get$('home:useNewHomePage', false)
Expand All @@ -116,6 +147,14 @@ export class ChromeNavGroupService {
this.navGroupsMap$.next(navGroupsMapAfterAdd);
},
getNavGroupEnabled: () => this.navGroupEnabled,
registerNavGroupUpdater: (updater$) => {
this.navGroupUpdaters$$.next([...this.navGroupUpdaters$$.getValue(), updater$]);
return () => {
this.navGroupUpdaters$$.next(
this.navGroupUpdaters$$.getValue().filter((item) => item !== updater$)
);
};
},
};
}
async start({
Expand Down
3 changes: 3 additions & 0 deletions src/core/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import {
RightNavigationButton,
RightNavigationButtonProps,
ChromeRegistrationNavLink,
ChromeNavGroupUpdater,
} from './chrome';
import { FatalErrorsSetup, FatalErrorsStart, FatalErrorInfo } from './fatal_errors';
import { HttpSetup, HttpStart } from './http';
Expand Down Expand Up @@ -118,6 +119,7 @@ export {
WorkspaceAttribute,
ChromeNavGroup,
NavGroupType,
NavGroupStatus,
} from '../types';

export {
Expand Down Expand Up @@ -371,6 +373,7 @@ export {
RightNavigationButton,
RightNavigationButtonProps,
ChromeRegistrationNavLink,
ChromeNavGroupUpdater,
};

export { __osdBootstrap__ } from './osd_bootstrap';
Expand Down
7 changes: 7 additions & 0 deletions src/core/types/nav_group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export enum NavGroupType {
SYSTEM = 'system',
}

export enum NavGroupStatus {
Visible,
Hidden,
}

/** @public */
export interface ChromeNavGroup {
id: string;
Expand All @@ -24,4 +29,6 @@ export interface ChromeNavGroup {
order?: number;
icon?: EuiIconType;
type?: NavGroupType;

status?: NavGroupStatus;
}

0 comments on commit e57195d

Please sign in to comment.