link_srv.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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, VariableOrigin, DataLinkBuiltInVars } from '@grafana/ui';
  7. import { DataLink, KeyValue, deprecationWarning, LinkModel, DataFrame, ScopedVars } from '@grafana/data';
  8. const timeRangeVars = [
  9. {
  10. value: `${DataLinkBuiltInVars.keepTime}`,
  11. label: 'Time range',
  12. documentation: 'Adds current time range',
  13. origin: VariableOrigin.BuiltIn,
  14. },
  15. {
  16. value: `${DataLinkBuiltInVars.timeRangeFrom}`,
  17. label: 'Time range: from',
  18. documentation: "Adds current time range's from value",
  19. origin: VariableOrigin.BuiltIn,
  20. },
  21. {
  22. value: `${DataLinkBuiltInVars.timeRangeTo}`,
  23. label: 'Time range: to',
  24. documentation: "Adds current time range's to value",
  25. origin: VariableOrigin.BuiltIn,
  26. },
  27. ];
  28. const fieldVars = [
  29. {
  30. value: `${DataLinkBuiltInVars.fieldName}`,
  31. label: 'Name',
  32. documentation: 'Field name of the clicked datapoint (in ms epoch)',
  33. origin: VariableOrigin.Field,
  34. },
  35. ];
  36. const valueVars = [
  37. {
  38. value: `${DataLinkBuiltInVars.valueNumeric}`,
  39. label: 'Numeric',
  40. documentation: 'Numeric representation of selected value',
  41. origin: VariableOrigin.Value,
  42. },
  43. {
  44. value: `${DataLinkBuiltInVars.valueText}`,
  45. label: 'Text',
  46. documentation: 'Text representation of selected value',
  47. origin: VariableOrigin.Value,
  48. },
  49. {
  50. value: `${DataLinkBuiltInVars.valueRaw}`,
  51. label: 'Raw',
  52. documentation: 'Raw value',
  53. origin: VariableOrigin.Value,
  54. },
  55. ];
  56. const buildLabelPath = (label: string) => {
  57. return label.indexOf('.') > -1 ? `["${label}"]` : `.${label}`;
  58. };
  59. export const getPanelLinksVariableSuggestions = (): VariableSuggestion[] => [
  60. ...templateSrv.variables.map(variable => ({
  61. value: variable.name as string,
  62. label: variable.name,
  63. origin: VariableOrigin.Template,
  64. })),
  65. {
  66. value: `${DataLinkBuiltInVars.includeVars}`,
  67. label: 'All variables',
  68. documentation: 'Adds current variables',
  69. origin: VariableOrigin.Template,
  70. },
  71. ...timeRangeVars,
  72. ];
  73. const getSeriesVars = (dataFrames: DataFrame[]) => {
  74. const labels = _.flatten(dataFrames.map(df => Object.keys(df.labels || {})));
  75. return [
  76. {
  77. value: `${DataLinkBuiltInVars.seriesName}`,
  78. label: 'Name',
  79. documentation: 'Name of the series',
  80. origin: VariableOrigin.Series,
  81. },
  82. ...labels.map(label => ({
  83. value: `__series.labels${buildLabelPath(label)}`,
  84. label: `labels.${label}`,
  85. documentation: `${label} label value`,
  86. origin: VariableOrigin.Series,
  87. })),
  88. ];
  89. };
  90. export const getDataLinksVariableSuggestions = (dataFrames: DataFrame[]): VariableSuggestion[] => {
  91. const seriesVars = getSeriesVars(dataFrames);
  92. const valueTimeVar = {
  93. value: `${DataLinkBuiltInVars.valueTime}`,
  94. label: 'Time',
  95. documentation: 'Time value of the clicked datapoint (in ms epoch)',
  96. origin: VariableOrigin.Value,
  97. };
  98. return [...seriesVars, ...fieldVars, ...valueVars, valueTimeVar, ...getPanelLinksVariableSuggestions()];
  99. };
  100. export const getCalculationValueDataLinksVariableSuggestions = (dataFrames: DataFrame[]): VariableSuggestion[] => {
  101. const seriesVars = getSeriesVars(dataFrames);
  102. const valueCalcVar = {
  103. value: `${DataLinkBuiltInVars.valueCalc}`,
  104. label: 'Calculation name',
  105. documentation: 'Name of the calculation the value is a result of',
  106. origin: VariableOrigin.Value,
  107. };
  108. return [...seriesVars, ...fieldVars, ...valueVars, valueCalcVar, ...getPanelLinksVariableSuggestions()];
  109. };
  110. export interface LinkService {
  111. getDataLinkUIModel: <T>(link: DataLink, scopedVars: ScopedVars, origin: T) => LinkModel<T>;
  112. }
  113. export class LinkSrv implements LinkService {
  114. /** @ngInject */
  115. constructor(private templateSrv: TemplateSrv, private timeSrv: TimeSrv) {}
  116. getLinkUrl(link: any) {
  117. const url = this.templateSrv.replace(link.url || '');
  118. const params: { [key: string]: any } = {};
  119. if (link.keepTime) {
  120. const range = this.timeSrv.timeRangeForUrl();
  121. params['from'] = range.from;
  122. params['to'] = range.to;
  123. }
  124. if (link.includeVars) {
  125. this.templateSrv.fillVariableValuesForUrl(params);
  126. }
  127. return appendQueryToUrl(url, toUrlParams(params));
  128. }
  129. getAnchorInfo(link: any) {
  130. const info: any = {};
  131. info.href = this.getLinkUrl(link);
  132. info.title = this.templateSrv.replace(link.title || '');
  133. return info;
  134. }
  135. getDataLinkUIModel = <T>(link: DataLink, scopedVars: ScopedVars, origin: T) => {
  136. const params: KeyValue = {};
  137. const timeRangeUrl = toUrlParams(this.timeSrv.timeRangeForUrl());
  138. const info: LinkModel<T> = {
  139. href: link.url.replace(/\s|\n/g, ''),
  140. title: this.templateSrv.replace(link.title || '', scopedVars),
  141. target: link.targetBlank ? '_blank' : '_self',
  142. origin,
  143. };
  144. this.templateSrv.fillVariableValuesForUrl(params, scopedVars);
  145. const variablesQuery = toUrlParams(params);
  146. info.href = this.templateSrv.replace(info.href, {
  147. ...scopedVars,
  148. [DataLinkBuiltInVars.keepTime]: {
  149. text: timeRangeUrl,
  150. value: timeRangeUrl,
  151. },
  152. [DataLinkBuiltInVars.includeVars]: {
  153. text: variablesQuery,
  154. value: variablesQuery,
  155. },
  156. });
  157. return info;
  158. };
  159. /**
  160. * getPanelLinkAnchorInfo method is left for plugins compatibility reasons
  161. *
  162. * @deprecated Drilldown links should be generated using getDataLinkUIModel method
  163. */
  164. getPanelLinkAnchorInfo(link: DataLink, scopedVars: ScopedVars) {
  165. deprecationWarning('link_srv.ts', 'getPanelLinkAnchorInfo', 'getDataLinkUIModel');
  166. return this.getDataLinkUIModel(link, scopedVars, {});
  167. }
  168. }
  169. let singleton: LinkService;
  170. export function setLinkSrv(srv: LinkService) {
  171. singleton = srv;
  172. }
  173. export function getLinkSrv(): LinkService {
  174. return singleton;
  175. }
  176. coreModule.service('linkSrv', LinkSrv);