Skip to content

Commit

Permalink
[Visualize] Fixes wrong header menu when navigating from a dashboard …
Browse files Browse the repository at this point in the history
…to a by ref viz (#117077)

* [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 <[email protected]>
  • Loading branch information
stratoula and kibanamachine authored Nov 3, 2021
1 parent 9d4045b commit 12c0075
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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],
},
]
`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ interface VisualizeCapabilities {
show: boolean;
}

interface TopNavConfigParams {
export interface TopNavConfigParams {
hasUnsavedChanges: boolean;
setHasUnsavedChanges: (value: boolean) => void;
openInspector: () => void;
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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
? [
Expand Down

0 comments on commit 12c0075

Please sign in to comment.