grafana/public/app/features/explore/state/datasource.ts
Piotr Jamróz 8939636492
Loki: Logs volume improvements (#40327)
* Skip logfmt errors

* Run volume queries as range queries

* Remove auto-skipping parsing errors

* Remove auto-skipping parsing errors

* Cache logs volume results

* Remove auto-loading

* Fix tests

* Clean up

* Disable logs volume in live streaming

* Clean up

* Add logs volume timeout

* Switch tooltip mode

* Increase timeout to 15s

* Fix test

* Change timeout to 10 seconds

* Remove unused code

* Extract styles

* Remove info about zoom level
2021-10-18 12:22:41 +02:00

107 lines
3.2 KiB
TypeScript

// Libraries
import { AnyAction, createAction } from '@reduxjs/toolkit';
import { RefreshPicker } from '@grafana/ui';
import { DataSourceApi, HistoryItem } from '@grafana/data';
import { stopQueryState } from 'app/core/utils/explore';
import { ExploreItemState, ThunkResult } from 'app/types';
import { ExploreId } from 'app/types/explore';
import { importQueries, runQueries } from './query';
import { changeRefreshInterval } from './time';
import { createEmptyQueryResponse, loadAndInitDatasource } from './utils';
//
// Actions and Payloads
//
/**
* Updates datasource instance before datasource loading has started
*/
export interface UpdateDatasourceInstancePayload {
exploreId: ExploreId;
datasourceInstance: DataSourceApi;
history: HistoryItem[];
}
export const updateDatasourceInstanceAction = createAction<UpdateDatasourceInstancePayload>(
'explore/updateDatasourceInstance'
);
//
// Action creators
//
/**
* Loads a new datasource identified by the given name.
*/
export function changeDatasource(
exploreId: ExploreId,
datasourceUid: string,
options?: { importQueries: boolean }
): ThunkResult<void> {
return async (dispatch, getState) => {
const orgId = getState().user.orgId;
const { history, instance } = await loadAndInitDatasource(orgId, datasourceUid);
const currentDataSourceInstance = getState().explore[exploreId]!.datasourceInstance;
dispatch(
updateDatasourceInstanceAction({
exploreId,
datasourceInstance: instance,
history,
})
);
if (options?.importQueries) {
const queries = getState().explore[exploreId]!.queries;
await dispatch(importQueries(exploreId, queries, currentDataSourceInstance, instance));
}
if (getState().explore[exploreId]!.isLive) {
dispatch(changeRefreshInterval(exploreId, RefreshPicker.offOption.value));
}
// Exception - we only want to run queries on data source change, if the queries were imported
if (options?.importQueries) {
dispatch(runQueries(exploreId));
}
};
}
//
// Reducer
//
/**
* Reducer for an Explore area, to be used by the global Explore reducer.
*/
// Redux Toolkit uses ImmerJs as part of their solution to ensure that state objects are not mutated.
// ImmerJs has an autoFreeze option that freezes objects from change which means this reducer can't be migrated to createSlice
// because the state would become frozen and during run time we would get errors because flot (Graph lib) would try to mutate
// the frozen state.
// https://github.com/reduxjs/redux-toolkit/issues/242
export const datasourceReducer = (state: ExploreItemState, action: AnyAction): ExploreItemState => {
if (updateDatasourceInstanceAction.match(action)) {
const { datasourceInstance, history } = action.payload;
// Custom components
stopQueryState(state.querySubscription);
return {
...state,
datasourceInstance,
graphResult: null,
tableResult: null,
logsResult: null,
logsVolumeDataProvider: undefined,
logsVolumeData: undefined,
queryResponse: createEmptyQueryResponse(),
loading: false,
queryKeys: [],
history,
datasourceMissing: false,
};
}
return state;
};