app.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. var $ = require('jquery');
  2. window.jQuery = $;
  3. var bootstrap = require('bootstrap'); //eslint-disable-line no-unused-vars
  4. var bootbox = require('bootbox');
  5. var AppState = require('../app_state');
  6. var Pubsub = require('../lib/pubsub');
  7. var Router = require('../router');
  8. var BaseView = require('./base');
  9. var HeaderView = require('./header');
  10. var TopicsView = require('./topics');
  11. var TopicView = require('./topic');
  12. var ChannelView = require('./channel');
  13. var LookupView = require('./lookup');
  14. var NodesView = require('./nodes');
  15. var NodeView = require('./node');
  16. var CounterView = require('./counter');
  17. var Node = require('../models/node'); //eslint-disable-line no-undef
  18. var Topic = require('../models/topic');
  19. var Channel = require('../models/channel');
  20. var AppView = BaseView.extend({
  21. // not a fan of setting a view's el to an existing element on the page
  22. // for the top-level AppView, it seems appropriate, however
  23. el: '#container',
  24. events: {
  25. 'click .link': 'onLinkClick',
  26. 'click .tombstone-link': 'onTombstoneClick'
  27. },
  28. initialize: function() {
  29. BaseView.prototype.initialize.apply(this, arguments);
  30. this.listenTo(Pubsub, 'topics:show', this.showTopics);
  31. this.listenTo(Pubsub, 'topic:show', this.showTopic);
  32. this.listenTo(Pubsub, 'channel:show', this.showChannel);
  33. this.listenTo(Pubsub, 'lookup:show', this.showLookup);
  34. this.listenTo(Pubsub, 'nodes:show', this.showNodes);
  35. this.listenTo(Pubsub, 'node:show', this.showNode);
  36. this.listenTo(Pubsub, 'counter:show', this.showCounter);
  37. this.listenTo(Pubsub, 'view:ready', function() {
  38. $('.rate').each(function(i, el) {
  39. var $el = $(el);
  40. var interval = AppState.get('STATSD_INTERVAL');
  41. var q = {
  42. 'target': $el.attr('target'),
  43. 'from': '-' + (2 * interval) + 'sec',
  44. 'until': '-' + interval + 'sec',
  45. 'format': 'json',
  46. };
  47. var formatRate = function(data) {
  48. if (data[0] === null ||
  49. data[0]['datapoints'][0] === null ||
  50. data[0]['datapoints'][0][0] < 0) {
  51. return 'N/A';
  52. } else {
  53. return (data[0]['datapoints'][0][0] / interval).toFixed(2);
  54. }
  55. };
  56. $.ajax({
  57. url: AppState.get('GRAPHITE_URL') + '/render',
  58. data: q,
  59. dataType: 'jsonp',
  60. jsonp: 'jsonp'
  61. })
  62. .done(function(data) { $el.html(formatRate(data)); })
  63. .fail(function() { $el.html('ERROR'); });
  64. });
  65. });
  66. this.render();
  67. },
  68. postRender: function() {
  69. this.appendSubview(new HeaderView());
  70. },
  71. showView: function(f) {
  72. window.scrollTo(0, 0);
  73. if (this.currentView) {
  74. this.currentView.remove();
  75. }
  76. this.currentView = f();
  77. this.appendSubview(this.currentView);
  78. },
  79. showTopics: function() {
  80. this.showView(function() {
  81. return new TopicsView();
  82. });
  83. },
  84. showTopic: function(topic) {
  85. this.showView(function() {
  86. var model = new Topic({'name': topic, 'isAdmin': AppState.get('IS_ADMIN')});
  87. return new TopicView({'model': model});
  88. });
  89. },
  90. showChannel: function(topic, channel) {
  91. this.showView(function() {
  92. var model = new Channel({
  93. 'topic': topic,
  94. 'name': channel,
  95. 'isAdmin': AppState.get('IS_ADMIN')
  96. });
  97. return new ChannelView({'model': model});
  98. });
  99. },
  100. showLookup: function() {
  101. this.showView(function() {
  102. return new LookupView({'isAdmin': AppState.get('IS_ADMIN')});
  103. });
  104. },
  105. showNodes: function() {
  106. this.showView(function() {
  107. return new NodesView();
  108. });
  109. },
  110. showNode: function(node) {
  111. this.showView(function() {
  112. var model = new Node({'name': node});
  113. return new NodeView({'model': model});
  114. });
  115. },
  116. showCounter: function() {
  117. this.showView(function() {
  118. return new CounterView();
  119. });
  120. },
  121. onLinkClick: function(e) {
  122. if (e.ctrlKey || e.metaKey) {
  123. // allow ctrl+click to open in a new tab
  124. return;
  125. }
  126. e.preventDefault();
  127. e.stopPropagation();
  128. Router.navigate($(e.currentTarget).attr('href'), {'trigger': true});
  129. },
  130. onTombstoneClick: function(e) {
  131. e.preventDefault();
  132. e.stopPropagation();
  133. var nodeName = $(e.target).data('node');
  134. var topicName = $(e.target).data('topic');
  135. var txt = 'Are you sure you want to <strong>tombstone</strong> <em>' + nodeName + '</em>?';
  136. bootbox.confirm(txt, function(result) {
  137. if (result !== true) {
  138. return;
  139. }
  140. var node = new Node({
  141. 'name': nodeName
  142. });
  143. node.tombstoneTopic(topicName)
  144. .done(function() { window.location.reload(true); })
  145. .fail(this.handleAJAXError.bind(this));
  146. }.bind(this));
  147. }
  148. });
  149. module.exports = AppView;