PageRenderTime 81ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 0ms

/devstream/static/js/dashboard.js

https://github.com/marconi/devstream
JavaScript | 267 lines | 218 code | 23 blank | 26 comment | 8 complexity | 9fa543fbb95604e0feacdc5b97197a17 MD5 | raw file
  1. (function($) {
  2. /**
  3. * Models and Collections
  4. */
  5. window.GroupItem = Backbone.Model.extend({
  6. urlRoot: '/group/',
  7. defaults: function() {
  8. return {
  9. owner_id: null,
  10. name: null,
  11. members: 0,
  12. last_activity: null,
  13. selected: false
  14. }
  15. },
  16. toggleSelected: function() {
  17. this.set({selected: !this.get('selected')});
  18. }
  19. });
  20. window.GroupItemList = Backbone.Collection.extend({
  21. model: GroupItem,
  22. url: '/groups/',
  23. comparator: function(groupItem) {
  24. // sort in descending so the last added is at the top
  25. return groupItem.get("id");
  26. },
  27. // filter down selected groups
  28. selected: function() {
  29. return this.filter(function(group){
  30. return group.get('selected');
  31. });
  32. }
  33. });
  34. /**
  35. * Views
  36. */
  37. window.GroupItemView = Backbone.View.extend({
  38. tagName: 'li',
  39. initialize: function() {
  40. _.bindAll(this, 'render');
  41. // listen for events
  42. this.model.bind('change', this.render, this);
  43. this.model.bind('destroy', this.remove, this);
  44. this.template = _.template($('#group-item-template').html());
  45. },
  46. events: {
  47. 'click .group-selection input': 'toggleSelection'
  48. },
  49. toggleSelection: function(e) {
  50. this.model.toggleSelected();
  51. },
  52. render: function() {
  53. var renderedContent = this.template(this.model.toJSON());
  54. $(this.el).html(renderedContent);
  55. return this;
  56. },
  57. remove: function() {
  58. $(this.el).remove();
  59. }
  60. });
  61. window.GroupsView = Backbone.View.extend({
  62. initialize: function() {
  63. _.bindAll(this, 'render');
  64. this.template = _.template($('#group-template').html());
  65. this.action_template = _.template($('#group-action-template').html());
  66. // listen for reset event
  67. this.collection.bind('change', this.render, this);
  68. this.collection.bind('reset', this.reset, this);
  69. this.collection.bind('add', this.addItem, this);
  70. this.collection.bind('remove', this.reset, this);
  71. this.collection.bind('remove', this.render, this);
  72. // render initially so adding items below
  73. // triggers the render.
  74. $(this.el).html(this.template({}));
  75. // also render group action
  76. this.$("#group-action-wrapper").html(this.action_template({
  77. selected: 0
  78. }));
  79. this.collection.fetch();
  80. },
  81. events: {
  82. 'click .modal-wrapper a.close': 'closeOverlay',
  83. 'click #create-group': 'createGroup',
  84. 'click .modal-footer a': 'createGroupSubmit',
  85. 'keypress input[name=groupName]': 'createGroupSubmit',
  86. 'submit #create-group-modal form': 'interceptFormSubmit',
  87. 'click #leave-group': 'leaveGroup',
  88. 'click #cancel': 'closeOverlay',
  89. 'click #leaving-ok': 'leaveGroupSubmit',
  90. 'keyup input[name=group_filter]': 'filterGroup'
  91. },
  92. filterGroup: function() {
  93. var filter = this.$("input[name=group_filter]").val();
  94. this.$("#group-list li").each(function () {
  95. var groupName = $(this).find(".group-name").text();
  96. if (groupName.search(new RegExp(filter, "i")) < 0) {
  97. $(this).hide();
  98. } else {
  99. $(this).show();
  100. }
  101. });
  102. },
  103. closeOverlay: function(e) {
  104. this.$("#create-group-modal").hide();
  105. this.$("#leaving-group-modal").hide();
  106. this.$(".modal-wrapper").hide();
  107. this.$(".modal-overlay").hide();
  108. this.$(".modal-body").removeClass("success");
  109. this.$(".modal-body").removeClass("error");
  110. this.$(".modal-body .message").html("").hide();
  111. // this check is needed since calling closeOverlay
  112. // directly makes e = undefined.
  113. if (e !== undefined) {
  114. e.preventDefault();
  115. }
  116. },
  117. createGroup: function(e) {
  118. this.$(".modal-overlay").show();
  119. this.$(".modal-wrapper").show();
  120. this.$("#create-group-modal").show();
  121. this.$("input[name=groupName]").val("").focus();
  122. e.preventDefault();
  123. },
  124. interceptFormSubmit: function(e) {
  125. return false;
  126. },
  127. createGroupSubmit: function(e) {
  128. if (e.keyCode !== 13) {
  129. return;
  130. }
  131. var groupsView = this;
  132. var groupName = this.$("input[name=groupName]").val();
  133. // clear message indicators
  134. this.$(".modal-body").removeClass("success");
  135. this.$(".modal-body").removeClass("error");
  136. // if the group name is empty,
  137. // show error message.
  138. if (groupName.trim() === "") {
  139. this.$(".modal-body").addClass("error");
  140. this.$(".modal-body .message").html("Group name is required");
  141. this.$(".modal-body .message").show();
  142. return;
  143. }
  144. var group = new GroupItem({name: groupName});
  145. group.save({}, {
  146. success: function(model, response) {
  147. groupsView.collection.add(model);
  148. groupsView.collection.sort();
  149. // show success message
  150. var msg = "Group has been added successfully.";
  151. groupsView.$(".modal-body").addClass("success");
  152. groupsView.$(".modal-body .message").html(msg);
  153. groupsView.$(".modal-body .message").show();
  154. groupsView.$("input[name=groupName]").val('').focus();
  155. },
  156. error: function(model, response) {
  157. var msg = "Unable to save your group, please try again.";
  158. groupsView.$(".modal-body").addClass("error");
  159. groupsView.$(".modal-body .message").html(msg);
  160. groupsView.$(".modal-body .message").show();
  161. }
  162. });
  163. e.preventDefault();
  164. },
  165. leaveGroup: function(e) {
  166. // reset leaving group overlay
  167. this.$("#leaving-group-modal h3").hide();
  168. this.$("#leaving-group-modal .modal-body p").hide();
  169. if (this._checkForOwnedGroup()) {
  170. this.$("#leaving-group-modal h3.owner").show();
  171. this.$("#leaving-group-modal .modal-body p.owner").show();
  172. }
  173. else {
  174. this.$("#leaving-group-modal h3.member").show();
  175. this.$("#leaving-group-modal .modal-body p.member").show();
  176. }
  177. // toggle title and body depending if the user is the
  178. // owner or just a member of one of the groups selected.
  179. this.$(".modal-overlay").show();
  180. this.$(".modal-wrapper").show();
  181. this.$("#leaving-group-modal").show();
  182. e.preventDefault();
  183. },
  184. _checkForOwnedGroup: function() {
  185. is_owner = false;
  186. _.each(this.collection.selected(), function(group) {
  187. if (group.get('owner_id') === currentUserId) {
  188. is_owner = true;
  189. }
  190. });
  191. return is_owner;
  192. },
  193. leaveGroupSubmit: function(e) {
  194. var groupsView = this;
  195. var collection = this.collection;
  196. var ids = [];
  197. _.each(collection.selected(), function(group) {
  198. ids.push(group.id);
  199. });
  200. var idsStr = ids.join("&");
  201. $.ajax({
  202. type: "POST",
  203. data: {ids: idsStr},
  204. url: "/groups/leave",
  205. dataType: "json",
  206. success: function(data, textStatus, jqXHR) {
  207. collection.remove(collection.selected());
  208. },
  209. complete: function(jqXHR, textStatus) {
  210. groupsView.closeOverlay();
  211. },
  212. statusCode: {
  213. 400: function (data, textStatus, jqXHR) {
  214. console.log("Error: " + data);
  215. }
  216. }
  217. });
  218. e.preventDefault();
  219. },
  220. addItem: function(item) {
  221. var groupItemView = new GroupItemView({model: item});
  222. this.$("#group-list ul").append(groupItemView.render().el);
  223. },
  224. reset: function() {
  225. // clear out existing rows, after all this is a reset
  226. this.$("li").remove();
  227. // then add each new item in the collection
  228. this.collection.each(this.addItem);
  229. },
  230. render: function() {
  231. // when main view is called,
  232. // only render the group action buttons.
  233. this.$("#group-action-wrapper").html(this.action_template({
  234. selected: this.collection.selected().length
  235. }));
  236. }
  237. });
  238. $(document).ready(function() {
  239. window.groupsView = new GroupsView({
  240. el: $("#dashboard-widget"),
  241. collection: new GroupItemList()
  242. });
  243. });
  244. })(jQuery);