link_srv.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import _ from 'lodash';
  2. import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
  3. import templateSrv, { TemplateSrv } from 'app/features/templating/template_srv';
  4. import coreModule from 'app/core/core_module';
  5. import { appendQueryToUrl, toUrlParams } from 'app/core/utils/url';
  6. import { VariableSuggestion, KeyValue, ScopedVars, deprecationWarning, VariableOrigin } from '@grafana/ui';
  7. import { TimeSeriesValue, DateTime, dateTime, DataLink } from '@grafana/data';
  8. export const DataLinkBuiltInVars = {
  9. keepTime: '__url_time_range',
  10. includeVars: '__all_variables',
  11. seriesName: '__series_name',
  12. valueTime: '__value_time',
  13. };
  14. export const getPanelLinksVariableSuggestions = (): VariableSuggestion[] => [
  15. ...templateSrv.variables.map(variable => ({
  16. value: variable.name as string,
  17. origin: VariableOrigin.Template,
  18. })),
  19. {
  20. value: `${DataLinkBuiltInVars.includeVars}`,
  21. documentation: 'Adds current variables',
  22. origin: VariableOrigin.BuiltIn,
  23. },
  24. {
  25. value: `${DataLinkBuiltInVars.keepTime}`,
  26. documentation: 'Adds current time range',
  27. origin: VariableOrigin.BuiltIn,
  28. },
  29. ];
  30. export const getDataLinksVariableSuggestions = (): VariableSuggestion[] => [
  31. ...getPanelLinksVariableSuggestions(),
  32. {
  33. value: `${DataLinkBuiltInVars.seriesName}`,
  34. documentation: 'Adds series name',
  35. origin: VariableOrigin.BuiltIn,
  36. },
  37. {
  38. value: `${DataLinkBuiltInVars.valueTime}`,
  39. documentation: 'Time value of the clicked datapoint (in ms epoch)',
  40. origin: VariableOrigin.BuiltIn,
  41. },
  42. ];
  43. type LinkTarget = '_blank' | '_self';
  44. export interface LinkModel {
  45. href: string;
  46. title: string;
  47. target: LinkTarget;
  48. }
  49. interface LinkDataPoint {
  50. datapoint: TimeSeriesValue[];
  51. seriesName: string;
  52. [key: number]: any;
  53. }
  54. export interface LinkService {
  55. getDataLinkUIModel: (link: DataLink, scopedVars: ScopedVars, dataPoint?: LinkDataPoint) => LinkModel;
  56. getDataPointVars: (seriesName: string, dataPointTs: DateTime) => ScopedVars;
  57. }
  58. export class LinkSrv implements LinkService {
  59. /** @ngInject */
  60. constructor(private templateSrv: TemplateSrv, private timeSrv: TimeSrv) {}
  61. getLinkUrl(link: any) {
  62. const url = this.templateSrv.replace(link.url || '');
  63. const params: { [key: string]: any } = {};
  64. if (link.keepTime) {
  65. const range = this.timeSrv.timeRangeForUrl();
  66. params['from'] = range.from;
  67. params['to'] = range.to;
  68. }
  69. if (link.includeVars) {
  70. this.templateSrv.fillVariableValuesForUrl(params);
  71. }
  72. return appendQueryToUrl(url, toUrlParams(params));
  73. }
  74. getAnchorInfo(link: any) {
  75. const info: any = {};
  76. info.href = this.getLinkUrl(link);
  77. info.title = this.templateSrv.replace(link.title || '');
  78. return info;
  79. }
  80. getDataPointVars = (seriesName: string, valueTime: DateTime) => {
  81. return {
  82. [DataLinkBuiltInVars.valueTime]: {
  83. text: valueTime.valueOf(),
  84. value: valueTime.valueOf(),
  85. },
  86. [DataLinkBuiltInVars.seriesName]: {
  87. text: seriesName,
  88. value: seriesName,
  89. },
  90. };
  91. };
  92. getDataLinkUIModel = (link: DataLink, scopedVars: ScopedVars, dataPoint?: LinkDataPoint) => {
  93. const params: KeyValue = {};
  94. const timeRangeUrl = toUrlParams(this.timeSrv.timeRangeForUrl());
  95. const info: LinkModel = {
  96. href: link.url,
  97. title: this.templateSrv.replace(link.title || '', scopedVars),
  98. target: link.targetBlank ? '_blank' : '_self',
  99. };
  100. this.templateSrv.fillVariableValuesForUrl(params, scopedVars);
  101. const variablesQuery = toUrlParams(params);
  102. info.href = this.templateSrv.replace(link.url, {
  103. ...scopedVars,
  104. [DataLinkBuiltInVars.keepTime]: {
  105. text: timeRangeUrl,
  106. value: timeRangeUrl,
  107. },
  108. [DataLinkBuiltInVars.includeVars]: {
  109. text: variablesQuery,
  110. value: variablesQuery,
  111. },
  112. });
  113. if (dataPoint) {
  114. info.href = this.templateSrv.replace(
  115. info.href,
  116. this.getDataPointVars(dataPoint.seriesName, dateTime(dataPoint.datapoint[0]))
  117. );
  118. }
  119. return info;
  120. };
  121. /**
  122. * getPanelLinkAnchorInfo method is left for plugins compatibility reasons
  123. *
  124. * @deprecated Drilldown links should be generated using getDataLinkUIModel method
  125. */
  126. getPanelLinkAnchorInfo(link: DataLink, scopedVars: ScopedVars) {
  127. deprecationWarning('link_srv.ts', 'getPanelLinkAnchorInfo', 'getDataLinkUIModel');
  128. return this.getDataLinkUIModel(link, scopedVars);
  129. }
  130. }
  131. let singleton: LinkService;
  132. export function setLinkSrv(srv: LinkService) {
  133. singleton = srv;
  134. }
  135. export function getLinkSrv(): LinkService {
  136. return singleton;
  137. }
  138. coreModule.service('linkSrv', LinkSrv);