D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
usr
/
share
/
grafana
/
public
/
app
/
features
/
explore
/
state
/
Filename :
datasource.ts
back
Copy
// Libraries import { AnyAction, createAction } from '@reduxjs/toolkit'; import { DataSourceApi, HistoryItem } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; import { DataSourceRef } from '@grafana/schema'; import { RefreshPicker } from '@grafana/ui'; import { stopQueryState } from 'app/core/utils/explore'; import { getCorrelationsBySourceUIDs } from 'app/features/correlations/utils'; import { ExploreItemState, ThunkResult } from 'app/types'; import { loadSupplementaryQueries } from '../utils/supplementaryQueries'; import { saveCorrelationsAction } from './explorePane'; import { importQueries, runQueries } from './query'; import { changeRefreshInterval } from './time'; import { createEmptyQueryResponse, getDatasourceUIDs, loadAndInitDatasource } from './utils'; // // Actions and Payloads // /** * Updates datasource instance before datasource loading has started */ export interface UpdateDatasourceInstancePayload { exploreId: string; 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: string, datasource: string | DataSourceRef, options?: { importQueries: boolean } ): ThunkResult<Promise<void>> { return async (dispatch, getState) => { const orgId = getState().user.orgId; const { history, instance } = await loadAndInitDatasource(orgId, datasource); const currentDataSourceInstance = getState().explore.panes[exploreId]!.datasourceInstance; reportInteraction('explore_change_ds', { from: (currentDataSourceInstance?.meta?.mixed ? 'mixed' : currentDataSourceInstance?.type) || 'unknown', to: instance.meta.mixed ? 'mixed' : instance.type, exploreId, }); dispatch( updateDatasourceInstanceAction({ exploreId, datasourceInstance: instance, history, }) ); const queries = getState().explore.panes[exploreId]!.queries; const datasourceUIDs = getDatasourceUIDs(instance.uid, queries); const correlations = await getCorrelationsBySourceUIDs(datasourceUIDs); dispatch(saveCorrelationsAction({ exploreId: exploreId, correlations: correlations.correlations || [] })); if (options?.importQueries) { await dispatch(importQueries(exploreId, queries, currentDataSourceInstance, instance)); } if (getState().explore.panes[exploreId]!.isLive) { dispatch(changeRefreshInterval({ exploreId, refreshInterval: 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, supplementaryQueries: loadSupplementaryQueries(), queryResponse: createEmptyQueryResponse(), queryKeys: [], history, }; } return state; };