mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: Cleanup redundant state variables and unused actions (#20837)
This commit is contained in:
parent
880fbcb09a
commit
c4c031ef43
@ -1,5 +1,5 @@
|
|||||||
// Libraries
|
// Libraries
|
||||||
import React, { ComponentType } from 'react';
|
import React from 'react';
|
||||||
import { hot } from 'react-hot-loader';
|
import { hot } from 'react-hot-loader';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
@ -27,13 +27,13 @@ import {
|
|||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
DataQuery,
|
DataQuery,
|
||||||
ExploreStartPageProps,
|
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
PanelData,
|
PanelData,
|
||||||
RawTimeRange,
|
RawTimeRange,
|
||||||
GraphSeriesXY,
|
GraphSeriesXY,
|
||||||
TimeZone,
|
TimeZone,
|
||||||
AbsoluteTimeRange,
|
AbsoluteTimeRange,
|
||||||
|
LoadingState,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -71,7 +71,6 @@ const getStyles = memoizeOne(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
interface ExploreProps {
|
interface ExploreProps {
|
||||||
StartPage?: ComponentType<ExploreStartPageProps>;
|
|
||||||
changeSize: typeof changeSize;
|
changeSize: typeof changeSize;
|
||||||
datasourceInstance: DataSourceApi;
|
datasourceInstance: DataSourceApi;
|
||||||
datasourceMissing: boolean;
|
datasourceMissing: boolean;
|
||||||
@ -87,7 +86,6 @@ interface ExploreProps {
|
|||||||
scanStopAction: typeof scanStopAction;
|
scanStopAction: typeof scanStopAction;
|
||||||
setQueries: typeof setQueries;
|
setQueries: typeof setQueries;
|
||||||
split: boolean;
|
split: boolean;
|
||||||
showingStartPage?: boolean;
|
|
||||||
queryKeys: string[];
|
queryKeys: string[];
|
||||||
initialDatasource: string;
|
initialDatasource: string;
|
||||||
initialQueries: DataQuery[];
|
initialQueries: DataQuery[];
|
||||||
@ -251,11 +249,9 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
StartPage,
|
|
||||||
datasourceInstance,
|
datasourceInstance,
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreId,
|
exploreId,
|
||||||
showingStartPage,
|
|
||||||
split,
|
split,
|
||||||
queryKeys,
|
queryKeys,
|
||||||
mode,
|
mode,
|
||||||
@ -270,6 +266,8 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
const exploreClass = split ? 'explore explore-split' : 'explore';
|
const exploreClass = split ? 'explore explore-split' : 'explore';
|
||||||
const styles = getStyles();
|
const styles = getStyles();
|
||||||
|
const StartPage = datasourceInstance?.components?.ExploreStartPage;
|
||||||
|
const showStartPage = !queryResponse || queryResponse.state === LoadingState.NotStarted;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={exploreClass} ref={this.getRef}>
|
<div className={exploreClass} ref={this.getRef}>
|
||||||
@ -288,7 +286,7 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
return (
|
return (
|
||||||
<main className={`m-t-2 ${styles.logsMain}`} style={{ width }}>
|
<main className={`m-t-2 ${styles.logsMain}`} style={{ width }}>
|
||||||
<ErrorBoundaryAlert>
|
<ErrorBoundaryAlert>
|
||||||
{showingStartPage && StartPage && (
|
{showStartPage && StartPage && (
|
||||||
<div className="grafana-info-box grafana-info-box--max-lg">
|
<div className="grafana-info-box grafana-info-box--max-lg">
|
||||||
<StartPage
|
<StartPage
|
||||||
onClickExample={this.onClickExample}
|
onClickExample={this.onClickExample}
|
||||||
@ -297,7 +295,7 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!showingStartPage && (
|
{!showStartPage && (
|
||||||
<>
|
<>
|
||||||
{mode === ExploreMode.Metrics && (
|
{mode === ExploreMode.Metrics && (
|
||||||
<ExploreGraphPanel
|
<ExploreGraphPanel
|
||||||
@ -353,11 +351,9 @@ function mapStateToProps(state: StoreState, { exploreId }: ExploreProps): Partia
|
|||||||
const item: ExploreItemState = explore[exploreId];
|
const item: ExploreItemState = explore[exploreId];
|
||||||
const timeZone = getTimeZone(state.user);
|
const timeZone = getTimeZone(state.user);
|
||||||
const {
|
const {
|
||||||
StartPage,
|
|
||||||
datasourceInstance,
|
datasourceInstance,
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
initialized,
|
initialized,
|
||||||
showingStartPage,
|
|
||||||
queryKeys,
|
queryKeys,
|
||||||
urlState,
|
urlState,
|
||||||
update,
|
update,
|
||||||
@ -398,11 +394,9 @@ function mapStateToProps(state: StoreState, { exploreId }: ExploreProps): Partia
|
|||||||
const initialUI = ui || DEFAULT_UI_STATE;
|
const initialUI = ui || DEFAULT_UI_STATE;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
StartPage,
|
|
||||||
datasourceInstance,
|
datasourceInstance,
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
initialized,
|
initialized,
|
||||||
showingStartPage,
|
|
||||||
split,
|
split,
|
||||||
queryKeys,
|
queryKeys,
|
||||||
update,
|
update,
|
||||||
|
@ -8,7 +8,7 @@ import { css } from 'emotion';
|
|||||||
|
|
||||||
import { ExploreId, ExploreItemState, ExploreMode } from 'app/types/explore';
|
import { ExploreId, ExploreItemState, ExploreMode } from 'app/types/explore';
|
||||||
import { ToggleButtonGroup, ToggleButton, Tooltip, ButtonSelect, SetInterval } from '@grafana/ui';
|
import { ToggleButtonGroup, ToggleButton, Tooltip, ButtonSelect, SetInterval } from '@grafana/ui';
|
||||||
import { RawTimeRange, TimeZone, TimeRange, DataSourceSelectItem, DataQuery } from '@grafana/data';
|
import { RawTimeRange, TimeZone, TimeRange, DataQuery } from '@grafana/data';
|
||||||
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
|
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
|
||||||
import { StoreState } from 'app/types/store';
|
import { StoreState } from 'app/types/store';
|
||||||
import {
|
import {
|
||||||
@ -31,6 +31,7 @@ import { LiveTailButton } from './LiveTailButton';
|
|||||||
import { ResponsiveButton } from './ResponsiveButton';
|
import { ResponsiveButton } from './ResponsiveButton';
|
||||||
import { RunButton } from './RunButton';
|
import { RunButton } from './RunButton';
|
||||||
import { LiveTailControls } from './useLiveTailControls';
|
import { LiveTailControls } from './useLiveTailControls';
|
||||||
|
import { getExploreDatasources } from './state/selectors';
|
||||||
|
|
||||||
const getStyles = memoizeOne(() => {
|
const getStyles = memoizeOne(() => {
|
||||||
return {
|
return {
|
||||||
@ -50,11 +51,9 @@ interface OwnProps {
|
|||||||
|
|
||||||
interface StateProps {
|
interface StateProps {
|
||||||
datasourceMissing: boolean;
|
datasourceMissing: boolean;
|
||||||
exploreDatasources: DataSourceSelectItem[];
|
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
range: TimeRange;
|
range: TimeRange;
|
||||||
timeZone: TimeZone;
|
timeZone: TimeZone;
|
||||||
selectedDatasource?: DataSourceSelectItem;
|
|
||||||
splitted: boolean;
|
splitted: boolean;
|
||||||
syncedTimes: boolean;
|
syncedTimes: boolean;
|
||||||
refreshInterval?: string;
|
refreshInterval?: string;
|
||||||
@ -67,6 +66,7 @@ interface StateProps {
|
|||||||
queries: DataQuery[];
|
queries: DataQuery[];
|
||||||
datasourceLoading?: boolean;
|
datasourceLoading?: boolean;
|
||||||
containerWidth: number;
|
containerWidth: number;
|
||||||
|
datasourceName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DispatchProps {
|
interface DispatchProps {
|
||||||
@ -137,16 +137,20 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getSelectedDatasource = () => {
|
||||||
|
const { datasourceName } = this.props;
|
||||||
|
const exploreDatasources = getExploreDatasources();
|
||||||
|
return datasourceName ? exploreDatasources.find(datasource => datasource.name === datasourceName) : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreDatasources,
|
|
||||||
closeSplit,
|
closeSplit,
|
||||||
exploreId,
|
exploreId,
|
||||||
loading,
|
loading,
|
||||||
range,
|
range,
|
||||||
timeZone,
|
timeZone,
|
||||||
selectedDatasource,
|
|
||||||
splitted,
|
splitted,
|
||||||
syncedTimes,
|
syncedTimes,
|
||||||
refreshInterval,
|
refreshInterval,
|
||||||
@ -203,8 +207,8 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
|||||||
>
|
>
|
||||||
<DataSourcePicker
|
<DataSourcePicker
|
||||||
onChange={this.onChangeDatasource}
|
onChange={this.onChangeDatasource}
|
||||||
datasources={exploreDatasources}
|
datasources={getExploreDatasources()}
|
||||||
current={selectedDatasource}
|
current={this.getSelectedDatasource()}
|
||||||
showLoading={datasourceLoading}
|
showLoading={datasourceLoading}
|
||||||
hideTextValue={showSmallDataSourcePicker}
|
hideTextValue={showSmallDataSourcePicker}
|
||||||
/>
|
/>
|
||||||
@ -331,7 +335,6 @@ const mapStateToProps = (state: StoreState, { exploreId }: OwnProps): StateProps
|
|||||||
const {
|
const {
|
||||||
datasourceInstance,
|
datasourceInstance,
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreDatasources,
|
|
||||||
range,
|
range,
|
||||||
refreshInterval,
|
refreshInterval,
|
||||||
loading,
|
loading,
|
||||||
@ -344,21 +347,15 @@ const mapStateToProps = (state: StoreState, { exploreId }: OwnProps): StateProps
|
|||||||
datasourceLoading,
|
datasourceLoading,
|
||||||
containerWidth,
|
containerWidth,
|
||||||
} = exploreItem;
|
} = exploreItem;
|
||||||
const selectedDatasource = datasourceInstance
|
|
||||||
? exploreDatasources.find(datasource => datasource.name === datasourceInstance.name)
|
const hasLiveOption = datasourceInstance?.meta?.streaming && mode === ExploreMode.Logs;
|
||||||
: undefined;
|
|
||||||
const hasLiveOption =
|
|
||||||
datasourceInstance && datasourceInstance.meta && datasourceInstance.meta.streaming && mode === ExploreMode.Logs
|
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
datasourceMissing,
|
datasourceMissing,
|
||||||
exploreDatasources,
|
datasourceName: datasourceInstance?.name,
|
||||||
loading,
|
loading,
|
||||||
range,
|
range,
|
||||||
timeZone: getTimeZone(state.user),
|
timeZone: getTimeZone(state.user),
|
||||||
selectedDatasource,
|
|
||||||
splitted,
|
splitted,
|
||||||
refreshInterval,
|
refreshInterval,
|
||||||
supportedModes,
|
supportedModes,
|
||||||
|
@ -4,7 +4,6 @@ import { Emitter } from 'app/core/core';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
DataQuery,
|
DataQuery,
|
||||||
DataSourceSelectItem,
|
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
QueryFixAction,
|
QueryFixAction,
|
||||||
PanelData,
|
PanelData,
|
||||||
@ -81,10 +80,6 @@ export interface ClearOriginPayload {
|
|||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClearRefreshIntervalPayload {
|
|
||||||
exploreId: ExploreId;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HighlightLogsExpressionPayload {
|
export interface HighlightLogsExpressionPayload {
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
expressions: string[];
|
expressions: string[];
|
||||||
@ -122,10 +117,6 @@ export interface ModifyQueriesPayload {
|
|||||||
modifier: (query: DataQuery, modification: QueryFixAction) => DataQuery;
|
modifier: (query: DataQuery, modification: QueryFixAction) => DataQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QueryStartPayload {
|
|
||||||
exploreId: ExploreId;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface QueryEndedPayload {
|
export interface QueryEndedPayload {
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
response: PanelData;
|
response: PanelData;
|
||||||
@ -199,11 +190,6 @@ export interface QueriesImportedPayload {
|
|||||||
queries: DataQuery[];
|
queries: DataQuery[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LoadExploreDataSourcesPayload {
|
|
||||||
exploreId: ExploreId;
|
|
||||||
exploreDatasources: DataSourceSelectItem[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SetUrlReplacedPayload {
|
export interface SetUrlReplacedPayload {
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
}
|
}
|
||||||
@ -312,10 +298,6 @@ export const loadDatasourceReadyAction = actionCreatorFactory<LoadDatasourceRead
|
|||||||
*/
|
*/
|
||||||
export const modifyQueriesAction = actionCreatorFactory<ModifyQueriesPayload>('explore/MODIFY_QUERIES').create();
|
export const modifyQueriesAction = actionCreatorFactory<ModifyQueriesPayload>('explore/MODIFY_QUERIES').create();
|
||||||
|
|
||||||
export const queryStartAction = actionCreatorFactory<QueryStartPayload>('explore/QUERY_START').create();
|
|
||||||
|
|
||||||
export const queryEndedAction = actionCreatorFactory<QueryEndedPayload>('explore/QUERY_ENDED').create();
|
|
||||||
|
|
||||||
export const queryStreamUpdatedAction = actionCreatorFactory<QueryEndedPayload>(
|
export const queryStreamUpdatedAction = actionCreatorFactory<QueryEndedPayload>(
|
||||||
'explore/QUERY_STREAM_UPDATED'
|
'explore/QUERY_STREAM_UPDATED'
|
||||||
).create();
|
).create();
|
||||||
@ -389,9 +371,6 @@ export const toggleLogLevelAction = actionCreatorFactory<ToggleLogLevelPayload>(
|
|||||||
*/
|
*/
|
||||||
export const resetExploreAction = actionCreatorFactory<ResetExplorePayload>('explore/RESET_EXPLORE').create();
|
export const resetExploreAction = actionCreatorFactory<ResetExplorePayload>('explore/RESET_EXPLORE').create();
|
||||||
export const queriesImportedAction = actionCreatorFactory<QueriesImportedPayload>('explore/QueriesImported').create();
|
export const queriesImportedAction = actionCreatorFactory<QueriesImportedPayload>('explore/QueriesImported').create();
|
||||||
export const loadExploreDatasources = actionCreatorFactory<LoadExploreDataSourcesPayload>(
|
|
||||||
'explore/LOAD_EXPLORE_DATASOURCES'
|
|
||||||
).create();
|
|
||||||
|
|
||||||
export const historyUpdatedAction = actionCreatorFactory<HistoryUpdatedPayload>('explore/HISTORY_UPDATED').create();
|
export const historyUpdatedAction = actionCreatorFactory<HistoryUpdatedPayload>('explore/HISTORY_UPDATED').create();
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ describe('refreshExplore', () => {
|
|||||||
.givenThunk(refreshExplore)
|
.givenThunk(refreshExplore)
|
||||||
.whenThunkIsDispatched(exploreId);
|
.whenThunkIsDispatched(exploreId);
|
||||||
|
|
||||||
const initializeExplore = dispatchedActions[2] as ActionOf<InitializeExplorePayload>;
|
const initializeExplore = dispatchedActions[1] as ActionOf<InitializeExplorePayload>;
|
||||||
const { type, payload } = initializeExplore;
|
const { type, payload } = initializeExplore;
|
||||||
|
|
||||||
expect(type).toEqual(initializeExploreAction.type);
|
expect(type).toEqual(initializeExploreAction.type);
|
||||||
|
@ -29,7 +29,6 @@ import {
|
|||||||
AbsoluteTimeRange,
|
AbsoluteTimeRange,
|
||||||
DataQuery,
|
DataQuery,
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
DataSourceSelectItem,
|
|
||||||
dateTimeForTimeZone,
|
dateTimeForTimeZone,
|
||||||
isDateTime,
|
isDateTime,
|
||||||
LoadingState,
|
LoadingState,
|
||||||
@ -57,7 +56,6 @@ import {
|
|||||||
loadDatasourcePendingAction,
|
loadDatasourcePendingAction,
|
||||||
loadDatasourceReadyAction,
|
loadDatasourceReadyAction,
|
||||||
LoadDatasourceReadyPayload,
|
LoadDatasourceReadyPayload,
|
||||||
loadExploreDatasources,
|
|
||||||
modifyQueriesAction,
|
modifyQueriesAction,
|
||||||
queriesImportedAction,
|
queriesImportedAction,
|
||||||
queryStoreSubscriptionAction,
|
queryStoreSubscriptionAction,
|
||||||
@ -84,6 +82,7 @@ import { getTimeSrv, TimeSrv } from '../../dashboard/services/TimeSrv';
|
|||||||
import { preProcessPanelData, runRequest } from '../../dashboard/state/runRequest';
|
import { preProcessPanelData, runRequest } from '../../dashboard/state/runRequest';
|
||||||
import { PanelModel } from 'app/features/dashboard/state';
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
import { DataSourceSrv } from '@grafana/runtime';
|
import { DataSourceSrv } from '@grafana/runtime';
|
||||||
|
import { getExploreDatasources } from './selectors';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates UI state and save it to the URL
|
* Updates UI state and save it to the URL
|
||||||
@ -244,18 +243,7 @@ export function loadExploreDatasourcesAndSetDatasource(
|
|||||||
datasourceName: string
|
datasourceName: string
|
||||||
): ThunkResult<void> {
|
): ThunkResult<void> {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
const exploreDatasources: DataSourceSelectItem[] = getDatasourceSrv()
|
const exploreDatasources = getExploreDatasources();
|
||||||
.getExternal()
|
|
||||||
.map(
|
|
||||||
(ds: any) =>
|
|
||||||
({
|
|
||||||
value: ds.name,
|
|
||||||
name: ds.name,
|
|
||||||
meta: ds.meta,
|
|
||||||
} as DataSourceSelectItem)
|
|
||||||
);
|
|
||||||
|
|
||||||
dispatch(loadExploreDatasources({ exploreId, exploreDatasources }));
|
|
||||||
|
|
||||||
if (exploreDatasources.length >= 1) {
|
if (exploreDatasources.length >= 1) {
|
||||||
dispatch(changeDatasource(exploreId, datasourceName));
|
dispatch(changeDatasource(exploreId, datasourceName));
|
||||||
@ -320,6 +308,14 @@ export const loadDatasourceReady = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import queries from previous datasource if possible eg Loki and Prometheus have similar query language so the
|
||||||
|
* labels part can be reused to get similar data.
|
||||||
|
* @param exploreId
|
||||||
|
* @param queries
|
||||||
|
* @param sourceDataSource
|
||||||
|
* @param targetDataSource
|
||||||
|
*/
|
||||||
export function importQueries(
|
export function importQueries(
|
||||||
exploreId: ExploreId,
|
exploreId: ExploreId,
|
||||||
queries: DataQuery[],
|
queries: DataQuery[],
|
||||||
@ -464,6 +460,8 @@ export function runQueries(exploreId: ExploreId): ThunkResult<void> {
|
|||||||
// Side-effect: Saving history in localstorage
|
// Side-effect: Saving history in localstorage
|
||||||
const nextHistory = updateHistory(history, datasourceId, queries);
|
const nextHistory = updateHistory(history, datasourceId, queries);
|
||||||
dispatch(historyUpdatedAction({ exploreId, history: nextHistory }));
|
dispatch(historyUpdatedAction({ exploreId, history: nextHistory }));
|
||||||
|
|
||||||
|
// We save queries to the URL here so that only successfully run queries change the URL.
|
||||||
dispatch(stateSave());
|
dispatch(stateSave());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,6 +503,10 @@ const toRawTimeRange = (range: TimeRange): RawTimeRange => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save local redux state back to the URL. Should be called when there is some change that should affect the URL.
|
||||||
|
* Not all of the redux state is reflected in URL though.
|
||||||
|
*/
|
||||||
export const stateSave = (): ThunkResult<void> => {
|
export const stateSave = (): ThunkResult<void> => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const { left, right, split } = getState().explore;
|
const { left, right, split } = getState().explore;
|
||||||
@ -714,6 +716,11 @@ export const changeDedupStrategy = (exploreId: ExploreId, dedupStrategy: LogsDed
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reacts to changes in URL state that we need to sync back to our redux state. Checks the internal update variable
|
||||||
|
* to see which parts change and need to be synced.
|
||||||
|
* @param exploreId
|
||||||
|
*/
|
||||||
export function refreshExplore(exploreId: ExploreId): ThunkResult<void> {
|
export function refreshExplore(exploreId: ExploreId): ThunkResult<void> {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const itemState = getState().explore[exploreId];
|
const itemState = getState().explore[exploreId];
|
||||||
|
@ -90,15 +90,11 @@ describe('Explore item reducer', () => {
|
|||||||
const queryKeys: string[] = [];
|
const queryKeys: string[] = [];
|
||||||
const initalState: Partial<ExploreItemState> = {
|
const initalState: Partial<ExploreItemState> = {
|
||||||
datasourceInstance: null,
|
datasourceInstance: null,
|
||||||
StartPage: null,
|
|
||||||
showingStartPage: false,
|
|
||||||
queries,
|
queries,
|
||||||
queryKeys,
|
queryKeys,
|
||||||
};
|
};
|
||||||
const expectedState: any = {
|
const expectedState: any = {
|
||||||
datasourceInstance,
|
datasourceInstance,
|
||||||
StartPage,
|
|
||||||
showingStartPage: true,
|
|
||||||
queries,
|
queries,
|
||||||
queryKeys,
|
queryKeys,
|
||||||
graphResult: null,
|
graphResult: null,
|
||||||
|
@ -27,12 +27,10 @@ import {
|
|||||||
ActionTypes,
|
ActionTypes,
|
||||||
splitCloseAction,
|
splitCloseAction,
|
||||||
SplitCloseActionPayload,
|
SplitCloseActionPayload,
|
||||||
loadExploreDatasources,
|
|
||||||
historyUpdatedAction,
|
historyUpdatedAction,
|
||||||
changeModeAction,
|
changeModeAction,
|
||||||
setUrlReplacedAction,
|
setUrlReplacedAction,
|
||||||
scanStopAction,
|
scanStopAction,
|
||||||
queryStartAction,
|
|
||||||
changeRangeAction,
|
changeRangeAction,
|
||||||
clearOriginAction,
|
clearOriginAction,
|
||||||
addQueryRowAction,
|
addQueryRowAction,
|
||||||
@ -84,13 +82,11 @@ export const makeInitialUpdateState = (): ExploreUpdateState => ({
|
|||||||
* Returns a fresh Explore area state
|
* Returns a fresh Explore area state
|
||||||
*/
|
*/
|
||||||
export const makeExploreItemState = (): ExploreItemState => ({
|
export const makeExploreItemState = (): ExploreItemState => ({
|
||||||
StartPage: undefined,
|
|
||||||
containerWidth: 0,
|
containerWidth: 0,
|
||||||
datasourceInstance: null,
|
datasourceInstance: null,
|
||||||
requestedDatasourceName: null,
|
requestedDatasourceName: null,
|
||||||
datasourceLoading: null,
|
datasourceLoading: null,
|
||||||
datasourceMissing: false,
|
datasourceMissing: false,
|
||||||
exploreDatasources: [],
|
|
||||||
history: [],
|
history: [],
|
||||||
queries: [],
|
queries: [],
|
||||||
initialized: false,
|
initialized: false,
|
||||||
@ -229,7 +225,6 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
graphResult: null,
|
graphResult: null,
|
||||||
tableResult: null,
|
tableResult: null,
|
||||||
logsResult: null,
|
logsResult: null,
|
||||||
showingStartPage: Boolean(state.StartPage),
|
|
||||||
queryKeys: getQueryKeys(queries, state.datasourceInstance),
|
queryKeys: getQueryKeys(queries, state.datasourceInstance),
|
||||||
queryResponse: createEmptyQueryResponse(),
|
queryResponse: createEmptyQueryResponse(),
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -277,7 +272,6 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
const { datasourceInstance, version } = action.payload;
|
const { datasourceInstance, version } = action.payload;
|
||||||
|
|
||||||
// Custom components
|
// Custom components
|
||||||
const StartPage = datasourceInstance.components.ExploreStartPage;
|
|
||||||
stopQueryState(state.querySubscription);
|
stopQueryState(state.querySubscription);
|
||||||
|
|
||||||
let newMetadata = datasourceInstance.meta;
|
let newMetadata = datasourceInstance.meta;
|
||||||
@ -308,8 +302,6 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
latency: 0,
|
latency: 0,
|
||||||
queryResponse: createEmptyQueryResponse(),
|
queryResponse: createEmptyQueryResponse(),
|
||||||
loading: false,
|
loading: false,
|
||||||
StartPage: datasourceInstance.components.ExploreStartPage,
|
|
||||||
showingStartPage: Boolean(StartPage),
|
|
||||||
queryKeys: [],
|
queryKeys: [],
|
||||||
supportedModes,
|
supportedModes,
|
||||||
mode,
|
mode,
|
||||||
@ -382,22 +374,6 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.addMapper({
|
|
||||||
filter: queryStartAction,
|
|
||||||
mapper: (state): ExploreItemState => {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
latency: 0,
|
|
||||||
queryResponse: {
|
|
||||||
...state.queryResponse,
|
|
||||||
state: LoadingState.Loading,
|
|
||||||
error: null,
|
|
||||||
},
|
|
||||||
loading: true,
|
|
||||||
update: makeInitialUpdateState(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.addMapper({
|
.addMapper({
|
||||||
filter: removeQueryRowAction,
|
filter: removeQueryRowAction,
|
||||||
mapper: (state, action): ExploreItemState => {
|
mapper: (state, action): ExploreItemState => {
|
||||||
@ -496,15 +472,6 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.addMapper({
|
|
||||||
filter: loadExploreDatasources,
|
|
||||||
mapper: (state, action): ExploreItemState => {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
exploreDatasources: action.payload.exploreDatasources,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.addMapper({
|
.addMapper({
|
||||||
filter: historyUpdatedAction,
|
filter: historyUpdatedAction,
|
||||||
mapper: (state, action): ExploreItemState => {
|
mapper: (state, action): ExploreItemState => {
|
||||||
@ -599,7 +566,6 @@ export const processQueryResponse = (
|
|||||||
graphResult: null,
|
graphResult: null,
|
||||||
tableResult: null,
|
tableResult: null,
|
||||||
logsResult: null,
|
logsResult: null,
|
||||||
showingStartPage: false,
|
|
||||||
update: makeInitialUpdateState(),
|
update: makeInitialUpdateState(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -625,7 +591,6 @@ export const processQueryResponse = (
|
|||||||
tableResult,
|
tableResult,
|
||||||
logsResult,
|
logsResult,
|
||||||
loading: loadingState === LoadingState.Loading || loadingState === LoadingState.Streaming,
|
loading: loadingState === LoadingState.Loading || loadingState === LoadingState.Streaming,
|
||||||
showingStartPage: false,
|
|
||||||
update: makeInitialUpdateState(),
|
update: makeInitialUpdateState(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { ExploreItemState } from 'app/types';
|
import { ExploreItemState } from 'app/types';
|
||||||
import { filterLogLevels, dedupLogRows } from 'app/core/logs_model';
|
import { filterLogLevels, dedupLogRows } from 'app/core/logs_model';
|
||||||
|
import { getDatasourceSrv } from '../../plugins/datasource_srv';
|
||||||
|
import { DataSourceSelectItem } from '@grafana/data';
|
||||||
|
|
||||||
const logsRowsSelector = (state: ExploreItemState) => state.logsResult && state.logsResult.rows;
|
const logsRowsSelector = (state: ExploreItemState) => state.logsResult && state.logsResult.rows;
|
||||||
const hiddenLogLevelsSelector = (state: ExploreItemState) => state.hiddenLogLevels;
|
const hiddenLogLevelsSelector = (state: ExploreItemState) => state.hiddenLogLevels;
|
||||||
@ -17,3 +19,16 @@ export const deduplicatedRowsSelector = createSelector(
|
|||||||
return dedupLogRows(filteredRows, dedupStrategy);
|
return dedupLogRows(filteredRows, dedupStrategy);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const getExploreDatasources = (): DataSourceSelectItem[] => {
|
||||||
|
return getDatasourceSrv()
|
||||||
|
.getExternal()
|
||||||
|
.map(
|
||||||
|
(ds: any) =>
|
||||||
|
({
|
||||||
|
value: ds.name,
|
||||||
|
name: ds.name,
|
||||||
|
meta: ds.meta,
|
||||||
|
} as DataSourceSelectItem)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
import { Unsubscribable } from 'rxjs';
|
import { Unsubscribable } from 'rxjs';
|
||||||
import { ComponentType } from 'react';
|
|
||||||
import {
|
import {
|
||||||
HistoryItem,
|
HistoryItem,
|
||||||
DataQuery,
|
DataQuery,
|
||||||
DataSourceSelectItem,
|
|
||||||
DataSourceApi,
|
DataSourceApi,
|
||||||
QueryHint,
|
QueryHint,
|
||||||
ExploreStartPageProps,
|
|
||||||
PanelData,
|
PanelData,
|
||||||
DataQueryRequest,
|
DataQueryRequest,
|
||||||
RawTimeRange,
|
RawTimeRange,
|
||||||
@ -54,10 +51,6 @@ export interface ExploreState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ExploreItemState {
|
export interface ExploreItemState {
|
||||||
/**
|
|
||||||
* React component to be shown when no queries have been run yet, e.g., for a query language cheat sheet.
|
|
||||||
*/
|
|
||||||
StartPage?: ComponentType<ExploreStartPageProps>;
|
|
||||||
/**
|
/**
|
||||||
* Width used for calculating the graph interval (can't have more datapoints than pixels)
|
* Width used for calculating the graph interval (can't have more datapoints than pixels)
|
||||||
*/
|
*/
|
||||||
@ -82,10 +75,6 @@ export interface ExploreItemState {
|
|||||||
* Emitter to send events to the rest of Grafana.
|
* Emitter to send events to the rest of Grafana.
|
||||||
*/
|
*/
|
||||||
eventBridge?: Emitter;
|
eventBridge?: Emitter;
|
||||||
/**
|
|
||||||
* List of datasources to be shown in the datasource selector.
|
|
||||||
*/
|
|
||||||
exploreDatasources: DataSourceSelectItem[];
|
|
||||||
/**
|
/**
|
||||||
* List of timeseries to be shown in the Explore graph result viewer.
|
* List of timeseries to be shown in the Explore graph result viewer.
|
||||||
*/
|
*/
|
||||||
@ -132,10 +121,6 @@ export interface ExploreItemState {
|
|||||||
* True if graph result viewer is expanded. Query runs will contain graph queries.
|
* True if graph result viewer is expanded. Query runs will contain graph queries.
|
||||||
*/
|
*/
|
||||||
showingGraph: boolean;
|
showingGraph: boolean;
|
||||||
/**
|
|
||||||
* True StartPage needs to be shown. Typically set to `false` once queries have been run.
|
|
||||||
*/
|
|
||||||
showingStartPage?: boolean;
|
|
||||||
/**
|
/**
|
||||||
* True if table result viewer is expanded. Query runs will contain table queries.
|
* True if table result viewer is expanded. Query runs will contain table queries.
|
||||||
*/
|
*/
|
||||||
@ -167,8 +152,15 @@ export interface ExploreItemState {
|
|||||||
*/
|
*/
|
||||||
refreshInterval?: string;
|
refreshInterval?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy of the state of the URL which is in store.location.query. This is duplicated here so we can diff the two
|
||||||
|
* after a change to see if we need to sync url state back to redux store (like on clicking Back in browser).
|
||||||
|
*/
|
||||||
urlState: ExploreUrlState;
|
urlState: ExploreUrlState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of what changed between real url and local urlState so we can partially update just the things that are needed.
|
||||||
|
*/
|
||||||
update: ExploreUpdateState;
|
update: ExploreUpdateState;
|
||||||
|
|
||||||
latency: number;
|
latency: number;
|
||||||
@ -189,6 +181,11 @@ export interface ExploreItemState {
|
|||||||
querySubscription?: Unsubscribable;
|
querySubscription?: Unsubscribable;
|
||||||
|
|
||||||
queryResponse: PanelData;
|
queryResponse: PanelData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel Id that is set if we come to explore from a penel. Used so we can get back to it and optionally modify the
|
||||||
|
* query of that panel.
|
||||||
|
*/
|
||||||
originPanelId?: number;
|
originPanelId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,11 +214,6 @@ export interface ExploreUrlState {
|
|||||||
context?: string;
|
context?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QueryIntervals {
|
|
||||||
interval: string;
|
|
||||||
intervalMs: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface QueryOptions {
|
export interface QueryOptions {
|
||||||
minInterval: string;
|
minInterval: string;
|
||||||
maxDataPoints?: number;
|
maxDataPoints?: number;
|
||||||
|
Loading…
Reference in New Issue
Block a user