mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(explore): make it possible to close left pane of split view (#16155)
* feat(explore): make it possible to close left pane of split view * Use action's type prop instead of enum
This commit is contained in:
@@ -108,11 +108,9 @@ export class UnConnectedExploreToolbar extends PureComponent<Props, {}> {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{exploreId === 'right' && (
|
||||
<a className="explore-toolbar-header-close" onClick={this.props.closeSplit}>
|
||||
<i className="fa fa-times fa-fw" />
|
||||
</a>
|
||||
)}
|
||||
<a className="explore-toolbar-header-close" onClick={() => this.props.closeSplit(exploreId)}>
|
||||
<i className="fa fa-times fa-fw" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="explore-toolbar-item">
|
||||
|
||||
@@ -24,16 +24,9 @@ import { LogLevel } from 'app/core/logs_model';
|
||||
*
|
||||
*/
|
||||
export enum ActionTypes {
|
||||
SplitClose = 'explore/SPLIT_CLOSE',
|
||||
SplitOpen = 'explore/SPLIT_OPEN',
|
||||
ResetExplore = 'explore/RESET_EXPLORE',
|
||||
}
|
||||
|
||||
export interface SplitCloseAction {
|
||||
type: ActionTypes.SplitClose;
|
||||
payload: {};
|
||||
}
|
||||
|
||||
export interface SplitOpenAction {
|
||||
type: ActionTypes.SplitOpen;
|
||||
payload: {
|
||||
@@ -167,6 +160,10 @@ export interface SetQueriesPayload {
|
||||
queries: DataQuery[];
|
||||
}
|
||||
|
||||
export interface SplitCloseActionPayload {
|
||||
itemId: ExploreId;
|
||||
}
|
||||
|
||||
export interface SplitOpenPayload {
|
||||
itemState: ExploreItemState;
|
||||
}
|
||||
@@ -350,7 +347,7 @@ export const setQueriesAction = actionCreatorFactory<SetQueriesPayload>('explore
|
||||
/**
|
||||
* Close the split view and save URL state.
|
||||
*/
|
||||
export const splitCloseAction = noPayloadActionCreatorFactory('explore/SPLIT_CLOSE').create();
|
||||
export const splitCloseAction = actionCreatorFactory<SplitCloseActionPayload>('explore/SPLIT_CLOSE').create();
|
||||
|
||||
/**
|
||||
* Open the split view and copy the left state to be the right state.
|
||||
@@ -395,7 +392,11 @@ export const toggleLogLevelAction = actionCreatorFactory<ToggleLogLevelPayload>(
|
||||
export const resetExploreAction = noPayloadActionCreatorFactory('explore/RESET_EXPLORE').create();
|
||||
export const queriesImportedAction = actionCreatorFactory<QueriesImportedPayload>('explore/QueriesImported').create();
|
||||
|
||||
export type HigherOrderAction = SplitCloseAction | SplitOpenAction | ResetExploreAction | ActionOf<any>;
|
||||
export type HigherOrderAction =
|
||||
| ActionOf<SplitCloseActionPayload>
|
||||
| SplitOpenAction
|
||||
| ResetExploreAction
|
||||
| ActionOf<any>;
|
||||
|
||||
export type Action =
|
||||
| ActionOf<AddQueryRowPayload>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Libraries
|
||||
import _ from 'lodash';
|
||||
import { ThunkAction } from 'redux-thunk';
|
||||
|
||||
// Services & Utils
|
||||
import store from 'app/core/store';
|
||||
@@ -23,7 +22,6 @@ import {
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
|
||||
// Types
|
||||
import { StoreState } from 'app/types';
|
||||
import {
|
||||
RawTimeRange,
|
||||
TimeRange,
|
||||
@@ -35,7 +33,6 @@ import {
|
||||
} from '@grafana/ui/src/types';
|
||||
import { ExploreId, ExploreUrlState, RangeScanner, ResultType, QueryOptions, ExploreUIState } from 'app/types/explore';
|
||||
import {
|
||||
Action,
|
||||
updateDatasourceInstanceAction,
|
||||
changeQueryAction,
|
||||
changeSizeAction,
|
||||
@@ -71,10 +68,9 @@ import {
|
||||
} from './actionTypes';
|
||||
import { ActionOf, ActionCreator } from 'app/core/redux/actionCreatorFactory';
|
||||
import { LogsDedupStrategy } from 'app/core/logs_model';
|
||||
import { ThunkResult } from 'app/types';
|
||||
import { parseTime } from '../TimePicker';
|
||||
|
||||
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action>;
|
||||
|
||||
/**
|
||||
* Updates UI state and save it to the URL
|
||||
*/
|
||||
@@ -645,9 +641,9 @@ export function setQueries(exploreId: ExploreId, rawQueries: DataQuery[]): Thunk
|
||||
/**
|
||||
* Close the split view and save URL state.
|
||||
*/
|
||||
export function splitClose(): ThunkResult<void> {
|
||||
export function splitClose(itemId: ExploreId): ThunkResult<void> {
|
||||
return dispatch => {
|
||||
dispatch(splitCloseAction());
|
||||
dispatch(splitCloseAction({ itemId }));
|
||||
dispatch(stateSave());
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { itemReducer, makeExploreItemState, exploreReducer, makeInitialUpdateState } from './reducers';
|
||||
import { ExploreId, ExploreItemState, ExploreUrlState } from 'app/types/explore';
|
||||
import {
|
||||
itemReducer,
|
||||
makeExploreItemState,
|
||||
exploreReducer,
|
||||
makeInitialUpdateState,
|
||||
initialExploreState,
|
||||
} from './reducers';
|
||||
import { ExploreId, ExploreItemState, ExploreUrlState, ExploreState } from 'app/types/explore';
|
||||
import { reducerTester } from 'test/core/redux/reducerTester';
|
||||
import { scanStartAction, scanStopAction } from './actionTypes';
|
||||
import { scanStartAction, scanStopAction, splitOpenAction, splitCloseAction } from './actionTypes';
|
||||
import { Reducer } from 'redux';
|
||||
import { ActionOf } from 'app/core/redux/actionCreatorFactory';
|
||||
import { updateLocation } from 'app/core/actions/location';
|
||||
@@ -76,6 +82,82 @@ export const setup = (urlStateOverrides?: any) => {
|
||||
};
|
||||
|
||||
describe('Explore reducer', () => {
|
||||
describe('split view', () => {
|
||||
it("should make right pane a duplicate of the given item's state on split open", () => {
|
||||
const leftItemMock = {
|
||||
containerWidth: 100,
|
||||
} as ExploreItemState;
|
||||
|
||||
const initalState = {
|
||||
split: null,
|
||||
left: leftItemMock as ExploreItemState,
|
||||
right: makeExploreItemState(),
|
||||
} as ExploreState;
|
||||
|
||||
reducerTester()
|
||||
.givenReducer(exploreReducer as Reducer<ExploreState, ActionOf<any>>, initalState)
|
||||
.whenActionIsDispatched(splitOpenAction({ itemState: leftItemMock }))
|
||||
.thenStateShouldEqual({
|
||||
split: true,
|
||||
left: leftItemMock,
|
||||
right: leftItemMock,
|
||||
});
|
||||
});
|
||||
|
||||
describe('split close', () => {
|
||||
it('should keep right pane as left when left is closed', () => {
|
||||
const leftItemMock = {
|
||||
containerWidth: 100,
|
||||
} as ExploreItemState;
|
||||
|
||||
const rightItemMock = {
|
||||
containerWidth: 200,
|
||||
} as ExploreItemState;
|
||||
|
||||
const initalState = {
|
||||
split: null,
|
||||
left: leftItemMock,
|
||||
right: rightItemMock,
|
||||
} as ExploreState;
|
||||
|
||||
// closing left item
|
||||
reducerTester()
|
||||
.givenReducer(exploreReducer as Reducer<ExploreState, ActionOf<any>>, initalState)
|
||||
.whenActionIsDispatched(splitCloseAction({ itemId: ExploreId.left }))
|
||||
.thenStateShouldEqual({
|
||||
split: false,
|
||||
left: rightItemMock,
|
||||
right: initialExploreState.right,
|
||||
});
|
||||
});
|
||||
it('should reset right pane when it is closed ', () => {
|
||||
const leftItemMock = {
|
||||
containerWidth: 100,
|
||||
} as ExploreItemState;
|
||||
|
||||
const rightItemMock = {
|
||||
containerWidth: 200,
|
||||
} as ExploreItemState;
|
||||
|
||||
const initalState = {
|
||||
split: null,
|
||||
left: leftItemMock,
|
||||
right: rightItemMock,
|
||||
} as ExploreState;
|
||||
|
||||
// closing left item
|
||||
reducerTester()
|
||||
.givenReducer(exploreReducer as Reducer<ExploreState, ActionOf<any>>, initalState)
|
||||
.whenActionIsDispatched(splitCloseAction({ itemId: ExploreId.right }))
|
||||
.thenStateShouldEqual({
|
||||
split: false,
|
||||
left: leftItemMock,
|
||||
right: initialExploreState.right,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateLocation is dispatched', () => {
|
||||
describe('and payload does not contain a query', () => {
|
||||
it('then it should just return state', () => {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import { ExploreItemState, ExploreState, QueryTransaction, ExploreId, ExploreUpdateState } from 'app/types/explore';
|
||||
import { DataQuery } from '@grafana/ui/src/types';
|
||||
|
||||
import { HigherOrderAction, ActionTypes } from './actionTypes';
|
||||
import { HigherOrderAction, ActionTypes, SplitCloseActionPayload, splitCloseAction } from './actionTypes';
|
||||
import { reducerFactory } from 'app/core/redux';
|
||||
import {
|
||||
addQueryRowAction,
|
||||
@@ -560,8 +560,17 @@ export const updateChildRefreshState = (
|
||||
*/
|
||||
export const exploreReducer = (state = initialExploreState, action: HigherOrderAction): ExploreState => {
|
||||
switch (action.type) {
|
||||
case ActionTypes.SplitClose: {
|
||||
return { ...state, split: false };
|
||||
case splitCloseAction.type: {
|
||||
const { itemId } = action.payload as SplitCloseActionPayload;
|
||||
const targetSplit = {
|
||||
left: itemId === ExploreId.left ? state.right : state.left,
|
||||
right: initialExploreState.right,
|
||||
};
|
||||
return {
|
||||
...state,
|
||||
...targetSplit,
|
||||
split: false,
|
||||
};
|
||||
}
|
||||
|
||||
case ActionTypes.SplitOpen: {
|
||||
|
||||
Reference in New Issue
Block a user