alert_definitions_view.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. var filters = require('views/common/filter_view'),
  20. sort = require('views/common/sort_view'),
  21. date = require('utils/date');
  22. App.MainAlertDefinitionsView = App.TableView.extend({
  23. templateName: require('templates/main/alerts'),
  24. content: function() {
  25. return this.get('controller.content') ? this.get('controller.content').toArray().sort(App.AlertDefinition.getSortDefinitionsByStatus(true)) : [];
  26. }.property('controller.content.@each'),
  27. willInsertElement: function () {
  28. if (!this.get('controller.showFilterConditionsFirstLoad')) {
  29. this.clearFilterCondition();
  30. this.clearStartIndex();
  31. }
  32. this.removeObserver('filteredCount', this, 'updatePaging');
  33. this.removeObserver('displayLength', this, 'updatePaging');
  34. var startIndex = App.db.getStartIndex(this.get('controller.name'));
  35. this._super();
  36. this.set('startIndex', startIndex ? startIndex : 1);
  37. this.addObserver('filteredCount', this, 'updatePaging');
  38. this.addObserver('displayLength', this, 'updatePaging');
  39. },
  40. /**
  41. * Method is same as in the parentView, but observes are set in the <code>willInsertElement</code>
  42. * and not in the declaration
  43. */
  44. updatePaging: function () {
  45. this._super();
  46. },
  47. didInsertElement: function () {
  48. var self = this;
  49. Em.run.next(function () {
  50. self.set('isInitialRendering', false);
  51. self.tooltipsUpdater();
  52. });
  53. },
  54. willDestroyElement: function () {
  55. this.removeObserver('pageContent.length', this, 'tooltipsUpdater');
  56. },
  57. /**
  58. * Save <code>startIndex</code> to the localStorage
  59. * @method saveStartIndex
  60. */
  61. saveStartIndex: function() {
  62. App.db.setStartIndex(this.get('controller.name'), this.get('startIndex'));
  63. }.observes('startIndex'),
  64. /**
  65. * Clear <code>startIndex</code> from the localStorage
  66. * @method clearStartIndex
  67. */
  68. clearStartIndex: function () {
  69. App.db.setStartIndex(this.get('controller.name'), null);
  70. },
  71. /**
  72. * @type {number}
  73. */
  74. totalCount: function () {
  75. return this.get('content.length');
  76. }.property('content.length'),
  77. colPropAssoc: ['', 'label', 'summary', 'serviceName', 'type', 'lastTriggered', 'enabled', 'groups'],
  78. /**
  79. * @type {string}
  80. */
  81. enabledTooltip: Em.I18n.t('alerts.table.state.enabled.tooltip'),
  82. /**
  83. * @type {string}
  84. */
  85. disabledTooltip: Em.I18n.t('alerts.table.state.disabled.tooltip'),
  86. /**
  87. * @type {string}
  88. */
  89. enabledDisplay: Em.I18n.t('alerts.table.state.enabled'),
  90. /**
  91. * @type {string}
  92. */
  93. disabledDisplay: Em.I18n.t('alerts.table.state.disabled'),
  94. sortView: sort.wrapperView,
  95. /**
  96. * Define whether initial view rendering has finished
  97. * @type {Boolean}
  98. */
  99. isInitialRendering: true,
  100. /**
  101. * Sorting header for <label>alertDefinition.label</label>
  102. * @type {Em.View}
  103. */
  104. nameSort: sort.fieldView.extend({
  105. column: 1,
  106. name: 'label',
  107. displayName: Em.I18n.t('alerts.table.header.definitionName')
  108. }),
  109. /**
  110. * Sorting header for <label>alertDefinition.status</label>
  111. * @type {Em.View}
  112. */
  113. statusSort: sort.fieldView.extend({
  114. column: 2,
  115. name: 'summary',
  116. displayName: Em.I18n.t('common.status'),
  117. type: 'alert_status',
  118. status: 'sorting_desc'
  119. }),
  120. /**
  121. * Sorting header for <label>alertDefinition.service.serviceName</label>
  122. * @type {Em.View}
  123. */
  124. serviceSort: sort.fieldView.extend({
  125. column: 3,
  126. name: 'serviceDisplayName',
  127. displayName: Em.I18n.t('common.service'),
  128. type: 'string'
  129. }),
  130. /**
  131. * Sorting header for <label>alertDefinition.type</label>
  132. * @type {Em.View}
  133. */
  134. typeSort: sort.fieldView.extend({
  135. column: 4,
  136. name: 'type',
  137. displayName: Em.I18n.t('common.type'),
  138. type: 'string'
  139. }),
  140. /**
  141. * Sorting header for <label>alertDefinition.lastTriggeredSort</label>
  142. * @type {Em.View}
  143. */
  144. lastTriggeredSort: sort.fieldView.extend({
  145. column: 5,
  146. name: 'lastTriggered',
  147. displayName: Em.I18n.t('alerts.table.header.lastTriggered'),
  148. type: 'number'
  149. }),
  150. /**
  151. * Sorting header for <label>alertDefinition.enabled</label>
  152. * @type {Em.View}
  153. */
  154. enabledSort: sort.fieldView.extend({
  155. template:Em.Handlebars.compile('<span {{bindAttr class="view.status :column-name"}}>{{t alerts.table.state}}</span>'),
  156. column: 6,
  157. name: 'enabled'
  158. }),
  159. /**
  160. * Filtering header for <label>alertDefinition.label</label>
  161. * @type {Em.View}
  162. */
  163. nameFilterView: filters.createTextView({
  164. column: 1,
  165. fieldType: 'filter-input-width',
  166. onChangeValue: function(){
  167. this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
  168. }
  169. }),
  170. /**
  171. * Filtering header for <label>alertDefinition.status</label>
  172. * @type {Em.View}
  173. */
  174. stateFilterView: filters.createSelectView({
  175. column: 2,
  176. fieldType: 'filter-input-width',
  177. content: [
  178. {
  179. value: '',
  180. label: Em.I18n.t('common.all')
  181. },
  182. {
  183. value: 'OK',
  184. label: 'OK'
  185. },
  186. {
  187. value: 'WARNING',
  188. label: 'WARNING'
  189. },
  190. {
  191. value: 'CRITICAL',
  192. label: 'CRITICAL'
  193. },
  194. {
  195. value: 'UNKNOWN',
  196. label: 'UNKNOWN'
  197. },
  198. {
  199. value: 'PENDING',
  200. label: 'NONE'
  201. }
  202. ],
  203. onChangeValue: function () {
  204. this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'alert_status');
  205. }
  206. }),
  207. /**
  208. * Filtering header for <label>alertDefinition.service.serviceName</label>
  209. * @type {Em.View}
  210. */
  211. serviceFilterView: filters.createSelectView({
  212. column: 3,
  213. fieldType: 'filter-input-width',
  214. content: function () {
  215. return [
  216. {
  217. value: '',
  218. label: Em.I18n.t('common.all')
  219. }
  220. ].concat(App.Service.find().map(function (service) {
  221. return {
  222. value: service.get('serviceName'),
  223. label: service.get('displayName')
  224. }
  225. }).concat([
  226. {
  227. value: 'AMBARI',
  228. label: Em.I18n.t('app.name')
  229. }
  230. ]));
  231. }.property('App.router.clusterController.isLoaded'),
  232. onChangeValue: function () {
  233. this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
  234. }
  235. }),
  236. /**
  237. * Filtering header for <label>alertDefinition.type</label>
  238. * @type {Em.View}
  239. */
  240. typeFilterView: filters.createSelectView({
  241. column: 4,
  242. fieldType: 'filter-input-width',
  243. content: [
  244. {
  245. value: '',
  246. label: Em.I18n.t('common.all')
  247. },
  248. {
  249. value: 'SCRIPT',
  250. label: 'SCRIPT'
  251. },
  252. {
  253. value: 'WEB',
  254. label: 'WEB'
  255. },
  256. {
  257. value: 'PORT',
  258. label: 'PORT'
  259. },
  260. {
  261. value: 'METRIC',
  262. label: 'METRIC'
  263. },
  264. {
  265. value: 'AGGREGATE',
  266. label: 'AGGREGATE'
  267. },
  268. {
  269. value: 'SERVER',
  270. label: 'SERVER'
  271. }
  272. ],
  273. onChangeValue: function(){
  274. this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
  275. }
  276. }),
  277. /**
  278. * Filtering header for <label>alertDefinition.lastTriggered</label>
  279. * @type {Em.View}
  280. */
  281. triggeredFilterView: filters.createSelectView({
  282. column: 5,
  283. appliedEmptyValue: ["", ""],
  284. fieldType: 'filter-input-width,modified-filter',
  285. content: [
  286. {
  287. value: 'Any',
  288. label: Em.I18n.t('any')
  289. },
  290. {
  291. value: 'Past 1 hour',
  292. label: 'Past 1 hour'
  293. },
  294. {
  295. value: 'Past 1 Day',
  296. label: 'Past 1 Day'
  297. },
  298. {
  299. value: 'Past 2 Days',
  300. label: 'Past 2 Days'
  301. },
  302. {
  303. value: 'Past 7 Days',
  304. label: 'Past 7 Days'
  305. },
  306. {
  307. value: 'Past 14 Days',
  308. label: 'Past 14 Days'
  309. },
  310. {
  311. value: 'Past 30 Days',
  312. label: 'Past 30 Days'
  313. }
  314. ],
  315. emptyValue: 'Any',
  316. onChangeValue: function () {
  317. this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'date');
  318. }
  319. }),
  320. /**
  321. * Filtering header for <label>alertDefinition.enabled</label>
  322. * @type {Em.View}
  323. */
  324. enabledFilterView: filters.createSelectView({
  325. column: 6,
  326. fieldType: 'filter-input-width',
  327. content: [
  328. {
  329. value: '',
  330. label: Em.I18n.t('common.all')
  331. },
  332. {
  333. value: 'enabled',
  334. label: Em.I18n.t('alerts.table.state.enabled')
  335. },
  336. {
  337. value: 'disabled',
  338. label: Em.I18n.t('alerts.table.state.disabled')
  339. }
  340. ],
  341. onChangeValue: function () {
  342. this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'enable_disable');
  343. }
  344. }),
  345. /**
  346. * Filtering header for <label>alertDefinition</label> groups
  347. * @type {Em.View}
  348. */
  349. alertGroupFilterView: filters.createSelectView({
  350. column: 7,
  351. fieldType: 'filter-input-width',
  352. template: Ember.Handlebars.compile(
  353. '<div class="btn-group display-inline-block">' +
  354. '<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">' +
  355. '<span class="filters-label">Groups:&nbsp;&nbsp;</span>' +
  356. '<span>{{view.selected.label}}&nbsp;<span class="caret"></span></span>' +
  357. '</a>' +
  358. '<ul class="dropdown-menu">' +
  359. '{{#each category in view.content}}' +
  360. '<li {{bindAttr class=":category-item category.selected:active"}}>' +
  361. '<a {{action selectCategory category target="view"}} href="#">' +
  362. '<span {{bindAttr class="category.class"}}></span>{{category.label}}</a>' +
  363. '</li>'+
  364. '{{/each}}' +
  365. '</ul>'+
  366. '</div>'
  367. ),
  368. content: [],
  369. didInsertElement: function() {
  370. this._super();
  371. this.updateContent();
  372. this.set('value', '');
  373. },
  374. emptyValue: '',
  375. /**
  376. * Update list of <code>App.AlertGroup</code> used in the filter
  377. * @method updateContent
  378. */
  379. updateContent: function() {
  380. var defaultGroups = [];
  381. var customGroups = [];
  382. App.AlertGroup.find().forEach(function (group) {
  383. var item = Em.Object.create({
  384. value: group.get('id'),
  385. label: group.get('displayNameDefinitions')
  386. });
  387. if (group.get('default')) {
  388. defaultGroups.push(item);
  389. } else {
  390. customGroups.push(item);
  391. }
  392. });
  393. defaultGroups = defaultGroups.sortProperty('label');
  394. customGroups = customGroups.sortProperty('label');
  395. this.set('content', [
  396. Em.Object.create({
  397. value: '',
  398. label: Em.I18n.t('common.all') + ' (' + this.get('parentView.controller.content.length') + ')'
  399. })
  400. ].concat(defaultGroups, customGroups));
  401. this.onValueChange();
  402. }.observes('App.router.clusterController.isLoaded', 'App.router.manageAlertGroupsController.changeTrigger'),
  403. selectCategory: function (event) {
  404. var category = event.context;
  405. this.set('value', category.value);
  406. this.get('parentView').updateFilter(this.get('column'), category.value, 'alert_group');
  407. },
  408. onValueChange: function () {
  409. var value = this.get('value');
  410. if (value != undefined) {
  411. this.get('content').setEach('selected', false);
  412. this.set('selected', this.get('content').findProperty('value', value));
  413. var selectEntry = this.get('content').findProperty('value', value);
  414. if (selectEntry) {
  415. selectEntry.set('selected', true);
  416. }
  417. this.get('parentView').updateFilter(this.get('column'), value, 'alert_group');
  418. } else {
  419. this.set('value', '');
  420. this.get('parentView').updateFilter(this.get('column'), '', 'alert_group');
  421. }
  422. }.observes('value')
  423. }),
  424. /**
  425. * Filtered number of all content number information displayed on the page footer bar
  426. * @returns {String}
  427. */
  428. filteredContentInfo: function () {
  429. return this.t('alerts.filters.filteredAlertsInfo').format(this.get('filteredCount'), this.get('totalCount'));
  430. }.property('filteredCount', 'totalCount'),
  431. /**
  432. * Determines how display "back"-link - as link or text
  433. * @type {string}
  434. */
  435. paginationLeftClass: function () {
  436. if (this.get("startIndex") > 1) {
  437. return "paginate_previous";
  438. }
  439. return "paginate_disabled_previous";
  440. }.property("startIndex", 'filteredCount'),
  441. /**
  442. * Determines how display "next"-link - as link or text
  443. * @type {string}
  444. */
  445. paginationRightClass: function () {
  446. if ((this.get("endIndex")) < this.get("filteredCount")) {
  447. return "paginate_next";
  448. }
  449. return "paginate_disabled_next";
  450. }.property("endIndex", 'filteredCount'),
  451. /**
  452. * Show previous-page if user not in the first page
  453. * @method previousPage
  454. */
  455. previousPage: function () {
  456. if (this.get('paginationLeftClass') === 'paginate_previous') {
  457. this._super();
  458. }
  459. this.tooltipsUpdater();
  460. },
  461. /**
  462. * Show next-page if user not in the last page
  463. * @method nextPage
  464. */
  465. nextPage: function () {
  466. if (this.get('paginationRightClass') === 'paginate_next') {
  467. this._super();
  468. }
  469. this.tooltipsUpdater();
  470. },
  471. /**
  472. * Update tooltips when <code>pageContent</code> is changed
  473. * @method tooltipsUpdater
  474. */
  475. tooltipsUpdater: function () {
  476. Em.run.next(this, function () {
  477. App.tooltip($(".enable-disable-button, .timeago"));
  478. });
  479. },
  480. updateFilter: function (iColumn, value, type) {
  481. if (!this.get('isInitialRendering')) {
  482. this._super(iColumn, value, type);
  483. }
  484. this.tooltipsUpdater();
  485. }
  486. });