Skip to content

Commit

Permalink
[Lens] Fixes the transition to a dashboard when originatingApp is not…
Browse files Browse the repository at this point in the history
… given (#172543)

## Summary

Closes #172410

This is a regression caused by
#167019.

The originatingApp on the navigateToPrefilledEditor defaults to ""
(empty string) and not undefined.

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
  • Loading branch information
stratoula authored Dec 5, 2023
1 parent 1e93160 commit 07f62bf
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 35 deletions.
37 changes: 2 additions & 35 deletions x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import type { LensAppProps, LensAppServices } from './types';
import type { SaveProps } from './app';
import { Document, checkForDuplicateTitle, SavedObjectIndexStore } from '../persistence';
import type { LensByReferenceInput, LensEmbeddableInput } from '../embeddable';
import { APP_ID, getFullPath, LENS_EMBEDDABLE_TYPE } from '../../common/constants';
import { APP_ID, getFullPath } from '../../common/constants';
import type { LensAppState } from '../state_management';
import { getPersisted } from '../state_management/init_middleware/load_initial';
import { VisualizeEditorContext } from '../types';
import { redirectToDashboard } from './save_modal_container_helpers';

type ExtraProps = Pick<LensAppProps, 'initialInput'> &
Partial<Pick<LensAppProps, 'redirectToOrigin' | 'redirectTo' | 'onAppLeave'>>;
Expand Down Expand Up @@ -171,40 +172,6 @@ export function SaveModalContainer({
);
}

const redirectToDashboard = ({
embeddableInput,
dashboardFeatureFlag,
dashboardId,
originatingApp,
getOriginatingPath,
stateTransfer,
}: {
embeddableInput: LensEmbeddableInput;
dashboardId: string;
dashboardFeatureFlag: LensAppServices['dashboardFeatureFlag'];
originatingApp?: string;
getOriginatingPath?: (dashboardId: string) => string | undefined;
stateTransfer: LensAppServices['stateTransfer'];
}) => {
if (!dashboardFeatureFlag.allowByValueEmbeddables) {
throw new Error('redirectToDashboard called with by-value embeddables disabled');
}

const state = {
input: embeddableInput,
type: LENS_EMBEDDABLE_TYPE,
};

const path =
getOriginatingPath?.(dashboardId) ??
(dashboardId === 'new' ? '#/create' : `#/view/${dashboardId}`);
const appId = originatingApp ?? 'dashboards';
stateTransfer.navigateToWithEmbeddablePackage(appId, {
state,
path,
});
};

const getDocToSave = (
lastKnownDoc: Document,
saveProps: SaveProps,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { makeDefaultServices } from '../mocks';
import type { LensEmbeddableInput } from '../embeddable';
import type { LensAppServices } from './types';
import { redirectToDashboard } from './save_modal_container_helpers';

describe('redirectToDashboard', () => {
const embeddableInput = {
test: 'test',
} as unknown as LensEmbeddableInput;
const mockServices = makeDefaultServices();

it('should return error in case of allowByValueEmbeddables false', () => {
expect(() => {
redirectToDashboard({
embeddableInput,
dashboardFeatureFlag: {
allowByValueEmbeddables: false,
},
dashboardId: 'id',
originatingApp: '',
getOriginatingPath: jest.fn(),
stateTransfer: mockServices.stateTransfer,
});
}).toThrow('redirectToDashboard called with by-value embeddables disabled');
});

it('should call the navigateToWithEmbeddablePackage with the correct args if originatingApp is given', () => {
const navigateToWithEmbeddablePackageSpy = jest.fn();
const transferService = {
...mockServices.stateTransfer,
navigateToWithEmbeddablePackage: navigateToWithEmbeddablePackageSpy,
} as unknown as LensAppServices['stateTransfer'];
redirectToDashboard({
embeddableInput,
dashboardFeatureFlag: {
allowByValueEmbeddables: true,
},
dashboardId: 'id',
originatingApp: 'security',
getOriginatingPath: jest.fn(),
stateTransfer: transferService,
});
expect(navigateToWithEmbeddablePackageSpy).toHaveBeenCalledWith('security', {
path: '#/view/id',
state: { input: { test: 'test' }, type: 'lens' },
});
});

it('should call the navigateToWithEmbeddablePackage with the correct args if originatingApp is an empty string', () => {
const navigateToWithEmbeddablePackageSpy = jest.fn();
const transferService = {
...mockServices.stateTransfer,
navigateToWithEmbeddablePackage: navigateToWithEmbeddablePackageSpy,
} as unknown as LensAppServices['stateTransfer'];
redirectToDashboard({
embeddableInput,
dashboardFeatureFlag: {
allowByValueEmbeddables: true,
},
dashboardId: 'id',
originatingApp: '',
getOriginatingPath: jest.fn(),
stateTransfer: transferService,
});
expect(navigateToWithEmbeddablePackageSpy).toHaveBeenCalledWith('dashboards', {
path: '#/view/id',
state: { input: { test: 'test' }, type: 'lens' },
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { LensAppServices } from './types';
import type { LensEmbeddableInput } from '../embeddable';
import { LENS_EMBEDDABLE_TYPE } from '../../common/constants';

export const redirectToDashboard = ({
embeddableInput,
dashboardFeatureFlag,
dashboardId,
originatingApp,
getOriginatingPath,
stateTransfer,
}: {
embeddableInput: LensEmbeddableInput;
dashboardId: string;
dashboardFeatureFlag: LensAppServices['dashboardFeatureFlag'];
originatingApp?: string;
getOriginatingPath?: (dashboardId: string) => string | undefined;
stateTransfer: LensAppServices['stateTransfer'];
}) => {
if (!dashboardFeatureFlag.allowByValueEmbeddables) {
throw new Error('redirectToDashboard called with by-value embeddables disabled');
}

const state = {
input: embeddableInput,
type: LENS_EMBEDDABLE_TYPE,
};

const path =
getOriginatingPath?.(dashboardId) ??
(dashboardId === 'new' ? '#/create' : `#/view/${dashboardId}`);
const appId = originatingApp || 'dashboards';
stateTransfer.navigateToWithEmbeddablePackage(appId, {
state,
path,
});
};

0 comments on commit 07f62bf

Please sign in to comment.