Skip to content

Commit f48755f

Browse files
yuye-awsSuZhou-Joeraintygao
authored andcommitted
Refactor navigation links from left menu hard code to workspace plugin register (opensearch-project#55)
* feature: add public/workspaces service Signed-off-by: SuZhoue-Joe <suzhou@amazon.com> * Exit workspace from left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Show exit workspace button with small window size Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove recently viewed and workspace overview on left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add buttons for outside, inside workspace case Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Implement home button and workspace over view button on left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Implement workspace dropdown list in left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add props on recently accessed and custom nav link Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Reuse method getWorkspaceUrl Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove recently accessed and custom nav props in test Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Revert "Remove recently accessed and custom nav props in test" This reverts commit 7895e5c. * Wrap title with i18n Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add redirect for workspace app Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Enable users to go to workspace lists page via see more under workspaces in left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Fix build error and part of test error (opensearch-project#42) * fix: fix build error and some ut Signed-off-by: tygao <tygao@amazon.com> * chore: remove saved object client test diff Signed-off-by: tygao <tygao@amazon.com> --------- Signed-off-by: tygao <tygao@amazon.com> * Comment Alerts and Favorites in left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Recover recently viewed items in left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Move exit workspace from left menu to update page Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove unused import Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add workspace category info Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove workspace nav link Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove unused import Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add FilteredNavLinks props to chrome service mock Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove workspace related constans from chrome Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove workspace related props from chrome and core Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove workspace related props from header Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Shorten import path for workspace updater Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add euiIconType for workspace left menu category Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove workspace related props for collapsible nav Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Remove workspace related props for collapsible nav Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Implement navigation for delete and exit workspace Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Navigate external links through url change Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Implement filteredNavLinks and sort ChromeNavLinks in nav link service Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add workspace list, see more, admin and overview into chromenavlinks Signed-off-by: yuye-aws <yuyezhu@amazon.com> * fix: unit test failure (opensearch-project#50) Signed-off-by: SuZhou-Joe <suzhou@amazon.com> * Fix osd bootstrap error Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Check workspace enabled for left menu Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Add home nav link to left menu when outside workspace Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Fix unit test for collapsible nav Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Fix unit test for header Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Fix unit test for collapsible nav Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Fix unit test for collapsible nav Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Update snapshot for unit tests Signed-off-by: yuye-aws <yuyezhu@amazon.com> * fix osd bootstrap error Signed-off-by: yuye-aws <yuyezhu@amazon.com> * fix combinelatest import error Signed-off-by: yuye-aws <yuyezhu@amazon.com> * update snapshot for unit tests Signed-off-by: yuye-aws <yuyezhu@amazon.com> * variable rename Signed-off-by: yuye-aws <yuyezhu@amazon.com> * move custom nav link to mock props Signed-off-by: yuye-aws <yuyezhu@amazon.com> * move default filtered nav link to core Signed-off-by: yuye-aws <yuyezhu@amazon.com> * change navigation method in workspace updater Signed-off-by: yuye-aws <yuyezhu@amazon.com> * Update src/plugins/workspace/public/components/workspace_updater/workspace_updater.tsx Co-authored-by: SuZhou-Joe <suzhou@amazon.com> * revert some unncessary changes Signed-off-by: yuye-aws <yuyezhu@amazon.com> * fix navigation url bug Signed-off-by: yuye-aws <yuyezhu@amazon.com> * move default filtered nav link value setting from core to workspace plugin Signed-off-by: yuye-aws <yuyezhu@amazon.com> * move filter nav link to a new function Signed-off-by: yuye-aws <yuyezhu@amazon.com> * process filter nav links when workspace is disabled Signed-off-by: yuye-aws <yuyezhu@amazon.com> * change navigation method Signed-off-by: yuye-aws <yuyezhu@amazon.com> --------- Signed-off-by: SuZhoue-Joe <suzhou@amazon.com> Signed-off-by: yuye-aws <yuyezhu@amazon.com> Signed-off-by: tygao <tygao@amazon.com> Signed-off-by: SuZhou-Joe <suzhou@amazon.com> Co-authored-by: SuZhoue-Joe <suzhou@amazon.com> Co-authored-by: raintygao <tygao@amazon.com>
1 parent 6f5c215 commit f48755f

16 files changed

+3371
-4127
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const createStartContractMock = () => {
3838
getHeaderComponent: jest.fn(),
3939
navLinks: {
4040
getNavLinks$: jest.fn(),
41+
getFilteredNavLinks$: jest.fn(),
42+
setFilteredNavLinks: jest.fn(),
4143
has: jest.fn(),
4244
get: jest.fn(),
4345
getAll: jest.fn(),

src/core/public/chrome/chrome_service.tsx

+3-45
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,21 @@ import { FormattedMessage } from '@osd/i18n/react';
3434
import { BehaviorSubject, combineLatest, merge, Observable, of, ReplaySubject } from 'rxjs';
3535
import { flatMap, map, takeUntil } from 'rxjs/operators';
3636
import { EuiLink } from '@elastic/eui';
37-
import { i18n } from '@osd/i18n';
3837
import { mountReactNode } from '../utils/mount';
3938
import { InternalApplicationStart } from '../application';
4039
import { DocLinksStart } from '../doc_links';
4140
import { HttpStart } from '../http';
4241
import { InjectedMetadataStart } from '../injected_metadata';
4342
import { NotificationsStart } from '../notifications';
4443
import { IUiSettingsClient } from '../ui_settings';
45-
import { OPENSEARCH_DASHBOARDS_ASK_OPENSEARCH_LINK, WORKSPACE_APP_ID } from './constants';
44+
import { OPENSEARCH_DASHBOARDS_ASK_OPENSEARCH_LINK } from './constants';
4645
import { ChromeDocTitle, DocTitleService } from './doc_title';
4746
import { ChromeNavControls, NavControlsService } from './nav_controls';
4847
import { ChromeNavLinks, NavLinksService, ChromeNavLink } from './nav_links';
4948
import { ChromeRecentlyAccessed, RecentlyAccessedService } from './recently_accessed';
5049
import { Header } from './ui';
5150
import { ChromeHelpExtensionMenuLink } from './ui/header/header_help_menu';
52-
import { Branding, WorkspacesStart } from '../';
51+
import { Branding } from '../';
5352
import { getLogos } from '../../common';
5453
import type { Logos } from '../../common/types';
5554

@@ -97,7 +96,6 @@ interface StartDeps {
9796
injectedMetadata: InjectedMetadataStart;
9897
notifications: NotificationsStart;
9998
uiSettings: IUiSettingsClient;
100-
workspaces: WorkspacesStart;
10199
}
102100

103101
/** @internal */
@@ -151,7 +149,6 @@ export class ChromeService {
151149
injectedMetadata,
152150
notifications,
153151
uiSettings,
154-
workspaces,
155152
}: StartDeps): Promise<InternalChromeStart> {
156153
this.initVisibility(application);
157154

@@ -177,41 +174,6 @@ export class ChromeService {
177174
docTitle.reset();
178175
});
179176

180-
const getWorkspaceUrl = (id: string) => {
181-
return workspaces.formatUrlWithWorkspaceId(
182-
application.getUrlForApp(WORKSPACE_APP_ID, {
183-
path: '/',
184-
absolute: true,
185-
}),
186-
id
187-
);
188-
};
189-
190-
const exitWorkspace = async () => {
191-
let result;
192-
try {
193-
result = await workspaces.client.exitWorkspace();
194-
} catch (error) {
195-
notifications?.toasts.addDanger({
196-
title: i18n.translate('workspace.exit.failed', {
197-
defaultMessage: 'Failed to exit workspace',
198-
}),
199-
text: error instanceof Error ? error.message : JSON.stringify(error),
200-
});
201-
return;
202-
}
203-
if (!result?.success) {
204-
notifications?.toasts.addDanger({
205-
title: i18n.translate('workspace.exit.failed', {
206-
defaultMessage: 'Failed to exit workspace',
207-
}),
208-
text: result?.error,
209-
});
210-
return;
211-
}
212-
await application.navigateToApp('home');
213-
};
214-
215177
const setIsNavDrawerLocked = (isLocked: boolean) => {
216178
isNavDrawerLocked$.next(isLocked);
217179
localStorage.setItem(IS_LOCKED_KEY, `${isLocked}`);
@@ -287,7 +249,7 @@ export class ChromeService {
287249
homeHref={http.basePath.prepend('/app/home')}
288250
isVisible$={this.isVisible$}
289251
opensearchDashboardsVersion={injectedMetadata.getOpenSearchDashboardsVersion()}
290-
navLinks$={navLinks.getNavLinks$()}
252+
navLinks$={navLinks.getFilteredNavLinks$()}
291253
customNavLink$={customNavLink$.pipe(takeUntil(this.stop$))}
292254
recentlyAccessed$={recentlyAccessed.get$()}
293255
navControlsLeft$={navControls.getLeft$()}
@@ -296,14 +258,10 @@ export class ChromeService {
296258
navControlsExpandedCenter$={navControls.getExpandedCenter$()}
297259
navControlsExpandedRight$={navControls.getExpandedRight$()}
298260
onIsLockedUpdate={setIsNavDrawerLocked}
299-
exitWorkspace={exitWorkspace}
300-
getWorkspaceUrl={getWorkspaceUrl}
301261
isLocked$={getIsNavDrawerLocked$}
302262
branding={injectedMetadata.getBranding()}
303263
logos={logos}
304264
survey={injectedMetadata.getSurvey()}
305-
currentWorkspace$={workspaces.client.currentWorkspace$}
306-
workspaceList$={workspaces.client.workspaceList$}
307265
/>
308266
),
309267

src/core/public/chrome/constants.ts

-6
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,3 @@
3131
export const OPENSEARCH_DASHBOARDS_ASK_OPENSEARCH_LINK = 'https://forum.opensearch.org/';
3232
export const GITHUB_CREATE_ISSUE_LINK =
3333
'https://github.com/opensearch-project/OpenSearch-Dashboards/issues/new/choose';
34-
35-
export const WORKSPACE_APP_ID = 'workspace';
36-
37-
export const PATHS = {
38-
list: '/list',
39-
};

src/core/public/chrome/nav_links/nav_link.ts

+5
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ export interface ChromeNavLink {
102102
* Hides a link from the navigation.
103103
*/
104104
readonly hidden?: boolean;
105+
106+
/**
107+
* Links can be navigated through url.
108+
*/
109+
readonly externalLink?: boolean;
105110
}
106111

107112
/** @public */

src/core/public/chrome/nav_links/nav_links_service.ts

+26
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ export interface ChromeNavLinks {
5353
*/
5454
getNavLinks$(): Observable<Array<Readonly<ChromeNavLink>>>;
5555

56+
/**
57+
* Set an observable for a sorted list of filtered navlinks.
58+
*/
59+
getFilteredNavLinks$(): Observable<Array<Readonly<ChromeNavLink>>>;
60+
61+
/**
62+
* Set filtered navlinks.
63+
*/
64+
setFilteredNavLinks(filteredNavLinks: ReadonlyMap<string, ChromeNavLink>): void;
65+
5666
/**
5767
* Get the state of a navlink at this point in time.
5868
* @param id
@@ -116,6 +126,7 @@ type LinksUpdater = (navLinks: Map<string, NavLinkWrapper>) => Map<string, NavLi
116126

117127
export class NavLinksService {
118128
private readonly stop$ = new ReplaySubject(1);
129+
private filteredNavLinks$ = new BehaviorSubject<ReadonlyMap<string, ChromeNavLink>>(new Map());
119130

120131
public start({ application, http }: StartDeps): ChromeNavLinks {
121132
const appLinks$ = application.applications$.pipe(
@@ -151,6 +162,14 @@ export class NavLinksService {
151162
return navLinks$.pipe(map(sortNavLinks), takeUntil(this.stop$));
152163
},
153164

165+
setFilteredNavLinks: (filteredNavLinks: ReadonlyMap<string, ChromeNavLink>) => {
166+
this.filteredNavLinks$.next(filteredNavLinks);
167+
},
168+
169+
getFilteredNavLinks$: () => {
170+
return this.filteredNavLinks$.pipe(map(sortChromeNavLinks), takeUntil(this.stop$));
171+
},
172+
154173
get(id: string) {
155174
const link = navLinks$.value.get(id);
156175
return link && link.properties;
@@ -215,3 +234,10 @@ function sortNavLinks(navLinks: ReadonlyMap<string, NavLinkWrapper>) {
215234
'order'
216235
);
217236
}
237+
238+
function sortChromeNavLinks(chromeNavLinks: ReadonlyMap<string, ChromeNavLink>) {
239+
return sortBy(
240+
[...chromeNavLinks.values()].map((link) => link as Readonly<ChromeNavLink>),
241+
'order'
242+
);
243+
}

0 commit comments

Comments
 (0)