{"version":3,"sources":["webpack:///./public/app/features/profile/state/selectors.ts","webpack:///./public/app/features/explore/state/selectors.ts","webpack:///./public/app/features/explore/state/actions.ts","webpack:///./public/app/core/utils/richHistory.ts"],"names":["getTimeZone","state","timeZone","deduplicatedRowsSelector","createSelector","logsResult","rows","hiddenLogLevels","dedupStrategy","length","filteredRows","filterLogLevels","Set","dedupLogRows","getExploreDatasources","getDatasourceSrv","getExternal","map","ds","value","name","meta","updateExploreUIState","exploreId","uiStateFragment","dispatch","updateUIStateAction","stateSave","addQueryRow","index","getState","queries","explore","query","generateEmptyQuery","addQueryRowAction","changeDatasource","datasourceName","get","newDataSourceInstance","currentDataSourceInstance","datasourceInstance","orgId","user","getVersion","datasourceVersion","prometheusToLoki","updateDatasourceInstanceAction","version","mode","ExploreMode","Logs","undefined","importQueries","isLive","changeRefreshInterval","RefreshPicker","offOption","loadDatasource","runQueries","changeMode","changeModeAction","changeQuery","override","refId","key","generateNewKeyAndAddRefIdIfMissing","changeQueryAction","changeSize","height","width","changeSizeAction","updateTimeRange","options","syncedTimes","updateTime","ExploreId","left","right","refreshInterval","changeRefreshIntervalAction","clearQueries","scanStopAction","clearQueriesAction","cancelQueries","cancelQueriesAction","loadExploreDatasourcesAndSetDatasource","loadDatasourceMissingAction","initializeExplore","range","containerWidth","eventBridge","ui","originPanelId","initializeExploreAction","richHistory","getRichHistory","richHistoryUpdatedAction","loadDatasourceReady","instance","historyKey","id","history","store","getObject","set","lastUsedDatasourceKeyForOrgId","loadDatasourceReadyAction","sourceDataSource","targetDataSource","queriesImportedAction","importedQueries","ensureQueries","nextQueries","loadDatasourcePendingAction","requestedDatasourceName","init","err","console","log","modifyQueries","modification","modifier","modifyQueriesAction","preventSubmit","exploreItemState","live","scanning","queryResponse","querySubscription","showingGraph","showingTable","hasNonEmptyQuery","minInterval","interval","stopQueryState","datasourceId","queryOptions","maxDataPoints","liveStreaming","transaction","buildQueryTransaction","firstResponse","changeLoadingStateAction","loadingState","LoadingState","Loading","newQuerySub","runRequest","request","pipe","throttleTime","identity","data","preProcessPanelData","subscribe","error","nextHistory","updateHistory","nextRichHistory","addToRichHistory","historyUpdatedAction","queryStreamUpdatedAction","response","Done","series","getShiftedTimeRange","absoluteRange","queryStoreSubscriptionAction","updateRichHistory","ts","property","updatedProperty","updateStarredInRichHistory","updateCommentInRichHistory","deleteQueryInRichHistory","deleteRichHistory","deleteAllFromRichHistory","toRawTimeRange","from","raw","isDateTime","valueOf","toString","to","split","replace","urlReplaced","urlStates","leftUrlState","datasource","clearQueryKeys","showingLogs","serializeStateToUrlParam","rightUrlState","updateLocation","setUrlReplacedAction","config","absRange","actionRange","rawRange","itemState","dateTimeForTimeZone","getTimeRange","getTimeSrv","time","refresh","getTimezone","timeRangeUpdated","changeRangeAction","scanStart","scanStartAction","setQueries","rawQueries","setQueriesAction","splitClose","itemId","splitCloseAction","splitOpen","leftState","rightState","queryState","location","urlState","parseUrlState","slice","splitOpenAction","dataSourceSettings","getDataSourceSettingsByUid","datasourceUid","syncTimes","isTimeSynced","syncTimesAction","togglePanelActionCreator","actionCreator","isPanelVisible","uiFragmentStateUpdate","shouldRunQueries","type","toggleGraphAction","toggleTableAction","toggleGraph","toggleTable","changeDedupStrategy","refreshExplore","initialized","update","urlRange","refreshQueries","push","getTimeRangeFromUrl","initialQueries","navigateToExplore","panel","dependencies","getDataSourceSrv","getExploreUrl","openInNewWindow","datasourceSrv","panelTargets","targets","panelDatasource","timeSrv","path","RICH_HISTORY_KEY","RICH_HISTORY_SETTING_KEYS","retentionPeriod","starredTabAsFirstTab","activeDatasourceOnly","datasourceFilters","starred","comment","sessionName","Date","now","newQueriesToSave","filter","strippedQuery","_","omit","Object","keys","notEmptyQuery","retentionPeriodLastTs","createRetentionPeriodBoundary","queriesToKeep","q","newQueriesToCompare","lastQueriesToCompare","isEqual","updatedHistory","setObject","appEvents","emit","AppEvents","alertError","transformedQueries","individualQuery","string","JSON","parse","e","isParsable","expr","createDataQuery","migrateRichHistory","delete","isStarred","assign","newComment","sortQueries","array","sortOrder","sortFunc","SortOrder","Ascending","a","b","Descending","DatasourceZA","DatasourceAZ","sort","copyStringToClipboard","el","document","createElement","body","appendChild","select","execCommand","removeChild","createUrlFromRichHistory","exploreState","Tracing","Metrics","context","serializedState","baseUrl","exec","window","href","urlUtil","renderUrl","mapNumbertoTimeInSlider","num","str","days","isLastTs","today","date","setDate","getDate","setHours","createQueryHeading","heading","dateTimeFormat","format","createQueryText","queryDsInstance","getQueryDisplayText","stringify","mapQueriesToHeadings","mappedQueriesToHeadings","forEach","createDatasourcesList","queriesDatasources","exploreDatasources","datasources","queryDsName","findIndex","exploreDs","label","imgUrl","info","logos","small","isRemoved"],"mappings":"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","file":"default~DashboardPage~SoloPanelPage~explore.d3489276abe5fda2bd26.js","sourcesContent":["import { UserState } from 'app/types';\n\nexport const getTimeZone = (state: UserState) => state.timeZone;\n","import { createSelector } from 'reselect';\nimport { ExploreItemState } from 'app/types';\nimport { filterLogLevels, dedupLogRows } from 'app/core/logs_model';\nimport { getDatasourceSrv } from '../../plugins/datasource_srv';\nimport { DataSourceSelectItem } from '@grafana/data';\n\nconst logsRowsSelector = (state: ExploreItemState) => state.logsResult && state.logsResult.rows;\nconst hiddenLogLevelsSelector = (state: ExploreItemState) => state.hiddenLogLevels;\nconst dedupStrategySelector = (state: ExploreItemState) => state.dedupStrategy;\nexport const deduplicatedRowsSelector = createSelector(\n logsRowsSelector,\n hiddenLogLevelsSelector,\n dedupStrategySelector,\n function dedupRows(rows, hiddenLogLevels, dedupStrategy) {\n if (!(rows && rows.length)) {\n return rows;\n }\n const filteredRows = filterLogLevels(rows, new Set(hiddenLogLevels));\n return dedupLogRows(filteredRows, dedupStrategy);\n }\n);\n\nexport const getExploreDatasources = (): DataSourceSelectItem[] => {\n return getDatasourceSrv()\n .getExternal()\n .map(\n (ds: any) =>\n ({\n value: ds.name,\n name: ds.name,\n meta: ds.meta,\n } as DataSourceSelectItem)\n );\n};\n","// Libraries\nimport { map, throttleTime } from 'rxjs/operators';\nimport { identity } from 'rxjs';\nimport { ActionCreatorWithPayload, PayloadAction } from '@reduxjs/toolkit';\nimport { DataSourceSrv } from '@grafana/runtime';\nimport { RefreshPicker } from '@grafana/ui';\nimport {\n AbsoluteTimeRange,\n DataQuery,\n DataSourceApi,\n dateTimeForTimeZone,\n isDateTime,\n LoadingState,\n LogsDedupStrategy,\n PanelData,\n QueryFixAction,\n RawTimeRange,\n TimeRange,\n ExploreMode,\n} from '@grafana/data';\n// Services & Utils\nimport store from 'app/core/store';\nimport { getDatasourceSrv } from 'app/features/plugins/datasource_srv';\nimport { Emitter } from 'app/core/core';\nimport {\n buildQueryTransaction,\n clearQueryKeys,\n ensureQueries,\n generateEmptyQuery,\n generateNewKeyAndAddRefIdIfMissing,\n GetExploreUrlArguments,\n getTimeRange,\n getTimeRangeFromUrl,\n hasNonEmptyQuery,\n lastUsedDatasourceKeyForOrgId,\n parseUrlState,\n serializeStateToUrlParam,\n stopQueryState,\n updateHistory,\n} from 'app/core/utils/explore';\nimport {\n addToRichHistory,\n deleteAllFromRichHistory,\n updateStarredInRichHistory,\n updateCommentInRichHistory,\n deleteQueryInRichHistory,\n getRichHistory,\n} from 'app/core/utils/richHistory';\n// Types\nimport { ExploreItemState, ExploreUrlState, ThunkResult } from 'app/types';\n\nimport { ExploreId, ExploreUIState, QueryOptions } from 'app/types/explore';\nimport {\n addQueryRowAction,\n changeModeAction,\n changeQueryAction,\n changeRangeAction,\n changeRefreshIntervalAction,\n ChangeRefreshIntervalPayload,\n changeSizeAction,\n ChangeSizePayload,\n clearQueriesAction,\n historyUpdatedAction,\n richHistoryUpdatedAction,\n initializeExploreAction,\n loadDatasourceMissingAction,\n loadDatasourcePendingAction,\n loadDatasourceReadyAction,\n LoadDatasourceReadyPayload,\n modifyQueriesAction,\n queriesImportedAction,\n queryStoreSubscriptionAction,\n queryStreamUpdatedAction,\n scanStartAction,\n scanStopAction,\n setQueriesAction,\n setUrlReplacedAction,\n splitCloseAction,\n splitOpenAction,\n syncTimesAction,\n toggleGraphAction,\n ToggleGraphPayload,\n toggleTableAction,\n ToggleTablePayload,\n updateDatasourceInstanceAction,\n updateUIStateAction,\n changeLoadingStateAction,\n cancelQueriesAction,\n} from './actionTypes';\nimport { getTimeZone } from 'app/features/profile/state/selectors';\nimport { getShiftedTimeRange } from 'app/core/utils/timePicker';\nimport { updateLocation } from '../../../core/actions';\nimport { getTimeSrv, TimeSrv } from '../../dashboard/services/TimeSrv';\nimport { preProcessPanelData, runRequest } from '../../dashboard/state/runRequest';\nimport { PanelModel } from 'app/features/dashboard/state';\nimport { getExploreDatasources } from './selectors';\n\n/**\n * Updates UI state and save it to the URL\n */\nconst updateExploreUIState = (exploreId: ExploreId, uiStateFragment: Partial<ExploreUIState>): ThunkResult<void> => {\n return dispatch => {\n dispatch(updateUIStateAction({ exploreId, ...uiStateFragment }));\n dispatch(stateSave());\n };\n};\n\n/**\n * Adds a query row after the row with the given index.\n */\nexport function addQueryRow(exploreId: ExploreId, index: number): ThunkResult<void> {\n return (dispatch, getState) => {\n const queries = getState().explore[exploreId].queries;\n const query = generateEmptyQuery(queries, index);\n\n dispatch(addQueryRowAction({ exploreId, index, query }));\n };\n}\n\n/**\n * Loads a new datasource identified by the given name.\n */\nexport function changeDatasource(exploreId: ExploreId, datasourceName: string): ThunkResult<void> {\n return async (dispatch, getState) => {\n let newDataSourceInstance: DataSourceApi;\n\n if (!datasourceName) {\n newDataSourceInstance = await getDatasourceSrv().get();\n } else {\n newDataSourceInstance = await getDatasourceSrv().get(datasourceName);\n }\n\n const currentDataSourceInstance = getState().explore[exploreId].datasourceInstance;\n const queries = getState().explore[exploreId].queries;\n const orgId = getState().user.orgId;\n const datasourceVersion = newDataSourceInstance.getVersion && (await newDataSourceInstance.getVersion());\n\n // HACK: Switch to logs mode if coming from Prometheus to Loki\n const prometheusToLoki =\n currentDataSourceInstance?.meta?.name === 'Prometheus' && newDataSourceInstance?.meta?.name === 'Loki';\n\n dispatch(\n updateDatasourceInstanceAction({\n exploreId,\n datasourceInstance: newDataSourceInstance,\n version: datasourceVersion,\n mode: prometheusToLoki ? ExploreMode.Logs : undefined,\n })\n );\n\n await dispatch(importQueries(exploreId, queries, currentDataSourceInstance, newDataSourceInstance));\n\n if (getState().explore[exploreId].isLive) {\n dispatch(changeRefreshInterval(exploreId, RefreshPicker.offOption.value));\n }\n\n await dispatch(loadDatasource(exploreId, newDataSourceInstance, orgId));\n dispatch(runQueries(exploreId));\n };\n}\n\n/**\n * Change the display mode in Explore.\n */\nexport function changeMode(exploreId: ExploreId, mode: ExploreMode): ThunkResult<void> {\n return dispatch => {\n dispatch(changeModeAction({ exploreId, mode }));\n };\n}\n\n/**\n * Query change handler for the query row with the given index.\n * If `override` is reset the query modifications and run the queries. Use this to set queries via a link.\n */\nexport function changeQuery(\n exploreId: ExploreId,\n query: DataQuery,\n index: number,\n override = false\n): ThunkResult<void> {\n return (dispatch, getState) => {\n // Null query means reset\n if (query === null) {\n const queries = getState().explore[exploreId].queries;\n const { refId, key } = queries[index];\n query = generateNewKeyAndAddRefIdIfMissing({ refId, key }, queries, index);\n }\n\n dispatch(changeQueryAction({ exploreId, query, index, override }));\n if (override) {\n dispatch(runQueries(exploreId));\n }\n };\n}\n\n/**\n * Keep track of the Explore container size, in particular the width.\n * The width will be used to calculate graph intervals (number of datapoints).\n */\nexport function changeSize(\n exploreId: ExploreId,\n { height, width }: { height: number; width: number }\n): PayloadAction<ChangeSizePayload> {\n return changeSizeAction({ exploreId, height, width });\n}\n\nexport const updateTimeRange = (options: {\n exploreId: ExploreId;\n rawRange?: RawTimeRange;\n absoluteRange?: AbsoluteTimeRange;\n}): ThunkResult<void> => {\n return (dispatch, getState) => {\n const { syncedTimes } = getState().explore;\n if (syncedTimes) {\n dispatch(updateTime({ ...options, exploreId: ExploreId.left }));\n dispatch(runQueries(ExploreId.left));\n dispatch(updateTime({ ...options, exploreId: ExploreId.right }));\n dispatch(runQueries(ExploreId.right));\n } else {\n dispatch(updateTime({ ...options }));\n dispatch(runQueries(options.exploreId));\n }\n };\n};\n/**\n * Change the refresh interval of Explore. Called from the Refresh picker.\n */\nexport function changeRefreshInterval(\n exploreId: ExploreId,\n refreshInterval: string\n): PayloadAction<ChangeRefreshIntervalPayload> {\n return changeRefreshIntervalAction({ exploreId, refreshInterval });\n}\n\n/**\n * Clear all queries and results.\n */\nexport function clearQueries(exploreId: ExploreId): ThunkResult<void> {\n return dispatch => {\n dispatch(scanStopAction({ exploreId }));\n dispatch(clearQueriesAction({ exploreId }));\n dispatch(stateSave());\n };\n}\n\n/**\n * Cancel running queries\n */\nexport function cancelQueries(exploreId: ExploreId): ThunkResult<void> {\n return dispatch => {\n dispatch(scanStopAction({ exploreId }));\n dispatch(cancelQueriesAction({ exploreId }));\n dispatch(stateSave());\n };\n}\n\n/**\n * Loads all explore data sources and sets the chosen datasource.\n * If there are no datasources a missing datasource action is dispatched.\n */\nexport function loadExploreDatasourcesAndSetDatasource(\n exploreId: ExploreId,\n datasourceName: string\n): ThunkResult<void> {\n return dispatch => {\n const exploreDatasources = getExploreDatasources();\n\n if (exploreDatasources.length >= 1) {\n dispatch(changeDatasource(exploreId, datasourceName));\n } else {\n dispatch(loadDatasourceMissingAction({ exploreId }));\n }\n };\n}\n\n/**\n * Initialize Explore state with state from the URL and the React component.\n * Call this only on components for with the Explore state has not been initialized.\n */\nexport function initializeExplore(\n exploreId: ExploreId,\n datasourceName: string,\n queries: DataQuery[],\n range: TimeRange,\n mode: ExploreMode,\n containerWidth: number,\n eventBridge: Emitter,\n ui: ExploreUIState,\n originPanelId: number\n): ThunkResult<void> {\n return async (dispatch, getState) => {\n dispatch(loadExploreDatasourcesAndSetDatasource(exploreId, datasourceName));\n dispatch(\n initializeExploreAction({\n exploreId,\n containerWidth,\n eventBridge,\n queries,\n range,\n mode,\n ui,\n originPanelId,\n })\n );\n dispatch(updateTime({ exploreId }));\n const richHistory = getRichHistory();\n dispatch(richHistoryUpdatedAction({ richHistory }));\n };\n}\n\n/**\n * Datasource loading was successfully completed.\n */\nexport const loadDatasourceReady = (\n exploreId: ExploreId,\n instance: DataSourceApi,\n orgId: number\n): PayloadAction<LoadDatasourceReadyPayload> => {\n const historyKey = `grafana.explore.history.${instance.meta?.id}`;\n const history = store.getObject(historyKey, []);\n // Save last-used datasource\n\n store.set(lastUsedDatasourceKeyForOrgId(orgId), instance.name);\n\n return loadDatasourceReadyAction({\n exploreId,\n history,\n });\n};\n\n/**\n * Import queries from previous datasource if possible eg Loki and Prometheus have similar query language so the\n * labels part can be reused to get similar data.\n * @param exploreId\n * @param queries\n * @param sourceDataSource\n * @param targetDataSource\n */\nexport const importQueries = (\n exploreId: ExploreId,\n queries: DataQuery[],\n sourceDataSource: DataSourceApi | undefined,\n targetDataSource: DataSourceApi\n): ThunkResult<void> => {\n return async dispatch => {\n if (!sourceDataSource) {\n // explore not initialized\n dispatch(queriesImportedAction({ exploreId, queries }));\n return;\n }\n\n let importedQueries = queries;\n // Check if queries can be imported from previously selected datasource\n if (sourceDataSource.meta?.id === targetDataSource.meta?.id) {\n // Keep same queries if same type of datasource\n importedQueries = [...queries];\n } else if (targetDataSource.importQueries) {\n // Datasource-specific importers\n importedQueries = await targetDataSource.importQueries(queries, sourceDataSource.meta);\n } else {\n // Default is blank queries\n importedQueries = ensureQueries();\n }\n\n const nextQueries = ensureQueries(importedQueries);\n\n dispatch(queriesImportedAction({ exploreId, queries: nextQueries }));\n };\n};\n\n/**\n * Main action to asynchronously load a datasource. Dispatches lots of smaller actions for feedback.\n */\nexport const loadDatasource = (exploreId: ExploreId, instance: DataSourceApi, orgId: number): ThunkResult<void> => {\n return async (dispatch, getState) => {\n const datasourceName = instance.name;\n\n // Keep ID to track selection\n dispatch(loadDatasourcePendingAction({ exploreId, requestedDatasourceName: datasourceName }));\n\n if (instance.init) {\n try {\n instance.init();\n } catch (err) {\n console.log(err);\n }\n }\n\n if (datasourceName !== getState().explore[exploreId].requestedDatasourceName) {\n // User already changed datasource, discard results\n return;\n }\n\n dispatch(loadDatasourceReady(exploreId, instance, orgId));\n };\n};\n\n/**\n * Action to modify a query given a datasource-specific modifier action.\n * @param exploreId Explore area\n * @param modification Action object with a type, e.g., ADD_FILTER\n * @param index Optional query row index. If omitted, the modification is applied to all query rows.\n * @param modifier Function that executes the modification, typically `datasourceInstance.modifyQueries`.\n */\nexport function modifyQueries(\n exploreId: ExploreId,\n modification: QueryFixAction,\n modifier: any,\n index?: number\n): ThunkResult<void> {\n return dispatch => {\n dispatch(modifyQueriesAction({ exploreId, modification, index, modifier }));\n if (!modification.preventSubmit) {\n dispatch(runQueries(exploreId));\n }\n };\n}\n\n/**\n * Main action to run queries and dispatches sub-actions based on which result viewers are active\n */\nexport const runQueries = (exploreId: ExploreId): ThunkResult<void> => {\n return (dispatch, getState) => {\n dispatch(updateTime({ exploreId }));\n\n const richHistory = getState().explore.richHistory;\n const exploreItemState = getState().explore[exploreId];\n const {\n datasourceInstance,\n queries,\n containerWidth,\n isLive: live,\n range,\n scanning,\n queryResponse,\n querySubscription,\n history,\n mode,\n showingGraph,\n showingTable,\n } = exploreItemState;\n\n if (!hasNonEmptyQuery(queries)) {\n dispatch(clearQueriesAction({ exploreId }));\n dispatch(stateSave()); // Remember to save to state and update location\n return;\n }\n\n // Some datasource's query builders allow per-query interval limits,\n // but we're using the datasource interval limit for now\n const minInterval = datasourceInstance.interval;\n\n stopQueryState(querySubscription);\n\n const datasourceId = datasourceInstance.meta.id;\n\n const queryOptions: QueryOptions = {\n minInterval,\n // maxDataPoints is used in:\n // Loki - used for logs streaming for buffer size, with undefined it falls back to datasource config if it supports that.\n // Elastic - limits the number of datapoints for the counts query and for logs it has hardcoded limit.\n // Influx - used to correctly display logs in graph\n maxDataPoints: mode === ExploreMode.Logs && datasourceId === 'loki' ? undefined : containerWidth,\n liveStreaming: live,\n showingGraph,\n showingTable,\n mode,\n };\n\n const datasourceName = exploreItemState.requestedDatasourceName;\n const timeZone = getTimeZone(getState().user);\n const transaction = buildQueryTransaction(queries, queryOptions, range, scanning, timeZone);\n\n let firstResponse = true;\n dispatch(changeLoadingStateAction({ exploreId, loadingState: LoadingState.Loading }));\n\n const newQuerySub = runRequest(datasourceInstance, transaction.request)\n .pipe(\n // Simple throttle for live tailing, in case of > 1000 rows per interval we spend about 200ms on processing and\n // rendering. In case this is optimized this can be tweaked, but also it should be only as fast as user\n // actually can see what is happening.\n live ? throttleTime(500) : identity,\n map((data: PanelData) => preProcessPanelData(data, queryResponse))\n )\n .subscribe((data: PanelData) => {\n if (!data.error && firstResponse) {\n // Side-effect: Saving history in localstorage\n const nextHistory = updateHistory(history, datasourceId, queries);\n const nextRichHistory = addToRichHistory(\n richHistory || [],\n datasourceId,\n datasourceName,\n queries,\n false,\n '',\n ''\n );\n dispatch(historyUpdatedAction({ exploreId, history: nextHistory }));\n dispatch(richHistoryUpdatedAction({ richHistory: nextRichHistory }));\n\n // We save queries to the URL here so that only successfully run queries change the URL.\n dispatch(stateSave());\n }\n\n firstResponse = false;\n\n dispatch(queryStreamUpdatedAction({ exploreId, response: data }));\n\n // Keep scanning for results if this was the last scanning transaction\n if (getState().explore[exploreId].scanning) {\n if (data.state === LoadingState.Done && data.series.length === 0) {\n const range = getShiftedTimeRange(-1, getState().explore[exploreId].range);\n dispatch(updateTime({ exploreId, absoluteRange: range }));\n dispatch(runQueries(exploreId));\n } else {\n // We can stop scanning if we have a result\n dispatch(scanStopAction({ exploreId }));\n }\n }\n });\n\n dispatch(queryStoreSubscriptionAction({ exploreId, querySubscription: newQuerySub }));\n };\n};\n\nexport const updateRichHistory = (ts: number, property: string, updatedProperty?: string): ThunkResult<void> => {\n return (dispatch, getState) => {\n // Side-effect: Saving rich history in localstorage\n let nextRichHistory;\n if (property === 'starred') {\n nextRichHistory = updateStarredInRichHistory(getState().explore.richHistory, ts);\n }\n if (property === 'comment') {\n nextRichHistory = updateCommentInRichHistory(getState().explore.richHistory, ts, updatedProperty);\n }\n if (property === 'delete') {\n nextRichHistory = deleteQueryInRichHistory(getState().explore.richHistory, ts);\n }\n dispatch(richHistoryUpdatedAction({ richHistory: nextRichHistory }));\n };\n};\n\nexport const deleteRichHistory = (): ThunkResult<void> => {\n return dispatch => {\n deleteAllFromRichHistory();\n dispatch(richHistoryUpdatedAction({ richHistory: [] }));\n };\n};\n\nconst toRawTimeRange = (range: TimeRange): RawTimeRange => {\n let from = range.raw.from;\n if (isDateTime(from)) {\n from = from.valueOf().toString(10);\n }\n\n let to = range.raw.to;\n if (isDateTime(to)) {\n to = to.valueOf().toString(10);\n }\n\n return {\n from,\n to,\n };\n};\n\n/**\n * Save local redux state back to the URL. Should be called when there is some change that should affect the URL.\n * Not all of the redux state is reflected in URL though.\n */\nexport const stateSave = (): ThunkResult<void> => {\n return (dispatch, getState) => {\n const { left, right, split } = getState().explore;\n const orgId = getState().user.orgId.toString();\n const replace = left && left.urlReplaced === false;\n const urlStates: { [index: string]: string } = { orgId };\n const leftUrlState: ExploreUrlState = {\n datasource: left.datasourceInstance.name,\n queries: left.queries.map(clearQueryKeys),\n range: toRawTimeRange(left.range),\n mode: left.mode,\n ui: {\n showingGraph: left.showingGraph,\n showingLogs: true,\n showingTable: left.showingTable,\n dedupStrategy: left.dedupStrategy,\n },\n };\n urlStates.left = serializeStateToUrlParam(leftUrlState, true);\n if (split) {\n const rightUrlState: ExploreUrlState = {\n datasource: right.datasourceInstance.name,\n queries: right.queries.map(clearQueryKeys),\n range: toRawTimeRange(right.range),\n mode: right.mode,\n ui: {\n showingGraph: right.showingGraph,\n showingLogs: true,\n showingTable: right.showingTable,\n dedupStrategy: right.dedupStrategy,\n },\n };\n\n urlStates.right = serializeStateToUrlParam(rightUrlState, true);\n }\n\n dispatch(updateLocation({ query: urlStates, replace }));\n if (replace) {\n dispatch(setUrlReplacedAction({ exploreId: ExploreId.left }));\n }\n };\n};\n\nexport const updateTime = (config: {\n exploreId: ExploreId;\n rawRange?: RawTimeRange;\n absoluteRange?: AbsoluteTimeRange;\n}): ThunkResult<void> => {\n return (dispatch, getState) => {\n const { exploreId, absoluteRange: absRange, rawRange: actionRange } = config;\n const itemState = getState().explore[exploreId];\n const timeZone = getTimeZone(getState().user);\n const { range: rangeInState } = itemState;\n let rawRange: RawTimeRange = rangeInState.raw;\n\n if (absRange) {\n rawRange = {\n from: dateTimeForTimeZone(timeZone, absRange.from),\n to: dateTimeForTimeZone(timeZone, absRange.to),\n };\n }\n\n if (actionRange) {\n rawRange = actionRange;\n }\n\n const range = getTimeRange(timeZone, rawRange);\n const absoluteRange: AbsoluteTimeRange = { from: range.from.valueOf(), to: range.to.valueOf() };\n\n getTimeSrv().init({\n time: range.raw,\n refresh: false,\n getTimezone: () => timeZone,\n timeRangeUpdated: (): any => undefined,\n });\n\n dispatch(changeRangeAction({ exploreId, range, absoluteRange }));\n };\n};\n\n/**\n * Start a scan for more results using the given scanner.\n * @param exploreId Explore area\n * @param scanner Function that a) returns a new time range and b) triggers a query run for the new range\n */\nexport function scanStart(exploreId: ExploreId): ThunkResult<void> {\n return (dispatch, getState) => {\n // Register the scanner\n dispatch(scanStartAction({ exploreId }));\n // Scanning must trigger query run, and return the new range\n const range = getShiftedTimeRange(-1, getState().explore[exploreId].range);\n // Set the new range to be displayed\n dispatch(updateTime({ exploreId, absoluteRange: range }));\n dispatch(runQueries(exploreId));\n };\n}\n\n/**\n * Reset queries to the given queries. Any modifications will be discarded.\n * Use this action for clicks on query examples. Triggers a query run.\n */\nexport function setQueries(exploreId: ExploreId, rawQueries: DataQuery[]): ThunkResult<void> {\n return (dispatch, getState) => {\n // Inject react keys into query objects\n const queries = getState().explore[exploreId].queries;\n const nextQueries = rawQueries.map((query, index) => generateNewKeyAndAddRefIdIfMissing(query, queries, index));\n dispatch(setQueriesAction({ exploreId, queries: nextQueries }));\n dispatch(runQueries(exploreId));\n };\n}\n\n/**\n * Close the split view and save URL state.\n */\nexport function splitClose(itemId: ExploreId): ThunkResult<void> {\n return dispatch => {\n dispatch(splitCloseAction({ itemId }));\n dispatch(stateSave());\n };\n}\n\n/**\n * Open the split view and the right state is automatically initialized.\n * If options are specified it initializes that pane with the datasource and query from options.\n * Otherwise it copies the left state to be the right state. The copy keeps all query modifications but wipes the query\n * results.\n */\nexport function splitOpen(options?: { datasourceUid: string; query: string }): ThunkResult<void> {\n return async (dispatch, getState) => {\n // Clone left state to become the right state\n const leftState: ExploreItemState = getState().explore[ExploreId.left];\n const rightState: ExploreItemState = {\n ...leftState,\n };\n const queryState = getState().location.query[ExploreId.left] as string;\n const urlState = parseUrlState(queryState);\n\n // TODO: Instead of splitting and then setting query/datasource we may probably do it in one action call\n rightState.queries = leftState.queries.slice();\n rightState.urlState = urlState;\n dispatch(splitOpenAction({ itemState: rightState }));\n\n if (options) {\n // TODO: This is hardcoded for Jaeger right now. Need to be changed so that target datasource can define the\n // query shape.\n const queries = [\n {\n query: options.query,\n refId: 'A',\n } as DataQuery,\n ];\n\n const dataSourceSettings = getDatasourceSrv().getDataSourceSettingsByUid(options.datasourceUid);\n await dispatch(changeDatasource(ExploreId.right, dataSourceSettings.name));\n await dispatch(setQueriesAction({ exploreId: ExploreId.right, queries }));\n }\n\n dispatch(stateSave());\n };\n}\n\n/**\n * Syncs time interval, if they are not synced on both panels in a split mode.\n * Unsyncs time interval, if they are synced on both panels in a split mode.\n */\nexport function syncTimes(exploreId: ExploreId): ThunkResult<void> {\n return (dispatch, getState) => {\n if (exploreId === ExploreId.left) {\n const leftState = getState().explore.left;\n dispatch(updateTimeRange({ exploreId: ExploreId.right, rawRange: leftState.range.raw }));\n } else {\n const rightState = getState().explore.right;\n dispatch(updateTimeRange({ exploreId: ExploreId.left, rawRange: rightState.range.raw }));\n }\n const isTimeSynced = getState().explore.syncedTimes;\n dispatch(syncTimesAction({ syncedTimes: !isTimeSynced }));\n dispatch(stateSave());\n };\n}\n\n/**\n * Creates action to collapse graph/logs/table panel. When panel is collapsed,\n * queries won't be run\n */\nconst togglePanelActionCreator = (\n actionCreator: ActionCreatorWithPayload<ToggleGraphPayload> | ActionCreatorWithPayload<ToggleTablePayload>\n) => (exploreId: ExploreId, isPanelVisible: boolean): ThunkResult<void> => {\n return dispatch => {\n let uiFragmentStateUpdate: Partial<ExploreUIState>;\n const shouldRunQueries = !isPanelVisible;\n\n switch (actionCreator.type) {\n case toggleGraphAction.type:\n uiFragmentStateUpdate = { showingGraph: !isPanelVisible };\n break;\n case toggleTableAction.type:\n uiFragmentStateUpdate = { showingTable: !isPanelVisible };\n break;\n }\n\n dispatch(actionCreator({ exploreId }));\n // The switch further up is exhaustive so uiFragmentStateUpdate should definitely be initialized\n dispatch(updateExploreUIState(exploreId, uiFragmentStateUpdate!));\n\n if (shouldRunQueries) {\n dispatch(runQueries(exploreId));\n }\n };\n};\n\n/**\n * Expand/collapse the graph result viewer. When collapsed, graph queries won't be run.\n */\nexport const toggleGraph = togglePanelActionCreator(toggleGraphAction);\n\n/**\n * Expand/collapse the table result viewer. When collapsed, table queries won't be run.\n */\nexport const toggleTable = togglePanelActionCreator(toggleTableAction);\n\n/**\n * Change logs deduplication strategy and update URL.\n */\nexport const changeDedupStrategy = (exploreId: ExploreId, dedupStrategy: LogsDedupStrategy): ThunkResult<void> => {\n return dispatch => {\n dispatch(updateExploreUIState(exploreId, { dedupStrategy }));\n };\n};\n\n/**\n * Reacts to changes in URL state that we need to sync back to our redux state. Checks the internal update variable\n * to see which parts change and need to be synced.\n * @param exploreId\n */\nexport function refreshExplore(exploreId: ExploreId): ThunkResult<void> {\n return (dispatch, getState) => {\n const itemState = getState().explore[exploreId];\n if (!itemState.initialized) {\n return;\n }\n\n const { urlState, update, containerWidth, eventBridge } = itemState;\n const { datasource, queries, range: urlRange, mode, ui, originPanelId } = urlState;\n const refreshQueries: DataQuery[] = [];\n for (let index = 0; index < queries.length; index++) {\n const query = queries[index];\n refreshQueries.push(generateNewKeyAndAddRefIdIfMissing(query, refreshQueries, index));\n }\n const timeZone = getTimeZone(getState().user);\n const range = getTimeRangeFromUrl(urlRange, timeZone);\n\n // need to refresh datasource\n if (update.datasource) {\n const initialQueries = ensureQueries(queries);\n dispatch(\n initializeExplore(\n exploreId,\n datasource,\n initialQueries,\n range,\n mode,\n containerWidth,\n eventBridge,\n ui,\n originPanelId\n )\n );\n return;\n }\n\n if (update.range) {\n dispatch(updateTime({ exploreId, rawRange: range.raw }));\n }\n\n // need to refresh ui state\n if (update.ui) {\n dispatch(updateUIStateAction({ ...ui, exploreId }));\n }\n\n // need to refresh queries\n if (update.queries) {\n dispatch(setQueriesAction({ exploreId, queries: refreshQueries }));\n }\n\n // need to refresh mode\n if (update.mode) {\n dispatch(changeModeAction({ exploreId, mode }));\n }\n\n // always run queries when refresh is needed\n if (update.queries || update.ui || update.range) {\n dispatch(runQueries(exploreId));\n }\n };\n}\n\nexport interface NavigateToExploreDependencies {\n getDataSourceSrv: () => DataSourceSrv;\n getTimeSrv: () => TimeSrv;\n getExploreUrl: (args: GetExploreUrlArguments) => Promise<string>;\n openInNewWindow?: (url: string) => void;\n}\n\nexport const navigateToExplore = (\n panel: PanelModel,\n dependencies: NavigateToExploreDependencies\n): ThunkResult<void> => {\n return async dispatch => {\n const { getDataSourceSrv, getTimeSrv, getExploreUrl, openInNewWindow } = dependencies;\n const datasourceSrv = getDataSourceSrv();\n const datasource = await datasourceSrv.get(panel.datasource);\n const path = await getExploreUrl({\n panel,\n panelTargets: panel.targets,\n panelDatasource: datasource,\n datasourceSrv,\n timeSrv: getTimeSrv(),\n });\n\n if (openInNewWindow) {\n openInNewWindow(path);\n return;\n }\n\n const query = {}; // strips any angular query param\n dispatch(updateLocation({ path, query }));\n };\n};\n","// Libraries\nimport _ from 'lodash';\n\n// Services & Utils\nimport { DataQuery, DataSourceApi, ExploreMode, dateTimeFormat, AppEvents, urlUtil } from '@grafana/data';\nimport appEvents from 'app/core/app_events';\nimport store from 'app/core/store';\nimport { serializeStateToUrlParam, SortOrder } from './explore';\nimport { getExploreDatasources } from '../../features/explore/state/selectors';\n\n// Types\nimport { ExploreUrlState, RichHistoryQuery } from 'app/types/explore';\n\nconst RICH_HISTORY_KEY = 'grafana.explore.richHistory';\n\nexport const RICH_HISTORY_SETTING_KEYS = {\n retentionPeriod: 'grafana.explore.richHistory.retentionPeriod',\n starredTabAsFirstTab: 'grafana.explore.richHistory.starredTabAsFirstTab',\n activeDatasourceOnly: 'grafana.explore.richHistory.activeDatasourceOnly',\n datasourceFilters: 'grafana.explore.richHistory.datasourceFilters',\n};\n\n/*\n * Add queries to rich history. Save only queries within the retention period, or that are starred.\n * Side-effect: store history in local storage\n */\n\nexport function addToRichHistory(\n richHistory: RichHistoryQuery[],\n datasourceId: string,\n datasourceName: string | null,\n queries: DataQuery[],\n starred: boolean,\n comment: string | null,\n sessionName: string\n): any {\n const ts = Date.now();\n /* Save only queries, that are not falsy (e.g. empty object, null, ...) */\n const newQueriesToSave: DataQuery[] = queries && queries.filter(query => notEmptyQuery(query));\n const retentionPeriod: number = store.getObject(RICH_HISTORY_SETTING_KEYS.retentionPeriod, 7);\n const retentionPeriodLastTs = createRetentionPeriodBoundary(retentionPeriod, false);\n\n /* Keep only queries, that are within the selected retention period or that are starred.\n * If no queries, initialize with empty array\n */\n const queriesToKeep = richHistory.filter(q => q.ts > retentionPeriodLastTs || q.starred === true) || [];\n\n if (newQueriesToSave.length > 0) {\n /* Compare queries of a new query and last saved queries. If they are the same, (except selected properties,\n * which can be different) don't save it in rich history.\n */\n const newQueriesToCompare = newQueriesToSave.map(q => _.omit(q, ['key', 'refId']));\n const lastQueriesToCompare =\n queriesToKeep.length > 0 &&\n queriesToKeep[0].queries.map(q => {\n return _.omit(q, ['key', 'refId']);\n });\n\n if (_.isEqual(newQueriesToCompare, lastQueriesToCompare)) {\n return richHistory;\n }\n\n let updatedHistory = [\n { queries: newQueriesToSave, ts, datasourceId, datasourceName, starred, comment, sessionName },\n ...queriesToKeep,\n ];\n\n try {\n store.setObject(RICH_HISTORY_KEY, updatedHistory);\n return updatedHistory;\n } catch (error) {\n appEvents.emit(AppEvents.alertError, [error]);\n return richHistory;\n }\n }\n\n return richHistory;\n}\n\nexport function getRichHistory(): RichHistoryQuery[] {\n const richHistory: RichHistoryQuery[] = store.getObject(RICH_HISTORY_KEY, []);\n const transformedRichHistory = migrateRichHistory(richHistory);\n return transformedRichHistory;\n}\n\nexport function deleteAllFromRichHistory() {\n return store.delete(RICH_HISTORY_KEY);\n}\n\nexport function updateStarredInRichHistory(richHistory: RichHistoryQuery[], ts: number) {\n const updatedHistory = richHistory.map(query => {\n /* Timestamps are currently unique - we can use them to identify specific queries */\n if (query.ts === ts) {\n const isStarred = query.starred;\n const updatedQuery = Object.assign({}, query, { starred: !isStarred });\n return updatedQuery;\n }\n return query;\n });\n\n try {\n store.setObject(RICH_HISTORY_KEY, updatedHistory);\n return updatedHistory;\n } catch (error) {\n appEvents.emit(AppEvents.alertError, [error]);\n return richHistory;\n }\n}\n\nexport function updateCommentInRichHistory(\n richHistory: RichHistoryQuery[],\n ts: number,\n newComment: string | undefined\n) {\n const updatedHistory = richHistory.map(query => {\n if (query.ts === ts) {\n const updatedQuery = Object.assign({}, query, { comment: newComment });\n return updatedQuery;\n }\n return query;\n });\n\n try {\n store.setObject(RICH_HISTORY_KEY, updatedHistory);\n return updatedHistory;\n } catch (error) {\n appEvents.emit(AppEvents.alertError, [error]);\n return richHistory;\n }\n}\n\nexport function deleteQueryInRichHistory(richHistory: RichHistoryQuery[], ts: number) {\n const updatedHistory = richHistory.filter(query => query.ts !== ts);\n try {\n store.setObject(RICH_HISTORY_KEY, updatedHistory);\n return updatedHistory;\n } catch (error) {\n appEvents.emit(AppEvents.alertError, [error]);\n return richHistory;\n }\n}\n\nexport const sortQueries = (array: RichHistoryQuery[], sortOrder: SortOrder) => {\n let sortFunc;\n\n if (sortOrder === SortOrder.Ascending) {\n sortFunc = (a: RichHistoryQuery, b: RichHistoryQuery) => (a.ts < b.ts ? -1 : a.ts > b.ts ? 1 : 0);\n }\n if (sortOrder === SortOrder.Descending) {\n sortFunc = (a: RichHistoryQuery, b: RichHistoryQuery) => (a.ts < b.ts ? 1 : a.ts > b.ts ? -1 : 0);\n }\n\n if (sortOrder === SortOrder.DatasourceZA) {\n sortFunc = (a: RichHistoryQuery, b: RichHistoryQuery) =>\n a.datasourceName < b.datasourceName ? -1 : a.datasourceName > b.datasourceName ? 1 : 0;\n }\n\n if (sortOrder === SortOrder.DatasourceAZ) {\n sortFunc = (a: RichHistoryQuery, b: RichHistoryQuery) =>\n a.datasourceName < b.datasourceName ? 1 : a.datasourceName > b.datasourceName ? -1 : 0;\n }\n\n return array.sort(sortFunc);\n};\n\nexport const copyStringToClipboard = (string: string) => {\n const el = document.createElement('textarea');\n el.value = string;\n document.body.appendChild(el);\n el.select();\n document.execCommand('copy');\n document.body.removeChild(el);\n};\n\nexport const createUrlFromRichHistory = (query: RichHistoryQuery) => {\n const exploreState: ExploreUrlState = {\n /* Default range, as we are not saving timerange in rich history */\n range: { from: 'now-1h', to: 'now' },\n datasource: query.datasourceName,\n queries: query.queries,\n /* Default mode is metrics. Exceptions are Loki (logs) and Jaeger (tracing) data sources.\n * In the future, we can remove this as we are working on metrics & logs logic.\n **/\n mode:\n query.datasourceId === 'loki'\n ? ExploreMode.Logs\n : query.datasourceId === 'jaeger'\n ? ExploreMode.Tracing\n : ExploreMode.Metrics,\n ui: {\n showingGraph: true,\n showingLogs: true,\n showingTable: true,\n },\n context: 'explore',\n };\n\n const serializedState = serializeStateToUrlParam(exploreState, true);\n const baseUrl = /.*(?=\\/explore)/.exec(`${window.location.href}`)[0];\n const url = urlUtil.renderUrl(`${baseUrl}/explore`, { left: serializedState });\n return url;\n};\n\n/* Needed for slider in Rich history to map numerical values to meaningful strings */\nexport const mapNumbertoTimeInSlider = (num: number) => {\n let str;\n switch (num) {\n case 0:\n str = 'today';\n break;\n case 1:\n str = 'yesterday';\n break;\n case 7:\n str = 'a week ago';\n break;\n case 14:\n str = 'two weeks ago';\n break;\n default:\n str = `${num} days ago`;\n }\n\n return str;\n};\n\nexport const createRetentionPeriodBoundary = (days: number, isLastTs: boolean) => {\n const today = new Date();\n const date = new Date(today.setDate(today.getDate() - days));\n /*\n * As a retention period boundaries, we consider:\n * - The last timestamp equals to the 24:00 of the last day of retention\n * - The first timestamp that equals to the 00:00 of the first day of retention\n */\n const boundary = isLastTs ? date.setHours(24, 0, 0, 0) : date.setHours(0, 0, 0, 0);\n return boundary;\n};\n\nexport function createDateStringFromTs(ts: number) {\n return dateTimeFormat(ts, {\n format: 'MMMM D',\n });\n}\n\nexport function getQueryDisplayText(query: DataQuery): string {\n /* If datasource doesn't have getQueryDisplayText, create query display text by\n * stringifying query that was stripped of key, refId and datasource for nicer\n * formatting and improved readability\n */\n const strippedQuery = _.omit(query, ['key', 'refId', 'datasource']);\n return JSON.stringify(strippedQuery);\n}\n\nexport function createQueryHeading(query: RichHistoryQuery, sortOrder: SortOrder) {\n let heading = '';\n if (sortOrder === SortOrder.DatasourceAZ || sortOrder === SortOrder.DatasourceZA) {\n heading = query.datasourceName;\n } else {\n heading = createDateStringFromTs(query.ts);\n }\n return heading;\n}\n\nexport function createQueryText(query: DataQuery, queryDsInstance: DataSourceApi) {\n /* query DatasourceInstance is necessary because we use its getQueryDisplayText method\n * to format query text\n */\n if (queryDsInstance?.getQueryDisplayText) {\n return queryDsInstance.getQueryDisplayText(query);\n }\n\n return getQueryDisplayText(query);\n}\n\nexport function mapQueriesToHeadings(query: RichHistoryQuery[], sortOrder: SortOrder) {\n let mappedQueriesToHeadings: any = {};\n\n query.forEach(q => {\n let heading = createQueryHeading(q, sortOrder);\n if (!(heading in mappedQueriesToHeadings)) {\n mappedQueriesToHeadings[heading] = [q];\n } else {\n mappedQueriesToHeadings[heading] = [...mappedQueriesToHeadings[heading], q];\n }\n });\n\n return mappedQueriesToHeadings;\n}\n\n/* Create datasource list with images. If specific datasource retrieved from Rich history is not part of\n * exploreDatasources add generic datasource image and add property isRemoved = true.\n */\nexport function createDatasourcesList(queriesDatasources: string[]) {\n const exploreDatasources = getExploreDatasources();\n const datasources: Array<{ label: string; value: string; imgUrl: string; isRemoved: boolean }> = [];\n\n queriesDatasources.forEach(queryDsName => {\n const index = exploreDatasources.findIndex(exploreDs => exploreDs.name === queryDsName);\n if (index !== -1) {\n datasources.push({\n label: queryDsName,\n value: queryDsName,\n imgUrl: exploreDatasources[index].meta.info.logos.small,\n isRemoved: false,\n });\n } else {\n datasources.push({\n label: queryDsName,\n value: queryDsName,\n imgUrl: 'public/img/icn-datasource.svg',\n isRemoved: true,\n });\n }\n });\n return datasources;\n}\n\nexport function notEmptyQuery(query: DataQuery) {\n /* Check if query has any other properties besides key, refId and datasource.\n * If not, then we consider it empty query.\n */\n const strippedQuery = _.omit(query, ['key', 'refId', 'datasource']);\n const queryKeys = Object.keys(strippedQuery);\n\n if (queryKeys.length > 0) {\n return true;\n }\n\n return false;\n}\n\n/* These functions are created to migrate string queries (from 6.7 release) to DataQueries. They can be removed after 7.1 release. */\nfunction migrateRichHistory(richHistory: RichHistoryQuery[]) {\n const transformedRichHistory = richHistory.map(query => {\n const transformedQueries: DataQuery[] = query.queries.map((q, index) => createDataQuery(query, q, index));\n return { ...query, queries: transformedQueries };\n });\n\n return transformedRichHistory;\n}\n\nfunction createDataQuery(query: RichHistoryQuery, individualQuery: DataQuery | string, index: number) {\n const letters = 'ABCDEFGHIJKLMNOPQRSTUVXYZ';\n if (typeof individualQuery === 'object') {\n return individualQuery;\n } else if (isParsable(individualQuery)) {\n return JSON.parse(individualQuery);\n }\n return { expr: individualQuery, refId: letters[index] };\n}\n\nfunction isParsable(string: string) {\n try {\n JSON.parse(string);\n } catch (e) {\n return false;\n }\n return true;\n}\n"],"sourceRoot":""}