editor.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <div ng-controller="VariableEditorCtrl" ng-init="init()">
  2. <div class="tabbed-view-header">
  3. <h2 class="tabbed-view-title">
  4. Templating
  5. </h2>
  6. <ul class="gf-tabs">
  7. <li class="gf-tabs-item" >
  8. <a class="gf-tabs-link" ng-click="mode = 'list';" ng-class="{active: mode === 'list'}">
  9. Variables
  10. </a>
  11. </li>
  12. <li class="gf-tabs-item" ng-show="mode === 'edit'">
  13. <a class="gf-tabs-link" ng-class="{active: mode === 'edit'}">
  14. Edit
  15. </a>
  16. </li>
  17. <li class="gf-tabs-item" ng-show="mode === 'new'">
  18. <span class="active gf-tabs-link">New</span>
  19. </li>
  20. <li class="gf-tabs-item" >
  21. <a class="gf-tabs-link" ng-click="mode = 'help';" ng-class="{active: mode === 'help'}">
  22. Help
  23. </a>
  24. </li>
  25. </ul>
  26. <button class="tabbed-view-close-btn" ng-click="dismiss();">
  27. <i class="fa fa-remove"></i>
  28. </button>
  29. </div>
  30. <div class="tabbed-view-body">
  31. <div ng-if="mode === 'list'">
  32. <div ng-if="variables.length === 0">
  33. <em>No template variables defined</em>
  34. <br /> <br />
  35. </div>
  36. <table class="grafana-options-table">
  37. <tr ng-repeat="variable in variables">
  38. <td style="width: 1%">
  39. <span class="template-variable">
  40. ${{variable.name}}
  41. </span>
  42. </td>
  43. <td class="max-width" style="max-width: 200px;">
  44. {{variable.query}}
  45. </td>
  46. <td style="width: 1%"><i ng-click="_.move(variables,$index,$index-1)" ng-hide="$first" class="pointer fa fa-arrow-up"></i></td>
  47. <td style="width: 1%"><i ng-click="_.move(variables,$index,$index+1)" ng-hide="$last" class="pointer fa fa-arrow-down"></i></td>
  48. <td style="width: 1%">
  49. <a ng-click="duplicate(variable)" class="btn btn-inverse btn-mini">
  50. Duplicate
  51. </a>
  52. </td>
  53. <td style="width: 1%">
  54. <a ng-click="edit(variable)" class="btn btn-inverse btn-mini">
  55. <i class="fa fa-edit"></i>
  56. Edit
  57. </a>
  58. </td>
  59. <td style="width: 1%">
  60. <a ng-click="removeVariable(variable)" class="btn btn-danger btn-mini">
  61. <i class="fa fa-remove"></i>
  62. </a>
  63. </td>
  64. </tr>
  65. </table>
  66. </div>
  67. <div ng-show="mode === 'help'">
  68. <div class="grafana-info-box col-lg-8">
  69. <h5>What does templating do?</h5>
  70. <p>Templating allows for more interactive and dynamic dashboards. Instead of hard-coding things like server, application
  71. and sensor name in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of
  72. the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
  73. <br>
  74. <br>
  75. Checkout the <a class="external-link" target="_blank" href="http://docs.grafana.org/reference/templating/">Templating documentation</a> for more information.
  76. </p>
  77. </div>
  78. </div>
  79. <div class="gf-form" ng-show="mode === 'list'">
  80. <div class="gf-form-button-row">
  81. <a type="button" class="btn gf-form-button btn-success" ng-click="mode = 'new';"><i class="fa fa-plus" ></i>&nbsp;&nbsp;New</a>
  82. </div>
  83. </div>
  84. <form ng-if="mode === 'edit' || mode === 'new'" name="ctrl.form">
  85. <h5 class="section-heading">Variable</h5>
  86. <div class="gf-form-group">
  87. <div class="gf-form-inline">
  88. <div class="gf-form max-width-19">
  89. <span class="gf-form-label width-6">Name</span>
  90. <input type="text" class="gf-form-input" name="name" placeholder="name" ng-model='current.name' required ng-pattern="namePattern"></input>
  91. </div>
  92. <div class="gf-form max-width-19">
  93. <span class="gf-form-label width-6">
  94. Type
  95. <info-popover mode="right-normal">
  96. {{variableTypes[current.type].description}}
  97. </info-popover>
  98. </span>
  99. <div class="gf-form-select-wrapper max-width-17">
  100. <select class="gf-form-input" ng-model="current.type" ng-options="k as v.name for (k, v) in variableTypes" ng-change="typeChanged()"></select>
  101. </div>
  102. </div>
  103. </div>
  104. <div class="gf-form" ng-show="ctrl.form.name.$error.pattern">
  105. <span class="gf-form-label gf-form-label--error">Template names cannot begin with '__' that's reserved for Grafanas global variables</span>
  106. </div>
  107. <div class="gf-form-inline">
  108. <div class="gf-form max-width-19">
  109. <span class="gf-form-label width-6">Label</span>
  110. <input type="text" class="gf-form-input" ng-model='current.label' placeholder="optional display name"></input>
  111. </div>
  112. <div class="gf-form max-width-19">
  113. <span class="gf-form-label width-6">Hide</span>
  114. <div class="gf-form-select-wrapper max-width-15">
  115. <select class="gf-form-input" ng-model="current.hide" ng-options="f.value as f.text for f in hideOptions"></select>
  116. </div>
  117. </div>
  118. </div>
  119. </div>
  120. <div ng-if="current.type === 'interval'" class="gf-form-group">
  121. <h5 class="section-heading">Interval Options</h5>
  122. <div class="gf-form">
  123. <span class="gf-form-label width-9">Values</span>
  124. <input type="text" class="gf-form-input" placeholder="name" ng-model='current.query' placeholder="1m,10m,1h,6h,1d,7d" ng-model-onblur ng-change="runQuery()" required></input>
  125. </div>
  126. <div class="gf-form-inline">
  127. <gf-form-switch class="gf-form" label="Auto Option" label-class="width-9" checked="current.auto" on-change="runQuery()">
  128. </gf-form-switch>
  129. <div class="gf-form">
  130. <span class="gf-form-label width-9" ng-show="current.auto">
  131. Step count <tip>How many times should the current time range be divided to calculate the value</tip>
  132. </span>
  133. <div class="gf-form-select-wrapper max-width-10" ng-show="current.auto">
  134. <select class="gf-form-input" ng-model="current.auto_count" ng-options="f for f in [1,2,3,4,5,10,20,30,40,50,100,200,300,400,500]" ng-change="runQuery()"></select>
  135. </div>
  136. </div>
  137. <div class="gf-form">
  138. <span class="gf-form-label" ng-show="current.auto">
  139. Min interval <tip>The calculated value will not go below this threshold</tip>
  140. </span>
  141. <input type="text" class="gf-form-input max-width-10" ng-show="current.auto" ng-model="current.auto_min" ng-change="runQuery()" placeholder="10s"></input>
  142. </div>
  143. </div>
  144. </div>
  145. <div ng-if="current.type === 'custom'" class="gf-form-group">
  146. <h5 class="section-heading">Custom Options</h5>
  147. <div class="gf-form">
  148. <span class="gf-form-label width-14">Values separated by comma</span>
  149. <input type="text" class="gf-form-input" ng-model='current.query' ng-blur="runQuery()" placeholder="1, 10, 20, myvalue" required></input>
  150. </div>
  151. </div>
  152. <div ng-if="current.type === 'constant'" class="gf-form-group">
  153. <h5 class="section-heading">Constant options</h5>
  154. <div class="gf-form">
  155. <span class="gf-form-label">Value</span>
  156. <input type="text" class="gf-form-input" ng-model='current.query' ng-blur="runQuery()" placeholder="your metric prefix"></input>
  157. </div>
  158. </div>
  159. <div ng-if="current.type === 'query'" class="gf-form-group">
  160. <h5 class="section-heading">Query Options</h5>
  161. <div class="gf-form-inline">
  162. <div class="gf-form max-width-21">
  163. <span class="gf-form-label width-7">Data source</span>
  164. <div class="gf-form-select-wrapper max-width-14">
  165. <select class="gf-form-input" ng-model="current.datasource" ng-options="f.value as f.name for f in datasources" required>
  166. <option value="" ng-if="false"></option>
  167. </select>
  168. </div>
  169. </div>
  170. <div class="gf-form max-width-21">
  171. <span class="gf-form-label width-7">
  172. Refresh
  173. <info-popover mode="right-normal">
  174. When to update the values of this variable.
  175. </info-popover>
  176. </span>
  177. <div class="gf-form-select-wrapper max-width-14">
  178. <select class="gf-form-input" ng-model="current.refresh" ng-options="f.value as f.text for f in refreshOptions"></select>
  179. </div>
  180. </div>
  181. </div>
  182. <div class="gf-form">
  183. <span class="gf-form-label width-7">Query</span>
  184. <input type="text" class="gf-form-input" ng-model='current.query' placeholder="metric name or tags query" ng-model-onblur ng-change="runQuery()" required></input>
  185. </div>
  186. <div class="gf-form">
  187. <span class="gf-form-label width-7">
  188. Regex
  189. <info-popover mode="right-normal">
  190. Optional, if you want to extract part of a series name or metric node segment.
  191. </info-popover>
  192. </span>
  193. <input type="text" class="gf-form-input" ng-model='current.regex' placeholder="/.*-(.*)-.*/" ng-model-onblur ng-change="runQuery()"></input>
  194. </div>
  195. <div class="gf-form max-width-21">
  196. <span class="gf-form-label width-7">
  197. Sort
  198. <info-popover mode="right-normal">
  199. How to sort the values of this variable.
  200. </info-popover>
  201. </span>
  202. <div class="gf-form-select-wrapper max-width-14">
  203. <select class="gf-form-input" ng-model="current.sort" ng-options="f.value as f.text for f in sortOptions" ng-change="runQuery()"></select>
  204. </div>
  205. </div>
  206. </div>
  207. <div ng-show="current.type === 'datasource'" class="gf-form-group">
  208. <h5 class="section-heading">Data source options</h5>
  209. <div class="gf-form">
  210. <label class="gf-form-label width-12">Type</label>
  211. <div class="gf-form-select-wrapper max-width-18">
  212. <select class="gf-form-input" ng-model="current.query" ng-options="f.value as f.text for f in datasourceTypes" ng-change="runQuery()"></select>
  213. </div>
  214. </div>
  215. <div class="gf-form">
  216. <label class="gf-form-label width-12">
  217. Instance name filter
  218. <info-popover mode="right-normal">
  219. Regex filter for which data source instances to choose from in
  220. the variable value dropdown. Leave empty for all.
  221. <br><br>
  222. Example: <code>/^prod/</code>
  223. </info-popover>
  224. </label>
  225. <input type="text" class="gf-form-input max-width-18" ng-model='current.regex' placeholder="/.*-(.*)-.*/" ng-model-onblur ng-change="runQuery()"></input>
  226. </div>
  227. </div>
  228. <div ng-if="current.type === 'adhoc'" class="gf-form-group">
  229. <h5 class="section-heading">Options</h5>
  230. <div class="gf-form max-width-21">
  231. <span class="gf-form-label width-8">Data source</span>
  232. <div class="gf-form-select-wrapper max-width-14">
  233. <select class="gf-form-input" ng-model="current.datasource" ng-options="f.value as f.name for f in datasources" required ng-change="validate()">
  234. <option value="" ng-if="false"></option>
  235. </select>
  236. </div>
  237. </div>
  238. </div>
  239. <div class="section gf-form-group" ng-show="variableTypes[current.type].supportsMulti">
  240. <h5 class="section-heading">Selection Options</h5>
  241. <div class="section">
  242. <gf-form-switch class="gf-form"
  243. label="Multi-value"
  244. label-class="width-10"
  245. tooltip="Enables multiple values to be selected at the same time"
  246. checked="current.multi"
  247. on-change="runQuery()">
  248. </gf-form-switch>
  249. <gf-form-switch class="gf-form"
  250. label="Include All option"
  251. label-class="width-10"
  252. checked="current.includeAll"
  253. on-change="runQuery()">
  254. </gf-form-switch>
  255. </div>
  256. <div class="gf-form" ng-if="current.includeAll">
  257. <span class="gf-form-label width-10">Custom all value</span>
  258. <input type="text" class="gf-form-input max-width-15" ng-model='current.allValue' placeholder="blank = auto"></input>
  259. </div>
  260. </div>
  261. <div class="gf-form-group" ng-if="current.type === 'query'">
  262. <h5>Value groups/tags (Experimental feature)</h5>
  263. <gf-form-switch class="gf-form" label="Enabled" label-class="width-10" checked="current.useTags" on-change="runQuery()">
  264. </gf-form-switch>
  265. <div class="gf-form last" ng-if="current.useTags">
  266. <span class="gf-form-label width-10">Tags query</span>
  267. <input type="text" class="gf-form-input" ng-model='current.tagsQuery' placeholder="metric name or tags query" ng-model-onblur></input>
  268. </div>
  269. <div class="gf-form" ng-if="current.useTags">
  270. <li class="gf-form-label width-10">Tag values query</li>
  271. <input type="text" class="gf-form-input" ng-model='current.tagValuesQuery' placeholder="apps.$tag.*" ng-model-onblur></input>
  272. </div>
  273. </div>
  274. <div class="gf-form-group" ng-show="current.options.length">
  275. <h5>Preview of values (shows max 20)</h5>
  276. <div class="gf-form-inline">
  277. <div class="gf-form" ng-repeat="option in current.options | limitTo: 20">
  278. <span class="gf-form-label">{{option.text}}</span>
  279. </div>
  280. </div>
  281. </div>
  282. <div class="alert alert-info gf-form-group" ng-if="infoText">
  283. {{infoText}}
  284. </div>
  285. <div class="gf-form-button-row p-y-0">
  286. <button type="submit" class="btn btn-success" ng-show="mode === 'edit'" ng-click="update();">Update</button>
  287. <button type="submit" class="btn btn-success" ng-show="mode === 'new'" ng-click="add();">Add</button>
  288. </div>
  289. </form>
  290. </div>
  291. </div>