[Visualize] Fixes wrong header menu when navigating from a dashboard to a by ref viz (#117077) (#117322)

* [Visualize] fixes share inactive button when navigating from a dashboard to a by ref vz

* Add unit test

* Remove the hardcoded 'dashboards'

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
Kibana Machine 2021-11-03 12:23:47 -04:00 committed by GitHub
parent 85487951fc
commit 8c49c871b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 215 additions and 9 deletions

View file

@ -5,9 +5,18 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { Observable } from 'rxjs';
import { Capabilities } from 'src/core/public';
import { showPublicUrlSwitch } from './get_top_nav_config';
import { showPublicUrlSwitch, getTopNavConfig, TopNavConfigParams } from './get_top_nav_config';
import type {
VisualizeEditorVisInstance,
VisualizeAppStateContainer,
VisualizeServices,
} from '../types';
import { createVisualizeServicesMock } from './mocks';
import { sharePluginMock } from '../../../../share/public/mocks';
import { createEmbeddableStateTransferMock } from '../../../../embeddable/public/mocks';
import { visualizeAppStateStub } from './stubs';
describe('showPublicUrlSwitch', () => {
test('returns false if "visualize" app is not available', () => {
@ -49,3 +58,201 @@ describe('showPublicUrlSwitch', () => {
expect(result).toBe(true);
});
});
describe('getTopNavConfig', () => {
const stateContainerGetStateMock = jest.fn(() => visualizeAppStateStub);
const stateContainer = {
getState: stateContainerGetStateMock,
state$: new Observable(),
transitions: {
updateVisState: jest.fn(),
set: jest.fn(),
},
} as unknown as VisualizeAppStateContainer;
const mockServices = createVisualizeServicesMock();
const share = sharePluginMock.createStartContract();
const services = {
...mockServices,
dashboard: {
dashboardFeatureFlagConfig: {
allowByValueEmbeddables: true,
},
},
visualizeCapabilities: {
save: true,
},
dashboardCapabilities: {
showWriteControls: true,
},
share,
};
test('returns correct links for by reference visualization', () => {
const vis = {
savedVis: {
id: 'test',
sharingSavedObjectProps: {
outcome: 'conflict',
aliasTargetId: 'alias_id',
},
},
vis: {
type: {
title: 'TSVB',
},
},
} as VisualizeEditorVisInstance;
const topNavLinks = getTopNavConfig(
{
hasUnsavedChanges: false,
setHasUnsavedChanges: jest.fn(),
hasUnappliedChanges: false,
onOpenInspector: jest.fn(),
originatingApp: 'dashboards',
setOriginatingApp: jest.fn(),
visInstance: vis,
stateContainer,
visualizationIdFromUrl: undefined,
stateTransfer: createEmbeddableStateTransferMock(),
} as unknown as TopNavConfigParams,
services as unknown as VisualizeServices
);
expect(topNavLinks).toMatchInlineSnapshot(`
Array [
Object {
"description": "Open Inspector for visualization",
"disableButton": [Function],
"id": "inspector",
"label": "inspect",
"run": undefined,
"testId": "openInspectorButton",
"tooltip": [Function],
},
Object {
"description": "Share Visualization",
"disableButton": false,
"id": "share",
"label": "share",
"run": [Function],
"testId": "shareTopNavButton",
},
Object {
"description": "Return to the last app without saving changes",
"emphasize": false,
"id": "cancel",
"label": "Cancel",
"run": [Function],
"testId": "visualizeCancelAndReturnButton",
"tooltip": [Function],
},
Object {
"description": "Save Visualization",
"disableButton": false,
"emphasize": false,
"iconType": undefined,
"id": "save",
"label": "Save as",
"run": [Function],
"testId": "visualizeSaveButton",
"tooltip": [Function],
},
Object {
"description": "Finish editing visualization and return to the last app",
"disableButton": false,
"emphasize": true,
"iconType": "checkInCircleFilled",
"id": "saveAndReturn",
"label": "Save and return",
"run": [Function],
"testId": "visualizesaveAndReturnButton",
"tooltip": [Function],
},
]
`);
});
test('returns correct links for by value visualization', () => {
const vis = {
savedVis: {
id: undefined,
sharingSavedObjectProps: {
outcome: 'conflict',
aliasTargetId: 'alias_id',
},
},
vis: {
type: {
title: 'TSVB',
},
},
} as VisualizeEditorVisInstance;
const topNavLinks = getTopNavConfig(
{
hasUnsavedChanges: false,
setHasUnsavedChanges: jest.fn(),
hasUnappliedChanges: false,
onOpenInspector: jest.fn(),
originatingApp: 'dashboards',
setOriginatingApp: jest.fn(),
visInstance: vis,
stateContainer,
visualizationIdFromUrl: undefined,
stateTransfer: createEmbeddableStateTransferMock(),
} as unknown as TopNavConfigParams,
services as unknown as VisualizeServices
);
expect(topNavLinks).toMatchInlineSnapshot(`
Array [
Object {
"description": "Open Inspector for visualization",
"disableButton": [Function],
"id": "inspector",
"label": "inspect",
"run": undefined,
"testId": "openInspectorButton",
"tooltip": [Function],
},
Object {
"description": "Share Visualization",
"disableButton": true,
"id": "share",
"label": "share",
"run": [Function],
"testId": "shareTopNavButton",
},
Object {
"description": "Return to the last app without saving changes",
"emphasize": false,
"id": "cancel",
"label": "Cancel",
"run": [Function],
"testId": "visualizeCancelAndReturnButton",
"tooltip": [Function],
},
Object {
"description": "Save Visualization",
"disableButton": false,
"emphasize": false,
"iconType": undefined,
"id": "save",
"label": "Save to library",
"run": [Function],
"testId": "visualizeSaveButton",
"tooltip": [Function],
},
Object {
"description": "Finish editing visualization and return to the last app",
"disableButton": false,
"emphasize": true,
"iconType": "checkInCircleFilled",
"id": "saveAndReturn",
"label": "Save and return",
"run": [Function],
"testId": "visualizesaveAndReturnButton",
"tooltip": [Function],
},
]
`);
});
});

View file

@ -49,7 +49,7 @@ interface VisualizeCapabilities {
show: boolean;
}
interface TopNavConfigParams {
export interface TopNavConfigParams {
hasUnsavedChanges: boolean;
setHasUnsavedChanges: (value: boolean) => void;
openInspector: () => void;
@ -243,18 +243,17 @@ export const getTopNavConfig = (
const allowByValue = dashboard.dashboardFeatureFlagConfig.allowByValueEmbeddables;
const saveButtonLabel =
embeddableId || (!savedVis.id && allowByValue && originatingApp)
!savedVis.id && allowByValue && originatingApp
? i18n.translate('visualize.topNavMenu.saveVisualizationToLibraryButtonLabel', {
defaultMessage: 'Save to library',
})
: originatingApp && (embeddableId || savedVis.id)
: originatingApp && savedVis.id
? i18n.translate('visualize.topNavMenu.saveVisualizationAsButtonLabel', {
defaultMessage: 'Save as',
})
: i18n.translate('visualize.topNavMenu.saveVisualizationButtonLabel', {
defaultMessage: 'Save',
});
const showSaveAndReturn = originatingApp && (savedVis?.id || allowByValue);
const showSaveButton =
@ -293,7 +292,7 @@ export const getTopNavConfig = (
}),
testId: 'shareTopNavButton',
run: (anchorElement) => {
if (share && !embeddableId) {
if (share) {
const currentState = stateContainer.getState();
const searchParams = parse(history.location.search);
const params: VisualizeLocatorParams = {
@ -336,8 +335,8 @@ export const getTopNavConfig = (
});
}
},
// disable the Share button if no action specified
disableButton: !share || !!embeddableId,
// disable the Share button if no action specified and fot byValue visualizations
disableButton: !share || Boolean(!savedVis.id && allowByValue && originatingApp),
},
...(originatingApp
? [