From 73cf5933ff12c0a9923365b2e85a5138afd3e6c3 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Fri, 15 Mar 2024 15:38:58 +0800 Subject: [PATCH 1/7] feat: validate if workspace exists when setup inside a workspace Signed-off-by: SuZhou-Joe --- src/plugins/workspace/common/constants.ts | 2 + .../workspace/opensearch_dashboards.json | 2 +- src/plugins/workspace/public/application.tsx | 26 +++ .../workspace_fatal_error.test.tsx.snap | 180 ++++++++++++++++++ .../components/workspace_fatal_error/index.ts | 6 + .../workspace_fatal_error.test.tsx | 71 +++++++ .../workspace_fatal_error.tsx | 68 +++++++ src/plugins/workspace/public/plugin.test.ts | 83 +++++++- src/plugins/workspace/public/plugin.ts | 65 ++++++- src/plugins/workspace/public/types.ts | 9 + 10 files changed, 507 insertions(+), 5 deletions(-) create mode 100644 src/plugins/workspace/public/application.tsx create mode 100644 src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap create mode 100644 src/plugins/workspace/public/components/workspace_fatal_error/index.ts create mode 100644 src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx create mode 100644 src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx create mode 100644 src/plugins/workspace/public/types.ts diff --git a/src/plugins/workspace/common/constants.ts b/src/plugins/workspace/common/constants.ts index e60bb6aea0eb..6ae89c0edad5 100644 --- a/src/plugins/workspace/common/constants.ts +++ b/src/plugins/workspace/common/constants.ts @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +export const WORKSPACE_OVERVIEW_APP_ID = 'workspace_overview'; +export const WORKSPACE_FATAL_ERROR_APP_ID = 'workspace_fatal_error'; export const WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID = 'workspace'; export const WORKSPACE_CONFLICT_CONTROL_SAVED_OBJECTS_CLIENT_WRAPPER_ID = 'workspace_conflict_control'; diff --git a/src/plugins/workspace/opensearch_dashboards.json b/src/plugins/workspace/opensearch_dashboards.json index f34106ab4fed..4443b7e99834 100644 --- a/src/plugins/workspace/opensearch_dashboards.json +++ b/src/plugins/workspace/opensearch_dashboards.json @@ -7,5 +7,5 @@ "savedObjects" ], "optionalPlugins": [], - "requiredBundles": [] + "requiredBundles": ["opensearchDashboardsReact"] } diff --git a/src/plugins/workspace/public/application.tsx b/src/plugins/workspace/public/application.tsx new file mode 100644 index 000000000000..a6f496304889 --- /dev/null +++ b/src/plugins/workspace/public/application.tsx @@ -0,0 +1,26 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { AppMountParameters, ScopedHistory } from '../../../core/public'; +import { OpenSearchDashboardsContextProvider } from '../../opensearch_dashboards_react/public'; +import { WorkspaceFatalError } from './components/workspace_fatal_error'; +import { Services } from './types'; + +export const renderFatalErrorApp = (params: AppMountParameters, services: Services) => { + const { element } = params; + const history = params.history as ScopedHistory<{ error?: string }>; + ReactDOM.render( + + + , + element + ); + + return () => { + ReactDOM.unmountComponentAtNode(element); + }; +}; diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap b/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap new file mode 100644 index 000000000000..594066e959f7 --- /dev/null +++ b/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap @@ -0,0 +1,180 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` render error with callout 1`] = ` +
+
+
+
+
+ +
+

+ + Something went wrong + +

+ +
+
+

+ + The workspace you want to go can not be found, try go back to home. + +

+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[` render normally 1`] = ` +
+
+
+
+
+ +
+

+ + Something went wrong + +

+ +
+
+

+ + The workspace you want to go can not be found, try go back to home. + +

