From 2c339b46d411fd6b1fdb603efc6580f0a1569d26 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 20 Apr 2023 10:07:27 +0300 Subject: [PATCH] Add custom timerange trasfer test --- .../public/lib/actions/edit_panel_action.ts | 5 +-- .../components/visualize_editor.tsx | 45 ++++++++++--------- .../utils/get_visualization_instance.test.ts | 19 +++++++- .../utils/use/use_saved_vis_instance.test.ts | 40 +++++++++++++++++ .../utils/use/use_saved_vis_instance.ts | 9 +++- .../apps/lens/open_in_lens/tsvb/dashboard.ts | 21 ++++++++- 6 files changed, 108 insertions(+), 31 deletions(-) diff --git a/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts b/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts index 1dcecf4ac894d..ba59d92cbef60 100644 --- a/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts +++ b/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts @@ -17,7 +17,6 @@ import { IEmbeddable, EmbeddableEditorState, EmbeddableStateTransfer, - SavedObjectEmbeddableInput, EmbeddableInput, Container, } from '../..'; @@ -124,13 +123,11 @@ export class EditPanelAction implements Action { if (app && path) { if (this.currentAppId) { - const byValueMode = !(embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId; - const originatingPath = this.getOriginatingPath?.(); const state: EmbeddableEditorState = { originatingApp: this.currentAppId, - valueInput: byValueMode ? this.getExplicitInput({ embeddable }) : undefined, + valueInput: this.getExplicitInput({ embeddable }), embeddableId: embeddable.id, searchSessionId: embeddable.getInput().searchSessionId, originatingPath, diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index 221cdcc9d8e10..70c0c111ce581 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -24,23 +24,46 @@ import { VisualizeServices } from '../types'; import { VisualizeEditorCommon } from './visualize_editor_common'; import { VisualizeAppProps } from '../app'; import { VisualizeConstants } from '../../../common/constants'; +import type { VisualizeInput } from '../..'; export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { const { id: visualizationIdFromUrl } = useParams<{ id: string }>(); const [originatingApp, setOriginatingApp] = useState(); const [originatingPath, setOriginatingPath] = useState(); const [embeddableIdValue, setEmbeddableId] = useState(); + const [embeddableInput, setEmbeddableInput] = useState(); const { services } = useKibana(); const [eventEmitter] = useState(new EventEmitter()); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(!visualizationIdFromUrl); const isChromeVisible = useChromeVisibility(services.chrome); + useEffect(() => { + const { stateTransferService, data } = services; + const { + originatingApp: value, + searchSessionId, + embeddableId, + originatingPath: pathValue, + valueInput: valueInputValue, + } = stateTransferService.getIncomingEditorState(VisualizeConstants.APP_ID) || {}; + + if (searchSessionId) { + data.search.session.continue(searchSessionId); + } else { + data.search.session.start(); + } + setEmbeddableInput(valueInputValue); + setEmbeddableId(embeddableId); + setOriginatingApp(value); + setOriginatingPath(pathValue); + }, [services]); const { savedVisInstance, visEditorRef, visEditorController } = useSavedVisInstance( services, eventEmitter, isChromeVisible, originatingApp, - visualizationIdFromUrl + visualizationIdFromUrl, + embeddableInput ); const editorName = savedVisInstance?.vis.type.title.toLowerCase().replace(' ', '_') || ''; @@ -66,26 +89,6 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { useLinkedSearchUpdates(services, eventEmitter, appState, savedVisInstance); useDataViewUpdates(services, eventEmitter, appState, savedVisInstance); - useEffect(() => { - const { stateTransferService, data } = services; - const { - originatingApp: value, - searchSessionId, - embeddableId, - originatingPath: pathValue, - } = stateTransferService.getIncomingEditorState(VisualizeConstants.APP_ID) || {}; - - if (searchSessionId) { - data.search.session.continue(searchSessionId); - } else { - data.search.session.start(); - } - - setEmbeddableId(embeddableId); - setOriginatingApp(value); - setOriginatingPath(pathValue); - }, [services]); - useEffect(() => { // clean up all registered listeners if any is left return () => { diff --git a/src/plugins/visualizations/public/visualize_app/utils/get_visualization_instance.test.ts b/src/plugins/visualizations/public/visualize_app/utils/get_visualization_instance.test.ts index 985f194acaf83..d4b7dbd5213e5 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/get_visualization_instance.test.ts +++ b/src/plugins/visualizations/public/visualize_app/utils/get_visualization_instance.test.ts @@ -170,6 +170,10 @@ describe('getVisualizationInstanceInput', () => { id: 'test-id', description: 'description', title: 'title', + timeRange: { + from: 'now-7d/d', + to: 'now', + }, savedVis: { title: '', description: '', @@ -196,8 +200,15 @@ describe('getVisualizationInstanceInput', () => { }, }, } as unknown as VisualizeInput; - const { savedVis, savedSearch, vis, embeddableHandler, panelDescription, panelTitle } = - await getVisualizationInstanceFromInput(mockServices, input); + const { + savedVis, + savedSearch, + vis, + embeddableHandler, + panelDescription, + panelTitle, + panelTimeRange, + } = await getVisualizationInstanceFromInput(mockServices, input); expect(getSavedVisualization).toHaveBeenCalled(); expect(createVisAsync).toHaveBeenCalledWith(serializedVisMock.type, input.savedVis); @@ -216,5 +227,9 @@ describe('getVisualizationInstanceInput', () => { expect(savedSearch).toBeUndefined(); expect(panelDescription).toBe('description'); expect(panelTitle).toBe('title'); + expect(panelTimeRange).toStrictEqual({ + from: 'now-7d/d', + to: 'now', + }); }); }); diff --git a/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.test.ts b/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.test.ts index 93f9e2ae0b0a4..4b6b87bd04f1f 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.test.ts +++ b/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.test.ts @@ -147,6 +147,46 @@ describe('useSavedVisInstance', () => { expect(result.current.savedVisInstance).toBeDefined(); }); + test('should pass the input timeRange if it exists', async () => { + const embeddableInput = { + timeRange: { + from: 'now-7d/d', + to: 'now', + }, + id: 'panel1', + }; + const { result, waitForNextUpdate } = renderHook(() => + useSavedVisInstance( + mockServices, + eventEmitter, + true, + undefined, + savedVisId, + embeddableInput + ) + ); + + result.current.visEditorRef.current = document.createElement('div'); + expect(mockGetVisualizationInstance).toHaveBeenCalledWith(mockServices, savedVisId); + expect(mockGetVisualizationInstance.mock.calls.length).toBe(1); + + await waitForNextUpdate(); + expect(mockServices.chrome.setBreadcrumbs).toHaveBeenCalledWith('Test Vis'); + expect(mockServices.chrome.docTitle.change).toHaveBeenCalledWith('Test Vis'); + expect(getEditBreadcrumbs).toHaveBeenCalledWith( + { originatingAppName: undefined, redirectToOrigin: undefined }, + 'Test Vis' + ); + expect(getCreateBreadcrumbs).not.toHaveBeenCalled(); + expect(mockEmbeddableHandlerRender).not.toHaveBeenCalled(); + expect(result.current.visEditorController).toBeDefined(); + expect(result.current.savedVisInstance).toBeDefined(); + expect(result.current.savedVisInstance?.panelTimeRange).toStrictEqual({ + from: 'now-7d/d', + to: 'now', + }); + }); + test('should destroy the editor and the savedVis on unmount if chrome exists', async () => { const { result, unmount, waitForNextUpdate } = renderHook(() => useSavedVisInstance(mockServices, eventEmitter, true, undefined, savedVisId) diff --git a/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.ts b/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.ts index 27cd03a8cc8ae..f84b7928dda39 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.ts +++ b/src/plugins/visualizations/public/visualize_app/utils/use/use_saved_vis_instance.ts @@ -17,6 +17,7 @@ import { SavedVisInstance, VisualizeServices, IEditorController } from '../../ty import { VisualizeConstants } from '../../../../common/constants'; import { getTypes } from '../../../services'; import { redirectToSavedObjectPage } from '../utils'; +import type { VisualizeInput } from '../../..'; /** * This effect is responsible for instantiating a saved vis or creating a new one @@ -27,13 +28,13 @@ export const useSavedVisInstance = ( eventEmitter: EventEmitter, isChromeVisible: boolean | undefined, originatingApp: string | undefined, - visualizationIdFromUrl: string | undefined + visualizationIdFromUrl: string | undefined, + embeddableInput?: VisualizeInput ) => { const [state, setState] = useState<{ savedVisInstance?: SavedVisInstance; visEditorController?: IEditorController; }>({}); - const visEditorRef = useRef(null); const visId = useRef(''); @@ -82,6 +83,9 @@ export const useSavedVisInstance = ( savedVisInstance = await getVisualizationInstance(services, visualizationIdFromUrl); } + if (embeddableInput && embeddableInput.timeRange) { + savedVisInstance.panelTimeRange = embeddableInput.timeRange; + } const { embeddableHandler, savedVis, vis } = savedVisInstance; const originatingAppName = originatingApp @@ -166,6 +170,7 @@ export const useSavedVisInstance = ( visualizationIdFromUrl, state.savedVisInstance, state.visEditorController, + embeddableInput, ]); useEffect(() => { diff --git a/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts b/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts index ef625b7116eea..579134c3ce287 100644 --- a/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts +++ b/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts @@ -17,7 +17,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'dashboard', 'canvas', ]); - + const dashboardCustomizePanel = getService('dashboardCustomizePanel'); + const dashboardBadgeActions = getService('dashboardBadgeActions'); + const dashboardPanelActions = getService('dashboardPanelActions'); const testSubjects = getService('testSubjects'); const retry = getService('retry'); const panelActions = getService('dashboardPanelActions'); @@ -42,6 +44,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await dashboard.waitForRenderComplete(); const originalEmbeddableCount = await canvas.getEmbeddableCount(); + await dashboardPanelActions.customizePanel(); + await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); + await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days'); + await dashboardCustomizePanel.clickSaveButton(); + await dashboard.waitForRenderComplete(); + await dashboardBadgeActions.expectExistsTimeRangeBadgeAction(); await panelActions.openContextMenu(); await panelActions.clickEdit(); @@ -59,6 +68,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); const titles = await dashboard.getPanelTitles(); expect(titles[0]).to.be('My TSVB to Lens viz 1 (converted)'); + await dashboardBadgeActions.expectExistsTimeRangeBadgeAction(); await panelActions.removePanel(); }); @@ -72,6 +82,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await dashboard.waitForRenderComplete(); const originalEmbeddableCount = await canvas.getEmbeddableCount(); + await dashboardPanelActions.customizePanel(); + await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); + await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days'); + await dashboardCustomizePanel.clickSaveButton(); + await dashboard.waitForRenderComplete(); + await dashboardBadgeActions.expectExistsTimeRangeBadgeAction(); await panelActions.openContextMenu(); await panelActions.clickEdit(); @@ -95,7 +112,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(descendants.length).to.equal(0); const titles = await dashboard.getPanelTitles(); expect(titles[0]).to.be('My TSVB to Lens viz 2 (converted)'); - + await dashboardBadgeActions.expectExistsTimeRangeBadgeAction(); await panelActions.removePanel(); }); });