PageRenderTime 38ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/web/js/models.js

https://bitbucket.org/wez/mtrack/
JavaScript | 310 lines | 274 code | 26 blank | 10 comment | 30 complexity | 0f439ce9eef890e83f8c07709105c7c1 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. /* vim:ts=2:sw=2:et:
  2. * For copyright and licensing terms, see the file named LICENSE */
  3. // https://gist.github.com/1610397
  4. function nestCollection(model, attributeName, nestedCollection) {
  5. //setup nested references
  6. for (var i = 0; i < nestedCollection.length; i++) {
  7. model.attributes[attributeName][i] = nestedCollection.at(i).attributes;
  8. }
  9. // create empty arrays if none
  10. nestedCollection.bind('add', function (initiative) {
  11. if (!model.get(attributeName)) {
  12. model.attributes[attributeName] = [];
  13. }
  14. model.get(attributeName).push(initiative.attributes);
  15. });
  16. nestedCollection.bind('remove', function (initiative) {
  17. var updateObj = {};
  18. updateObj[attributeName] = _.without(
  19. model.get(attributeName),
  20. initiative.attributes);
  21. model.set(updateObj);
  22. });
  23. return nestedCollection;
  24. }
  25. var MTrackProject = Backbone.Model.extend({
  26. defaults: {
  27. "shortname": '',
  28. "name": '',
  29. "notifyemail": ''
  30. },
  31. url: function() {
  32. if (this.isNew()) {
  33. return ABSWEB + "api.php/project";
  34. }
  35. return ABSWEB + "api.php/project/" + this.id;
  36. }
  37. });
  38. var MTrackProjectCollection = Backbone.Collection.extend({
  39. model: MTrackProject,
  40. url: function() {
  41. return ABSWEB + 'api.php/project';
  42. }
  43. });
  44. var MTrackRepo = Backbone.Model.extend({
  45. defaults: {
  46. "shortname": '',
  47. "description": '',
  48. "canDelete": false,
  49. "links": []
  50. },
  51. url: function() {
  52. if (this.isNew()) {
  53. return ABSWEB + "api.php/repo/properties/";
  54. }
  55. return ABSWEB + "api.php/repo/properties/" + this.id;
  56. }
  57. });
  58. var MTrackRepoList = Backbone.Collection.extend({
  59. model: MTrackRepo,
  60. url: function() {
  61. return ABSWEB + "api.php/repo/properties";
  62. }
  63. });
  64. var MTrackTicketChange = Backbone.Model.extend({
  65. });
  66. var MTrackAttachment = Backbone.Model.extend({
  67. url: function() {
  68. return ABSWEB + "api.php/attachment/" + this.id;
  69. }
  70. });
  71. var MTrackTicketAttachmentCollection = Backbone.Collection.extend({
  72. model: MTrackAttachment,
  73. ticket: null,
  74. url: function() {
  75. return ABSWEB + "api.php/ticket/" + this.ticket.id + "/attach";
  76. }
  77. });
  78. var MTrackTicketChangesCollection = Backbone.Collection.extend({
  79. model: MTrackTicketChange,
  80. ticket: null,
  81. comparator: function(cs) {
  82. return -parseInt(cs.id);
  83. },
  84. url: function() {
  85. return ABSWEB + "api.php/ticket/" + this.ticket.id + "/changes";
  86. }
  87. });
  88. var MTrackTicketCollection = null;
  89. var MTrackTicket = Backbone.Model.extend({
  90. urlRoot: ABSWEB + "api.php/ticket",
  91. url: function() {
  92. if (this.isNew()) {
  93. return ABSWEB + "api.php/ticket";
  94. }
  95. return ABSWEB + "api.php/ticket/" + this.id;
  96. },
  97. defaults: {
  98. "nsident": null,
  99. "summary": null,
  100. "description": null,
  101. "classification": mtrack_ticket_defaults.classification,
  102. "severity": mtrack_ticket_defaults.severity,
  103. "priority": mtrack_ticket_defaults.priority
  104. },
  105. tktChanges: null,
  106. getChanges: function() {
  107. if (this.tktChanges == null) {
  108. this.tktChanges = new MTrackTicketChangesCollection;
  109. this.tktChanges.ticket = this;
  110. }
  111. return this.tktChanges;
  112. },
  113. tktAttachments: null,
  114. getAttachments: function() {
  115. if (this.tktAttachments == null) {
  116. this.tktAttachments = new MTrackTicketAttachmentCollection;
  117. this.tktAttachments.ticket = this;
  118. }
  119. return this.tktAttachments;
  120. },
  121. tktChildren: null,
  122. getChildren: function() {
  123. if (this.tktChildren == null) {
  124. this.tktChildren = new MTrackTicketCollection;
  125. this.tktChildren.ticket = this;
  126. var tkt = this;
  127. this.tktChildren.bind('add', function(model, col) {
  128. if (tkt.collection) {
  129. tkt.collection.trigger('childticketadd', tkt, model);
  130. }
  131. tkt.trigger('childticketadd', model);
  132. });
  133. this.tktChildren.bind('remove', function(model, col) {
  134. if (tkt.collection) {
  135. tkt.collection.trigger('childticketremove', tkt, model);
  136. }
  137. tkt.trigger('childticketremove', model);
  138. });
  139. }
  140. return this.tktChildren;
  141. },
  142. validate: function(attrs) {
  143. var m = {
  144. summary: [/\S/, "summary must not be empty", false],
  145. estimated: [/^\d*\.?\d*$/, "estimated time must be numeric", true],
  146. effortSpent: [/^-?\d*\.?\d*$/, "logged hours must be numeric", true]
  147. };
  148. for (var k in attrs) {
  149. if (k in m) {
  150. var pat = m[k][0];
  151. var reason = m[k][1];
  152. var nullok = m[k][2];
  153. if (attrs[k] == null) {
  154. if (nullok) continue;
  155. return reason;
  156. }
  157. if (attrs[k] != null && !attrs[k].match(pat)) {
  158. return reason;
  159. }
  160. }
  161. }
  162. }
  163. });
  164. MTrackTicketCollection = Backbone.Collection.extend({
  165. model: MTrackTicket,
  166. ticket: null,
  167. url: function () {
  168. return ABSWEB + "api.php/ticket/" + this.ticket.id + "/children";
  169. }
  170. });
  171. var MTrackMilestoneTicketCollection = Backbone.Collection.extend({
  172. model: MTrackTicket,
  173. milestone: null,
  174. /* synthesize the ordinal priority field.
  175. * We pretend that the tickets have a pri_ord field here,
  176. * then in the comparator we sneak it out of the attributes hash
  177. * and promote it to the ticket model itself */
  178. parse: function(response) {
  179. var i;
  180. for (i in response) {
  181. response[i].pri_ord = i;
  182. }
  183. return response;
  184. },
  185. comparator: function(tkt) {
  186. /* sneak the ordinal out of the attributes (see comment above parse()) */
  187. if ('pri_ord' in tkt.attributes) {
  188. tkt.pri_ord = parseInt(tkt.attributes.pri_ord);
  189. delete tkt.attributes.pri_ord;
  190. return tkt.pri_ord;
  191. }
  192. if ('pri_ord' in tkt) {
  193. return tkt.pri_ord;
  194. }
  195. return 0;
  196. },
  197. savePriorities: function () {
  198. var bulk = [];
  199. var collection = this;
  200. var i = 0;
  201. this.each(function(tkt) {
  202. tkt.pri_ord = i++;
  203. bulk.push(tkt.id);
  204. });
  205. var b = new Backbone.Model({tickets: bulk});
  206. b.url = ABSWEB + "api.php/milestone/" + this.milestone.id + "/prioritize";
  207. b.save();
  208. },
  209. url: function () {
  210. return ABSWEB + "api.php/milestone/" + this.milestone.id + "/tickets";
  211. }
  212. });
  213. var MTrackMilestone = Backbone.Model.extend({
  214. urlRoot: ABSWEB + "api.php/milestone",
  215. initialize: function (attributes) {
  216. this.tickets = new MTrackMilestoneTicketCollection();
  217. this.tickets.milestone = this;
  218. }
  219. });
  220. var MTrackMilestoneCollection = Backbone.Collection.extend({
  221. model: MTrackMilestone,
  222. url: ABSWEB + 'api.php/milestones'
  223. });
  224. var MTrackUserKey = Backbone.Model.extend({
  225. validate: function(attrs) {
  226. if ('key' in attrs) {
  227. if (!attrs.key.match(/^ssh-\S+\s+\S+$/)) {
  228. return "key " + attrs.key + " is not a valid ssh key";
  229. }
  230. }
  231. }
  232. });
  233. var MTrackUserKeysCollection = Backbone.Collection.extend({
  234. model: MTrackUserKey,
  235. user: null,
  236. url: function() {
  237. return ABSWEB + 'api.php/user/' + this.user.id + '/keys';
  238. }
  239. });
  240. var MTrackUser = Backbone.Model.extend({
  241. urlRoot: ABSWEB + "api.php/user",
  242. defaults: {
  243. "active": true,
  244. "role": "authenticated"
  245. },
  246. initialize: function (attributes, options) {
  247. this.keys = new MTrackUserKeysCollection(options ? options.keys : []);
  248. this.keys.user = this;
  249. }
  250. });
  251. var MTrackWatchItem = Backbone.Model.extend({
  252. });
  253. var MTrackWatchList = Backbone.Collection.extend({
  254. model: MTrackWatchItem,
  255. url: ABSWEB + 'api.php/watch/list'
  256. });
  257. var MTrackWikiAttachmentCollection = Backbone.Collection.extend({
  258. model: MTrackAttachment,
  259. WIKI: null,
  260. url: function() {
  261. return ABSWEB + "api.php/wiki/attach/" + this.WIKI.id;
  262. }
  263. });
  264. var MTrackWiki = Backbone.Model.extend({
  265. wikiAttachments: null,
  266. getAttachments: function() {
  267. if (this.wikiAttachments == null) {
  268. this.wikiAttachments = new MTrackWikiAttachmentCollection;
  269. this.wikiAttachments.WIKI = this;
  270. }
  271. return this.wikiAttachments;
  272. },
  273. isNew: function() {
  274. var c = this.previous('content');
  275. if (c && c.length) {
  276. return false;
  277. }
  278. return true;
  279. },
  280. urlRoot: ABSWEB + "api.php/wiki/page",
  281. url: function() {
  282. return ABSWEB + "api.php/wiki/page/" + this.id;
  283. }
  284. });