+
+ +
+
+
+ +
+
+
+
+
+
+
+`; diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/index.ts b/src/plugins/workspace/public/components/workspace_fatal_error/index.ts new file mode 100644 index 000000000000..afb34b10d913 --- /dev/null +++ b/src/plugins/workspace/public/components/workspace_fatal_error/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export { WorkspaceFatalError } from './workspace_fatal_error'; diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx new file mode 100644 index 000000000000..d98e0063dcfa --- /dev/null +++ b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx @@ -0,0 +1,71 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { IntlProvider } from 'react-intl'; +import { fireEvent, render, waitFor } from '@testing-library/react'; +import { WorkspaceFatalError } from './workspace_fatal_error'; +import { context } from '../../../../opensearch_dashboards_react/public'; +import { coreMock } from '../../../../../core/public/mocks'; + +describe('', () => { + it('render normally', async () => { + const { findByText, container } = render( + + + + ); + await findByText('Something went wrong'); + expect(container).toMatchSnapshot(); + }); + + it('render error with callout', async () => { + const { findByText, container } = render( + + + + ); + await findByText('errorInCallout'); + expect(container).toMatchSnapshot(); + }); + + it('click go back to home', async () => { + const { location } = window; + const setHrefSpy = jest.fn((href) => href); + if (window.location) { + // @ts-ignore + delete window.location; + } + window.location = {} as Location; + Object.defineProperty(window.location, 'href', { + get: () => 'http://localhost/', + set: setHrefSpy, + }); + const coreStartMock = coreMock.createStart(); + const { getByText } = render( + + + + + + ); + fireEvent.click(getByText('Go back to home')); + await waitFor( + () => { + expect(setHrefSpy).toBeCalledTimes(1); + }, + { + container: document.body, + } + ); + window.location = location; + }); +}); diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx new file mode 100644 index 000000000000..b1081e92237f --- /dev/null +++ b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx @@ -0,0 +1,68 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + EuiButton, + EuiEmptyPrompt, + EuiPage, + EuiPageBody, + EuiPageContent, + EuiCallOut, +} from '@elastic/eui'; +import React from 'react'; +import { FormattedMessage } from '@osd/i18n/react'; +import { IBasePath } from 'opensearch-dashboards/public'; +import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public'; +import { formatUrlWithWorkspaceId } from '../../../../../core/public/utils'; + +export function WorkspaceFatalError(props: { error?: string }) { + const { + services: { application, http }, + } = useOpenSearchDashboards(); + const goBackToHome = () => { + window.location.href = formatUrlWithWorkspaceId( + application?.getUrlForApp('home') || '', + '', + http?.basePath as IBasePath + ); + }; + return ( + + + + + + + } + body={ +

+ +

+ } + actions={[ + + + , + ]} + /> + {props.error ? : null} +
+
+
+ ); +} diff --git a/src/plugins/workspace/public/plugin.test.ts b/src/plugins/workspace/public/plugin.test.ts index e54a20552329..a0bf6b0f9704 100644 --- a/src/plugins/workspace/public/plugin.test.ts +++ b/src/plugins/workspace/public/plugin.test.ts @@ -3,9 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { waitFor } from '@testing-library/dom'; import { workspaceClientMock, WorkspaceClientMock } from './workspace_client.mock'; -import { chromeServiceMock, coreMock } from '../../../core/public/mocks'; +import { applicationServiceMock, chromeServiceMock, coreMock } from '../../../core/public/mocks'; import { WorkspacePlugin } from './plugin'; +import { WORKSPACE_FATAL_ERROR_APP_ID, WORKSPACE_OVERVIEW_APP_ID } from '../common/constants'; +import { Observable, Subscriber } from 'rxjs'; describe('Workspace plugin', () => { const getSetupMock = () => ({ @@ -25,10 +28,15 @@ describe('Workspace plugin', () => { it('#call savedObjectsClient.setCurrentWorkspace when current workspace id changed', () => { const workspacePlugin = new WorkspacePlugin(); + const setupMock = getSetupMock(); const coreStart = coreMock.createStart(); + workspacePlugin.setup(setupMock); workspacePlugin.start(coreStart); coreStart.workspaces.currentWorkspaceId$.next('foo'); expect(coreStart.savedObjects.client.setCurrentWorkspace).toHaveBeenCalledWith('foo'); + expect(setupMock.application.register).toBeCalledTimes(1); + expect(WorkspaceClientMock).toBeCalledTimes(1); + expect(workspaceClientMock.enterWorkspace).toBeCalledTimes(0); }); it('#setup when workspace id is in url and enterWorkspace return error', async () => { @@ -41,11 +49,82 @@ describe('Workspace plugin', () => { }, } as any) ); + workspaceClientMock.enterWorkspace.mockResolvedValue({ + success: false, + error: 'error', + }); + const setupMock = getSetupMock(); + const applicationStartMock = applicationServiceMock.createStartContract(); + const chromeStartMock = chromeServiceMock.createStartContract(); + setupMock.getStartServices.mockImplementation(() => { + return Promise.resolve([ + { + application: applicationStartMock, + chrome: chromeStartMock, + }, + {}, + {}, + ]) as any; + }); + + const workspacePlugin = new WorkspacePlugin(); + await workspacePlugin.setup(setupMock); + expect(setupMock.application.register).toBeCalledTimes(1); + expect(WorkspaceClientMock).toBeCalledTimes(1); + expect(workspaceClientMock.enterWorkspace).toBeCalledWith('workspaceId'); + expect(setupMock.getStartServices).toBeCalledTimes(1); + await waitFor( + () => { + expect(applicationStartMock.navigateToApp).toBeCalledWith(WORKSPACE_FATAL_ERROR_APP_ID, { + replace: true, + state: { + error: 'error', + }, + }); + }, + { + container: document.body, + } + ); + windowSpy.mockRestore(); + }); + + it('#setup when workspace id is in url and enterWorkspace return success', async () => { + const windowSpy = jest.spyOn(window, 'window', 'get'); + windowSpy.mockImplementation( + () => + ({ + location: { + href: 'http://localhost/w/workspaceId/app', + }, + } as any) + ); + workspaceClientMock.enterWorkspace.mockResolvedValue({ + success: true, + error: 'error', + }); const setupMock = getSetupMock(); + const applicationStartMock = applicationServiceMock.createStartContract(); + let currentAppIdSubscriber: Subscriber | undefined; + setupMock.getStartServices.mockImplementation(() => { + return Promise.resolve([ + { + application: { + ...applicationStartMock, + currentAppId$: new Observable((subscriber) => { + currentAppIdSubscriber = subscriber; + }), + }, + }, + {}, + {}, + ]) as any; + }); const workspacePlugin = new WorkspacePlugin(); await workspacePlugin.setup(setupMock); - expect(setupMock.workspaces.currentWorkspaceId$.getValue()).toEqual('workspaceId'); + currentAppIdSubscriber?.next(WORKSPACE_FATAL_ERROR_APP_ID); + expect(applicationStartMock.navigateToApp).toBeCalledWith(WORKSPACE_OVERVIEW_APP_ID); windowSpy.mockRestore(); }); }); diff --git a/src/plugins/workspace/public/plugin.ts b/src/plugins/workspace/public/plugin.ts index 8a69d597c84b..8289351e0721 100644 --- a/src/plugins/workspace/public/plugin.ts +++ b/src/plugins/workspace/public/plugin.ts @@ -4,10 +4,20 @@ */ import type { Subscription } from 'rxjs'; -import { Plugin, CoreStart, CoreSetup } from '../../../core/public'; +import { + Plugin, + CoreStart, + CoreSetup, + AppMountParameters, + AppNavLinkStatus, +} from '../../../core/public'; +import { WORKSPACE_FATAL_ERROR_APP_ID, WORKSPACE_OVERVIEW_APP_ID } from '../common/constants'; import { getWorkspaceIdFromUrl } from '../../../core/public/utils'; +import { Services } from './types'; import { WorkspaceClient } from './workspace_client'; +type WorkspaceAppType = (params: AppMountParameters, services: Services) => () => void; + export class WorkspacePlugin implements Plugin<{}, {}, {}> { private coreStart?: CoreStart; private currentWorkspaceSubscription?: Subscription; @@ -33,9 +43,60 @@ export class WorkspacePlugin implements Plugin<{}, {}, {}> { const workspaceId = this.getWorkspaceIdFromURL(core.http.basePath.getBasePath()); if (workspaceId) { - core.workspaces.currentWorkspaceId$.next(workspaceId); + const result = await workspaceClient.enterWorkspace(workspaceId); + if (!result.success) { + /** + * Fatal error service does not support customized actions + * So we have to use a self-hosted page to show the errors and redirect. + */ + (async () => { + const [{ application, chrome }] = await core.getStartServices(); + chrome.setIsVisible(false); + application.navigateToApp(WORKSPACE_FATAL_ERROR_APP_ID, { + replace: true, + state: { + error: result.error, + }, + }); + })(); + } else { + /** + * If the workspace id is valid and user is currently on workspace_fatal_error page, + * we should redirect user to overview page of workspace. + */ + (async () => { + const [{ application }] = await core.getStartServices(); + const currentAppIdSubscription = application.currentAppId$.subscribe((currentAppId) => { + if (currentAppId === WORKSPACE_FATAL_ERROR_APP_ID) { + application.navigateToApp(WORKSPACE_OVERVIEW_APP_ID); + } + currentAppIdSubscription.unsubscribe(); + }); + })(); + } } + const mountWorkspaceApp = async (params: AppMountParameters, renderApp: WorkspaceAppType) => { + const [coreStart] = await core.getStartServices(); + const services = { + ...coreStart, + workspaceClient, + }; + + return renderApp(params, services); + }; + + // workspace fatal error + core.application.register({ + id: WORKSPACE_FATAL_ERROR_APP_ID, + title: '', + navLinkStatus: AppNavLinkStatus.hidden, + async mount(params: AppMountParameters) { + const { renderFatalErrorApp } = await import('./application'); + return mountWorkspaceApp(params, renderFatalErrorApp); + }, + }); + return {}; } diff --git a/src/plugins/workspace/public/types.ts b/src/plugins/workspace/public/types.ts new file mode 100644 index 000000000000..1b3f38e50857 --- /dev/null +++ b/src/plugins/workspace/public/types.ts @@ -0,0 +1,9 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { CoreStart } from '../../../core/public'; +import { WorkspaceClient } from './workspace_client'; + +export type Services = CoreStart & { workspaceClient: WorkspaceClient }; From b4ebc8bd28ccad030dd54e4ba5d12a99790793aa Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Fri, 15 Mar 2024 15:48:32 +0800 Subject: [PATCH 2/7] feat: add CHANGELOG Signed-off-by: SuZhou-Joe --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c806cccd64e..fe54b0d0deec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [Discover] Options button to configure legacy mode and remove the top navigation option ([#6170](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6170)) - [Multiple Datasource] Add default functionality for customer to choose default datasource ([#6058](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/6058)) - [Multiple Datasource] Add import support for Vega when specifying a datasource ([#6123](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6123)) +- [Workspace] Validate if workspace exists when setup inside a workspace ([#6154](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6154)) ### 🐛 Bug Fixes From 0300d10350ea5c5f394b43ef04a665393074a0fa Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Fri, 15 Mar 2024 16:30:06 +0800 Subject: [PATCH 3/7] fix: unit test Signed-off-by: SuZhou-Joe --- src/plugins/workspace/public/plugin.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/workspace/public/plugin.test.ts b/src/plugins/workspace/public/plugin.test.ts index a0bf6b0f9704..07d1480c42c4 100644 --- a/src/plugins/workspace/public/plugin.test.ts +++ b/src/plugins/workspace/public/plugin.test.ts @@ -26,11 +26,11 @@ describe('Workspace plugin', () => { expect(WorkspaceClientMock).toBeCalledTimes(1); }); - it('#call savedObjectsClient.setCurrentWorkspace when current workspace id changed', () => { + it('#call savedObjectsClient.setCurrentWorkspace when current workspace id changed', async () => { const workspacePlugin = new WorkspacePlugin(); const setupMock = getSetupMock(); const coreStart = coreMock.createStart(); - workspacePlugin.setup(setupMock); + await workspacePlugin.setup(setupMock); workspacePlugin.start(coreStart); coreStart.workspaces.currentWorkspaceId$.next('foo'); expect(coreStart.savedObjects.client.setCurrentWorkspace).toHaveBeenCalledWith('foo'); From 3547286898480b8762b9e2eeeec9389e4dba7806 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Fri, 15 Mar 2024 17:10:11 +0800 Subject: [PATCH 4/7] feat: optimize import order Signed-off-by: SuZhou-Joe --- src/plugins/workspace/public/plugin.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/workspace/public/plugin.test.ts b/src/plugins/workspace/public/plugin.test.ts index 07d1480c42c4..1bdbd7ef31ad 100644 --- a/src/plugins/workspace/public/plugin.test.ts +++ b/src/plugins/workspace/public/plugin.test.ts @@ -3,12 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { Observable, Subscriber } from 'rxjs'; import { waitFor } from '@testing-library/dom'; import { workspaceClientMock, WorkspaceClientMock } from './workspace_client.mock'; import { applicationServiceMock, chromeServiceMock, coreMock } from '../../../core/public/mocks'; import { WorkspacePlugin } from './plugin'; import { WORKSPACE_FATAL_ERROR_APP_ID, WORKSPACE_OVERVIEW_APP_ID } from '../common/constants'; -import { Observable, Subscriber } from 'rxjs'; describe('Workspace plugin', () => { const getSetupMock = () => ({ From 8350bef37b7238ed012c441b77f881ab576c07aa Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Wed, 20 Mar 2024 11:07:42 +0800 Subject: [PATCH 5/7] feat: add protection Signed-off-by: SuZhou-Joe --- src/plugins/workspace/public/application.tsx | 2 +- src/plugins/workspace/public/plugin.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/workspace/public/application.tsx b/src/plugins/workspace/public/application.tsx index a6f496304889..f70c627e02b0 100644 --- a/src/plugins/workspace/public/application.tsx +++ b/src/plugins/workspace/public/application.tsx @@ -15,7 +15,7 @@ export const renderFatalErrorApp = (params: AppMountParameters, services: Servic const history = params.history as ScopedHistory<{ error?: string }>; ReactDOM.render( - + , element ); diff --git a/src/plugins/workspace/public/plugin.ts b/src/plugins/workspace/public/plugin.ts index 8289351e0721..e3ecdc34bfb9 100644 --- a/src/plugins/workspace/public/plugin.ts +++ b/src/plugins/workspace/public/plugin.ts @@ -55,7 +55,7 @@ export class WorkspacePlugin implements Plugin<{}, {}, {}> { application.navigateToApp(WORKSPACE_FATAL_ERROR_APP_ID, { replace: true, state: { - error: result.error, + error: result?.error, }, }); })(); From 2e9385a63e7c34b33fc16d8b738af3feb60fa35c Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Wed, 20 Mar 2024 11:43:15 +0800 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Yulong Ruan Signed-off-by: SuZhou-Joe --- .../workspace_fatal_error/workspace_fatal_error.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx index b1081e92237f..42cdf4df51a0 100644 --- a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx +++ b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx @@ -47,7 +47,7 @@ export function WorkspaceFatalError(props: { error?: string }) {

} @@ -55,7 +55,7 @@ export function WorkspaceFatalError(props: { error?: string }) { , ]} From fc570f3b336643fb47bdd9b613d490db6de9669e Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Wed, 20 Mar 2024 13:41:40 +0800 Subject: [PATCH 7/7] feat: jump to landing page Signed-off-by: SuZhou-Joe --- .../workspace_fatal_error.test.tsx.snap | 8 ++++---- .../workspace_fatal_error.test.tsx | 4 ++-- .../workspace_fatal_error/workspace_fatal_error.tsx | 13 +++++-------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap b/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap index 594066e959f7..01403b9bc33c 100644 --- a/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap +++ b/src/plugins/workspace/public/components/workspace_fatal_error/__snapshots__/workspace_fatal_error.test.tsx.snap @@ -41,7 +41,7 @@ exports[` render error with callout 1`] = ` >

