Fixed dynamic style loading for Safari
[ajatus.git] / js / ajatus.preferences.js
blob5e5625b232c221ac3c538eb94aa2de4160508df3
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         //         cookies: {            
81         //             expire: (24 * 60 * 60) // 24hrs in seconds
82         //         }
83     };
84             
85     $.ajatus.preferences.loader = function() {
86         this.loaded = false;
87         
88         var on_success = function(data) {
89             this.loaded = true;
90             
91             $.ajatus.events.lock_pool.decrease();
92             $.ajatus.preferences.revision = data._rev;
93             
94             $.ajatus.preferences.local = data.value;
95             $.each($.ajatus.preferences.local_defaults, function(i,n){
96                 if (typeof $.ajatus.preferences.local[i] == 'undefined') {
97                     $.ajatus.preferences.modified = true;
98                     $.ajatus.preferences.local[i] = n;
99                 }
100                 if (typeof n == 'object') {
101                     $.each(n, function(xi,xn){
102                         if (typeof $.ajatus.preferences.local[i][xi] == 'undefined') {
103                             $.ajatus.preferences.modified = true;
104                             $.ajatus.preferences.local[i][xi] = xn;
105                         }
106                     });
107                 }
108             });
109             
110             return data;
111         };
112         
113         this.dc = $.jqCouch.connection('doc', on_success);
114     }
115     $.extend($.ajatus.preferences.loader.prototype, {
116         load: function() {
117             $.ajatus.events.lock_pool.increase();
118             var data = this.dc.get($.ajatus.preferences.client.application_database + '/preferences');
119             if (! data._id) {
120                 this.loaded = false;
121                 $.ajatus.events.lock_pool.decrease();
122                 $.ajatus.ajax_error(data.request);
123             }
124         }
125     });
126     
127     $.ajatus.preferences.view = {
128         title: 'Preferences',
129         icon: 'preferences.png',
130         options: {},
131         sections: [
132             'user', 'localization', 'layout', 'replication', 'backups', 'expansions', 'auto_save'
133         ],
134         
135         tab: {
136             on_click: function(e)
137             {
138                 $.ajatus.tabs.on_click(e);
139                 $.ajatus.preferences.view.render();
140             }
141         },
142         
143         render: function() {
144             $.ajatus.application_content_area.html('');
145             $.ajatus.layout.body.set_class('preferences');
146             $.ajatus.views.on_change("#view.preferences");
147             
148             $.ajatus.toolbar.show();
149             
150             var form = $('<form name="preferences" id="preferences_form"/>');
151             form.appendTo($.ajatus.application_content_area);
152             
153             var hidden_data = {
154                 _id: 'preferences',
155                 _rev: $.ajatus.preferences.revision
156             };
157             var hidden_fields = function() {
158                 return [
159                     'input', { type: 'hidden', id: 'preferences_id', name: '_id', value: this._id }, '',
160                     'input', { type: 'hidden', id: 'preferences_revision', name: '_rev', value: this._rev }, ''
161                 ];
162             };
163             $(form).tplAppend(hidden_data, hidden_fields);
164             
165             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>');
166             
167             var sections_holder = $('<div id="preference_sections" />');
168             sections_holder.appendTo(form);
169             
170             $.each($.ajatus.preferences.view.sections, function(i,s){
171                 var section_holder = $('<div class="section" id="section_' + s + '" />');
172                 section_holder.appendTo(sections_holder);
173                 
174                 var form_items = $.ajatus.preferences.view.generate_section_form(s);
175                 
176                 if (form_items) {
177                     var title = $('<h3 />').html($.ajatus.i10n.get(s));
178                     title.appendTo(section_holder);
179                     
180                     form_items.appendTo(section_holder);
181                 }
182             });
184             form_actions.appendTo(form);
185             
186             $.ajatus.toolbar.add_item($.ajatus.i10n.get('Save'), 'save.png', function(){
187                 $('#preferences_form input[@type=submit][name*=save]').trigger("click", []);
188             });
189             $.ajatus.toolbar.add_item($.ajatus.i10n.get('Cancel'), 'cancel.png', function(){
190                 $('#preferences_form input[@type=submit][name*=cancel]').trigger("click", []);
191             });
192             
193             $.ajatus.forms.register.custom(form, '$.ajatus.preferences.view.process_form');
194         },
195         
196         process_form: function(form_data, form) {
197             // $.ajatus.debug('Process preferences');
198             // console.log(form_data);
199             
200             var doc = {
201                 _id: '',
202                 _rev: '',
203                 value: {}
204             };
205             var form_values = {};
206             var form_id = '';
207             
208             $.each(form_data, function(i,row){
209                 if (row.name.toString().match(/__(.*?)/)) {
210                     return;
211                 }
212                 if (   row.name == '_id'
213                     && (   row.value != undefined
214                         && row.value != ''))
215                 {
216                     doc['_id'] = String(row.value);
217                     form_id = doc['_id'];
218                 }
219                 else if(   row.name == '_rev'
220                         && (   typeof row.value != "undefined"
221                             && row.value != ''))
222                 {
223                     doc['_rev'] = String(row.value);
224                 } else {
225                     if (row.name != 'submit') {
226                         if (row.name == '_type') {
227                             }
228                             else if (   row.name.substr(0,6) != "widget"
229                                      && row.name.substr(0,8) != "metadata")
230                             {
231                                 var item = {};
232                                 var widget = {};
233                                 var prev_val = false;
234                                 var name_parts = [];
235                                 var name_parts_count = 0;
236                                 if (row.name.toString().match(/;/g)) {
237                                     name_parts = row.name.toString().split(";");
238                                     name_parts_count = name_parts.length;
239                                 }
240                                 
241                                 $.each(form_data, function(x,r){
242                                     if (r.name == 'widget['+row.name+':name]') {
243                                         widget['name'] = r.value;
244                                     } else if (r.name == 'widget['+row.name+':config]') {
245                                     widget['config'] = $.ajatus.converter.parseJSON(r.value);
246                                 } else if (r.name == 'widget['+row.name+':prev_val]') {
247                                     prev_val = $.ajatus.converter.parseJSON(r.value);
248                                 }
249                             });
250                             
251                             var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
252                                 item['val'] = wdgt.value_on_save(row.value, prev_val);
253                                 item['widget'] = widget;
254                                 
255                                 if (name_parts_count > 0) {
256                                     var prevs = [];
257                                     for (var i=0; i < name_parts_count; i++) {                                  
258                                         var arr_keys = false;
259                                         var key_prefix = '';
260                                         
261                                         if (name_parts[i].match(/\[/g)) {
262                                             var arr_keys = name_parts[i].split('[');
263                                             
264                                             name_parts[i] = name_parts[i].replace(/\[/g, '"][');
265                                             var key = '["'+name_parts[i];
266                                         } else {
267                                             var key = "['"+name_parts[i]+"']";
268                                         }
269                                     
270                                     if (prevs.length > 0) {
271                                         $.each(prevs, function(pi, pk){
272                                             key_prefix = "['" + pk + "']" + key_prefix;
273                                         });
274                                         key = key_prefix + key;
275                                     }
276                                                                             
277                                     if (arr_keys) {
278                                         var tmp_key = key_prefix + "['" + arr_keys[0] + "']";
279                                         if (typeof eval("form_values"+tmp_key) == 'undefined') {
280                                             eval("form_values"+tmp_key+"=[];");
281                                         }                    
282                                     }
283                                     
284                                     var multiple = false;
285                                         if (typeof eval("form_values"+key) == 'undefined') {
286                                             if (key_prefix != '') {
287                                             eval("form_values"+key+"=new Array();");
288                                             } else {
289                                             eval("form_values"+key+"={};");                                             
290                                             }
291                                         } else {                                            
292                                             multiple = true;
293                                         }
294                                         
295                                         prevs.push(name_parts[i]);
296                                     if (i == name_parts_count-1) {
297                                         if (typeof item['val'] == 'undefined') {
298                                             return;
299                                         }
300                                         if (multiple) {
301                                             if (typeof item == 'object') {
302                                                 // eval("form_values"+key+".push('"+item.toSource()+"');");
303                                                 if (item.widget.name == 'boolean') {
304                                                     eval("form_values"+key+"="+item.val+";");
305                                                 } else {
306                                                     eval("form_values"+key+".push('"+item.val+"');");                                                    
307                                                 }
308                                             } else {
309                                                 eval("form_values"+key+".push('"+item+"');");
310                                             }                                                
311                                         } else {
312                                             if (typeof item == 'object') {
313                                                 eval("form_values"+key+"='"+item.val+"';");
314                                             } else {
315                                                 eval("form_values"+key+"='"+item.val+"';");
316                                             }
317                                         }
318                                     }
319                                     }
320                                 } else {
321                                     form_values[row.name] = item;
322                                 }
323                             }
324                             else if (row.name.substr(0,8) == "metadata")
325                             {
326                                 if (! form_values['metadata']) {
327                                     form_values['metadata'] = {};
328                                 }
330                                 var re = /\bmetadata\[([a-z]+)\b/;
331                                 var results = re.exec(row.name);
332                                 var key = results[1];
334                                 form_values['metadata'][key] = {
335                                     val: row.value
336                                 };
337                             }
338                     }
339                 }
340             });
341             doc['value'] = form_values;
343             doc = new $.ajatus.document(doc);
345             $.ajatus.preferences.view.save(doc.value);
346         },
347         
348         save: function(preferences) {
349             var saved = false;
351             var on_success = function(data) {
352                 saved = true;
353                 $.ajatus.preferences.revision = data.rev;
354                 $.ajatus.events.named_lock_pool.decrease('unsaved');                
355                 window.location.reload();
356                 
357                 return data;
358             };
359             
360             prefs_doc = new $.ajatus.document({
361                 _id: 'preferences',
362                 _rev: $.ajatus.preferences.revision,
363                 value: preferences
364             });
365             prefs_doc.value._type = 'preferences';
367             var new_metadata = {
368                 revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
369                 revisor: $.ajatus.preferences.local.user.email
370             };
371             prefs_doc = $.ajatus.document.modify_metadata(prefs_doc, new_metadata);
372             
373             var prefs = {
374                 metadata: prefs_doc.value.metadata
375             };
376             $.each($.ajatus.preferences.local_defaults, function(k,data){                
377                 if (typeof prefs[k] == 'undefined') {
378                     prefs[k] = {};
379                 }
380                 
381                 if (typeof data == 'object') {                    
382                     $.each(data, function(sk, sdata){                        
383                         if (typeof prefs_doc.value[k] == 'undefined') {
384                             prefs[k][sk] = sdata;
385                         } else {
386                             if (typeof prefs_doc.value[k][sk] == 'undefined') {
387                                 prefs[k][sk] = sdata;
388                             } else {
389                                 if (typeof prefs_doc.value[k][sk]['val'] == 'undefined') {
390                                     prefs[k][sk] = prefs_doc.value[k][sk];
391                                 } else {
392                                     prefs[k][sk] = prefs_doc.value[k][sk].val;
393                                 }
394                             }                            
395                         }
396                     });
397                 } else {
398                     if (typeof prefs_doc.value[k] == 'undefined') {
399                         prefs[k] = data;
400                     } else {
401                         if (typeof prefs_doc.value[k]['val'] == 'undefined') {
402                             prefs[k] = prefs_doc.value[k];
403                         } else {
404                             prefs[k] = prefs_doc.value[k].val;
405                         }
406                     }
407                 }                
408             });
410             prefs_doc.value = prefs;
411             
412             $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.application_database, prefs_doc);
413             
414             return saved;
415         },
416         
417         generate_section_form: function(section) {
418             if (typeof $.ajatus.preferences.local[section] == 'undefined') {
419                 return false;
420             }
422             var items = false;            
423             var section_data = $.ajatus.preferences.local[section];
424             
425             function auto_gen(section, data) {
426                 var rows = $('<ul/>');
427                 
428                 $.each(data, function(i,s){
429                     // console.log("i: "+i+" s: ");
430                     // console.log(s);
431                     var s_type = typeof(s);
432                     // console.log('type: '+s_type);
433                     var wdgt = null;
434                     var normalized_name = i.toString().replace('_', ' ');
436                     switch (s_type) {
437                         case 'boolean':
438                             wdgt = $.ajatus.widget('boolean');
439                         break;
440                         case 'number':
441                             wdgt = $.ajatus.widget('integer');
442                         break;
443                         case 'string':
444                         default:
445                             wdgt = $.ajatus.widget('text');
446                     };
448                     rows.createAppend(
449                         'li', { id: '_setting_'+section+'_'+i, className: 'row' }, [
450                             'label', { id: '_setting_'+section+'_'+i+'_label' }, $.ajatus.i10n.get(normalized_name),
451                             'div', { id: '_setting_'+section+'_'+i+'_widget', className: wdgt.name }, wdgt.get_edit_tpl(section+';'+i, {val: s}),
452                             'br', { className: 'clear_fix' }, ''
453                         ]
454                     );            
455                     wdgt.init($('#_setting_'+i+'_widget',rows), true);
456                 });
458                 $('li:first', rows).addClass('first');
459                 $('li:last', rows).addClass('last');
460                 
461                 return rows;
462             }
463             
464             function gen_localization(data) {
465                 var rows = $('<ul/>');
466                 var langs = $.ajatus.i10n.get_available_langs();
467                 var lang_opts = {};
468                 
469                 $.each(langs, function(i,l) {
470                     lang_opts[i] = l;
471                 });
473                 wdgt = $.ajatus.widget('selection', {
474                     items: lang_opts
475                 });
476                 rows.createAppend(
477                     'li', { id: '_setting_localization_language', className: 'row' }, [
478                         'label', { id: '_setting_localization_language_label' }, $.ajatus.i10n.get('Language'),
479                         'div', { id: '_setting_localization_language_widget', className: wdgt.name }, wdgt.get_edit_tpl('localization;language', {val: data.language}),
480                         'br', { className: 'clear_fix' }, ''
481                     ]
482                 );            
483                 wdgt.init($('#_setting_localization_language_widget',rows), true);
484                 
485                 return rows;                
486             }
487             
488             function gen_layout(data) {
489                 var rows = $('<ul/>');
490                 var themes = $.ajatus.preferences.client.themes.available;
491                 var theme_opts = {};
492                 
493                 $.each(themes, function(i,l) {
494                     theme_opts[i] = $.ajatus.i10n.get(l);
495                 });
497                 wdgt = $.ajatus.widget('selection', {
498                     items: theme_opts
499                 });
500                 rows.createAppend(
501                     'li', { id: '_setting_layout_theme_name', className: 'row' }, [
502                         'label', { id: '_setting_layout_theme_name_label' }, $.ajatus.i10n.get('Theme'),
503                         'div', { id: '_setting_layout_theme_name_widget', className: wdgt.name }, wdgt.get_edit_tpl('layout;theme_name', {val: data.theme_name}),
504                         'br', { className: 'clear_fix' }, ''
505                     ]
506                 );            
507                 wdgt.init($('#_setting_layout_theme_name_widget', rows), true);
508                 
509                 return rows;
510             }
511             
512             function gen_autosave(data) {
513                 var rows = $('<ul/>');
514                 var section = 'auto_save';
515                 
516                 
517                 $.each(data, function(i,s){
518                     // console.log("i: "+i+" s: ");
519                     // console.log(s);
520                     var s_type = typeof(s);
521                     // console.log('type: '+s_type);
522                     var wdgt = null;
523                     var normalized_name = i.toString().replace('_', ' ');
524                     
525                     switch (i) {
526                         case 'enabled':
527                             wdgt = $.ajatus.widget('boolean');
528                         break;
529                         case 'interval':
530                             wdgt = $.ajatus.widget('integer',{
531                                 value_suffix: 's'
532                             });
533                         break;
534                         default:
535                             wdgt = $.ajatus.widget('text');
536                     };
538                     rows.createAppend(
539                         'li', { id: '_setting_'+section+'_'+i, className: 'row' }, [
540                             'label', { id: '_setting_'+section+'_'+i+'_label' }, $.ajatus.i10n.get(normalized_name),
541                             'div', { id: '_setting_'+section+'_'+i+'_widget', className: wdgt.name }, wdgt.get_edit_tpl(section+';'+i, {val: s}),
542                             'br', { className: 'clear_fix' }, ''
543                         ]
544                     );            
545                     wdgt.init($('#_setting_'+i+'_widget',rows), true);
546                 });
548                 $('li:first', rows).addClass('first');
549                 $('li:last', rows).addClass('last');
550                 
551                 return rows;
552             }
553             
554             // Example how to handle arrays with checkboxes
555             // function gen_types(data) {
556             //     var rows = $('<ul />');
557             //     
558             //     $.each($.ajatus.types.available, function(key,type){
559             //         // console.log("key: "+key);
560             //         // console.log(type);
561             //         
562             //         var selected = false;
563             //         $.each(data.active, function(i,t){
564             //             if (t == key) {
565             //                 selected = true;
566             //             }
567             //         });
568             //         
569             //         var widget = new $.ajatus.widget('boolean', {
570             //             value: key
571             //         });
572             // 
573             //         rows.createAppend(
574             //             'li', { id: '_setting_types_active_'+key, className: 'row' }, [
575             //                 'label', { id: '_setting_types_active_'+key+'_label' }, $.ajatus.i10n.get(type.title),
576             //                 'div', { id: '_setting_types_active_'+key+'_widget', className: widget.name }, widget.get_edit_tpl('types;active', {val: (selected ? key : '')}), //["'+key+'"]
577             //                 'br', { className: 'clear_fix' }, ''
578             //             ]
579             //         );            
580             //         widget.init($('#_setting_types_active_'+key+'_widget',rows), true);
581             //     });
582             //     
583             //     return rows;
584             // }
585             
586             switch (section) {
587                 case 'localization':
588                     items = gen_localization(section_data);
589                 break;
590                 case 'layout':
591                     items = gen_layout(section_data);
592                 break;
593                 case 'auto_save':
594                     items = gen_autosave(section_data);
595                 break;
596                 case 'replication':
597                 case 'backups':
598                 case 'expansions':
599                 break;
600                 default:
601                     items = auto_gen(section, section_data);
602             }
603             
604             return items;
605         }
606     };
607     
608 })(jQuery);