Skip to content

Commit

Permalink
Add rightNavigationButton component in chrome service for applicati…
Browse files Browse the repository at this point in the history
…ons to register and add dev tool to top right navigation.

Signed-off-by: tygao <tygao@amazon.com>
  • Loading branch information
raintygao committed Apr 29, 2024
1 parent c5ff561 commit 2d1a8ee
Show file tree
Hide file tree
Showing 15 changed files with 37 additions and 125 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Multiple Datasource] Extract the button component for datasource picker to avoid duplicate code ([#6559](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6559))
- [Workspace] Add workspaces filter to saved objects page. ([#6458](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6458))
- [Multiple Datasource] Support multi data source in Region map ([#6654](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6654))
- Introduce `registerRightNavigation` in chrome service to register standard top right navigation and add dev tool to top right navigation. ([#6553](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6553))
- Add `rightNavigationButton` component in chrome service for applications to register and add dev tool to top right navigation. ([#6553](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6553))

### 🐛 Bug Fixes

Expand Down
13 changes: 0 additions & 13 deletions src/core/public/chrome/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,6 @@ chrome.navControls.registerLeft({
}
})
```

Register a top right navigation.

```jsx
chrome.navControls.registerRightNavigation({
order: '1',
appId: 'app_id',
iconType: 'consoleApp',
title: 'app_title,
})
```
In this case, a circle icon navigation will be registered to top right header.It will navigate to app after clicked.
### NavLinksService :
- Interface : ChromeNavLinks
- **Signature** - `navLinks: ChromeNavLinks`
Expand Down
1 change: 0 additions & 1 deletion src/core/public/chrome/chrome_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ const createStartContractMock = () => {
getLeft$: jest.fn(),
getCenter$: jest.fn(),
getRight$: jest.fn(),
registerRightNavigation: jest.fn(),
},
setAppTitle: jest.fn(),
setIsVisible: jest.fn(),
Expand Down
2 changes: 1 addition & 1 deletion src/core/public/chrome/chrome_service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export class ChromeService {
const isNavDrawerLocked$ = new BehaviorSubject(localStorage.getItem(IS_LOCKED_KEY) === 'true');
const sidecarConfig$ = overlays.sidecar.getSidecarConfig$();

const navControls = this.navControls.start({ application, http });
const navControls = this.navControls.start();
const navLinks = this.navLinks.start({ application, http });
const recentlyAccessed = await this.recentlyAccessed.start({ http });
const docTitle = this.docTitle.start({ document: window.document });
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 @@ -44,7 +44,7 @@ export {
ChromeHelpExtensionMenuDocumentationLink,
ChromeHelpExtensionMenuGitHubLink,
} from './ui/header/header_help_menu';
export { NavType } from './ui';
export { NavType, RightNavigationButton, RightNavigationButtonProps } from './ui';
export { ChromeNavLink, ChromeNavLinks, ChromeNavLinkUpdateableFields } from './nav_links';
export { ChromeRecentlyAccessed, ChromeRecentlyAccessedHistoryItem } from './recently_accessed';
export { ChromeNavControl, ChromeNavControls } from './nav_controls';
Expand Down
50 changes: 1 addition & 49 deletions src/core/public/chrome/nav_controls/nav_controls_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,10 @@

import { NavControlsService } from './nav_controls_service';
import { take } from 'rxjs/operators';
import { applicationServiceMock, httpServiceMock } from '../../../../core/public/mocks';

const mockMountReactNode = jest.fn().mockReturnValue('mock mount point');
jest.mock('../../utils', () => ({
mountReactNode: () => mockMountReactNode(),
}));

describe('RecentlyAccessed#start()', () => {
const getStart = () => {
return new NavControlsService().start({
application: applicationServiceMock.createInternalStartContract(),
http: httpServiceMock.createStartContract(),
});
return new NavControlsService().start();
};

describe('left contorols', () => {
Expand Down Expand Up @@ -85,45 +76,6 @@ describe('RecentlyAccessed#start()', () => {
});
});

describe('top right navigation', () => {
const mockProps = {
application: applicationServiceMock.createStartContract(),
http: httpServiceMock.createStartContract(),
appId: 'app_id',
iconType: 'icon',
title: 'title',
order: 1,
};
it('allows registration', async () => {
const navControls = getStart();
navControls.registerRightNavigation(mockProps);
expect(await navControls.getRight$().pipe(take(1)).toPromise()).toEqual([
{
mount: 'mock mount point',
order: 1,
},
]);
});

it('sorts controls by order property', async () => {
const navControls = getStart();
const props1 = { ...mockProps, order: 10 };
const props2 = { ...mockProps, order: 0 };
navControls.registerRightNavigation(props1);
navControls.registerRightNavigation(props2);
expect(await navControls.getRight$().pipe(take(1)).toPromise()).toEqual([
{
mount: 'mock mount point',
order: 0,
},
{
mount: 'mock mount point',
order: 10,
},
]);
});
});

describe('center controls', () => {
it('allows registration', async () => {
const navControls = getStart();
Expand Down
42 changes: 5 additions & 37 deletions src/core/public/chrome/nav_controls/nav_controls_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,17 @@
* under the License.
*/

import React from 'react';
import { sortBy } from 'lodash';
import { BehaviorSubject, ReplaySubject, Observable } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { MountPoint } from '../../types';
import {
RightNavigationButton,
RightNavigationButtonProps,
} from '../ui/header/right_navigation_button';
import { mountReactNode } from '../../utils';
import { InternalApplicationStart } from '../../application';
import { HttpStart } from '../../http';

/** @public */
export interface ChromeNavControl {
order?: number;
mount: MountPoint;
}

interface StartDeps {
application: InternalApplicationStart;
http: HttpStart;
}

interface RightNavigationProps extends Omit<RightNavigationButtonProps, 'http' | 'application'> {
order: number;
}

/**
* {@link ChromeNavControls | APIs} for registering new controls to be displayed in the navigation bar.
*
Expand All @@ -79,8 +62,6 @@ export interface ChromeNavControls {
registerRight(navControl: ChromeNavControl): void;
/** Register a nav control to be presented on the top-center side of the chrome header. */
registerCenter(navControl: ChromeNavControl): void;
/** Register a nav control to be presented on the top-right side of the chrome header. The component and style will be uniformly maintained in chrome */
registerRightNavigation(props: RightNavigationProps): void;
/** @internal */
getLeft$(): Observable<ChromeNavControl[]>;
/** @internal */
Expand All @@ -93,7 +74,7 @@ export interface ChromeNavControls {
export class NavControlsService {
private readonly stop$ = new ReplaySubject(1);

public start({ application, http }: StartDeps) {
public start() {
const navControlsLeft$ = new BehaviorSubject<ReadonlySet<ChromeNavControl>>(new Set());
const navControlsRight$ = new BehaviorSubject<ReadonlySet<ChromeNavControl>>(new Set());
const navControlsCenter$ = new BehaviorSubject<ReadonlySet<ChromeNavControl>>(new Set());
Expand All @@ -102,16 +83,15 @@ export class NavControlsService {
new Set()
);

const registerRight = (navControl: ChromeNavControl) =>
navControlsRight$.next(new Set([...navControlsRight$.value.values(), navControl]));

return {
// In the future, registration should be moved to the setup phase. This
// is not possible until the legacy nav controls are no longer supported.
registerLeft: (navControl: ChromeNavControl) =>
navControlsLeft$.next(new Set([...navControlsLeft$.value.values(), navControl])),

registerRight,
registerRight: (navControl: ChromeNavControl) =>
navControlsRight$.next(new Set([...navControlsRight$.value.values(), navControl])),

registerCenter: (navControl: ChromeNavControl) =>
navControlsCenter$.next(new Set([...navControlsCenter$.value.values(), navControl])),

Expand All @@ -124,19 +104,7 @@ export class NavControlsService {
navControlsExpandedCenter$.next(
new Set([...navControlsExpandedCenter$.value.values(), navControl])
),
registerRightNavigation: (props: RightNavigationProps) => {
const nav = {
order: props.order,
mount: mountReactNode(
React.createElement(RightNavigationButton, {
...props,
http,
application,
})
),
};
return registerRight(nav);
},

getLeft$: () =>
navControlsLeft$.pipe(
map((controls) => sortBy([...controls.values()], 'order')),
Expand Down
1 change: 1 addition & 0 deletions src/core/public/chrome/ui/header/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ export {
ChromeHelpExtensionMenuDocumentationLink,
ChromeHelpExtensionMenuGitHubLink,
} from './header_help_menu';
export { RightNavigationButton, RightNavigationButtonProps } from './right_navigation_button';
8 changes: 4 additions & 4 deletions src/core/public/chrome/ui/header/right_navigation_button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

import { EuiHeaderSectionItemButton, EuiIcon } from '@elastic/eui';
import React, { useMemo } from 'react';
import { InternalApplicationStart } from '../../../application';
import { HttpStart } from '../../../http';
import { CoreStart } from '../../..';

import { isModifiedOrPrevented } from './nav_link';
export interface RightNavigationButtonProps {
application: InternalApplicationStart;
http: HttpStart;
application: CoreStart['application'];
http: CoreStart['http'];
appId: string;
iconType: string;
title: string;
Expand Down
2 changes: 2 additions & 0 deletions src/core/public/chrome/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ export {
ChromeHelpExtensionMenuDocumentationLink,
ChromeHelpExtensionMenuGitHubLink,
NavType,
RightNavigationButton,
RightNavigationButtonProps,
} from './header';
4 changes: 4 additions & 0 deletions src/core/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ import {
ChromeRecentlyAccessedHistoryItem,
NavType,
RightNavigationOrder,
RightNavigationButton,
RightNavigationButtonProps,
} from './chrome';
import { FatalErrorsSetup, FatalErrorsStart, FatalErrorInfo } from './fatal_errors';
import { HttpSetup, HttpStart } from './http';
Expand Down Expand Up @@ -362,6 +364,8 @@ export {
NavType,
Branding,
RightNavigationOrder,
RightNavigationButton,
RightNavigationButtonProps,
};

export { __osdBootstrap__ } from './osd_bootstrap';
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/plugins/dev_tools/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"server": false,
"ui": true,
"optionalPlugins": ["dataSource", "managementOverview", "dataSourceManagement"],
"requiredPlugins": ["urlForwarding"]
"requiredPlugins": ["urlForwarding"],
"requiredBundles": ["opensearchDashboardsReact"]
}
Loading

0 comments on commit 2d1a8ee

Please sign in to comment.