4 |
4 |
5 var Backbone = root.Backbone; |
5 var Backbone = root.Backbone; |
6 |
6 |
7 var Models = root.Rkns.Models = {}; |
7 var Models = root.Rkns.Models = {}; |
8 |
8 |
9 |
|
10 Models.getUID = function(obj) { |
9 Models.getUID = function(obj) { |
11 var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { |
10 var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, |
12 var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8); |
11 function(c) { |
13 return v.toString(16); |
12 var r = Math.random() * 16 | 0, v = c === 'x' ? r |
14 }); |
13 : (r & 0x3 | 0x8); |
15 if(typeof obj !== 'undefined') { |
14 return v.toString(16); |
|
15 }); |
|
16 if (typeof obj !== 'undefined') { |
16 return obj.type + "-" + guid; |
17 return obj.type + "-" + guid; |
17 } |
18 } |
18 else { |
19 else { |
19 return guid; |
20 return guid; |
20 } |
21 } |
21 }; |
22 }; |
22 |
23 |
23 |
|
24 var RenkanModel = Backbone.RelationalModel.extend({ |
24 var RenkanModel = Backbone.RelationalModel.extend({ |
25 idAttribute : "_id", |
25 idAttribute : "_id", |
26 constructor: function(options) { |
26 constructor : function(options) { |
27 |
27 |
28 if (typeof options !== "undefined") { |
28 if (typeof options !== "undefined") { |
29 options._id = options._id || options.id || Models.getUID(this); |
29 options._id = options._id || options.id || Models.getUID(this); |
30 options.title = options.title || ""; |
30 options.title = options.title || ""; |
31 options.description = options.description || ""; |
31 options.description = options.description || ""; |
32 options.uri = options.uri || ""; |
32 options.uri = options.uri || ""; |
33 |
33 |
34 if(typeof this.prepare === "function") { |
34 if (typeof this.prepare === "function") { |
35 options = this.prepare(options); |
35 options = this.prepare(options); |
36 } |
36 } |
37 } |
37 } |
38 Backbone.RelationalModel.prototype.constructor.call(this, options); |
38 Backbone.RelationalModel.prototype.constructor.call(this, options); |
39 }, |
39 }, |
40 validate: function() { |
40 validate : function() { |
41 if(!this.type) { |
41 if (!this.type) { |
42 return "object has no type"; |
42 return "object has no type"; |
43 } |
43 } |
44 }, |
44 }, |
45 addReference : function(_options, _propName, _list, _id, _default) { |
45 addReference : function(_options, _propName, _list, _id, _default) { |
46 var _element = _list.get(_id); |
46 var _element = _list.get(_id); |
47 if (typeof _element === "undefined" && typeof _default !== "undefined") { |
47 if (typeof _element === "undefined" && |
48 _options[_propName ] = _default; |
48 typeof _default !== "undefined") { |
|
49 _options[_propName] = _default; |
49 } |
50 } |
50 else { |
51 else { |
51 _options[_propName ] = _element; |
52 _options[_propName] = _element; |
52 } |
53 } |
53 } |
54 } |
54 }); |
55 }); |
55 |
56 |
56 // USER |
57 // USER |
57 var User = Models.User = RenkanModel.extend({ |
58 var User = Models.User = RenkanModel.extend({ |
58 type: "user", |
59 type : "user", |
59 prepare: function(options) { |
60 prepare : function(options) { |
60 options.color = options.color || "#666666"; |
61 options.color = options.color || "#666666"; |
61 return options; |
62 return options; |
62 }, |
63 }, |
63 toJSON: function() { |
64 toJSON : function() { |
64 return { |
65 return { |
65 _id: this.get("_id"), |
66 _id : this.get("_id"), |
66 title: this.get("title"), |
67 title : this.get("title"), |
67 uri: this.get("uri"), |
68 uri : this.get("uri"), |
68 description: this.get("description"), |
69 description : this.get("description"), |
69 color: this.get("color") |
70 color : this.get("color") |
70 }; |
71 }; |
71 } |
72 } |
72 }); |
73 }); |
73 |
74 |
74 // NODE |
75 // NODE |
75 var Node = Models.Node = RenkanModel.extend({ |
76 var Node = Models.Node = RenkanModel.extend({ |
76 type: "node", |
77 type : "node", |
77 relations: [{ |
78 relations : [ { |
78 type: Backbone.HasOne, |
79 type : Backbone.HasOne, |
79 key: "created_by", |
80 key : "created_by", |
80 relatedModel: User |
81 relatedModel : User |
81 }], |
82 } ], |
82 prepare: function(options) { |
83 prepare : function(options) { |
83 var project = options.project; |
84 var project = options.project; |
84 this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user); |
85 this.addReference(options, "created_by", project.get("users"), |
|
86 options.created_by, project.current_user); |
85 options.description = options.description || ""; |
87 options.description = options.description || ""; |
86 return options; |
88 return options; |
87 }, |
89 }, |
88 toJSON: function() { |
90 toJSON : function() { |
89 return { |
91 return { |
90 _id: this.get("_id"), |
92 _id : this.get("_id"), |
91 title: this.get("title"), |
93 title : this.get("title"), |
92 uri: this.get("uri"), |
94 uri : this.get("uri"), |
93 description: this.get("description"), |
95 description : this.get("description"), |
94 position: this.get("position"), |
96 position : this.get("position"), |
95 image: this.get("image"), |
97 image : this.get("image"), |
96 color: this.get("color"), |
98 color : this.get("color"), |
97 created_by: this.get("created_by") ? this.get("created_by").get("_id") : null, |
99 created_by : this.get("created_by") ? this.get("created_by") |
98 size: this.get("size"), |
100 .get("_id") : null, |
99 clip_path: this.get("clip_path"), |
101 size : this.get("size"), |
100 shape: this.get("shape") |
102 clip_path : this.get("clip_path"), |
|
103 shape : this.get("shape") |
101 }; |
104 }; |
102 } |
105 } |
103 }); |
106 }); |
104 |
107 |
105 // EDGE |
108 // EDGE |
106 var Edge = Models.Edge = RenkanModel.extend({ |
109 var Edge = Models.Edge = RenkanModel.extend({ |
107 type: "edge", |
110 type : "edge", |
108 relations: [ |
111 relations : [ { |
109 { |
112 type : Backbone.HasOne, |
110 type: Backbone.HasOne, |
113 key : "created_by", |
111 key: "created_by", |
114 relatedModel : User |
112 relatedModel: User |
115 }, { |
113 }, |
116 type : Backbone.HasOne, |
114 { |
117 key : "from", |
115 type: Backbone.HasOne, |
118 relatedModel : Node |
116 key: "from", |
119 }, { |
117 relatedModel: Node |
120 type : Backbone.HasOne, |
118 }, |
121 key : "to", |
119 { |
122 relatedModel : Node |
120 type: Backbone.HasOne, |
123 } ], |
121 key: "to", |
124 prepare : function(options) { |
122 relatedModel: Node |
|
123 } |
|
124 ], |
|
125 prepare: function(options) { |
|
126 var project = options.project; |
125 var project = options.project; |
127 this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user); |
126 this.addReference(options, "created_by", project.get("users"), |
128 this.addReference(options, "from", project.get("nodes"), options.from); |
127 options.created_by, project.current_user); |
|
128 this.addReference(options, "from", project.get("nodes"), |
|
129 options.from); |
129 this.addReference(options, "to", project.get("nodes"), options.to); |
130 this.addReference(options, "to", project.get("nodes"), options.to); |
130 return options; |
131 return options; |
131 }, |
132 }, |
132 toJSON: function() { |
133 toJSON : function() { |
133 return { |
134 return { |
134 _id: this.get("_id"), |
135 _id : this.get("_id"), |
135 title: this.get("title"), |
136 title : this.get("title"), |
136 uri: this.get("uri"), |
137 uri : this.get("uri"), |
137 description: this.get("description"), |
138 description : this.get("description"), |
138 from: this.get("from") ? this.get("from").get("_id") : null, |
139 from : this.get("from") ? this.get("from").get("_id") : null, |
139 to: this.get("to") ? this.get("to").get("_id") : null, |
140 to : this.get("to") ? this.get("to").get("_id") : null, |
140 color: this.get("color"), |
141 color : this.get("color"), |
141 created_by: this.get("created_by") ? this.get("created_by").get("_id") : null |
142 created_by : this.get("created_by") ? this.get("created_by") |
|
143 .get("_id") : null |
142 }; |
144 }; |
143 } |
145 } |
144 }); |
146 }); |
145 |
147 |
146 // View |
148 // View |
147 var View = Models.View = RenkanModel.extend({ |
149 var View = Models.View = RenkanModel.extend({ |
148 type: "view", |
150 type : "view", |
149 relations: [ |
151 relations : [ { |
150 { |
152 type : Backbone.HasOne, |
151 type: Backbone.HasOne, |
153 key : "created_by", |
152 key: "created_by", |
154 relatedModel : User |
153 relatedModel: User |
155 } ], |
154 } |
156 prepare : function(options) { |
155 ], |
|
156 prepare: function(options) { |
|
157 var project = options.project; |
157 var project = options.project; |
158 this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user); |
158 this.addReference(options, "created_by", project.get("users"), |
|
159 options.created_by, project.current_user); |
159 options.description = options.description || ""; |
160 options.description = options.description || ""; |
160 if(typeof options.offset !== "undefined") { |
161 if (typeof options.offset !== "undefined") { |
161 var offset = {}; |
162 var offset = {}; |
162 if (Array.isArray(options.offset)) { |
163 if (Array.isArray(options.offset)) { |
163 offset.x = options.offset[0]; |
164 offset.x = options.offset[0]; |
164 offset.y = options.offset.length > 1 ? options.offset[1] : options.offset[0]; |
165 offset.y = options.offset.length > 1 ? options.offset[1] |
|
166 : options.offset[0]; |
165 } |
167 } |
166 else if (options.offset.x != null) { |
168 else if (options.offset.x != null) { |
167 offset.x = options.offset.x; |
169 offset.x = options.offset.x; |
168 offset.y = options.offset.y; |
170 offset.y = options.offset.y; |
169 } |
171 } |
170 options.offset = offset; |
172 options.offset = offset; |
171 } |
173 } |
172 return options; |
174 return options; |
173 }, |
175 }, |
174 toJSON: function() { |
176 toJSON : function() { |
175 return { |
177 return { |
176 _id: this.get("_id"), |
178 _id : this.get("_id"), |
177 zoom_level: this.get("zoom_level"), |
179 zoom_level : this.get("zoom_level"), |
178 offset: this.get("offset"), |
180 offset : this.get("offset"), |
179 title: this.get("title"), |
181 title : this.get("title"), |
180 description: this.get("description"), |
182 description : this.get("description"), |
181 created_by: this.get("created_by") ? this.get("created_by").get("_id") : null |
183 created_by : this.get("created_by") ? this.get("created_by") |
182 // Don't need project id |
184 .get("_id") : null |
|
185 // Don't need project id |
183 }; |
186 }; |
184 } |
187 } |
185 }); |
188 }); |
186 |
189 |
187 // PROJECT |
190 // PROJECT |
188 var Project = Models.Project = RenkanModel.extend({ |
191 var Project = Models.Project = RenkanModel.extend({ |
189 type: "project", |
192 type : "project", |
190 blacklist: ['save_status',], |
193 blacklist : [ 'save_status', ], |
191 relations: [ |
194 relations : [ { |
192 { |
195 type : Backbone.HasMany, |
193 type: Backbone.HasMany, |
196 key : "users", |
194 key: "users", |
197 relatedModel : User, |
195 relatedModel: User, |
198 reverseRelation : { |
196 reverseRelation: { |
199 key : 'project', |
197 key: 'project', |
200 includeInJSON : '_id' |
198 includeInJSON: '_id' |
201 } |
199 } |
202 }, { |
200 }, |
203 type : Backbone.HasMany, |
201 { |
204 key : "nodes", |
202 type: Backbone.HasMany, |
205 relatedModel : Node, |
203 key: "nodes", |
206 reverseRelation : { |
204 relatedModel: Node, |
207 key : 'project', |
205 reverseRelation: { |
208 includeInJSON : '_id' |
206 key: 'project', |
209 } |
207 includeInJSON: '_id' |
210 }, { |
208 } |
211 type : Backbone.HasMany, |
209 }, |
212 key : "edges", |
210 { |
213 relatedModel : Edge, |
211 type: Backbone.HasMany, |
214 reverseRelation : { |
212 key: "edges", |
215 key : 'project', |
213 relatedModel: Edge, |
216 includeInJSON : '_id' |
214 reverseRelation: { |
217 } |
215 key: 'project', |
218 }, { |
216 includeInJSON: '_id' |
219 type : Backbone.HasMany, |
217 } |
220 key : "views", |
218 }, |
221 relatedModel : View, |
219 { |
222 reverseRelation : { |
220 type: Backbone.HasMany, |
223 key : 'project', |
221 key: "views", |
224 includeInJSON : '_id' |
222 relatedModel: View, |
225 } |
223 reverseRelation: { |
226 } ], |
224 key: 'project', |
227 addUser : function(_props, _options) { |
225 includeInJSON: '_id' |
|
226 } |
|
227 } |
|
228 ], |
|
229 addUser: function(_props, _options) { |
|
230 _props.project = this; |
228 _props.project = this; |
231 var _user = User.findOrCreate(_props); |
229 var _user = User.findOrCreate(_props); |
232 this.get("users").push(_user, _options); |
230 this.get("users").push(_user, _options); |
233 return _user; |
231 return _user; |
234 }, |
232 }, |
235 addNode: function(_props, _options) { |
233 addNode : function(_props, _options) { |
236 _props.project = this; |
234 _props.project = this; |
237 var _node = Node.findOrCreate(_props); |
235 var _node = Node.findOrCreate(_props); |
238 this.get("nodes").push(_node, _options); |
236 this.get("nodes").push(_node, _options); |
239 return _node; |
237 return _node; |
240 }, |
238 }, |
241 addEdge: function(_props, _options) { |
239 addEdge : function(_props, _options) { |
242 _props.project = this; |
240 _props.project = this; |
243 var _edge = Edge.findOrCreate(_props); |
241 var _edge = Edge.findOrCreate(_props); |
244 this.get("edges").push(_edge, _options); |
242 this.get("edges").push(_edge, _options); |
245 return _edge; |
243 return _edge; |
246 }, |
244 }, |
247 addView: function(_props, _options) { |
245 addView : function(_props, _options) { |
248 _props.project = this; |
246 _props.project = this; |
249 // TODO: check if need to replace with create only |
247 // TODO: check if need to replace with create only |
250 var _view = View.findOrCreate(_props); |
248 var _view = View.findOrCreate(_props); |
251 // TODO: Should we remember only one view? |
249 // TODO: Should we remember only one view? |
252 this.get("views").push(_view, _options); |
250 this.get("views").push(_view, _options); |
253 return _view; |
251 return _view; |
254 }, |
252 }, |
255 removeNode: function(_model) { |
253 removeNode : function(_model) { |
256 this.get("nodes").remove(_model); |
254 this.get("nodes").remove(_model); |
257 }, |
255 }, |
258 removeEdge: function(_model) { |
256 removeEdge : function(_model) { |
259 this.get("edges").remove(_model); |
257 this.get("edges").remove(_model); |
260 }, |
258 }, |
261 validate: function(options) { |
259 validate : function(options) { |
262 var _project = this; |
260 var _project = this; |
263 _([].concat(options.users, options.nodes, options.edges, options.views)).each(function(_item) { |
261 _( |
264 if(_item) { |
262 [].concat(options.users, options.nodes, options.edges, |
|
263 options.views)).each(function(_item) { |
|
264 if (_item) { |
265 _item.project = _project; |
265 _item.project = _project; |
266 } |
266 } |
267 }); |
267 }); |
268 }, |
268 }, |
269 // Add event handler to remove edges when a node is removed |
269 // Add event handler to remove edges when a node is removed |
270 initialize: function() { |
270 initialize : function() { |
271 var _this = this; |
271 var _this = this; |
272 this.on("remove:nodes", function(_node) { |
272 this.on("remove:nodes", function(_node) { |
273 _this.get("edges").remove( |
273 _this.get("edges").remove( |
274 _this.get("edges").filter(function(_edge) { |
274 _this.get("edges").filter( |
275 return _edge.get("from") === _node || _edge.get("to") === _node; |
275 function(_edge) { |
276 }) |
276 return _edge.get("from") === _node || |
277 ); |
277 _edge.get("to") === _node; |
|
278 })); |
278 }); |
279 }); |
279 }, |
280 }, |
280 toJSON: function(){ |
281 toJSON : function() { |
281 var json = _.clone(this.attributes); |
282 var json = _.clone(this.attributes); |
282 for(var attr in json) { |
283 for ( var attr in json) { |
283 if((json[attr] instanceof Backbone.Model) || (json[attr] instanceof Backbone.Collection) || (json[attr] instanceof RenkanModel)) { |
284 if ((json[attr] instanceof Backbone.Model) || |
284 json[attr] = json[attr].toJSON(); |
285 (json[attr] instanceof Backbone.Collection) || |
285 } |
286 (json[attr] instanceof RenkanModel)) { |
286 } |
287 json[attr] = json[attr].toJSON(); |
287 return _.omit(json, this.blacklist); |
288 } |
288 } |
289 } |
289 }); |
290 return _.omit(json, this.blacklist); |
290 |
291 } |
291 var RosterUser = Models.RosterUser = Backbone.Model.extend({ |
292 }); |
292 type: "roster_user", |
293 |
293 idAttribute : "_id", |
294 var RosterUser = Models.RosterUser = Backbone.Model |
294 |
295 .extend({ |
295 constructor: function(options) { |
296 type : "roster_user", |
296 |
297 idAttribute : "_id", |
297 if (typeof options !== "undefined") { |
298 |
298 options._id = options._id || options.id || Models.getUID(this); |
299 constructor : function(options) { |
299 options.title = options.title || "(untitled " + this.type + ")"; |
300 |
300 options.description = options.description || ""; |
301 if (typeof options !== "undefined") { |
301 options.uri = options.uri || ""; |
302 options._id = options._id || |
302 options.project = options.project || null; |
303 options.id || |
303 options.site_id = options.site_id || 0; |
304 Models.getUID(this); |
304 |
305 options.title = options.title || "(untitled " + this.type + ")"; |
305 if(typeof this.prepare === "function") { |
306 options.description = options.description || ""; |
306 options = this.prepare(options); |
307 options.uri = options.uri || ""; |
307 } |
308 options.project = options.project || null; |
308 } |
309 options.site_id = options.site_id || 0; |
309 Backbone.Model.prototype.constructor.call(this, options); |
310 |
310 }, |
311 if (typeof this.prepare === "function") { |
311 |
312 options = this.prepare(options); |
312 validate: function() { |
313 } |
313 if(!this.type) { |
314 } |
314 return "object has no type"; |
315 Backbone.Model.prototype.constructor.call(this, options); |
315 } |
316 }, |
316 }, |
317 |
317 |
318 validate : function() { |
318 prepare: function(options) { |
319 if (!this.type) { |
319 options.color = options.color || "#666666"; |
320 return "object has no type"; |
320 return options; |
321 } |
321 }, |
322 }, |
322 |
323 |
323 toJSON: function() { |
324 prepare : function(options) { |
324 return { |
325 options.color = options.color || "#666666"; |
325 _id: this.get("_id"), |
326 return options; |
326 title: this.get("title"), |
327 }, |
327 uri: this.get("uri"), |
328 |
328 description: this.get("description"), |
329 toJSON : function() { |
329 color: this.get("color"), |
330 return { |
330 project: (this.get("project") != null)?this.get("project").get("id"):null, |
331 _id : this.get("_id"), |
331 site_id: this.get("site_id") |
332 title : this.get("title"), |
332 }; |
333 uri : this.get("uri"), |
333 } |
334 description : this.get("description"), |
334 }); |
335 color : this.get("color"), |
|
336 project : (this.get("project") != null) ? this.get( |
|
337 "project").get("id") : null, |
|
338 site_id : this.get("site_id") |
|
339 }; |
|
340 } |
|
341 }); |
335 |
342 |
336 var UsersList = Models.UsersList = Backbone.Collection.extend({ |
343 var UsersList = Models.UsersList = Backbone.Collection.extend({ |
337 model: RosterUser |
344 model : RosterUser |
338 }); |
345 }); |
339 |
|
340 |
346 |
341 }).call(window); |
347 }).call(window); |