diff --git a/x-pack/plugins/graph/public/apps/workspace_route.tsx b/x-pack/plugins/graph/public/apps/workspace_route.tsx
index 9087c2ce601cb..79f687d789fb7 100644
--- a/x-pack/plugins/graph/public/apps/workspace_route.tsx
+++ b/x-pack/plugins/graph/public/apps/workspace_route.tsx
@@ -115,13 +115,20 @@ export const WorkspaceRoute = ({
})
);
- const { savedWorkspace, indexPatterns, sharingSavedObjectProps } = useWorkspaceLoader({
+ const loaded = useWorkspaceLoader({
workspaceRef,
store,
savedObjectsClient,
- toastNotifications,
+ spaces,
+ coreStart,
});
+ if (!loaded) {
+ return null;
+ }
+
+ const { savedWorkspace, indexPatterns, sharingSavedObjectProps } = loaded;
+
if (!savedWorkspace || !indexPatterns) {
return null;
}
diff --git a/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.test.tsx b/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.test.tsx
index 20dea4322b601..ae1a726464be5 100644
--- a/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.test.tsx
+++ b/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.test.tsx
@@ -52,17 +52,4 @@ describe('workspace_layout', () => {
otherObjectPath: '#/workspace/conflictId',
});
});
-
- it('should redirect if outcome is aliasMatch', () => {
- shallow(
-
- );
- expect(defaultProps.spaces.ui.redirectLegacyUrl).toHaveBeenCalledWith(
- '#/workspace/aliasMatchId',
- 'Graph'
- );
- });
});
diff --git a/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.tsx b/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.tsx
index 9299b6c8ba1f9..4bb04264bb520 100644
--- a/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.tsx
+++ b/x-pack/plugins/graph/public/components/workspace_layout/workspace_layout.tsx
@@ -180,19 +180,6 @@ export const WorkspaceLayoutComponent = ({
return null;
}, [savedWorkspace.id, sharingSavedObjectProps, spaces, coreStart.http]);
- if (spaces && sharingSavedObjectProps?.outcome === 'aliasMatch') {
- // We found this object by a legacy URL alias from its old ID; redirect the user to the page with its new ID, preserving any URL hash
- const newObjectId = sharingSavedObjectProps?.aliasTargetId!; // This is always defined if outcome === 'aliasMatch'
- const newPath = getEditUrl(coreStart.http.basePath.prepend, { id: newObjectId });
- spaces.ui.redirectLegacyUrl(
- newPath,
- i18n.translate('xpack.graph.legacyUrlConflict.objectNoun', {
- defaultMessage: 'Graph',
- })
- );
- return null;
- }
-
return (
({
+ useHistory: () => ({
+ replace: jest.fn(),
+ }),
+ useLocation: () => ({
+ location: jest.fn(),
+ }),
+ useParams: () => ({
+ id: jest.fn(),
+ }),
+}));
+
+jest.mock('React', () => ({
+ ...jest.requireActual('React'),
+ useEffect: jest.fn(),
+}));
+
+const mockSavedObjectsClient = ({
+ resolve: jest.fn().mockResolvedValue({
+ saved_object: { id: 10, _version: '7.15.0', attributes: { wsState: '{}' } },
+ outcome: 'aliasMatch',
+ alias_target_id: 'aliasTargetId',
+ }),
+ find: jest.fn().mockResolvedValue({ title: 'test' }),
+} as unknown) as SavedObjectsClientCommon;
+
+async function setup(props: UseWorkspaceLoaderProps) {
+ const returnVal = {};
+ function TestComponent() {
+ Object.assign(returnVal, useWorkspaceLoader(props));
+ return null;
+ }
+ await act(async () => {
+ const promise = Promise.resolve();
+ mount();
+ await act(() => promise);
+ });
+ return returnVal;
+}
+
+describe('use_workspace_loader', () => {
+ const defaultProps = {
+ workspaceRef: { current: {} as Workspace },
+ store: createMockGraphStore({}).store,
+ savedObjectsClient: mockSavedObjectsClient,
+ coreStart: coreMock.createStart(),
+ spaces: spacesPluginMock.createStartContract(),
+ };
+
+ it('should redirect if outcome is aliasMatch', async () => {
+ await act(async () => {
+ await setup((defaultProps as unknown) as UseWorkspaceLoaderProps);
+ });
+ expect(defaultProps.spaces.ui.redirectLegacyUrl).toHaveBeenCalledWith(
+ '#/workspace/aliasTargetId',
+ 'Graph'
+ );
+ });
+});
diff --git a/x-pack/plugins/graph/public/helpers/use_workspace_loader.ts b/x-pack/plugins/graph/public/helpers/use_workspace_loader.ts
index 05a53ff23bfd9..74ba2f3bfbbd3 100644
--- a/x-pack/plugins/graph/public/helpers/use_workspace_loader.ts
+++ b/x-pack/plugins/graph/public/helpers/use_workspace_loader.ts
@@ -5,19 +5,22 @@
* 2.0.
*/
-import { SavedObjectsClientContract, ToastsStart } from 'kibana/public';
+import { SavedObjectsClientContract } from 'kibana/public';
import { useEffect, useState } from 'react';
import { useHistory, useLocation, useParams } from 'react-router-dom';
import { i18n } from '@kbn/i18n';
+import { CoreStart } from 'kibana/public';
import { GraphStore } from '../state_management';
import { GraphWorkspaceSavedObject, IndexPatternSavedObject, Workspace } from '../types';
import { getEmptyWorkspace, getSavedWorkspace } from './saved_workspace_utils';
-
-interface UseWorkspaceLoaderProps {
+import { getEditUrl } from '../services/url';
+import { SpacesApi } from '../../../spaces/public';
+export interface UseWorkspaceLoaderProps {
store: GraphStore;
workspaceRef: React.MutableRefObject;
savedObjectsClient: SavedObjectsClientContract;
- toastNotifications: ToastsStart;
+ spaces: SpacesApi;
+ coreStart: CoreStart;
}
interface WorkspaceUrlParams {
@@ -29,10 +32,11 @@ export interface SharingSavedObjectProps {
}
export const useWorkspaceLoader = ({
+ coreStart,
+ spaces,
workspaceRef,
store,
savedObjectsClient,
- toastNotifications,
}: UseWorkspaceLoaderProps) => {
const [indexPatterns, setIndexPatterns] = useState();
const [savedWorkspace, setSavedWorkspace] = useState();
@@ -82,7 +86,7 @@ export const useWorkspaceLoader = ({
}> {
return id
? await getSavedWorkspace(savedObjectsClient, id).catch(function (e) {
- toastNotifications.addError(e, {
+ coreStart.notifications.toasts.addError(e, {
title: i18n.translate('xpack.graph.missingWorkspaceErrorMessage', {
defaultMessage: "Couldn't load graph with ID",
}),
@@ -101,6 +105,19 @@ export const useWorkspaceLoader = ({
sharingSavedObjectProps: fetchedSharingSavedObjectProps,
} = await fetchSavedWorkspace();
+ if (spaces && fetchedSharingSavedObjectProps?.outcome === 'aliasMatch') {
+ // We found this object by a legacy URL alias from its old ID; redirect the user to the page with its new ID, preserving any URL hash
+ const newObjectId = fetchedSharingSavedObjectProps?.aliasTargetId!; // This is always defined if outcome === 'aliasMatch'
+ const newPath = getEditUrl(coreStart.http.basePath.prepend, { id: newObjectId });
+ spaces.ui.redirectLegacyUrl(
+ newPath,
+ i18n.translate('xpack.graph.legacyUrlConflict.objectNoun', {
+ defaultMessage: 'Graph',
+ })
+ );
+ return null;
+ }
+
/**
* Deal with situation of request to open saved workspace. Otherwise clean up store,
* when navigating to a new workspace from existing one.
@@ -124,8 +141,9 @@ export const useWorkspaceLoader = ({
history,
savedObjectsClient,
setSavedWorkspace,
- toastNotifications,
+ coreStart,
workspaceRef,
+ spaces,
]);
return { savedWorkspace, indexPatterns, sharingSavedObjectProps };