summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
Unidiff
Diffstat (limited to 'frontend/delta/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js685
1 files changed, 685 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js b/frontend/delta/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
new file mode 100644
index 0000000..5681f70
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
@@ -0,0 +1,685 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.PM.DataModel.User.Header.RecordIndex depends on Clipperz.PM.DataModel.User!";
26}
27
28if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.DataModel.User.Header = {}; }
29
30Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
31 Clipperz.PM.DataModel.User.Header.RecordIndex.superclass.constructor.apply(this, arguments);
32
33 this._recordsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
34 'name':'recordsData',
35 'retrieveKeyFunction': args.retrieveKeyFunction,
36 'remoteData': {
37 'data': args.recordsData['data'],
38 'version': args.encryptedDataVersion,
39 'recordsStats': args.recordsStats
40 }//,
41 // 'encryptedDataKeypath': 'data',
42 // 'encryptedVersionKeypath': 'version'
43 });
44
45 this._directLoginsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
46 'name':'directLoginsData',
47 'retrieveKeyFunction': args.retrieveKeyFunction,
48 'remoteData': {
49 'data': args.directLoginsData['data'],
50 'version': args.encryptedDataVersion
51 }//,
52 // 'encryptedDataKeypath': 'data',
53 // 'encryptedVersionKeypath': 'version'
54 });
55
56 this._lock = new MochiKit.Async.DeferredLock();
57 this._transientState = null;
58
59 this._retrieveRecordDetailFunction = args.retrieveRecordDetailFunction|| Clipperz.Base.exception.raise('MandatoryParameter');
60 this._recordsIndex = args.recordsData['index'] || Clipperz.Base.exception.raise('MandatoryParameter');
61 this._directLoginsIndex = args.directLoginsData['index']|| Clipperz.Base.exception.raise('MandatoryParameter');
62
63 this._records = null;
64
65 return this;
66}
67
68
69Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
70
71 'toString': function() {
72 return "Clipperz.PM.DataModel.User.Header.RecordIndex";
73 },
74
75 //-------------------------------------------------------------------------
76
77 'retrieveRecordDetailFunction': function () {
78 return this._retrieveRecordDetailFunction;
79 },
80
81 //-------------------------------------------------------------------------
82
83 'recordsIndex': function () {
84 return this._recordsIndex;
85 },
86
87 'recordsData': function () {
88 return this._recordsData;
89 },
90
91 //-------------------------------------------------------------------------
92
93 'directLoginsIndex': function () {
94 return this._directLoginsIndex;
95 },
96
97 'directLoginsData': function () {
98 return this._directLoginsData;
99 },
100
101 //-------------------------------------------------------------------------
102
103 'lock': function () {
104 return this._lock;
105 },
106
107 //-------------------------------------------------------------------------
108
109 'transientState': function () {
110 if (this._transientState == null) {
111 this._transientState = new Clipperz.KeyValueObjectStore(/*{'name':'User.Header.RecordIndex.transientState [1]'}*/);
112 }
113
114 return this._transientState;
115 },
116
117 'resetTransientState': function (isCommitting) {
118 if (this._transientState != null) {
119 this._transientState.removeAllData();
120 }
121
122 this._transientState = null;
123 },
124
125 //-------------------------------------------------------------------------
126
127 'getRecordKey': function (aRecordReference) {
128 return Clipperz.Async.callbacks("User.Header.RecordIndex.getRecordKey", [
129 MochiKit.Base.method(this, 'getRecordIndexData', aRecordReference),
130 MochiKit.Base.itemgetter('key')
131 ], {trace:false});
132 },
133
134 'setRecordKey': function (aRecordReference, aValue) {
135 return this.updateRecordIndexData(aRecordReference, 'key', aValue);
136 },
137
138 //-------------------------------------------------------------------------
139
140 'getRecordIndexData': function (aRecordReference) {
141 return this.recordsData().getValue(this.recordsIndex()[aRecordReference]);
142 },
143
144 //.........................................................................
145
146 'updateRecordIndexData': function (aRecordReference, aKey, aValue) {
147 return this.recordsData().setValue(this.recordsIndex()[aRecordReference]+'.'+aKey, aValue);
148 },
149
150 //-------------------------------------------------------------------------
151
152 'getDirectLoginIndexData': function (aDirectLoginReference) {
153 return this.directLoginsData().getValue(this.directLoginsIndex()[aDirectLoginReference]);
154 },
155
156 'setDirectLoginIndexData': function (aDirectLoginReference, aKey, aValue) {
157//if (MochiKit.Base.isUndefinedOrNull(this.directLoginsIndex()[aDirectLoginReference])) {
158 //throw "PIPPO";
159//}
160 return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference] + '.' + aKey, aValue);
161 },
162
163 'addDirectLoginIndexData': function (aDirectLoginReference) {
164 return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference], {});
165 },
166
167 'removeDirectLoginIndexData': function (aDirectLoginReference) {
168 return this.directLoginsData().removeValue(this.directLoginsIndex()[aDirectLoginReference])
169 },
170
171 //-------------------------------------------------------------------------
172
173 'records': function () {
174 vardeferredResult;
175
176 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records", {trace:false});
177 deferredResult.acquireLock(this.lock());
178 deferredResult.addCallback(MochiKit.Base.bind(function () {
179 var innerDeferredResult;
180
181 if (this._records == null) {
182 innerDeferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records <inner deferred>", {trace:false});
183 innerDeferredResult.collectResults({
184 'records': [
185 // MochiKit.Base.method(this.recordsData(), 'getObjectDataStore'),
186 // MochiKit.Base.methodcaller('values')
187 MochiKit.Base.method(this.recordsData(), 'values')
188 ],
189 'recordsStats': [
190 MochiKit.Base.method(this.recordsData(), 'getRemoteData'),
191 MochiKit.Base.itemgetter('recordsStats')
192 ],
193 'directLogins': [
194 // MochiKit.Base.method(this.directLoginsData(), 'getObjectDataStore'),
195 // MochiKit.Base.methodcaller('values')
196 MochiKit.Base.method(this.directLoginsData(), 'values')
197 ]
198 })
199 innerDeferredResult.addCallback(MochiKit.Base.bind(function (someData) {
200 var indexReference;
201 var recordsInvertedIndex;
202 var directLoginsInvertedIndex;
203
204 recordsInvertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.recordsIndex());
205 directLoginsInvertedIndex= Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.directLoginsIndex());
206
207 this._records = {};
208
209 for (indexReference in someData['records']) {
210 varrecord;
211 var reference;
212 var updateDate;
213
214 reference = recordsInvertedIndex[indexReference];
215
216 if (typeof(someData['recordsStats'][reference]) != 'undefined') {
217 updateDate = someData['recordsStats'][reference]['updateDate'];
218
219 record = new Clipperz.PM.DataModel.Record({
220 'reference': reference,
221 'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
222 'retrieveRemoteDataFunction':this.retrieveRecordDetailFunction(),
223
224 'retrieveIndexDataFunction':MochiKit.Base.method(this, 'getRecordIndexData'),
225 'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
226 'updateDate': updateDate,
227
228 'retrieveDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'getDirectLoginIndexData'),
229 'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
230 'removeDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
231
232 'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
233 });
234
235 this._records[reference] = record;
236 } else {
237Clipperz.log("SKIPPING record " + reference + " as there are no stas associated - " + Clipperz.Base.serializeJSON(someData['records'][reference]));
238 //# skip the record, as it seems it is not present in the DB
239 //updateDate = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
240 }
241 }
242
243 for (indexReference in someData['directLogins']) {
244 // vardirectLogin;
245 var reference;
246 var record;
247
248 reference = directLoginsInvertedIndex[indexReference];
249 record = this._records[recordsInvertedIndex[someData['directLogins'][indexReference]['record']]];
250
251 if (record != null) {
252 // directLogin = new Clipperz.PM.DataModel.DirectLogin({
253 new Clipperz.PM.DataModel.DirectLogin({
254 'reference': reference,
255 'record': record
256 });
257 } else {
258 Clipperz.logWarning("WARNING: DIRECT LOGIN without a matching RECORD!!");
259 }
260 }
261
262 return this._records;
263 }, this));
264 innerDeferredResult.callback();
265 } else {
266 innerDeferredResult = MochiKit.Async.succeed(this._records);
267 }
268
269 return innerDeferredResult;
270 }, this));
271 deferredResult.releaseLock(this.lock());
272 deferredResult.callback();
273
274 return deferredResult;
275 },
276
277 //-------------------------------------------------------------------------
278
279 'updateRecordIndexForNewRecord': function (aNewRecord) {
280 var newRecordIndex;
281 var recordReference;
282
283 recordReference = aNewRecord.reference();
284 newRecordIndex = (MochiKit.Base.listMax(MochiKit.Base.map(MochiKit.Base.partial(MochiKit.Base.operator.mul, 1), MochiKit.Base.values(this.recordsIndex()))) + 1) + '';
285 this.recordsIndex()[recordReference] = newRecordIndex;
286
287 this.transientState().setValue('newlyCreatedRecordsIndex' + '.' + recordReference, newRecordIndex);
288 this.transientState().setValue('newlyCreatedRecordsReferences'+ '.' + recordReference, aNewRecord);
289 },
290
291 //.........................................................................
292
293 'createNewRecord': function () {
294 var deferredResult;
295 var newRecord;
296
297 newRecord = new Clipperz.PM.DataModel.Record({
298 'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
299 'retrieveRemoteDataFunction':this.retrieveRecordDetailFunction(),
300
301 'retrieveIndexDataFunction':MochiKit.Base.method(this, 'getRecordIndexData'),
302 'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
303 'updateDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
304
305 'retrieveDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'getDirectLoginIndexData'),
306 'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
307 'removeDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
308
309 'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
310 });
311
312 this.transientState().setValue('newRecordsReferences' + '.' + newRecord.reference(), newRecord);
313 this.updateRecordIndexForNewRecord(newRecord);
314
315 deferredResult = Clipperz.Async.callbacks("User.Header.RecordIndex.createNewRecord", [
316 MochiKit.Base.method(this, 'records'),
317 MochiKit.Base.partial(Clipperz.Async.setItemOnObject, newRecord.reference(), newRecord),
318 MochiKit.Base.method(this, 'setRecordKey', newRecord.reference(), Clipperz.PM.Crypto.randomKey()),
319 MochiKit.Base.method(newRecord, 'setLabel', ''),
320 MochiKit.Base.partial(MochiKit.Async.succeed, newRecord)
321 ], {trace:false});
322
323
324 return deferredResult;
325 },
326
327 //-------------------------------------------------------------------------
328
329 'deleteRecord': function (aRecord) {
330 var deferredResult;
331 var recordReference;
332
333 recordReference = aRecord.reference();
334
335 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.deleteRecord", {trace:false});
336
337 deferredResult.addMethod(aRecord, 'directLogins');
338 deferredResult.addCallback(MochiKit.Base.values);
339 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'removeDirectLogin'));
340
341 deferredResult.addMethod(this.recordsData(), 'removeValue', this.recordsIndex()[recordReference]);
342 deferredResult.addCallback(MochiKit.Base.bind(function () {
343 this.transientState().setValue('deleteRecordsIndex' + '.' + recordReference, this.recordsIndex()[recordReference]);
344 delete this.recordsIndex()[recordReference];
345 }, this));
346
347 deferredResult.addMethod(this, 'records');
348 deferredResult.addCallback(MochiKit.Base.itemgetter(recordReference));
349 deferredResult.addMethod(this.transientState(), 'setValue', 'deleteRecordsReferences' + '.' + recordReference);
350
351 deferredResult.addMethod(this, 'records');
352 deferredResult.addCallback(MochiKit.Base.bind(function (someRecords) {
353 delete someRecords[recordReference];
354 }, this));
355 deferredResult.callback();
356
357 return deferredResult;
358 },
359
360 //=========================================================================
361
362 'removeDirectLogin': function (aDirectLogin) {
363 this.directLoginsData().removeValue(this.directLoginsIndex()[aDirectLogin.reference()]);
364 },
365
366 //-------------------------------------------------------------------------
367
368 'createNewDirectLogin': function (aRecord) {
369 var newDirectLogin;
370 varnewDirectLoginIndexValue;
371
372 newDirectLogin = new Clipperz.PM.DataModel.DirectLogin({record:aRecord});
373 newDirectLoginIndexValue = MochiKit.Base.listMax(MochiKit.Base.map(function (aValue) { return aValue * 1; }, MochiKit.Base.values(this.directLoginsIndex()))) + 1;
374
375 this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
376
377 this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
378 this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
379
380 return newDirectLogin;
381 },
382
383 //=========================================================================
384
385 'deleteAllCleanTextData': function () {
386 return Clipperz.Async.callbacks("User.Header.RecordIndex.deleteAllCleanTextData", [
387 // MochiKit.Base.method(this, 'records'),
388 // MochiKit.Base.values,
389 // MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
390
391 MochiKit.Base.method(this, 'recordsData'),
392 MochiKit.Base.methodcaller('deleteAllCleanTextData'),
393 MochiKit.Base.method(this, 'directLoginsData'),
394 MochiKit.Base.methodcaller('deleteAllCleanTextData')
395 ], {trace:false});
396 },
397
398 //-------------------------------------------------------------------------
399
400 'hasAnyCleanTextData': function () {
401 var deferredResult;
402
403 deferredResult = new Clipperz.Async.Deferred({trace:false});
404 deferredResult.collectResults({
405 'recordsData': [
406 MochiKit.Base.method(this, 'recordsData'),
407 MochiKit.Base.methodcaller('hasAnyCleanTextData')
408 ],
409 'directLoginsData':[
410 MochiKit.Base.method(this, 'directLoginsData'),
411 MochiKit.Base.methodcaller('hasAnyCleanTextData')
412 ],
413 // 'records': [
414 // MochiKit.Base.method(this, 'records'),
415 // MochiKit.Base.values,
416 // MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
417 // Clipperz.Async.collectAll
418 // ]
419 });
420
421 // deferredResult.addCallback(MochiKit.Base.values);
422 // deferredResult.addCallback(MochiKit.Base.flattenArguments);
423 // deferredResult.addCallback(function(someValues) {
424 // return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
425 // });
426 deferredResult.addCallback(Clipperz.Async.or);
427
428 deferredResult.callback();
429
430 return deferredResult;
431 },
432
433 //-------------------------------------------------------------------------
434
435 'hasPendingChanges': function () {
436 vardeferredResult;
437
438 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.hasPendingChanges", {trace:false});
439 deferredResult.collectResults({
440 'recordsData': [
441 MochiKit.Base.method(this, 'recordsData'),
442 MochiKit.Base.methodcaller('hasPendingChanges')
443 ],
444 'directLoginsData': [
445 MochiKit.Base.method(this, 'directLoginsData'),
446 MochiKit.Base.methodcaller('hasPendingChanges')
447 ]
448 });
449 deferredResult.addCallback(Clipperz.Async.or);
450 // deferredResult.addCallback(MochiKit.Base.values);
451 // deferredResult.addCallback(MochiKit.Base.flattenArguments);
452 // deferredResult.addCallback(function(someValues) {
453 // return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
454 // });
455 deferredResult.callback();
456
457 return deferredResult;
458 },
459
460 //-------------------------------------------------------------------------
461
462 'commitTransientState': function () {
463 var deferredResult;
464
465 deferredResut = Clipperz.Async.callbacks("User.Header.RecordIndex.commitTransientState", [
466 MochiKit.Base.method(this, 'recordsData'),
467 MochiKit.Base.methodcaller('commitTransientState'),
468
469 MochiKit.Base.method(this, 'directLoginsData'),
470 MochiKit.Base.methodcaller('commitTransientState'),
471
472 MochiKit.Base.method(this, 'resetTransientState', true)
473 ], {trace:false});
474
475 return deferredResult;
476 },
477
478 //-------------------------------------------------------------------------
479
480 'revertChanges': function () {
481 return Clipperz.Async.callbacks("User.Header.RecordIndex.revertChanges", [
482 MochiKit.Base.method(this, 'recordsData'),
483 MochiKit.Base.methodcaller('revertChanges'),
484
485 // MochiKit.Base.method(this, 'directLoginsData'),
486 // MochiKit.Base.methodcaller('revertChanges'),
487
488 MochiKit.Base.method(this, 'records'),
489 MochiKit.Base.bind(function (someRecords) {
490 varrecordReference;
491
492 for (recordReference in this.transientState().getValue('deleteRecordsReferences')) {
493 this.recordsIndex()[recordReference] = this.transientState().getValue('deleteRecordsIndex' + '.' + recordReference);
494 someRecords[recordReference] = this.transientState().getValue('deleteRecordsReferences' + '.' + recordReference);
495 }
496
497 for (recordReference in this.transientState().getValue('newRecordsReferences')) {
498 delete this.recordsIndex()[recordReference];
499 delete someRecords[recordReference];
500 }
501 }, this),
502
503 // MochiKit.Base.method(this, 'directLogins'),
504 MochiKit.Base.bind(function () {
505 vardirectLoginReference;
506
507 //this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
508//
509 //this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
510 //this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
511
512
513 // for (directLoginReference in this.transientState().getValue('deleteDirectLoginReferences')) {
514 // someDirectLogins[directLoginReference] = this.transientState().getValue('deleteDirectLoginReferences' + '.' + recordReference);
515 // }
516
517 for (directLoginReference in this.transientState().getValue('newDirectLoginReferences')) {
518 // this.directLoginsData().removeValue(this.directLoginsIndex()[directLoginReference]);
519 delete this.directLoginsIndex()[directLoginReference];
520 }
521 }, this),
522
523 MochiKit.Base.method(this, 'directLoginsData'),
524 MochiKit.Base.methodcaller('revertChanges'),
525
526 MochiKit.Base.method(this, 'resetTransientState', false)
527 ], {trace:false});
528 },
529
530 //-------------------------------------------------------------------------
531
532 'prepareRemoteDataWithKey': function (aKey) {
533 // "records": {
534 // "index": {
535 // "eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5": "0",
536 // "13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551": "1",
537 // ...
538 // "465a067a0bd2b470fa834de5397e38494de0c7707938262fae3427932e219744": "18",
539 // "4fd1dc2ca860b7fb47cef10a84edb3270da05510b0a30a6b0b083898712d4b9e": "19"
540 // },
541 // "data": "n+AzGEEQXaSRSY4d ... BDypotrXgPo94uHfoXvGFzwCn8w="
542 // },
543 // "directLogins": {
544 // "index": {
545 // "61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0",
546 // "989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1",
547 // ...
548 // "cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17",
549 // "7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18"
550 // },
551 // "data":"5YG9KKU/OZ5guUgFlms6k1 ... ZG/5Fn0uN+LoAsNfHm+EE62x"
552 // },
553
554 var deferredResult;
555 var result;
556
557 result = {};
558
559 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.prepareRemoteDataWithKey", {trace:false});
560 deferredResult.collectResults({
561 'index':MochiKit.Base.partial(MochiKit.Async.succeed, this.recordsIndex()),
562 'data': [
563 MochiKit.Base.method(this.recordsData(), 'prepareRemoteDataWithKey', aKey),
564 MochiKit.Base.itemgetter('data')
565 ]
566 });
567 deferredResult.addCallback(Clipperz.Async.setItem, result, 'records');
568
569 deferredResult.collectResults({
570 'index':MochiKit.Base.partial(MochiKit.Async.succeed, this.directLoginsIndex()),
571 'data': [
572 MochiKit.Base.method(this.directLoginsData(), 'prepareRemoteDataWithKey', aKey),
573 MochiKit.Base.itemgetter('data')
574 ]
575 });
576 deferredResult.addCallback(Clipperz.Async.setItem, result, 'directLogins');
577
578 deferredResult.addCallback(MochiKit.Async.succeed, result);
579
580 deferredResult.callback();
581
582 return deferredResult;
583 },
584
585 //-------------------------------------------------------------------------
586
587 'updateRecordKeyAndPrepareRemoteData': function (aRecord) {
588 varnewRecordKey;
589 var deferredResult;
590
591 newRecordKey = Clipperz.PM.Crypto.randomKey();
592
593 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.updateRecordKeyAndPrepareRemoteData", {trace:false});
594 deferredResult.addCallback(MochiKit.Base.method(aRecord, 'prepareRemoteDataWithKey', newRecordKey));
595 deferredResult.addCallbackPass(MochiKit.Base.method(this, 'setRecordKey', aRecord.reference(), newRecordKey));
596 deferredResult.callback();
597
598 return deferredResult;
599 },
600
601 //.........................................................................
602
603 'removeNewRecordWithNoChanges': function (aRecord) {
604 var deferredResult;
605 var recordReference;
606
607 recordReference = aRecord.reference();
608
609 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.removeNewRecordWithNoChanges", {trace:false});
610
611 deferredResult.addMethod(this.recordsData(), 'removeValue', this.recordsIndex()[recordReference]);
612 deferredResult.addCallback(MochiKit.Base.bind(function () {
613 delete this.recordsIndex()[recordReference];
614 }, this));
615
616 deferredResult.addMethod(this, 'records');
617 deferredResult.addCallback(MochiKit.Base.bind(function (someRecords) {
618 delete someRecords[recordReference];
619 }, this));
620 deferredResult.callback();
621
622 return deferredResult;
623 },
624
625 //.........................................................................
626
627 'prepareRemoteDataForChangedRecords': function () {
628 vardeferredResult;
629 varresult;
630
631 result = {};
632
633 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.prepareRemoteDataForChangedRecords", {trace:false});
634
635 deferredResult.addMethod(this, 'records');
636 deferredResult.addCallback(MochiKit.Base.values);
637 deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.methodcaller('isBrandNewWithNoPendingChanges'));
638 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'removeNewRecordWithNoChanges'));
639
640 deferredResult.addMethod(this, 'records');
641 deferredResult.addCallback(MochiKit.Base.values);
642 deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.methodcaller('hasPendingChanges'));
643 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'updateRecordKeyAndPrepareRemoteData'));
644 deferredResult.addCallback(Clipperz.Async.collectAll);
645
646 deferredResult.addCallback(Clipperz.Async.deferredIf("updated records != null", [
647 MochiKit.Base.operator.identity
648 ], [
649 MochiKit.Base.partial(MochiKit.Async.succeed, [])
650 ]));
651 deferredResult.addCallback(Clipperz.Async.setItem, result, 'updated');
652
653 deferredResult.addMethod(this.transientState(), 'getValue', 'deleteRecordsReferences');
654 deferredResult.addCallback(MochiKit.Base.keys);
655 deferredResult.addCallback(Clipperz.Async.deferredIf("deleted records != null", [
656 MochiKit.Base.operator.identity
657 ], [
658 MochiKit.Base.partial(MochiKit.Async.succeed, [])
659 ]));
660 deferredResult.addCallback(Clipperz.Async.setItem, result, 'deleted');
661
662 deferredResult.addCallback(MochiKit.Async.succeed, result);
663 deferredResult.callback();
664
665 return deferredResult;
666 },
667
668 //-------------------------------------------------------------------------
669 __syntaxFix__: "syntax fix"
670});
671
672
673
674Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex = function (anIndex) {
675 var result;
676 var key;
677
678 result = {};
679
680 for (key in anIndex) {
681 result[anIndex[key]] = key;
682 }
683
684 return result;
685}; \ No newline at end of file