editor.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <div ng-controller="VariableEditorCtrl" ng-init="init()">
  2. <div class="page-action-bar">
  3. <h3 class="dashboard-settings__header">
  4. <a ng-click="setMode('list')">Variables</a>
  5. <span ng-show="mode === 'new'">&gt; New</span>
  6. <span ng-show="mode === 'edit'">&gt; Edit</span>
  7. </h3>
  8. <div class="page-action-bar__spacer"></div>
  9. <a
  10. type="button"
  11. class="btn btn-primary"
  12. ng-click="setMode('new');"
  13. ng-if="variables.length > 0"
  14. ng-hide="mode === 'edit' || mode === 'new'">
  15. New
  16. </a>
  17. </div>
  18. <div ng-if="mode === 'list'">
  19. <div ng-if="variables.length === 0">
  20. <div class="empty-list-cta">
  21. <div class="empty-list-cta__title">There are no variables added yet</div>
  22. <a ng-click="setMode('new')" class="empty-list-cta__button btn btn-large btn-primary">
  23. <i class="gicon gicon-variable"></i>
  24. Add variable
  25. </a>
  26. <div class="grafana-info-box">
  27. <h5>What do variables do?</h5>
  28. <p>
  29. Variables enable more interactive and dynamic dashboards. Instead of hard-coding things like server or
  30. sensor names in your metric queries you can use variables in their place. Variables are shown as dropdown
  31. select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in
  32. your dashboard. Check out the
  33. <a class="external-link" href="http://docs.grafana.org/reference/templating/" target="_blank">
  34. Templating documentation
  35. </a>
  36. for more information.
  37. </p>
  38. </div>
  39. </div>
  40. </div>
  41. <div ng-if="variables.length">
  42. <table class="filter-table filter-table--hover">
  43. <thead>
  44. <tr>
  45. <th>Variable</th>
  46. <th>Definition</th>
  47. <th colspan="5"></th>
  48. </tr>
  49. </thead>
  50. <tbody>
  51. <tr ng-repeat="variable in variables">
  52. <td style="width: 1%">
  53. <span ng-click="edit(variable)" class="pointer template-variable"> ${{ variable.name }} </span>
  54. </td>
  55. <td style="max-width: 200px;" ng-click="edit(variable)" class="pointer max-width">
  56. {{ variable.definition ? variable.definition : variable.query }}
  57. </td>
  58. <td style="width: 1%">
  59. <i ng-click="_.move(variables,$index,$index-1)" ng-hide="$first" class="pointer fa fa-arrow-up"></i>
  60. </td>
  61. <td style="width: 1%">
  62. <i ng-click="_.move(variables,$index,$index+1)" ng-hide="$last" class="pointer fa fa-arrow-down"></i>
  63. </td>
  64. <td style="width: 1%">
  65. <a ng-click="duplicate(variable)" class="btn btn-inverse btn-small">
  66. Duplicate
  67. </a>
  68. </td>
  69. <td style="width: 1%">
  70. <a ng-click="removeVariable(variable)" class="btn btn-danger btn-small">
  71. <i class="fa fa-remove"></i>
  72. </a>
  73. </td>
  74. </tr>
  75. </tbody>
  76. </table>
  77. </div>
  78. </div>
  79. <form ng-if="mode === 'edit' || mode === 'new'" name="ctrl.form">
  80. <h5 class="section-heading">General</h5>
  81. <div class="gf-form-group">
  82. <div class="gf-form-inline">
  83. <div class="gf-form max-width-19">
  84. <span class="gf-form-label width-6">Name</span>
  85. <input
  86. type="text"
  87. class="gf-form-input"
  88. name="name"
  89. placeholder="name"
  90. ng-model="current.name"
  91. required
  92. ng-pattern="namePattern"
  93. />
  94. </div>
  95. <div class="gf-form max-width-19">
  96. <span class="gf-form-label width-6">
  97. Type
  98. <info-popover mode="right-normal">
  99. {{ variableTypes[current.type].description }}
  100. </info-popover>
  101. </span>
  102. <div class="gf-form-select-wrapper max-width-17">
  103. <select
  104. class="gf-form-input"
  105. ng-model="current.type"
  106. ng-options="k as v.name for (k, v) in variableTypes"
  107. ng-change="typeChanged()"
  108. ></select>
  109. </div>
  110. </div>
  111. </div>
  112. <div class="gf-form" ng-show="ctrl.form.name.$error.pattern">
  113. <span class="gf-form-label gf-form-label--error"
  114. >Template names cannot begin with '__', that's reserved for Grafana's global variables</span
  115. >
  116. </div>
  117. <div class="gf-form-inline">
  118. <div class="gf-form max-width-19">
  119. <span class="gf-form-label width-6">Label</span>
  120. <input type="text" class="gf-form-input" ng-model="current.label" placeholder="optional display name" />
  121. </div>
  122. <div class="gf-form max-width-19">
  123. <span class="gf-form-label width-6">Hide</span>
  124. <div class="gf-form-select-wrapper max-width-15">
  125. <select
  126. class="gf-form-input"
  127. ng-model="current.hide"
  128. ng-options="f.value as f.text for f in hideOptions"
  129. ></select>
  130. </div>
  131. </div>
  132. </div>
  133. </div>
  134. <div ng-if="current.type === 'interval'" class="gf-form-group">
  135. <h5 class="section-heading">Interval Options</h5>
  136. <div class="gf-form">
  137. <span class="gf-form-label width-9">Values</span>
  138. <input
  139. type="text"
  140. class="gf-form-input"
  141. ng-model="current.query"
  142. placeholder="1m,10m,1h,6h,1d,7d"
  143. ng-model-onblur
  144. ng-change="runQuery()"
  145. required
  146. />
  147. </div>
  148. <div class="gf-form-inline">
  149. <gf-form-switch
  150. class="gf-form"
  151. label="Auto Option"
  152. label-class="width-9"
  153. checked="current.auto"
  154. on-change="runQuery()"
  155. >
  156. </gf-form-switch>
  157. <div class="gf-form">
  158. <span class="gf-form-label width-9" ng-show="current.auto">
  159. Step count <tip>How many times should the current time range be divided to calculate the value</tip>
  160. </span>
  161. <div class="gf-form-select-wrapper max-width-10" ng-show="current.auto">
  162. <select
  163. class="gf-form-input"
  164. ng-model="current.auto_count"
  165. ng-options="f for f in [1,2,3,4,5,10,20,30,40,50,100,200,300,400,500]"
  166. ng-change="runQuery()"
  167. ></select>
  168. </div>
  169. </div>
  170. <div class="gf-form">
  171. <span class="gf-form-label" ng-show="current.auto">
  172. Min interval <tip>The calculated value will not go below this threshold</tip>
  173. </span>
  174. <input
  175. type="text"
  176. class="gf-form-input max-width-10"
  177. ng-show="current.auto"
  178. ng-model="current.auto_min"
  179. ng-change="runQuery()"
  180. placeholder="10s"
  181. />
  182. </div>
  183. </div>
  184. </div>
  185. <div ng-if="current.type === 'custom'" class="gf-form-group">
  186. <h5 class="section-heading">Custom Options</h5>
  187. <div class="gf-form">
  188. <span class="gf-form-label width-14">Values separated by comma</span>
  189. <input
  190. type="text"
  191. class="gf-form-input"
  192. ng-model="current.query"
  193. ng-blur="runQuery()"
  194. placeholder="1, 10, 20, myvalue, escaped\,value"
  195. required
  196. />
  197. </div>
  198. </div>
  199. <div ng-if="current.type === 'constant'" class="gf-form-group">
  200. <h5 class="section-heading">Constant options</h5>
  201. <div class="gf-form">
  202. <span class="gf-form-label">Value</span>
  203. <input
  204. type="text"
  205. class="gf-form-input"
  206. ng-model="current.query"
  207. ng-blur="runQuery()"
  208. placeholder="your metric prefix"
  209. />
  210. </div>
  211. </div>
  212. <div ng-if="current.type === 'textbox'" class="gf-form-group">
  213. <h5 class="section-heading">Text options</h5>
  214. <div class="gf-form">
  215. <span class="gf-form-label">Default value</span>
  216. <input
  217. type="text"
  218. class="gf-form-input"
  219. ng-model="current.query"
  220. ng-blur="runQuery()"
  221. placeholder="default value, if any"
  222. />
  223. </div>
  224. </div>
  225. <div ng-if="current.type === 'query'" class="gf-form-group">
  226. <h5 class="section-heading">Query Options</h5>
  227. <div class="gf-form-inline">
  228. <div class="gf-form max-width-21">
  229. <span class="gf-form-label width-10">Data source</span>
  230. <div class="gf-form-select-wrapper max-width-14">
  231. <select
  232. class="gf-form-input"
  233. ng-model="current.datasource"
  234. ng-options="f.value as f.name for f in datasources"
  235. ng-change="datasourceChanged()"
  236. required
  237. >
  238. <option value="" ng-if="false"></option>
  239. </select>
  240. </div>
  241. </div>
  242. <div class="gf-form max-width-22">
  243. <span class="gf-form-label width-10">
  244. Refresh
  245. <info-popover mode="right-normal">
  246. When to update the values of this variable.
  247. </info-popover>
  248. </span>
  249. <div class="gf-form-select-wrapper width-15">
  250. <select
  251. class="gf-form-input"
  252. ng-model="current.refresh"
  253. ng-options="f.value as f.text for f in refreshOptions"
  254. ></select>
  255. </div>
  256. </div>
  257. </div>
  258. <rebuild-on-change property="currentDatasource">
  259. <variable-query-editor-loader> </variable-query-editor-loader>
  260. </rebuild-on-change>
  261. <div class="gf-form">
  262. <span class="gf-form-label width-10">
  263. Regex
  264. <info-popover mode="right-normal">
  265. Optional, if you want to extract part of a series name or metric node segment.
  266. </info-popover>
  267. </span>
  268. <input
  269. type="text"
  270. class="gf-form-input"
  271. ng-model="current.regex"
  272. placeholder="/.*-(.*)-.*/"
  273. ng-model-onblur
  274. ng-change="runQuery()"
  275. />
  276. </div>
  277. <div class="gf-form max-width-21">
  278. <span class="gf-form-label width-10">
  279. Sort
  280. <info-popover mode="right-normal">
  281. How to sort the values of this variable.
  282. </info-popover>
  283. </span>
  284. <div class="gf-form-select-wrapper max-width-14">
  285. <select
  286. class="gf-form-input"
  287. ng-model="current.sort"
  288. ng-options="f.value as f.text for f in sortOptions"
  289. ng-change="runQuery()"
  290. ></select>
  291. </div>
  292. </div>
  293. </div>
  294. <div ng-show="current.type === 'datasource'" class="gf-form-group">
  295. <h5 class="section-heading">Data source options</h5>
  296. <div class="gf-form">
  297. <label class="gf-form-label width-12">Type</label>
  298. <div class="gf-form-select-wrapper max-width-18">
  299. <select
  300. class="gf-form-input"
  301. ng-model="current.query"
  302. ng-options="f.value as f.text for f in datasourceTypes"
  303. ng-change="runQuery()"
  304. ></select>
  305. </div>
  306. </div>
  307. <div class="gf-form">
  308. <label class="gf-form-label width-12">
  309. Instance name filter
  310. <info-popover mode="right-normal">
  311. Regex filter for which data source instances to choose from in the variable value dropdown. Leave empty for
  312. all.
  313. <br /><br />
  314. Example: <code>/^prod/</code>
  315. </info-popover>
  316. </label>
  317. <input
  318. type="text"
  319. class="gf-form-input max-width-18"
  320. ng-model="current.regex"
  321. placeholder="/.*-(.*)-.*/"
  322. ng-model-onblur
  323. ng-change="runQuery()"
  324. />
  325. </div>
  326. </div>
  327. <div ng-if="current.type === 'adhoc'" class="gf-form-group">
  328. <h5 class="section-heading">Options</h5>
  329. <div class="gf-form max-width-21">
  330. <span class="gf-form-label width-8">Data source</span>
  331. <div class="gf-form-select-wrapper max-width-14">
  332. <select
  333. class="gf-form-input"
  334. ng-model="current.datasource"
  335. ng-options="f.value as f.name for f in datasources"
  336. required
  337. ng-change="validate()"
  338. >
  339. <option value="" ng-if="false"></option>
  340. </select>
  341. </div>
  342. </div>
  343. </div>
  344. <div class="section gf-form-group" ng-show="variableTypes[current.type].supportsMulti">
  345. <h5 class="section-heading">Selection Options</h5>
  346. <div class="section">
  347. <gf-form-switch
  348. class="gf-form"
  349. label="Multi-value"
  350. label-class="width-10"
  351. tooltip="Enables multiple values to be selected at the same time"
  352. checked="current.multi"
  353. on-change="runQuery()"
  354. >
  355. </gf-form-switch>
  356. <gf-form-switch
  357. class="gf-form"
  358. label="Include All option"
  359. label-class="width-10"
  360. checked="current.includeAll"
  361. on-change="runQuery()"
  362. >
  363. </gf-form-switch>
  364. </div>
  365. <div class="gf-form" ng-if="current.includeAll">
  366. <span class="gf-form-label width-10">Custom all value</span>
  367. <input type="text" class="gf-form-input max-width-15" ng-model="current.allValue" placeholder="blank = auto" />
  368. </div>
  369. </div>
  370. <div class="gf-form-group" ng-if="current.type === 'query'">
  371. <h5>Value groups/tags (Experimental feature)</h5>
  372. <gf-form-switch
  373. class="gf-form"
  374. label="Enabled"
  375. label-class="width-10"
  376. checked="current.useTags"
  377. on-change="runQuery()"
  378. >
  379. </gf-form-switch>
  380. <div class="gf-form last" ng-if="current.useTags">
  381. <span class="gf-form-label width-10">Tags query</span>
  382. <input
  383. type="text"
  384. class="gf-form-input"
  385. ng-model="current.tagsQuery"
  386. placeholder="metric name or tags query"
  387. ng-model-onblur
  388. />
  389. </div>
  390. <div class="gf-form" ng-if="current.useTags">
  391. <li class="gf-form-label width-10">Tag values query</li>
  392. <input
  393. type="text"
  394. class="gf-form-input"
  395. ng-model="current.tagValuesQuery"
  396. placeholder="apps.$tag.*"
  397. ng-model-onblur
  398. />
  399. </div>
  400. </div>
  401. <div class="gf-form-group" ng-show="current.options.length">
  402. <h5>Preview of values</h5>
  403. <div class="gf-form-inline">
  404. <div class="gf-form" ng-repeat="option in current.options | limitTo: optionsLimit">
  405. <span class="gf-form-label">{{ option.text }}</span>
  406. </div>
  407. <div class="gf-form" ng-if="current.options.length > optionsLimit">
  408. <a class="gf-form-label btn-secondary" ng-click="showMoreOptions()">Show more</a>
  409. </div>
  410. </div>
  411. </div>
  412. <div class="alert alert-info gf-form-group" ng-if="infoText">
  413. {{ infoText }}
  414. </div>
  415. <div class="gf-form-button-row p-y-0">
  416. <button type="submit" class="btn btn-primary" ng-show="mode === 'edit'" ng-click="update();">Update</button>
  417. <button type="submit" class="btn btn-primary" ng-show="mode === 'new'" ng-click="add();">Add</button>
  418. </div>
  419. </form>
  420. </div>