[Lens] Fixes the transition to a dashboard when originatingApp is not given (#172543)

## Summary

Closes https://github.com/elastic/kibana/issues/172410

This is a regression caused by
https://github.com/elastic/kibana/pull/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
This commit is contained in:
Stratoula Kalafateli 2023-12-05 18:42:19 +02:00 committed by GitHub
parent 1e931607d7
commit 07f62bf560
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 122 additions and 35 deletions

View file

@ -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'>>;
@ -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,

View file

@ -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' },
});
});
});

View file

@ -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,
});
};