Explore: Ensure old panes are removed before opening split view (#70670)

This commit is contained in:
Piotr Jamróz 2023-06-27 14:59:13 +02:00 committed by GitHub
parent e3a4d7c099
commit c9c357fc19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 11 deletions

View File

@ -94,7 +94,7 @@ export function changeSize(exploreId: string, { width }: { width: number }): Pay
return changeSizeAction({ exploreId, width });
}
interface InitializeExploreOptions {
export interface InitializeExploreOptions {
exploreId: string;
datasource: DataSourceRef | string | undefined;
queries: DataQuery[];

View File

@ -7,9 +7,10 @@ import { PanelModel } from 'app/features/dashboard/state';
import { reducerTester } from '../../../../test/core/redux/reducerTester';
import { MockDataSourceApi } from '../../../../test/mocks/datasource_srv';
import { ExploreItemState, ExploreState } from '../../../types';
import { configureStore } from '../../../store/configureStore';
import { ExploreItemState, ExploreState, StoreState, ThunkDispatch } from '../../../types';
import { exploreReducer, navigateToExplore, splitClose } from './main';
import { exploreReducer, navigateToExplore, splitClose, splitOpen } from './main';
const getNavigateToExploreContext = async (openInNewWindow?: (url: string) => void) => {
const url = '/explore';
@ -116,6 +117,35 @@ describe('navigateToExplore', () => {
describe('Explore reducer', () => {
describe('split view', () => {
describe('split open', () => {
it('it should create only ony new pane', async () => {
let dispatch: ThunkDispatch, getState: () => StoreState;
const store: { dispatch: ThunkDispatch; getState: () => StoreState } = configureStore({
explore: {
panes: {
one: { queries: [], range: {} },
},
},
} as unknown as Partial<StoreState>);
dispatch = store.dispatch;
getState = store.getState;
await dispatch(splitOpen());
let splitPanes = Object.keys(getState().explore.panes);
expect(splitPanes).toHaveLength(2);
let secondSplitPaneId = splitPanes[1];
await dispatch(splitOpen());
splitPanes = Object.keys(getState().explore.panes);
// only 2 panes exist...
expect(splitPanes).toHaveLength(2);
// ...and the second pane is replaced
expect(splitPanes[0]).toBe('one');
expect(splitPanes[1]).not.toBe(secondSplitPaneId);
});
});
describe('split close', () => {
it('should reset right pane when it is closed', () => {
const leftItemMock = {

View File

@ -14,7 +14,7 @@ import { CorrelationData } from '../../correlations/useCorrelations';
import { TimeSrv } from '../../dashboard/services/TimeSrv';
import { withUniqueRefIds } from '../utils/queries';
import { initializeExplore, paneReducer } from './explorePane';
import { initializeExplore, InitializeExploreOptions, paneReducer } from './explorePane';
import { DEFAULT_RANGE, makeExplorePaneState } from './utils';
//
@ -63,10 +63,7 @@ export const setPaneState = createAction<SetPaneStateActionPayload>('explore/set
export const clearPanes = createAction('explore/clearPanes');
/**
* Opens a new split pane. It either copies existing state of an already present pane
* or uses values from options arg.
*
* TODO: this can be improved by better inferring fallback values.
* Ensure Explore doesn't exceed supported number of panes and initializes the new pane.
*/
export const splitOpen = createAsyncThunk(
'explore/splitOpen',
@ -76,8 +73,15 @@ export const splitOpen = createAsyncThunk(
const queries = options?.queries ?? (options?.query ? [options?.query] : originState?.queries || []);
Object.keys(getState().explore.panes).forEach((paneId, index) => {
// Only 2 panes are supported. Remove panes before create a new one.
if (index >= 1) {
dispatch(splitClose(paneId));
}
});
await dispatch(
initializeExplore({
createNewSplitOpenPane({
exploreId: requestId,
datasource: options?.datasourceUid || originState?.datasourceInstance?.getRef(),
queries: withUniqueRefIds(queries),
@ -91,6 +95,19 @@ export const splitOpen = createAsyncThunk(
}
);
/**
* Opens a new split pane. It either copies existing state of an already present pane
* or uses values from options arg.
*
* TODO: this can be improved by better inferring fallback values.
*/
const createNewSplitOpenPane = createAsyncThunk(
'explore/createNewSplitOpen',
async (options: InitializeExploreOptions, { dispatch }) => {
await dispatch(initializeExplore(options));
}
);
export interface NavigateToExploreDependencies {
getDataSourceSrv: () => DataSourceSrv;
getTimeSrv: () => TimeSrv;
@ -215,12 +232,12 @@ export const exploreReducer = (state = initialExploreState, action: AnyAction):
};
}
if (splitOpen.pending.match(action)) {
if (createNewSplitOpenPane.pending.match(action)) {
return {
...state,
panes: {
...state.panes,
[action.meta.requestId]: initialExploreItemState,
[action.meta.arg.exploreId]: initialExploreItemState,
},
};
}