Rework on data structure to add uuid as objects identifier and add lastChange metadata to each objects
Benjamin Renard

Benjamin Renard commited on 2016-09-07 23:23:15
Showing 4 changed files, with 136 additions and 101 deletions.

... ...
@@ -0,0 +1,6 @@
1
+generate_uuid=function() {
2
+	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
3
+		var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
4
+		return v.toString(16);
5
+	});
6
+}
... ...
@@ -280,7 +280,7 @@ on_li_click=function(event) {
280 280
     if (cat) {
281 281
       var thing=cat.byLabel(li.data('label'));
282 282
       if (thing) {
283
-        thing.checked=li.hasClass('done');
283
+        thing.setChecked(li.hasClass('done'));
284 284
         scases.save();
285 285
       }
286 286
       show_scase(scase,cat.name);
... ...
@@ -315,7 +315,7 @@ on_valid_add_thing_modal=function (e) {
315 315
         alert("Cet élément existe déjà !");
316 316
         return;
317 317
       }
318
-      cat.things.push(new Thing(label,false));
318
+      cat.newThing(label);
319 319
       scases.save();
320 320
       show_scase(scase,cat.name);
321 321
     }
... ...
@@ -405,15 +405,13 @@ show_cat=function(cat,displayed) {
405 405
   var panel_title=$('<h4 class="panel-title">'+cat.name+' </h4>');
406 406
   panel_title.bind('click',on_title_click);
407 407
 
408
-
409
-  var count=cat.count();
410
-  var countDone=cat.countDone();
408
+  var stats=cat.stats();
411 409
   var tag=$('<span class="count-tag pull-right"></span>');
412
-  if (count==countDone) {
410
+  if (stats.things==stats.done) {
413 411
     tag.append($('<span class="label label-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></span>'));
414 412
   }
415 413
   else {
416
-    tag.append($('<span class="badge">'+countDone+' / '+count+'</span>'));
414
+    tag.append($('<span class="badge">'+stats.done+' / '+stats.things+'</span>'));
417 415
   }
418 416
 
419 417
   var delete_btn=$('<button class="btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-trash"></button>');
... ...
@@ -1,54 +1,31 @@
1
-exampleData={
2
-  'lastChange': 0,
3
-  'scases': {
4
-    0: {
5
-      'name': 'Vacances',
6
-      'cats': {
7
-        'lastChange': 0,
8
-        'cats': {
9
-          0: {
10
-            'name': 'Papier',
1
+
2
+
3
+function SCaseList() {
4
+  lastChange=0;
5
+
6
+  this.importExampleData=function() {
7
+    var exampleData={
8
+      'Vacances': {
9
+        'Papier': {
11 10
           'color': '#f00',
12
-            'things': [
13
-              {
14
-                'label': 'Papier blanc',
15
-                'checked': false
11
+          'things': ['Papier blanc', 'Stylo', "Carte d'identité"]
16 12
         },
17
-              {
18
-                'label': 'Stylo',
19
-                'checked': true
20
-              },
21
-              {
22
-                'label': "Carte d'identité",
23
-                'checked': false
24
-              }
25
-            ]
26
-          },
27
-          1: {
28
-            'name': 'Multimédia',
13
+        'Multimédia' : {
29 14
           'color': '#0f0',
30
-            'things': [
31
-              {
32
-                'label': 'Montre',
33
-                'checked': false
34
-              },
35
-              {
36
-                'label': 'Chargeur montre',
37
-                'checked': true
38
-              },
39
-              {
40
-                'label': "PC",
41
-                'checked': false
15
+          'things': ['Montre', 'Chargeur montre', "PC portable"]
42 16
         }
43
-            ]
44 17
       }
18
+    };
19
+    for (scaseName in exampleData) {
20
+      var scase=this.newSCase(scaseName);
21
+      for (catName in exampleData[scaseName]) {
22
+        var cat=scase.cats.newCat(catName);
23
+        for (idx in exampleData[scaseName][catName].things) {
24
+          cat.newThing(exampleData[scaseName][catName].things[idx]);
45 25
         }
46 26
       }
47 27
     }
48 28
   }
49
-};
50
-function SCaseList() {
51
-  lastChange=0;
52 29
 
53 30
   this.loadFromLocalStorage=function() {
54 31
     if (jQuery.type(localStorage.scases)!='undefined') {
... ...
@@ -56,7 +33,7 @@ function SCaseList() {
56 33
         var data=JSON.parse(localStorage.scases);
57 34
         this.lastChange=data.lastChange;
58 35
         for (el in data.scases) {
59
-          this[el]=new SCase(false,data.scases[el]);
36
+          this[el]=new SCase(false,false,data.scases[el]);
60 37
         }
61 38
       }
62 39
       catch(e) {
... ...
@@ -75,10 +52,13 @@ function SCaseList() {
75 52
     }
76 53
     else {
77 54
       myconfirm("<h2>Bienvenu !</h2><p>Souhaitez-vous charger les données d'exemple ?</p>",
78
-        function(data) {
79
-          localStorage.scases=JSON.stringify(exampleData);
80
-          location.reload();
81
-        }
55
+        function(scases) {
56
+          scases.importExampleData();
57
+          scases.save();
58
+          show_scases();
59
+        },
60
+        false,
61
+        this
82 62
       );
83 63
     }
84 64
   }
... ...
@@ -101,7 +81,7 @@ function SCaseList() {
101 81
     }
102 82
     this.lastChange=data.lastChange;
103 83
     for (el in data.scases) {
104
-      this[el]=new SCase(false,data.scases[el]);
84
+      this[el]=new SCase(false,false,data.scases[el]);
105 85
     }
106 86
     return true;
107 87
   }
... ...
@@ -155,9 +135,10 @@ function SCaseList() {
155 135
   }
156 136
 
157 137
   this.newSCase=function(name) {
158
-    if (!this.isSCase(this[name])) {
159
-      this[name]=new SCase(name);
160
-      return this[name];
138
+    if (!this.byName(this[name])) {
139
+      var uuid=uuid||generate_uuid();
140
+      this[uuid]=new SCase(uuid,name);
141
+      return this[uuid];
161 142
     }
162 143
     return false;
163 144
   }
... ...
@@ -166,6 +147,7 @@ function SCaseList() {
166 147
     var scase=this.byName(name);
167 148
     if (scase && !this.byName(newname)) {
168 149
       scase.name=newname;
150
+      scase.lastChange=new Date().getTime();
169 151
       return scase;
170 152
     }
171 153
     return false;
... ...
@@ -174,9 +156,12 @@ function SCaseList() {
174 156
   this.copySCase=function(name,newname) {
175 157
     var orig_scase=this.byName(name);
176 158
     if (this.isSCase(orig_scase) && !this.byName(newname)) {
177
-      this[newname]=new SCase(false,orig_scase.export());
178
-      this[newname].name=newname;
179
-      return this[newname];
159
+      var uuid=uuid||generate_uuid();
160
+      this[uuid]=new SCase(false,false,orig_scase.export());
161
+      this[uuid].uuid=uuid;
162
+      this[uuid].lastChange=new Date().getTime();
163
+      this[uuid].name=newname;
164
+      return this[uuid];
180 165
     }
181 166
     return false;
182 167
   }
... ...
@@ -191,16 +176,30 @@ function SCaseList() {
191 176
   }
192 177
 }
193 178
 
194
-function SCase(name,data) {
179
+function SCase(uuid,name,data) {
180
+  this.uuid=uuid||generate_uuid();
195 181
   this.name=name;
196 182
   this.cats=new CatList();
183
+  this.lastChange=new Date().getTime();
197 184
 
198 185
   this.isSCase=function() {
199 186
     return true;
200 187
   }
201 188
 
189
+  this.import=function(data) {
190
+    this.uuid=data.uuid || generate_uuid();
191
+    this.lastChange=data.lastChange || new Date().getTime();
192
+    this.name=decodeURIComponent(data.name);
193
+    if (jQuery.type(data.cats) == 'object') {
194
+      this.cats=new CatList(data.cats);
195
+    }
196
+    return true;
197
+  }
198
+
202 199
   this.export=function() {
203 200
     return {
201
+      'uuid': this.uuid,
202
+      'lastChange': this.lastChange,
204 203
       'name': encodeURIComponent(this.name),
205 204
       'cats': this.cats.export()
206 205
     };
... ...
@@ -243,6 +242,7 @@ function SCase(name,data) {
243 242
         }
244 243
       }
245 244
     });
245
+    this.lastChange=new Date().getTime();
246 246
     return true;
247 247
   }
248 248
 
... ...
@@ -251,10 +251,7 @@ function SCase(name,data) {
251 251
    */
252 252
   if (jQuery.type(data)=='object') {
253 253
     try {
254
-      this.name=decodeURIComponent(data.name);
255
-      if (jQuery.type(data.cats) == 'object') {
256
-        this.cats=new CatList(data.cats);
257
-      }
254
+      this.import(data);
258 255
     }
259 256
     catch (e) {
260 257
       console.log(e);
... ...
@@ -266,15 +263,10 @@ function SCase(name,data) {
266 263
 
267 264
 
268 265
 function CatList(data) {
269
-  lastChange=0;
270
-  
271 266
   this.export=function() {
272
-    return {
273
-      'lastChange': this.lastChange,
274
-      'cats': this.each(function(idx,cat) {
267
+    return this.each(function(idx,cat) {
275 268
       return cat.export();
276
-      })
277
-    };
269
+    });
278 270
   }
279 271
 
280 272
   this.import=function(data) {
... ...
@@ -283,9 +275,8 @@ function CatList(data) {
283 275
         delete this[el];
284 276
       }
285 277
     }
286
-    this.lastChange=data.lastChange;
287
-    for (el in data.cats) {
288
-      this[el]=new Cat(el,false,data.cats[el]);
278
+    for (el in data) {
279
+      this[el]=new Cat(el,false,false,data[el]);
289 280
     }
290 281
     return true;
291 282
   }
... ...
@@ -326,8 +317,9 @@ function CatList(data) {
326 317
 
327 318
   this.newCat=function(name) {
328 319
     if (!this.isCat(this[name])) {
329
-      this[name]=new Cat(name);
330
-      return this[name];
320
+      var uuid=uuid||generate_uuid();
321
+      this[uuid]=new Cat(uuid,name);
322
+      return this[uuid];
331 323
     }
332 324
     return false;
333 325
   }
... ...
@@ -336,6 +328,7 @@ function CatList(data) {
336 328
     var cat=this.byName(name);
337 329
     if (cat && !this.byName(newname)) {
338 330
       cat.name=newname;
331
+      cat.lastChange=new Date().getTime();
339 332
       return cat;
340 333
     }
341 334
     return false;
... ...
@@ -368,34 +361,45 @@ function CatList(data) {
368 361
 
369 362
 }
370 363
 
371
-function Cat(name,color,data) {
364
+function Cat(uuid,name,color,data) {
365
+  this.uuid=generate_uuid();
366
+  this.lastChange=new Date().getTime();
372 367
   this.name=name;
373 368
   this.color=color || '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);
374
-  this.things=[];
369
+  this.things={};
375 370
 
376 371
   this.isCat=function() {
377 372
     return true;
378 373
   }
379 374
 
375
+  this.import=function(data) {
376
+    this.uuid=data.uuid || generate_uuid();
377
+    this.lastChange=data.lastChange||new Date().getTime();
378
+    this.name=decodeURIComponent(data.name);
379
+    this.color=data.color;
380
+    if (jQuery.type(data.things) == 'object') {
381
+      for (tuuid in data.things) {
382
+        this.things[tuuid]=new Thing(tuuid);
383
+        this.things[tuuid].import(data.things[tuuid]);
384
+      }
385
+    }
386
+    return true;
387
+  }
388
+
380 389
   this.export=function() {
381
-    var things=[];
382
-    for (idx in this.things) {
383
-      things.push(this.things[idx].export());
390
+    var things={};
391
+    for (tuuid in this.things) {
392
+      things[tuuid]=this.things[tuuid].export();
384 393
     }
385 394
     return {
395
+      'uuid': this.uuid,
396
+      'lastChange': this.lastChange,
386 397
       'name': encodeURIComponent(this.name),
387 398
       'color': this.color,
388 399
       'things': things
389 400
     };
390 401
   }
391 402
 
392
-  this.importThing=function(data) {
393
-    return new Thing(
394
-      decodeURIComponent(data.label),
395
-      data.checked
396
-    );
397
-  }
398
-
399 403
   this.byLabel=function(label) {
400 404
     for (idx in this.things) {
401 405
       if (label==this.things[idx].label) {
... ...
@@ -406,23 +410,38 @@ function Cat(name,color,data) {
406 410
   }
407 411
 
408 412
   this.count=function() {
409
-    return this.things.length;
413
+    return keys(this.things).length;
410 414
   }
411 415
 
412
-  this.countDone=function() {
416
+  this.stats=function() {
413 417
     var count=0;
418
+    var done=0;
414 419
     for (idx in this.things) {
415 420
       if (this.things[idx].checked) {
421
+        done+=1;
422
+      }
416 423
       count+=1;
417 424
     }
425
+    return {
426
+      'things': count,
427
+      'done': done
428
+    };
418 429
   }
419
-    return count;
430
+
431
+  this.newThing=function(label) {
432
+    if (!this.byLabel(label)) {
433
+      var uuid=generate_uuid();
434
+      this.things[uuid]=new Thing(uuid,label);
435
+      return true;
436
+    }
437
+    return false;
420 438
   }
421 439
 
422 440
   this.renameThing=function(label,newlabel) {
423 441
     var thing=this.byLabel(label);
424 442
     if (thing && !this.byLabel(newlabel)) {
425 443
       thing.label=newlabel;
444
+      thing.lastChange=new Date().getTime();
426 445
       return thing;
427 446
     }
428 447
     return false;
... ...
@@ -443,13 +462,7 @@ function Cat(name,color,data) {
443 462
    */
444 463
   if (jQuery.type(data)=='object') {
445 464
     try {
446
-      this.name=decodeURIComponent(data.name);
447
-      this.color=data.color;
448
-      if (jQuery.type(data.things) == 'array') {
449
-        for (idx in data.things) {
450
-          this.things.push(this.importThing(data.things[idx]));
451
-        }
452
-      }
465
+      this.import(data);
453 466
     }
454 467
     catch (e) {
455 468
       console.log(e);
... ...
@@ -459,13 +472,30 @@ function Cat(name,color,data) {
459 472
 
460 473
 }
461 474
 
462
-function Thing(label,checked) {
475
+function Thing(uuid,label,checked) {
476
+  this.uuid=uuid||generate_uuid();
477
+  this.lastChange=new Date().getTime();
463 478
   this.label=label;
464 479
   this.checked=checked;
480
+
481
+  this.import=function(data) {
482
+    this.uuid=data.uuid||generate_uuid();
483
+    this.lastChange=data.lastChange||new Date().getTime();
484
+    this.label=decodeURIComponent(data.label),
485
+    this.checked=data.checked;
486
+  }
487
+
465 488
   this.export=function() {
466 489
     return {
490
+      'uuid': this.uuid,
491
+      'lastChange': this.lastChange,
467 492
       'label': encodeURIComponent(this.label),
468 493
       'checked': this.checked
469 494
     };
470 495
   }
496
+
497
+  this.setChecked=function(value) {
498
+    this.checked=value;
499
+    this.lastChange=new Date().getTime();
500
+  }
471 501
 }
... ...
@@ -284,6 +284,7 @@ div.panel-heading, li.list-group-item, a {
284 284
 
285 285
 </script>
286 286
 
287
+<script src="inc/lib/uuid.js"></script>
287 288
 <script src="inc/mydialog.js"></script>
288 289
 <script src="inc/mysc_objects.js"></script>
289 290
 <script src="inc/main.js"></script>
290 291