mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #15306 from grafana/explore/dedup-strategu-url
Persist deduplication strategy in url
This commit is contained in:
commit
a79bd42414
@ -8,6 +8,7 @@ import {
|
|||||||
} from './explore';
|
} from './explore';
|
||||||
import { ExploreUrlState } from 'app/types/explore';
|
import { ExploreUrlState } from 'app/types/explore';
|
||||||
import store from 'app/core/store';
|
import store from 'app/core/store';
|
||||||
|
import { LogsDedupStrategy } from 'app/core/logs_model';
|
||||||
|
|
||||||
const DEFAULT_EXPLORE_STATE: ExploreUrlState = {
|
const DEFAULT_EXPLORE_STATE: ExploreUrlState = {
|
||||||
datasource: null,
|
datasource: null,
|
||||||
@ -17,6 +18,7 @@ const DEFAULT_EXPLORE_STATE: ExploreUrlState = {
|
|||||||
showingGraph: true,
|
showingGraph: true,
|
||||||
showingTable: true,
|
showingTable: true,
|
||||||
showingLogs: true,
|
showingLogs: true,
|
||||||
|
dedupStrategy: LogsDedupStrategy.none,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,7 +80,7 @@ describe('state functions', () => {
|
|||||||
expect(serializeStateToUrlParam(state)).toBe(
|
expect(serializeStateToUrlParam(state)).toBe(
|
||||||
'{"datasource":"foo","queries":[{"expr":"metric{test=\\"a/b\\"}"},' +
|
'{"datasource":"foo","queries":[{"expr":"metric{test=\\"a/b\\"}"},' +
|
||||||
'{"expr":"super{foo=\\"x/z\\"}"}],"range":{"from":"now-5h","to":"now"},' +
|
'{"expr":"super{foo=\\"x/z\\"}"}],"range":{"from":"now-5h","to":"now"},' +
|
||||||
'"ui":{"showingGraph":true,"showingTable":true,"showingLogs":true}}'
|
'"ui":{"showingGraph":true,"showingTable":true,"showingLogs":true,"dedupStrategy":"none"}}'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ describe('state functions', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(serializeStateToUrlParam(state, true)).toBe(
|
expect(serializeStateToUrlParam(state, true)).toBe(
|
||||||
'["now-5h","now","foo",{"expr":"metric{test=\\"a/b\\"}"},{"expr":"super{foo=\\"x/z\\"}"},{"ui":[true,true,true]}]'
|
'["now-5h","now","foo",{"expr":"metric{test=\\"a/b\\"}"},{"expr":"super{foo=\\"x/z\\"}"},{"ui":[true,true,true,"none"]}]'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
QueryIntervals,
|
QueryIntervals,
|
||||||
QueryOptions,
|
QueryOptions,
|
||||||
} from 'app/types/explore';
|
} from 'app/types/explore';
|
||||||
|
import { LogsDedupStrategy } from 'app/core/logs_model';
|
||||||
|
|
||||||
export const DEFAULT_RANGE = {
|
export const DEFAULT_RANGE = {
|
||||||
from: 'now-6h',
|
from: 'now-6h',
|
||||||
@ -31,6 +32,7 @@ export const DEFAULT_UI_STATE = {
|
|||||||
showingTable: true,
|
showingTable: true,
|
||||||
showingGraph: true,
|
showingGraph: true,
|
||||||
showingLogs: true,
|
showingLogs: true,
|
||||||
|
dedupStrategy: LogsDedupStrategy.none,
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAX_HISTORY_ITEMS = 100;
|
const MAX_HISTORY_ITEMS = 100;
|
||||||
@ -183,6 +185,7 @@ export function parseUrlState(initial: string | undefined): ExploreUrlState {
|
|||||||
showingGraph: segment.ui[0],
|
showingGraph: segment.ui[0],
|
||||||
showingLogs: segment.ui[1],
|
showingLogs: segment.ui[1],
|
||||||
showingTable: segment.ui[2],
|
showingTable: segment.ui[2],
|
||||||
|
dedupStrategy: segment.ui[3],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -204,7 +207,7 @@ export function serializeStateToUrlParam(urlState: ExploreUrlState, compact?: bo
|
|||||||
urlState.range.to,
|
urlState.range.to,
|
||||||
urlState.datasource,
|
urlState.datasource,
|
||||||
...urlState.queries,
|
...urlState.queries,
|
||||||
{ ui: [!!urlState.ui.showingGraph, !!urlState.ui.showingLogs, !!urlState.ui.showingTable] },
|
{ ui: [!!urlState.ui.showingGraph, !!urlState.ui.showingLogs, !!urlState.ui.showingTable, urlState.ui.dedupStrategy] },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return JSON.stringify(urlState);
|
return JSON.stringify(urlState);
|
||||||
|
@ -25,7 +25,7 @@ interface GraphContainerProps {
|
|||||||
|
|
||||||
export class GraphContainer extends PureComponent<GraphContainerProps> {
|
export class GraphContainer extends PureComponent<GraphContainerProps> {
|
||||||
onClickGraphButton = () => {
|
onClickGraphButton = () => {
|
||||||
this.props.toggleGraph(this.props.exploreId);
|
this.props.toggleGraph(this.props.exploreId, this.props.showingGraph);
|
||||||
};
|
};
|
||||||
|
|
||||||
onChangeTime = (timeRange: TimeRange) => {
|
onChangeTime = (timeRange: TimeRange) => {
|
||||||
|
@ -58,14 +58,15 @@ interface Props {
|
|||||||
range?: RawTimeRange;
|
range?: RawTimeRange;
|
||||||
scanning?: boolean;
|
scanning?: boolean;
|
||||||
scanRange?: RawTimeRange;
|
scanRange?: RawTimeRange;
|
||||||
|
dedupStrategy: LogsDedupStrategy;
|
||||||
onChangeTime?: (range: RawTimeRange) => void;
|
onChangeTime?: (range: RawTimeRange) => void;
|
||||||
onClickLabel?: (label: string, value: string) => void;
|
onClickLabel?: (label: string, value: string) => void;
|
||||||
onStartScanning?: () => void;
|
onStartScanning?: () => void;
|
||||||
onStopScanning?: () => void;
|
onStopScanning?: () => void;
|
||||||
|
onDedupStrategyChange: (dedupStrategy: LogsDedupStrategy) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
dedup: LogsDedupStrategy;
|
|
||||||
deferLogs: boolean;
|
deferLogs: boolean;
|
||||||
hiddenLogLevels: Set<LogLevel>;
|
hiddenLogLevels: Set<LogLevel>;
|
||||||
renderAll: boolean;
|
renderAll: boolean;
|
||||||
@ -79,7 +80,6 @@ export default class Logs extends PureComponent<Props, State> {
|
|||||||
renderAllTimer: NodeJS.Timer;
|
renderAllTimer: NodeJS.Timer;
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
dedup: LogsDedupStrategy.none,
|
|
||||||
deferLogs: true,
|
deferLogs: true,
|
||||||
hiddenLogLevels: new Set(),
|
hiddenLogLevels: new Set(),
|
||||||
renderAll: false,
|
renderAll: false,
|
||||||
@ -112,12 +112,11 @@ export default class Logs extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChangeDedup = (dedup: LogsDedupStrategy) => {
|
onChangeDedup = (dedup: LogsDedupStrategy) => {
|
||||||
this.setState(prevState => {
|
const { onDedupStrategyChange } = this.props;
|
||||||
if (prevState.dedup === dedup) {
|
if (this.props.dedupStrategy === dedup) {
|
||||||
return { dedup: LogsDedupStrategy.none };
|
return onDedupStrategyChange(LogsDedupStrategy.none);
|
||||||
}
|
}
|
||||||
return { dedup };
|
return onDedupStrategyChange(dedup);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onChangeLabels = (event: React.SyntheticEvent) => {
|
onChangeLabels = (event: React.SyntheticEvent) => {
|
||||||
@ -173,17 +172,19 @@ export default class Logs extends PureComponent<Props, State> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { dedup, deferLogs, hiddenLogLevels, renderAll, showLocalTime, showUtc } = this.state;
|
const { deferLogs, hiddenLogLevels, renderAll, showLocalTime, showUtc, } = this.state;
|
||||||
let { showLabels } = this.state;
|
let { showLabels } = this.state;
|
||||||
|
const { dedupStrategy } = this.props;
|
||||||
const hasData = data && data.rows && data.rows.length > 0;
|
const hasData = data && data.rows && data.rows.length > 0;
|
||||||
const showDuplicates = dedup !== LogsDedupStrategy.none;
|
const showDuplicates = dedupStrategy !== LogsDedupStrategy.none;
|
||||||
|
|
||||||
// Filtering
|
// Filtering
|
||||||
const filteredData = filterLogLevels(data, hiddenLogLevels);
|
const filteredData = filterLogLevels(data, hiddenLogLevels);
|
||||||
const dedupedData = dedupLogRows(filteredData, dedup);
|
const dedupedData = dedupLogRows(filteredData, dedupStrategy);
|
||||||
const dedupCount = dedupedData.rows.reduce((sum, row) => sum + row.duplicates, 0);
|
const dedupCount = dedupedData.rows.reduce((sum, row) => sum + row.duplicates, 0);
|
||||||
const meta = [...data.meta];
|
const meta = [...data.meta];
|
||||||
if (dedup !== LogsDedupStrategy.none) {
|
|
||||||
|
if (dedupStrategy !== LogsDedupStrategy.none) {
|
||||||
meta.push({
|
meta.push({
|
||||||
label: 'Dedup count',
|
label: 'Dedup count',
|
||||||
value: dedupCount,
|
value: dedupCount,
|
||||||
@ -236,7 +237,7 @@ export default class Logs extends PureComponent<Props, State> {
|
|||||||
key={i}
|
key={i}
|
||||||
value={dedupType}
|
value={dedupType}
|
||||||
onChange={this.onChangeDedup}
|
onChange={this.onChangeDedup}
|
||||||
selected={dedup === dedupType}
|
selected={dedupStrategy === dedupType}
|
||||||
tooltip={LogsDedupDescription[dedupType]}
|
tooltip={LogsDedupDescription[dedupType]}
|
||||||
>
|
>
|
||||||
{dedupType}
|
{dedupType}
|
||||||
|
@ -4,10 +4,10 @@ import { connect } from 'react-redux';
|
|||||||
import { RawTimeRange, TimeRange } from '@grafana/ui';
|
import { RawTimeRange, TimeRange } from '@grafana/ui';
|
||||||
|
|
||||||
import { ExploreId, ExploreItemState } from 'app/types/explore';
|
import { ExploreId, ExploreItemState } from 'app/types/explore';
|
||||||
import { LogsModel } from 'app/core/logs_model';
|
import { LogsModel, LogsDedupStrategy } from 'app/core/logs_model';
|
||||||
import { StoreState } from 'app/types';
|
import { StoreState } from 'app/types';
|
||||||
|
|
||||||
import { toggleLogs } from './state/actions';
|
import { toggleLogs, changeDedupStrategy } from './state/actions';
|
||||||
import Logs from './Logs';
|
import Logs from './Logs';
|
||||||
import Panel from './Panel';
|
import Panel from './Panel';
|
||||||
|
|
||||||
@ -25,12 +25,18 @@ interface LogsContainerProps {
|
|||||||
scanRange?: RawTimeRange;
|
scanRange?: RawTimeRange;
|
||||||
showingLogs: boolean;
|
showingLogs: boolean;
|
||||||
toggleLogs: typeof toggleLogs;
|
toggleLogs: typeof toggleLogs;
|
||||||
|
changeDedupStrategy: typeof changeDedupStrategy;
|
||||||
|
dedupStrategy: LogsDedupStrategy;
|
||||||
width: number;
|
width: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LogsContainer extends PureComponent<LogsContainerProps> {
|
export class LogsContainer extends PureComponent<LogsContainerProps> {
|
||||||
onClickLogsButton = () => {
|
onClickLogsButton = () => {
|
||||||
this.props.toggleLogs(this.props.exploreId);
|
this.props.toggleLogs(this.props.exploreId, this.props.showingLogs);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleDedupStrategyChange = (dedupStrategy: LogsDedupStrategy) => {
|
||||||
|
this.props.changeDedupStrategy(this.props.exploreId, dedupStrategy);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -53,6 +59,7 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
|
|||||||
return (
|
return (
|
||||||
<Panel label="Logs" loading={loading} isOpen={showingLogs} onToggle={this.onClickLogsButton}>
|
<Panel label="Logs" loading={loading} isOpen={showingLogs} onToggle={this.onClickLogsButton}>
|
||||||
<Logs
|
<Logs
|
||||||
|
dedupStrategy={this.props.dedupStrategy || LogsDedupStrategy.none}
|
||||||
data={logsResult}
|
data={logsResult}
|
||||||
exploreId={exploreId}
|
exploreId={exploreId}
|
||||||
key={logsResult && logsResult.id}
|
key={logsResult && logsResult.id}
|
||||||
@ -62,6 +69,7 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
|
|||||||
onClickLabel={onClickLabel}
|
onClickLabel={onClickLabel}
|
||||||
onStartScanning={onStartScanning}
|
onStartScanning={onStartScanning}
|
||||||
onStopScanning={onStopScanning}
|
onStopScanning={onStopScanning}
|
||||||
|
onDedupStrategyChange={this.handleDedupStrategyChange}
|
||||||
range={range}
|
range={range}
|
||||||
scanning={scanning}
|
scanning={scanning}
|
||||||
scanRange={scanRange}
|
scanRange={scanRange}
|
||||||
@ -72,11 +80,23 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectItemUIState = (itemState: ExploreItemState) => {
|
||||||
|
const { showingGraph, showingLogs, showingTable, showingStartPage, dedupStrategy } = itemState;
|
||||||
|
return {
|
||||||
|
showingGraph,
|
||||||
|
showingLogs,
|
||||||
|
showingTable,
|
||||||
|
showingStartPage,
|
||||||
|
dedupStrategy,
|
||||||
|
};
|
||||||
|
};
|
||||||
function mapStateToProps(state: StoreState, { exploreId }) {
|
function mapStateToProps(state: StoreState, { exploreId }) {
|
||||||
const explore = state.explore;
|
const explore = state.explore;
|
||||||
const item: ExploreItemState = explore[exploreId];
|
const item: ExploreItemState = explore[exploreId];
|
||||||
const { logsHighlighterExpressions, logsResult, queryTransactions, scanning, scanRange, showingLogs, range } = item;
|
const { logsHighlighterExpressions, logsResult, queryTransactions, scanning, scanRange, range } = item;
|
||||||
const loading = queryTransactions.some(qt => qt.resultType === 'Logs' && !qt.done);
|
const loading = queryTransactions.some(qt => qt.resultType === 'Logs' && !qt.done);
|
||||||
|
const {showingLogs, dedupStrategy} = selectItemUIState(item);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
loading,
|
loading,
|
||||||
logsHighlighterExpressions,
|
logsHighlighterExpressions,
|
||||||
@ -85,11 +105,13 @@ function mapStateToProps(state: StoreState, { exploreId }) {
|
|||||||
scanRange,
|
scanRange,
|
||||||
showingLogs,
|
showingLogs,
|
||||||
range,
|
range,
|
||||||
|
dedupStrategy,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
toggleLogs,
|
toggleLogs,
|
||||||
|
changeDedupStrategy,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(LogsContainer));
|
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(LogsContainer));
|
||||||
|
@ -21,7 +21,7 @@ interface TableContainerProps {
|
|||||||
|
|
||||||
export class TableContainer extends PureComponent<TableContainerProps> {
|
export class TableContainer extends PureComponent<TableContainerProps> {
|
||||||
onClickTableButton = () => {
|
onClickTableButton = () => {
|
||||||
this.props.toggleTable(this.props.exploreId);
|
this.props.toggleTable(this.props.exploreId, this.props.showingTable);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -192,6 +192,10 @@ export interface ToggleLogsPayload {
|
|||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdateUIStatePayload extends Partial<ExploreUIState>{
|
||||||
|
exploreId: ExploreId;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UpdateDatasourceInstancePayload {
|
export interface UpdateDatasourceInstancePayload {
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
datasourceInstance: DataSourceApi;
|
datasourceInstance: DataSourceApi;
|
||||||
@ -366,6 +370,11 @@ export const splitCloseAction = noPayloadActionCreatorFactory('explore/SPLIT_CLO
|
|||||||
export const splitOpenAction = actionCreatorFactory<SplitOpenPayload>('explore/SPLIT_OPEN').create();
|
export const splitOpenAction = actionCreatorFactory<SplitOpenPayload>('explore/SPLIT_OPEN').create();
|
||||||
export const stateSaveAction = noPayloadActionCreatorFactory('explore/STATE_SAVE').create();
|
export const stateSaveAction = noPayloadActionCreatorFactory('explore/STATE_SAVE').create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update state of Explores UI elements (panels visiblity and deduplication strategy)
|
||||||
|
*/
|
||||||
|
export const updateUIStateAction = actionCreatorFactory<UpdateUIStatePayload>('explore/UPDATE_UI_STATE').create();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand/collapse the table result viewer. When collapsed, table queries won't be run.
|
* Expand/collapse the table result viewer. When collapsed, table queries won't be run.
|
||||||
*/
|
*/
|
||||||
|
@ -67,14 +67,26 @@ import {
|
|||||||
ToggleGraphPayload,
|
ToggleGraphPayload,
|
||||||
ToggleLogsPayload,
|
ToggleLogsPayload,
|
||||||
ToggleTablePayload,
|
ToggleTablePayload,
|
||||||
|
updateUIStateAction,
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
import { ActionOf, ActionCreator } from 'app/core/redux/actionCreatorFactory';
|
import { ActionOf, ActionCreator } from 'app/core/redux/actionCreatorFactory';
|
||||||
|
import { LogsDedupStrategy } from 'app/core/logs_model';
|
||||||
|
|
||||||
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action>;
|
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action>;
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Adds a query row after the row with the given index.
|
* Updates UI state and save it to the URL
|
||||||
// */
|
*/
|
||||||
|
const updateExploreUIState = (exploreId, uiStateFragment: Partial<ExploreUIState>) => {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch(updateUIStateAction({ exploreId, ...uiStateFragment }));
|
||||||
|
dispatch(stateSave());
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a query row after the row with the given index.
|
||||||
|
*/
|
||||||
export function addQueryRow(exploreId: ExploreId, index: number): ActionOf<AddQueryRowPayload> {
|
export function addQueryRow(exploreId: ExploreId, index: number): ActionOf<AddQueryRowPayload> {
|
||||||
const query = generateEmptyQuery(index + 1);
|
const query = generateEmptyQuery(index + 1);
|
||||||
return addQueryRowAction({ exploreId, index, query });
|
return addQueryRowAction({ exploreId, index, query });
|
||||||
@ -669,6 +681,7 @@ export function stateSave() {
|
|||||||
showingGraph: left.showingGraph,
|
showingGraph: left.showingGraph,
|
||||||
showingLogs: left.showingLogs,
|
showingLogs: left.showingLogs,
|
||||||
showingTable: left.showingTable,
|
showingTable: left.showingTable,
|
||||||
|
dedupStrategy: left.dedupStrategy,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
urlStates.left = serializeStateToUrlParam(leftUrlState, true);
|
urlStates.left = serializeStateToUrlParam(leftUrlState, true);
|
||||||
@ -677,7 +690,12 @@ export function stateSave() {
|
|||||||
datasource: right.datasourceInstance.name,
|
datasource: right.datasourceInstance.name,
|
||||||
queries: right.queries.map(clearQueryKeys),
|
queries: right.queries.map(clearQueryKeys),
|
||||||
range: right.range,
|
range: right.range,
|
||||||
ui: { showingGraph: right.showingGraph, showingLogs: right.showingLogs, showingTable: right.showingTable },
|
ui: {
|
||||||
|
showingGraph: right.showingGraph,
|
||||||
|
showingLogs: right.showingLogs,
|
||||||
|
showingTable: right.showingTable,
|
||||||
|
dedupStrategy: right.dedupStrategy,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
urlStates.right = serializeStateToUrlParam(rightUrlState, true);
|
urlStates.right = serializeStateToUrlParam(rightUrlState, true);
|
||||||
@ -696,24 +714,26 @@ const togglePanelActionCreator = (
|
|||||||
| ActionCreator<ToggleGraphPayload>
|
| ActionCreator<ToggleGraphPayload>
|
||||||
| ActionCreator<ToggleLogsPayload>
|
| ActionCreator<ToggleLogsPayload>
|
||||||
| ActionCreator<ToggleTablePayload>
|
| ActionCreator<ToggleTablePayload>
|
||||||
) => (exploreId: ExploreId) => {
|
) => (exploreId: ExploreId, isPanelVisible: boolean) => {
|
||||||
return (dispatch, getState) => {
|
return dispatch => {
|
||||||
let shouldRunQueries;
|
let uiFragmentStateUpdate: Partial<ExploreUIState>;
|
||||||
dispatch(actionCreator({ exploreId }));
|
const shouldRunQueries = !isPanelVisible;
|
||||||
dispatch(stateSave());
|
|
||||||
|
|
||||||
switch (actionCreator.type) {
|
switch (actionCreator.type) {
|
||||||
case toggleGraphAction.type:
|
case toggleGraphAction.type:
|
||||||
shouldRunQueries = getState().explore[exploreId].showingGraph;
|
uiFragmentStateUpdate = { showingGraph: !isPanelVisible };
|
||||||
break;
|
break;
|
||||||
case toggleLogsAction.type:
|
case toggleLogsAction.type:
|
||||||
shouldRunQueries = getState().explore[exploreId].showingLogs;
|
uiFragmentStateUpdate = { showingLogs: !isPanelVisible };
|
||||||
break;
|
break;
|
||||||
case toggleTableAction.type:
|
case toggleTableAction.type:
|
||||||
shouldRunQueries = getState().explore[exploreId].showingTable;
|
uiFragmentStateUpdate = { showingTable: !isPanelVisible };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch(actionCreator({ exploreId }));
|
||||||
|
dispatch(updateExploreUIState(exploreId, uiFragmentStateUpdate));
|
||||||
|
|
||||||
if (shouldRunQueries) {
|
if (shouldRunQueries) {
|
||||||
dispatch(runQueries(exploreId));
|
dispatch(runQueries(exploreId));
|
||||||
}
|
}
|
||||||
@ -734,3 +754,12 @@ export const toggleLogs = togglePanelActionCreator(toggleLogsAction);
|
|||||||
* Expand/collapse the table result viewer. When collapsed, table queries won't be run.
|
* Expand/collapse the table result viewer. When collapsed, table queries won't be run.
|
||||||
*/
|
*/
|
||||||
export const toggleTable = togglePanelActionCreator(toggleTableAction);
|
export const toggleTable = togglePanelActionCreator(toggleTableAction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change logs deduplication strategy and update URL.
|
||||||
|
*/
|
||||||
|
export const changeDedupStrategy = (exploreId, dedupStrategy: LogsDedupStrategy) => {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch(updateExploreUIState(exploreId, { dedupStrategy }));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -37,6 +37,7 @@ import {
|
|||||||
toggleLogsAction,
|
toggleLogsAction,
|
||||||
toggleTableAction,
|
toggleTableAction,
|
||||||
queriesImportedAction,
|
queriesImportedAction,
|
||||||
|
updateUIStateAction,
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
|
|
||||||
export const DEFAULT_RANGE = {
|
export const DEFAULT_RANGE = {
|
||||||
@ -406,6 +407,12 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
.addMapper({
|
||||||
|
filter: updateUIStateAction,
|
||||||
|
mapper: (state, action): ExploreItemState => {
|
||||||
|
return { ...state, ...action.payload };
|
||||||
|
},
|
||||||
|
})
|
||||||
.addMapper({
|
.addMapper({
|
||||||
filter: toggleGraphAction,
|
filter: toggleGraphAction,
|
||||||
mapper: (state): ExploreItemState => {
|
mapper: (state): ExploreItemState => {
|
||||||
@ -415,7 +422,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
// Discard transactions related to Graph query
|
// Discard transactions related to Graph query
|
||||||
nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Graph');
|
nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Graph');
|
||||||
}
|
}
|
||||||
return { ...state, queryTransactions: nextQueryTransactions, showingGraph };
|
return { ...state, queryTransactions: nextQueryTransactions };
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.addMapper({
|
.addMapper({
|
||||||
@ -427,7 +434,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
// Discard transactions related to Logs query
|
// Discard transactions related to Logs query
|
||||||
nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Logs');
|
nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Logs');
|
||||||
}
|
}
|
||||||
return { ...state, queryTransactions: nextQueryTransactions, showingLogs };
|
return { ...state, queryTransactions: nextQueryTransactions };
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.addMapper({
|
.addMapper({
|
||||||
@ -435,7 +442,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
mapper: (state): ExploreItemState => {
|
mapper: (state): ExploreItemState => {
|
||||||
const showingTable = !state.showingTable;
|
const showingTable = !state.showingTable;
|
||||||
if (showingTable) {
|
if (showingTable) {
|
||||||
return { ...state, showingTable, queryTransactions: state.queryTransactions };
|
return { ...state, queryTransactions: state.queryTransactions };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle off needs discarding of table queries and results
|
// Toggle off needs discarding of table queries and results
|
||||||
@ -446,7 +453,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
|
|||||||
state.queryIntervals.intervalMs
|
state.queryIntervals.intervalMs
|
||||||
);
|
);
|
||||||
|
|
||||||
return { ...state, ...results, queryTransactions: nextQueryTransactions, showingTable };
|
return { ...state, ...results, queryTransactions: nextQueryTransactions };
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.addMapper({
|
.addMapper({
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
jest.mock('app/core/core', () => ({}));
|
jest.mock('app/core/core', () => ({}));
|
||||||
jest.mock('app/core/config', () => {
|
jest.mock('app/core/config', () => {
|
||||||
return {
|
return {
|
||||||
|
bootData: {
|
||||||
|
user: {},
|
||||||
|
},
|
||||||
panels: {
|
panels: {
|
||||||
test: {
|
test: {
|
||||||
id: 'test',
|
id: 'test',
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
|
|
||||||
import { Emitter } from 'app/core/core';
|
import { Emitter } from 'app/core/core';
|
||||||
import { LogsModel } from 'app/core/logs_model';
|
import { LogsModel, LogsDedupStrategy } from 'app/core/logs_model';
|
||||||
import TableModel from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
|
|
||||||
export interface CompletionItem {
|
export interface CompletionItem {
|
||||||
@ -237,12 +237,18 @@ export interface ExploreItemState {
|
|||||||
* React keys for rendering of QueryRows
|
* React keys for rendering of QueryRows
|
||||||
*/
|
*/
|
||||||
queryKeys: string[];
|
queryKeys: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current logs deduplication strategy
|
||||||
|
*/
|
||||||
|
dedupStrategy?: LogsDedupStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExploreUIState {
|
export interface ExploreUIState {
|
||||||
showingTable: boolean;
|
showingTable: boolean;
|
||||||
showingGraph: boolean;
|
showingGraph: boolean;
|
||||||
showingLogs: boolean;
|
showingLogs: boolean;
|
||||||
|
dedupStrategy?: LogsDedupStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExploreUrlState {
|
export interface ExploreUrlState {
|
||||||
|
Loading…
Reference in New Issue
Block a user