query_parameter_ctrl.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import angular, { IQService } from 'angular';
  2. import coreModule from 'app/core/core_module';
  3. import _ from 'lodash';
  4. import { TemplateSrv } from 'app/features/templating/template_srv';
  5. import DatasourceSrv from 'app/features/plugins/datasource_srv';
  6. export class CloudWatchQueryParameterCtrl {
  7. /** @ngInject */
  8. constructor($scope: any, templateSrv: TemplateSrv, uiSegmentSrv: any, datasourceSrv: DatasourceSrv, $q: IQService) {
  9. $scope.init = () => {
  10. const target = $scope.target;
  11. target.namespace = target.namespace || '';
  12. target.metricName = target.metricName || '';
  13. target.statistics = target.statistics || ['Average'];
  14. target.dimensions = target.dimensions || {};
  15. target.period = target.period || '';
  16. target.region = target.region || 'default';
  17. target.id = target.id || '';
  18. target.expression = target.expression || '';
  19. target.highResolution = target.highResolution || false;
  20. $scope.regionSegment = uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region');
  21. $scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');
  22. $scope.metricSegment = uiSegmentSrv.getSegmentForValue($scope.target.metricName, 'select metric');
  23. $scope.dimSegments = _.reduce(
  24. $scope.target.dimensions,
  25. (memo, value, key) => {
  26. memo.push(uiSegmentSrv.newKey(key));
  27. memo.push(uiSegmentSrv.newOperator('='));
  28. memo.push(uiSegmentSrv.newKeyValue(value));
  29. return memo;
  30. },
  31. []
  32. );
  33. $scope.statSegments = _.map($scope.target.statistics, stat => {
  34. return uiSegmentSrv.getSegmentForValue(stat);
  35. });
  36. $scope.ensurePlusButton($scope.statSegments);
  37. $scope.ensurePlusButton($scope.dimSegments);
  38. $scope.removeDimSegment = uiSegmentSrv.newSegment({
  39. fake: true,
  40. value: '-- remove dimension --',
  41. });
  42. $scope.removeStatSegment = uiSegmentSrv.newSegment({
  43. fake: true,
  44. value: '-- remove stat --',
  45. });
  46. if (_.isEmpty($scope.target.region)) {
  47. $scope.target.region = 'default';
  48. }
  49. if (!$scope.onChange) {
  50. $scope.onChange = () => {};
  51. }
  52. };
  53. $scope.getStatSegments = () => {
  54. return $q.when(
  55. _.flatten([
  56. angular.copy($scope.removeStatSegment),
  57. _.map($scope.datasource.standardStatistics, s => {
  58. return uiSegmentSrv.getSegmentForValue(s);
  59. }),
  60. uiSegmentSrv.getSegmentForValue('pNN.NN'),
  61. ])
  62. );
  63. };
  64. $scope.statSegmentChanged = (segment: any, index: number) => {
  65. if (segment.value === $scope.removeStatSegment.value) {
  66. $scope.statSegments.splice(index, 1);
  67. } else {
  68. segment.type = 'value';
  69. }
  70. $scope.target.statistics = _.reduce(
  71. $scope.statSegments,
  72. (memo, seg) => {
  73. if (!seg.fake) {
  74. memo.push(seg.value);
  75. }
  76. return memo;
  77. },
  78. []
  79. );
  80. $scope.ensurePlusButton($scope.statSegments);
  81. $scope.onChange();
  82. };
  83. $scope.ensurePlusButton = (segments: any) => {
  84. const count = segments.length;
  85. const lastSegment = segments[Math.max(count - 1, 0)];
  86. if (!lastSegment || lastSegment.type !== 'plus-button') {
  87. segments.push(uiSegmentSrv.newPlusButton());
  88. }
  89. };
  90. $scope.getDimSegments = (segment: any, $index: number) => {
  91. if (segment.type === 'operator') {
  92. return $q.when([]);
  93. }
  94. const target = $scope.target;
  95. let query = $q.when([]);
  96. if (segment.type === 'key' || segment.type === 'plus-button') {
  97. query = $scope.datasource.getDimensionKeys($scope.target.namespace, $scope.target.region);
  98. } else if (segment.type === 'value') {
  99. const dimensionKey = $scope.dimSegments[$index - 2].value;
  100. delete target.dimensions[dimensionKey];
  101. query = $scope.datasource.getDimensionValues(
  102. target.region,
  103. target.namespace,
  104. target.metricName,
  105. dimensionKey,
  106. target.dimensions
  107. );
  108. }
  109. return query.then($scope.transformToSegments(true)).then(results => {
  110. if (segment.type === 'key') {
  111. results.splice(0, 0, angular.copy($scope.removeDimSegment));
  112. }
  113. return results;
  114. });
  115. };
  116. $scope.dimSegmentChanged = (segment: any, index: number) => {
  117. $scope.dimSegments[index] = segment;
  118. if (segment.value === $scope.removeDimSegment.value) {
  119. $scope.dimSegments.splice(index, 3);
  120. } else if (segment.type === 'plus-button') {
  121. $scope.dimSegments.push(uiSegmentSrv.newOperator('='));
  122. $scope.dimSegments.push(uiSegmentSrv.newFake('select dimension value', 'value', 'query-segment-value'));
  123. segment.type = 'key';
  124. segment.cssClass = 'query-segment-key';
  125. }
  126. $scope.syncDimSegmentsWithModel();
  127. $scope.ensurePlusButton($scope.dimSegments);
  128. $scope.onChange();
  129. };
  130. $scope.syncDimSegmentsWithModel = () => {
  131. const dims: any = {};
  132. const length = $scope.dimSegments.length;
  133. for (let i = 0; i < length - 2; i += 3) {
  134. const keySegment = $scope.dimSegments[i];
  135. const valueSegment = $scope.dimSegments[i + 2];
  136. if (!valueSegment.fake) {
  137. dims[keySegment.value] = valueSegment.value;
  138. }
  139. }
  140. $scope.target.dimensions = dims;
  141. };
  142. $scope.getRegions = () => {
  143. return $scope.datasource
  144. .metricFindQuery('regions()')
  145. .then((results: any) => {
  146. results.unshift({ text: 'default' });
  147. return results;
  148. })
  149. .then($scope.transformToSegments(true));
  150. };
  151. $scope.getNamespaces = () => {
  152. return $scope.datasource.metricFindQuery('namespaces()').then($scope.transformToSegments(true));
  153. };
  154. $scope.getMetrics = () => {
  155. return $scope.datasource
  156. .metricFindQuery('metrics(' + $scope.target.namespace + ',' + $scope.target.region + ')')
  157. .then($scope.transformToSegments(true));
  158. };
  159. $scope.regionChanged = () => {
  160. $scope.target.region = $scope.regionSegment.value;
  161. $scope.onChange();
  162. };
  163. $scope.namespaceChanged = () => {
  164. $scope.target.namespace = $scope.namespaceSegment.value;
  165. $scope.onChange();
  166. };
  167. $scope.metricChanged = () => {
  168. $scope.target.metricName = $scope.metricSegment.value;
  169. $scope.onChange();
  170. };
  171. $scope.transformToSegments = (addTemplateVars: any) => {
  172. return (results: any) => {
  173. const segments = _.map(results, segment => {
  174. return uiSegmentSrv.newSegment({
  175. value: segment.text,
  176. expandable: segment.expandable,
  177. });
  178. });
  179. if (addTemplateVars) {
  180. _.each(templateSrv.variables, variable => {
  181. segments.unshift(
  182. uiSegmentSrv.newSegment({
  183. type: 'template',
  184. value: '$' + variable.name,
  185. expandable: true,
  186. })
  187. );
  188. });
  189. }
  190. return segments;
  191. };
  192. };
  193. $scope.init();
  194. }
  195. }
  196. export function cloudWatchQueryParameter() {
  197. return {
  198. templateUrl: 'public/app/plugins/datasource/cloudwatch/partials/query.parameter.html',
  199. controller: CloudWatchQueryParameterCtrl,
  200. restrict: 'E',
  201. scope: {
  202. target: '=',
  203. datasource: '=',
  204. onChange: '&',
  205. },
  206. };
  207. }
  208. coreModule.directive('cloudwatchQueryParameter', cloudWatchQueryParameter);