- The workspace you want to go can not be found, try go back to home. + The workspace you are trying to access cannot be found. Please return to the homepage and try again.

@@ -66,7 +66,7 @@ exports[` render error with callout 1`] = ` class="euiButton__text" > - Go back to home + Go back to homepage @@ -140,7 +140,7 @@ exports[` render normally 1`] = ` >

- The workspace you want to go can not be found, try go back to home. + The workspace you are trying to access cannot be found. Please return to the homepage and try again.

@@ -165,7 +165,7 @@ exports[` render normally 1`] = ` class="euiButton__text" > - Go back to home + Go back to homepage diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx index d98e0063dcfa..11b229c9ccac 100644 --- a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx +++ b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.test.tsx @@ -31,7 +31,7 @@ describe('', () => { expect(container).toMatchSnapshot(); }); - it('click go back to home', async () => { + it('click go back to homepage', async () => { const { location } = window; const setHrefSpy = jest.fn((href) => href); if (window.location) { @@ -57,7 +57,7 @@ describe('', () => { ); - fireEvent.click(getByText('Go back to home')); + fireEvent.click(getByText('Go back to homepage')); await waitFor( () => { expect(setHrefSpy).toBeCalledTimes(1); diff --git a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx index 42cdf4df51a0..604dec277553 100644 --- a/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx +++ b/src/plugins/workspace/public/components/workspace_fatal_error/workspace_fatal_error.tsx @@ -13,20 +13,17 @@ import { } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@osd/i18n/react'; -import { IBasePath } from 'opensearch-dashboards/public'; +import { HttpSetup } from 'opensearch-dashboards/public'; import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public'; -import { formatUrlWithWorkspaceId } from '../../../../../core/public/utils'; export function WorkspaceFatalError(props: { error?: string }) { const { - services: { application, http }, + services: { http }, } = useOpenSearchDashboards(); const goBackToHome = () => { - window.location.href = formatUrlWithWorkspaceId( - application?.getUrlForApp('home') || '', - '', - http?.basePath as IBasePath - ); + window.location.href = (http as HttpSetup).basePath.prepend('/', { + withoutClientBasePath: true, + }); }; return (