client/js/models.js
changeset 414 276042cb477c
parent 362 8f33cbeb4f32
child 433 e457ec945e50
equal deleted inserted replaced
413:bed069ef446c 414:276042cb477c
     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);