Updated to work with the latest metadata scheme
[ajatus.git] / js / ajatus.preferences.js
blobf8cb6f06f33f10190396b0cc18bd1e20e25d450b
1 /*
2  * This file is part of
3  *
4  * Ajatus - Distributed CRM
5  * @requires jQuery v1.2.1
6  * 
7  * Copyright (c) 2007 Jerry Jalava <jerry.jalava@gmail.com>
8  * Copyright (c) 2007 Nemein Oy <http://nemein.com>
9  * Website: http://ajatus.info
10  * Licensed under the GPL license
11  * http://www.gnu.org/licenses/gpl.html
12  * 
13  */
15 (function($){
16     $.ajatus = $.ajatus || {};    
18     $.ajatus.preferences = {
19         revision: null,
20         modified: false
21     };
22     
23     $.ajatus.preferences.local = {};
24     $.ajatus.preferences.local_defaults = {
25         user: {
26             name: 'Root Ajatus',
27             email: 'root@ajatus.info'
28         },
29         replication: {
30             enabled: false,
31             public_key: '',
32             allowed_keys: ''
33         },
34         layout: {
35             theme_name: 'default',
36             icon_set: 'default'
37         },
38         localization: {
39             language: 'en_GB'
40         },
41         backups: {
42             enabled: false,
43             auto: false
44         },
45         expansions: {
46             active: []
47         },
48         auto_save: {
49             enabled: true,
50             interval: 300
51         }
52     };
53     
54     $.ajatus.preferences.client = {};
55     $.ajatus.preferences.client_defaults = {
56         debug: false,
57         language: null,
58         server_url: '/',
59         theme_url: 'themes/default/',
60         theme_icons_url: 'themes/default/images/icons/',
61         application_url: '/_utils/ajatus/',
62         application_database_identifier: '',
63         content_types: {},
64         custom_views: [],
65         custom_widgets: [],
66         extensions: [],
67         types: {
68             in_use: [
69                 'note', 'contact', 'event', 'expense', 'hour_report'
70             ],
71             system: [
72                 'tag'
73             ]
74         },
75         themes: {
76             available: [
77                 'default'
78             ]
79         }
80     };
81             
82     $.ajatus.preferences.loader = function() {
83         this.loaded = false;
84         
85         var on_success = function(data) {
86             this.loaded = true;
87             
88             $.ajatus.events.lock_pool.decrease();
89             $.ajatus.preferences.revision = data._rev;
90             
91             $.ajatus.preferences.local = data.value;
92             $.each($.ajatus.preferences.local_defaults, function(i,n){
93                 if (typeof $.ajatus.preferences.local[i] == 'undefined') {
94                     $.ajatus.preferences.modified = true;
95                     $.ajatus.preferences.local[i] = n;
96                 }
97                 if (typeof n == 'object') {
98                     $.each(n, function(xi,xn){
99                         if (typeof $.ajatus.preferences.local[i][xi] == 'undefined') {
100                             $.ajatus.preferences.modified = true;
101                             $.ajatus.preferences.local[i][xi] = xn;
102                         }
103                     });
104                 }
105             });
106             
107             return data;
108         };
109         
110         this.dc = $.jqCouch.connection('doc', on_success);
111     }
112     $.extend($.ajatus.preferences.loader.prototype, {
113         load: function() {
114             $.ajatus.events.lock_pool.increase();
115             var data = this.dc.get($.ajatus.preferences.client.application_database + '/preferences');
116             if (! data._id) {
117                 this.loaded = false;
118                 $.ajatus.events.lock_pool.decrease();
119                 $.ajatus.ajax_error(data.request);
120             }
121         }
122     });
123     
124     $.ajatus.preferences.view = {
125         title: 'Preferences',
126         options: {},
127         sections: [
128             'user', 'localization', 'layout', 'replication', 'backups', 'expansions', 'auto_save'
129         ],
130         
131         tab: {
132             on_click: function(e)
133             {
134                 $.ajatus.tabs.on_click(e);
135                 $.ajatus.preferences.view.render();
136             }
137         },
138         
139         render: function() {
140             $.ajatus.application_content_area.html('');
141             $.ajatus.layout.body.set_class('preferences');
142             $.ajatus.views.on_change("#view.preferences");
143             
144             $.ajatus.toolbar.show();
145             
146             var form = $('<form name="preferences" id="preferences_form"/>');
147             form.appendTo($.ajatus.application_content_area);
148             
149             var hidden_data = {
150                 _id: 'preferences',
151                 _rev: $.ajatus.preferences.revision
152             };
153             var hidden_fields = function() {
154                 return [
155                     'input', { type: 'hidden', id: 'preferences_id', name: '_id', value: this._id }, '',
156                     'input', { type: 'hidden', id: 'preferences_revision', name: '_rev', value: this._rev }, ''
157                 ];
158             };
159             $(form).tplAppend(hidden_data, hidden_fields);
160             
161             var form_actions = $('<div class="form_actions"><input type="submit" name="save" value="' + $.ajatus.i10n.get('Save') + '" /><input type="submit" name="cancel" value="' + $.ajatus.i10n.get('Cancel') + '" /></div>');
162             
163             var sections_holder = $('<div id="preference_sections" />');
164             sections_holder.appendTo(form);
165             
166             $.each($.ajatus.preferences.view.sections, function(i,s){
167                 var section_holder = $('<div class="section" id="section_' + s + '" />');
168                 section_holder.appendTo(sections_holder);
169                 
170                 var form_items = $.ajatus.preferences.view.generate_section_form(s);
171                 
172                 if (form_items) {
173                     var title = $('<h3 />').html($.ajatus.i10n.get(s));
174                     title.appendTo(section_holder);
175                     
176                     form_items.appendTo(section_holder);
177                 }
178             });
180             form_actions.appendTo(form);
181             
182             $.ajatus.toolbar.add_item($.ajatus.i10n.get('Save'), 'save.png', function(){
183                 $('#preferences_form input[@type=submit][name*=save]').trigger("click", []);
184             });
185             $.ajatus.toolbar.add_item($.ajatus.i10n.get('Cancel'), 'cancel.png', function(){
186                 $('#preferences_form input[@type=submit][name*=cancel]').trigger("click", []);
187             });
188             
189             $.ajatus.forms.register.custom(form, '$.ajatus.preferences.view.process_form');
190         },
191         
192         process_form: function(form_data, form) {
193             // $.ajatus.debug('Process preferences');
194             // console.log(form_data);
195             
196             var doc = {
197                 _id: '',
198                 _rev: '',
199                 value: {}
200             };
201             var form_values = {};
202             var form_id = '';
204             $.each(form_data, function(i,row){
205                 if (row.name.toString().match(/__(.*?)/)) {
206                     return;
207                 }
208                 if (   row.name == '_id'
209                     && (   row.value != undefined
210                         && row.value != ''))
211                 {
212                     doc['_id'] = String(row.value);
213                     form_id = doc['_id'];
214                 }
215                 else if(   row.name == '_rev'
216                         && (   typeof row.value != "undefined"
217                             && row.value != ''))
218                 {
219                     doc['_rev'] = String(row.value);
220                 } else {
221                     if (row.name != 'submit') {
222                         if (row.name == '_type') {
223                             }
224                             else if (   row.name.substr(0,6) != "widget"
225                                      && row.name.substr(0,8) != "metadata")
226                             {
227                                 var item = {};
228                                 var widget = {};
229                                 var prev_val = false;
230                                 var name_parts = [];
231                                 var name_parts_count = 0;
232                                 if (row.name.toString().match(/;/g)) {
233                                     name_parts = row.name.toString().split(";");
234                                     name_parts_count = name_parts.length;
235                                 }
236                                 
237                                 $.each(form_data, function(x,r){
238                                     if (r.name == 'widget['+row.name+':name]') {
239                                         widget['name'] = r.value;
240                                     } else if (r.name == 'widget['+row.name+':config]') {
241                                     widget['config'] = $.ajatus.converter.parseJSON(r.value);
242                                 } else if (r.name == 'widget['+row.name+':prev_val]') {
243                                     prev_val = $.ajatus.converter.parseJSON(r.value);
244                                 }
245                             });
246                             
247                             var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
248                                 item['val'] = wdgt.value_on_save(row.value, prev_val);
249                                 item['widget'] = widget;
250                                 
251                                 if (name_parts_count > 0) {
252                                     var prevs = [];
253                                     for (var i=0; i < name_parts_count; i++) {
254                                         var arr_keys = false;
255                                         var key_prefix = '';
256                                         
257                                         if (name_parts[i].match(/\[/g)) {
258                                             var arr_keys = name_parts[i].split('[');
259                                             
260                                             name_parts[i] = name_parts[i].replace(/\[/g, '"][');
261                                             var key = '["'+name_parts[i];
262                                         } else {
263                                             var key = "['"+name_parts[i]+"']";
264                                         }
265                                     
266                                     if (prevs.length > 0) {
267                                         $.each(prevs, function(pi, pk){
268                                             key_prefix = "['" + pk + "']" + key_prefix;
269                                         });
270                                         key = key_prefix + key;
271                                     }
272                                                                             
273                                     if (arr_keys) {
274                                         var tmp_key = key_prefix + "['" + arr_keys[0] + "']";
275                                         if (typeof eval("form_values"+tmp_key) == 'undefined') {
276                                             eval("form_values"+tmp_key+"=[];");
277                                         }                    
278                                     }
279                                     
280                                     var multiple = false;
281                                         if (typeof eval("form_values"+key) == 'undefined') {
282                                             if (key_prefix != '') {
283                                             eval("form_values"+key+"=new Array();");
284                                             } else {
285                                             eval("form_values"+key+"={};");                                             
286                                             }
287                                         } else {                                            
288                                             multiple = true;
289                                         }
290                                         
291                                         prevs.push(name_parts[i]);
292                                     if (i == name_parts_count-1) {
293                                         if (item.val == '') {
294                                             return;
295                                         }
296                                         if (multiple) {
297                                             if (typeof item == 'object') {
298                                                 // eval("form_values"+key+".push('"+item.toSource()+"');");
299                                                 eval("form_values"+key+".push('"+item.val+"');");
300                                             } else {
301                                                 eval("form_values"+key+".push('"+item.val+"');");
302                                             }                                                
303                                         } else {
304                                             if (typeof item == 'object') {
305                                                 // eval("form_values"+key+"="+item.toSource()+";");
306                                                 eval("form_values"+key+"='"+item.val+"';");
307                                             } else {
308                                                 eval("form_values"+key+"='"+item.val+"';");
309                                             }                                                
310                                         }
311                                     }
312                                     }
313                                 } else {
314                                     form_values[row.name] = item;
315                                 }
316                             }
317                             else if (row.name.substr(0,8) == "metadata")
318                             {
319                                 if (!form_values['metadata'])
320                                 {
321                                     form_values['metadata'] = {};
322                                 }
324                                 var re = /\bmetadata\[([a-z]+)\b/;
325                                 var results = re.exec(row.name);
326                                 var key = results[1];
328                                 form_values['metadata'][key] = {
329                                     val: row.value
330                                 };
331                             }
332                     }
333                 }
334             });
335             doc['value'] = form_values;
337             doc = new $.ajatus.document(doc);
338             
339             $.ajatus.preferences.view.save(doc.value);
340         },
341         
342         save: function(preferences) {
343             var saved = false;
345             var on_success = function(data) {
346                 saved = true;
347                 $.ajatus.preferences.revision = data.rev;
348                 $.ajatus.events.named_lock_pool.decrease('unsaved');                
349                 window.location.reload();
350                 
351                 return data;
352             };
353             
354             prefs_doc = new $.ajatus.document({
355                 _id: 'preferences',
356                 _rev: $.ajatus.preferences.revision,
357                 value: preferences
358             });
359             prefs_doc.value._type = 'preferences';
361             var new_metadata = {
362                 revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
363                 revisor: $.ajatus.preferences.local.user.email
364             };
365             prefs_doc = $.ajatus.document.modify_metadata(prefs_doc, new_metadata);
366             
367             var prefs = {
368                 metadata: prefs_doc.value.metadata
369             };
370             $.each($.ajatus.preferences.local_defaults, function(k,data){                
371                 if (typeof prefs[k] == 'undefined') {
372                     prefs[k] = {};
373                 }
374                 
375                 if (typeof data == 'object') {                    
376                     $.each(data, function(sk, sdata){                        
377                         if (typeof prefs_doc.value[k] == 'undefined') {
378                             prefs[k][sk] = sdata;
379                         } else {
380                             if (typeof prefs_doc.value[k][sk] == 'undefined') {
381                                 prefs[k][sk] = sdata;
382                             } else {
383                                 if (typeof prefs_doc.value[k][sk]['val'] == 'undefined') {
384                                     prefs[k][sk] = prefs_doc.value[k][sk];
385                                 } else {
386                                     prefs[k][sk] = prefs_doc.value[k][sk].val;
387                                 }
388                             }                            
389                         }
390                     });
391                 } else {
392                     if (typeof prefs_doc.value[k] == 'undefined') {
393                         prefs[k] = data;
394                     } else {
395                         if (typeof prefs_doc.value[k]['val'] == 'undefined') {
396                             prefs[k] = prefs_doc.value[k];
397                         } else {
398                             prefs[k] = prefs_doc.value[k].val;
399                         }
400                     }
401                 }                
402             });
403             prefs_doc.value = prefs;
405             $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.application_database, prefs_doc);
406             
407             return saved;
408         },
409         
410         generate_section_form: function(section) {
411             if (typeof $.ajatus.preferences.local[section] == 'undefined') {
412                 return false;
413             }
415             var items = false;            
416             var section_data = $.ajatus.preferences.local[section];
417             
418             function auto_gen(section, data) {
419                 var rows = $('<ul/>');
420                 
421                 $.each(data, function(i,s){
422                     // console.log("i: "+i+" s: ");
423                     // console.log(s);
424                     var s_type = typeof(s);
425                     // console.log('type: '+s_type);
426                     var wdgt = null;
427                     var normalized_name = i.toString().replace('_', ' ');
429                     switch (s_type) {
430                         case 'boolean':
431                             wdgt = $.ajatus.widget('boolean');
432                         break;
433                         case 'number':
434                             wdgt = $.ajatus.widget('integer');
435                         break;
436                         case 'string':
437                         default:
438                             wdgt = $.ajatus.widget('text');
439                     };
441                     rows.createAppend(
442                         'li', { id: '_setting_'+section+'_'+i, className: 'row' }, [
443                             'label', { id: '_setting_'+section+'_'+i+'_label' }, $.ajatus.i10n.get(normalized_name),
444                             'div', { id: '_setting_'+section+'_'+i+'_widget', className: wdgt.name }, wdgt.get_edit_tpl(section+';'+i, {val: s}),
445                             'br', { className: 'clear_fix' }, ''
446                         ]
447                     );            
448                     wdgt.init($('#_setting_'+i+'_widget',rows), true);
449                 });
451                 $('li:first', rows).addClass('first');
452                 $('li:last', rows).addClass('last');
453                 
454                 return rows;
455             }
456             
457             function gen_localization(data) {
458                 var rows = $('<ul/>');
459                 var langs = $.ajatus.i10n.get_available_langs();
460                 var lang_opts = {};
461                 
462                 $.each(langs, function(i,l) {
463                     lang_opts[i] = l;
464                 });
466                 wdgt = $.ajatus.widget('selection', {
467                     items: lang_opts
468                 });
469                 rows.createAppend(
470                     'li', { id: '_setting_localization_language', className: 'row' }, [
471                         'label', { id: '_setting_localization_language_label' }, $.ajatus.i10n.get('Language'),
472                         'div', { id: '_setting_localization_language_widget', className: wdgt.name }, wdgt.get_edit_tpl('localization;language', {val: data.language}),
473                         'br', { className: 'clear_fix' }, ''
474                     ]
475                 );            
476                 wdgt.init($('#_setting_localization_language_widget',rows), true);
477                 
478                 return rows;                
479             }
480             
481             function gen_layout(data) {
482                 var rows = $('<ul/>');
483                 var themes = $.ajatus.preferences.client.themes.available;
484                 var theme_opts = {};
485                 
486                 $.each(themes, function(i,l) {
487                     theme_opts[i] = $.ajatus.i10n.get(l);
488                 });
490                 wdgt = $.ajatus.widget('selection', {
491                     items: theme_opts
492                 });
493                 rows.createAppend(
494                     'li', { id: '_setting_layout_theme_name', className: 'row' }, [
495                         'label', { id: '_setting_layout_theme_name_label' }, $.ajatus.i10n.get('Theme'),
496                         'div', { id: '_setting_layout_theme_name_widget', className: wdgt.name }, wdgt.get_edit_tpl('layout;theme_name', {val: data.theme_name}),
497                         'br', { className: 'clear_fix' }, ''
498                     ]
499                 );            
500                 wdgt.init($('#_setting_layout_theme_name_widget', rows), true);
501                 
502                 return rows;
503             }
504             
505             // Example how to handle arrays with checkboxes
506             // function gen_types(data) {
507             //     var rows = $('<ul />');
508             //     
509             //     $.each($.ajatus.types.available, function(key,type){
510             //         // console.log("key: "+key);
511             //         // console.log(type);
512             //         
513             //         var selected = false;
514             //         $.each(data.active, function(i,t){
515             //             if (t == key) {
516             //                 selected = true;
517             //             }
518             //         });
519             //         
520             //         var widget = new $.ajatus.widget('boolean', {
521             //             value: key
522             //         });
523             // 
524             //         rows.createAppend(
525             //             'li', { id: '_setting_types_active_'+key, className: 'row' }, [
526             //                 'label', { id: '_setting_types_active_'+key+'_label' }, $.ajatus.i10n.get(type.title),
527             //                 'div', { id: '_setting_types_active_'+key+'_widget', className: widget.name }, widget.get_edit_tpl('types;active', {val: (selected ? key : '')}), //["'+key+'"]
528             //                 'br', { className: 'clear_fix' }, ''
529             //             ]
530             //         );            
531             //         widget.init($('#_setting_types_active_'+key+'_widget',rows), true);
532             //     });
533             //     
534             //     return rows;
535             // }
536             
537             switch (section) {
538                 case 'localization':
539                     items = gen_localization(section_data);
540                 break;
541                 case 'layout':
542                     items = gen_layout(section_data);
543                 break;
544                 case 'replication':
545                 case 'backups':
546                 case 'expansions':
547                 break;
548                 default:
549                     items = auto_gen(section, section_data);
550             }
551             
552             return items;
553         }
554     };
555     
556 })(jQuery);