alert_definitions_view.js 13 KB

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