explore.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { renderUrl } from 'app/core/utils/url';
  2. import { ExploreState, ExploreUrlState } from 'app/types/explore';
  3. export const DEFAULT_RANGE = {
  4. from: 'now-6h',
  5. to: 'now',
  6. };
  7. /**
  8. * Returns an Explore-URL that contains a panel's queries and the dashboard time range.
  9. *
  10. * @param panel Origin panel of the jump to Explore
  11. * @param panelTargets The origin panel's query targets
  12. * @param panelDatasource The origin panel's datasource
  13. * @param datasourceSrv Datasource service to query other datasources in case the panel datasource is mixed
  14. * @param timeSrv Time service to get the current dashboard range from
  15. */
  16. export async function getExploreUrl(
  17. panel: any,
  18. panelTargets: any[],
  19. panelDatasource: any,
  20. datasourceSrv: any,
  21. timeSrv: any
  22. ) {
  23. let exploreDatasource = panelDatasource;
  24. let exploreTargets = panelTargets;
  25. let url;
  26. // Mixed datasources need to choose only one datasource
  27. if (panelDatasource.meta.id === 'mixed' && panelTargets) {
  28. // Find first explore datasource among targets
  29. let mixedExploreDatasource;
  30. for (const t of panel.targets) {
  31. const datasource = await datasourceSrv.get(t.datasource);
  32. if (datasource && datasource.meta.explore) {
  33. mixedExploreDatasource = datasource;
  34. break;
  35. }
  36. }
  37. // Add all its targets
  38. if (mixedExploreDatasource) {
  39. exploreDatasource = mixedExploreDatasource;
  40. exploreTargets = panelTargets.filter(t => t.datasource === mixedExploreDatasource.name);
  41. }
  42. }
  43. if (exploreDatasource && exploreDatasource.meta.explore) {
  44. const range = timeSrv.timeRangeForUrl();
  45. const state = {
  46. ...exploreDatasource.getExploreState(exploreTargets),
  47. range,
  48. };
  49. const exploreState = JSON.stringify(state);
  50. url = renderUrl('/explore', { state: exploreState });
  51. }
  52. return url;
  53. }
  54. export function parseUrlState(initial: string | undefined): ExploreUrlState {
  55. if (initial) {
  56. try {
  57. const parsed = JSON.parse(decodeURI(initial));
  58. if (Array.isArray(parsed)) {
  59. if (parsed.length <= 3) {
  60. throw new Error('Error parsing compact URL state for Explore.');
  61. }
  62. const range = {
  63. from: parsed[0],
  64. to: parsed[1],
  65. };
  66. const datasource = parsed[2];
  67. const queries = parsed.slice(3).map(query => ({ query }));
  68. return { datasource, queries, range };
  69. }
  70. return parsed;
  71. } catch (e) {
  72. console.error(e);
  73. }
  74. }
  75. return { datasource: null, queries: [], range: DEFAULT_RANGE };
  76. }
  77. export function serializeStateToUrlParam(state: ExploreState, compact?: boolean): string {
  78. const urlState: ExploreUrlState = {
  79. datasource: state.datasourceName,
  80. queries: state.queries.map(q => ({ query: q.query })),
  81. range: state.range,
  82. };
  83. if (compact) {
  84. return JSON.stringify([
  85. urlState.range.from,
  86. urlState.range.to,
  87. urlState.datasource,
  88. ...urlState.queries.map(q => q.query),
  89. ]);
  90. }
  91. return JSON.stringify(urlState);
  92. }