89b2b26a806d0b2de4fc5c7497f59f6714552117
[tine20] / tine20 / Tinebase / js / Models.js
1 /*
2  * Tine 2.0
3  * 
4  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
5  * @author      Cornelius Weiss <c.weiss@metaways.de>
6  * @copyright   Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
7  */
8 Ext.ns('Tine.Tinebase.Model');
9
10 /**
11  * @type {Array}
12  * 
13  * modlog Fields
14  */
15
16 Tine.Tinebase.Model.modlogFields = [
17     { name: 'creation_time',      type: 'date', dateFormat: Date.patterns.ISO8601Long, omitDuplicateResolving: true },
18     { name: 'created_by',                                                              omitDuplicateResolving: true },
19     { name: 'last_modified_time', type: 'date', dateFormat: Date.patterns.ISO8601Long, omitDuplicateResolving: true },
20     { name: 'last_modified_by',                                                        omitDuplicateResolving: true },
21     { name: 'is_deleted',         type: 'boolean',                                     omitDuplicateResolving: true },
22     { name: 'deleted_time',       type: 'date', dateFormat: Date.patterns.ISO8601Long, omitDuplicateResolving: true },
23     { name: 'deleted_by',                                                              omitDuplicateResolving: true },
24     { name: 'seq',                                                                     omitDuplicateResolving: true }
25 ];
26
27 /**
28  * @type {Array}
29  * generic Record fields
30  */
31 Tine.Tinebase.Model.genericFields = Tine.Tinebase.Model.modlogFields.concat([
32     { name: 'container_id', header: 'Container',                                       omitDuplicateResolving: false}
33 ]);
34     
35 /**
36  * Model of a language
37  */
38 Tine.Tinebase.Model.Language = Ext.data.Record.create([
39     { name: 'locale' },
40     { name: 'language' },
41     { name: 'region' }
42 ]);
43
44 /**
45  * Model of a timezone
46  */
47 Tine.Tinebase.Model.Timezone = Ext.data.Record.create([
48     { name: 'timezone' },
49     { name: 'timezoneTranslation' }
50 ]);
51
52 /**
53  * Model of a role
54  */
55 Tine.Tinebase.Model.Role = Tine.Tinebase.data.Record.create([
56     {name: 'id'},
57     {name: 'name'},
58     {name: 'description'}
59 ], {
60     appName: 'Tinebase',
61     modelName: 'Role',
62     idProperty: 'id',
63     titleProperty: 'name',
64     recordName: 'Role',
65     recordsName: 'Roles'
66 });
67
68 /**
69  * Model of a generalised account (user or group)
70  */
71 Tine.Tinebase.Model.Account = Ext.data.Record.create([
72     {name: 'id'},
73     {name: 'type'},
74     {name: 'name'},
75     {name: 'data'} // todo: throw away data
76 ]);
77
78 /**
79  * Model of a container
80  */
81 Tine.Tinebase.Model.Container = Tine.Tinebase.data.Record.create(Tine.Tinebase.Model.modlogFields.concat([
82     {name: 'id'},
83     {name: 'name'},
84     {name: 'type'},
85     {name: 'backend'},
86     {name: 'order'},
87     {name: 'color'},
88     {name: 'application_id'},
89     {name: 'owner_id'},
90     {name: 'model'},
91     {name: 'uuid'},
92     {name: 'content_seq'},
93     {name: 'account_grants'},
94     {name: 'path'},
95     {name: 'xprops'},
96     // virtual
97     {name: 'ownerContact'},
98     {name: 'is_container_node', type: 'boolean'},
99     {name: 'dtselect', type: 'number'},
100 ]), {
101     appName: 'Tinebase',
102     modelName: 'Container',
103     idProperty: 'id',
104     titleProperty: 'name'
105 });
106
107 /**
108  * Model of a grant
109  */
110 Tine.Tinebase.Model.Grant = Ext.data.Record.create([
111     {name: 'id'},
112     {name: 'record_id'},
113     {name: 'account_id'},
114     {name: 'account_type'},
115     {name: 'account_name', sortType: Tine.Tinebase.common.accountSortType},
116     {name: 'freebusyGrant',type: 'boolean'},
117     {name: 'readGrant',    type: 'boolean'},
118     {name: 'addGrant',     type: 'boolean'},
119     {name: 'editGrant',    type: 'boolean'},
120     {name: 'deleteGrant',  type: 'boolean'},
121     {name: 'privateGrant', type: 'boolean'},
122     {name: 'exportGrant',  type: 'boolean'},
123     {name: 'syncGrant',    type: 'boolean'},
124     {name: 'adminGrant',   type: 'boolean'}
125 ]);
126
127 /**
128  * Model of a tag
129  * 
130  * @constructor {Tine.Tinebase.data.Record}
131  */
132 Tine.Tinebase.Model.Tag = Tine.Tinebase.data.Record.create(Tine.Tinebase.Model.modlogFields.concat([
133     {name: 'id'         },
134     {name: 'app'        },
135     {name: 'owner'      },
136     {name: 'name'       },
137     {name: 'type'       },
138     {name: 'description'},
139     {name: 'color'      },
140     {name: 'occurrence' },
141     {name: 'rights'     },
142     {name: 'contexts'   },
143     {name: 'selection_occurrence', type: 'number'}
144 ]), {
145     appName: 'Tinebase',
146     modelName: 'Tag',
147     idProperty: 'id',
148     titleProperty: 'name',
149     // ngettext('Tag', 'Tags', n); gettext('Tag');
150     recordName: 'Tag',
151     recordsName: 'Tags'
152 });
153
154 /**
155  * replace template fields with data
156  * @static
157  */
158 Tine.Tinebase.Model.Tag.replaceTemplateField = function(tagData) {
159     if (Ext.isArray(tagData)) {
160         return Ext.each(tagData, Tine.Tinebase.Model.Tag.replaceTemplateField);
161     }
162     
163     if (Ext.isFunction(tagData.beginEdit)) {
164         tagData = tagData.data;
165     }
166     
167     var replace = {
168         'CURRENTDATE': Tine.Tinebase.common.dateRenderer(new Date()),
169         'CURRENTTIME': Tine.Tinebase.common.timeRenderer(new Date()),
170         'USERFULLNAME': Tine.Tinebase.registry.get('currentAccount').accountDisplayName
171     };
172     
173     Ext.each(['name', 'description'], function(field) {
174         for(var token in replace) {
175             if (replace.hasOwnProperty(token) && Ext.isString(tagData[field])) {
176                 tagData[field] = tagData[field].replace(new RegExp('###' + token + '###', 'g'), replace[token]);
177             }
178         }
179     }, this);
180     
181 };
182
183 /**
184  * Model of a PickerRecord
185  * 
186  * @constructor {Ext.data.Record}
187  * 
188  * @deprecated
189  */
190 Tine.Tinebase.PickerRecord = Ext.data.Record.create([
191     {name: 'id'}, 
192     {name: 'name'}, 
193     {name: 'data'}
194 ]);
195
196 /**
197  * Model of a note
198  * 
199  * @constructor {Ext.data.Record}
200  */
201 Tine.Tinebase.Model.Note = Ext.data.Record.create([
202     {name: 'id'             },
203     {name: 'note_type_id'   },
204     {name: 'note'           },
205     {name: 'creation_time', type: 'date', dateFormat: Date.patterns.ISO8601Long },
206     {name: 'created_by'     }
207 ]);
208
209 /**
210  * Model of a note type
211  * 
212  * @constructor {Ext.data.Record}
213  */
214 Tine.Tinebase.Model.NoteType = Ext.data.Record.create([
215     {name: 'id'             },
216     {name: 'name'           },
217     {name: 'icon'           },
218     {name: 'icon_class'     },
219     {name: 'description'    },
220     {name: 'is_user_type'   }
221 ]);
222
223 /**
224  * Model of a customfield definition
225  */
226 Tine.Tinebase.Model.Customfield = Ext.data.Record.create([
227     { name: 'id'             },
228     { name: 'application_id' },
229     { name: 'model'          },
230     { name: 'name'           },
231     { name: 'definition'     },
232     { name: 'account_grants' }
233 ]);
234
235 /**
236  * Model of a customfield value
237  */
238 Tine.Tinebase.Model.CustomfieldValue = Ext.data.Record.create([
239     { name: 'record_id'      },
240     { name: 'customfield_id' },
241     { name: 'value'          }
242 ]);
243
244 /**
245  * Model of a preference
246  * 
247  * @constructor {Ext.data.Record}
248  */
249 Tine.Tinebase.Model.Preference = Ext.data.Record.create([
250     {name: 'id'             },
251     {name: 'name'           },
252     {name: 'value'          },
253     {name: 'type'           },
254     {name: 'label'          },
255     {name: 'description'    },
256     {name: 'personal_only',         type: 'boolean' },
257     {name: 'locked',                type: 'boolean' },
258     {name: 'options'        }
259 ]);
260
261 /**
262  * Model of an alarm
263  * 
264  * @constructor {Ext.data.Record}
265  */
266 Tine.Tinebase.Model.Alarm = Tine.Tinebase.data.Record.create([
267     {name: 'id'             },
268     {name: 'record_id'      },
269     {name: 'model'          },
270     {name: 'alarm_time',      type: 'date', dateFormat: Date.patterns.ISO8601Long },
271     {name: 'minutes_before',  sortType: Ext.data.SortTypes.asInt},
272     {name: 'sent_time',       type: 'date', dateFormat: Date.patterns.ISO8601Long },
273     {name: 'sent_status'    },
274     {name: 'sent_message'   },
275     {name: 'options'        }
276 ], {
277     appName: 'Tinebase',
278     modelName: 'Alarm',
279     idProperty: 'id',
280     titleProperty: 'minutes_before',
281     // ngettext('Alarm', 'Alarms', n); gettext('Alarm');
282     recordName: 'Alarm',
283     recordsName: 'Alarms',
284     getOption: function(name) {
285         var encodedOptions = this.get('options'),
286             options = encodedOptions ? Ext.decode(encodedOptions) : {};
287         
288         return options[name];
289     },
290     setOption: function(name, value) {
291         var encodedOptions = this.get('options'),
292             options = encodedOptions ? Ext.decode(encodedOptions) : {};
293         
294         options[name] = value;
295         this.set('options', Ext.encode(options));
296     }
297 });
298
299 /**
300  * @namespace Tine.Tinebase.Model
301  * @class     Tine.Tinebase.Model.ImportJob
302  * @extends   Tine.Tinebase.data.Record
303  * 
304  * Model of an import job
305  */
306 Tine.Tinebase.Model.ImportJob = Tine.Tinebase.data.Record.create([
307     {name: 'files'                  },
308     {name: 'import_definition_id'   },
309     {name: 'model'                  },
310     {name: 'import_function'        },
311     {name: 'container_id'           },
312     {name: 'dry_run'                },
313     {name: 'options'                }
314 ], {
315     appName: 'Tinebase',
316     modelName: 'Import',
317     idProperty: 'id',
318     titleProperty: 'model',
319     // ngettext('Import', 'Imports', n); gettext('Import');
320     recordName: 'Import',
321     recordsName: 'Imports'
322 });
323
324 /**
325  * @namespace Tine.Tinebase.Model
326  * @class     Tine.Tinebase.Model.ExportJob
327  * @extends   Tine.Tinebase.data.Record
328  * 
329  * Model of an export job
330  */
331 Tine.Tinebase.Model.ExportJob = Tine.Tinebase.data.Record.create([
332     {name: 'scope'                  },
333     {name: 'filter'                 },
334     {name: 'export_definition_id'   },
335     {name: 'format'                 },
336     {name: 'exportFunction'         },
337     {name: 'recordsName'            },
338     {name: 'model'                  },
339     {name: 'count', type: 'int'     },
340     {name: 'options'                }
341 ], {
342     appName: 'Tinebase',
343     modelName: 'Export',
344     idProperty: 'id',
345     titleProperty: 'model',
346     // ngettext('Export', 'Export', n); gettext('Export');
347     recordName: 'Export',
348     recordsName: 'Exports'
349 });
350
351 /**
352  * Model of an export/import definition
353  * 
354  * @constructor {Ext.data.Record}
355  */
356 Tine.Tinebase.Model.ImportExportDefinition = Ext.data.Record.create(Tine.Tinebase.Model.genericFields.concat([
357     {name: 'id'             },
358     {name: 'name'           },
359     {name: 'label', sortType: Ext.data.SortTypes.asUCText },
360     {name: 'filename'       },
361     {name: 'plugin'         },
362     {name: 'description'    },
363     {name: 'model'          },
364     {name: 'plugin_options' }
365 ]));
366
367 /**
368  * @namespace Tine.Tinebase.Model
369  * @class     Tine.Tinebase.Model.Credentials
370  * @extends   Tine.Tinebase.data.Record
371  * 
372  * Model of user credentials
373  */
374 Tine.Tinebase.Model.Credentials = Tine.Tinebase.data.Record.create([
375     {name: 'id'},
376     {name: 'username'},
377     {name: 'password'}
378 ], {
379     appName: 'Tinebase',
380     modelName: 'Credentials',
381     idProperty: 'id',
382     titleProperty: 'username',
383     // ngettext('Credentials', 'Credentials', n); gettext('Credentials');
384     recordName: 'Credentials',
385     recordsName: 'Credentials'
386 });
387
388 /**
389  * @namespace Tine.Tinebase.Model
390  * @class     Tine.Tinebase.Model.Relation
391  * @extends   Tine.Tinebase.data.Record
392  * 
393  * Model of a Relation
394  */
395 Tine.Tinebase.Model.Relation = Tine.Tinebase.data.Record.create([
396     {name: 'id'},
397     {name: 'own_model'},
398     {name: 'own_id'},
399     {name: 'related_model'},
400     {name: 'related_id'},
401     {name: 'type'},
402     {name: 'remark'},
403     {name: 'related_record', sortType: Tine.Tinebase.common.recordSortType},
404     {name: 'creation_time'}
405 ], {
406     appName: 'Tinebase',
407     modelName: 'Relation',
408     idProperty: 'id',
409     titleProperty: 'related_model',
410     // ngettext('Relation', 'Relations', n); gettext('Relation');
411     recordName: 'Relation',
412     recordsName: 'Relations'
413 });
414
415 /**
416  * find duplicate relation in store
417  *
418  * @param store
419  * @param record
420  * @return int index in store
421  */
422 Tine.Tinebase.Model.Relation.findDuplicate = function(store, record) {
423     return store.findBy(function(r) {
424         return r.get('related_model') == record.get('related_model') &&
425             r.get('related_id') == record.get('related_id') &&
426             r.get('type') == record.get('type');
427     }, this);
428 };
429
430 /**
431  * @namespace Tine.Tinebase.Model
432  * @class     Tine.Tinebase.Model.Department
433  * @extends   Tine.Tinebase.data.Record
434  * 
435  * Model of a Department
436  */
437 Tine.Tinebase.Model.Department = Tine.Tinebase.data.Record.create([
438     {name: 'id'},
439     {name: 'name'},
440     {name: 'description'}
441 ], {
442     appName: 'Tinebase',
443     modelName: 'Department',
444     idProperty: 'id',
445     titleProperty: 'name',
446     // ngettext('Department', 'Departments', n); gettext('Department');
447     recordName: 'Department',
448     recordsName: 'Departments'
449 });
450
451 Tine.Tinebase.Model.Department.getFilterModel = function() {
452     return [
453         {label: i18n._('Name'),          field: 'name',       operators: ['contains']}
454     ];
455 };
456
457 /**
458  * @namespace Tine.Tinebase.Model
459  * @class     Tine.Tinebase.Model.Config
460  * @extends   Tine.Tinebase.data.Record
461  * 
462  * Model of a application config settings
463  */
464 Tine.Tinebase.Model.Config = Tine.Tinebase.data.Record.create([
465     {name: 'id'},
466     {name: 'application_id'},
467     {name: 'name'},
468     {name: 'value'},
469     {name: 'label'},
470     {name: 'description'},
471     {name: 'type'},
472     {name: 'clientRegistryInclude'},
473     {name: 'setByAdminModule'},
474     {name: 'setBySetupModule'},
475     {name: 'default'},
476     {name: 'source'}
477     //{name: 'settings'}
478 ], {
479     appName: 'Tinebase',
480     modelName: 'Config',
481     idProperty: 'id',
482     titleProperty: 'name',
483     // ngettext('Config', 'Configs', n); gettext('Configs');
484     recordName: 'Config',
485     recordsName: 'Configs'
486 });
487
488 Tine.Tinebase.Model.Tree_NodeArray = Tine.Tinebase.Model.modlogFields.concat([
489     { name: 'id' },
490     { name: 'name', label: 'Name' }, // _('Name')
491     { name: 'path', label: 'Path' }, // _('Path')
492     { name: 'size', label: 'Size' }, // _('Size')
493     { name: 'revision', label: 'Revision' }, // _('Revision')
494     { name: 'available_revisions', label: 'Available Revision' }, // _('Available Revision')
495     { name: 'type', label: 'Type' }, // _('Type')
496     { name: 'contenttype', label: 'Content Type' }, // _('Content Type')
497     { name: 'description', label: 'Description' }, // _('Description')
498     { name: 'account_grants' },
499     { name: 'grants' },
500     { name: 'acl_node' },
501     { name: 'object_id'},
502     { name: 'revision_size', label: 'Revision Size' }, // _('Revision Size')
503     { name: 'preview_count', label: 'Preview Count' }, // _('Preview Count')
504     { name: 'isIndexed', label: 'Indexed' }, // _('Indexed')
505
506     { name: 'relations' },
507     { name: 'customfields' },
508     { name: 'notes' },
509     { name: 'tags' },
510
511     { name: 'revisionProps' },
512     { name: 'notificationProps' }
513 ]);
514 /**
515  * @namespace   Tine.Tinebase.Model
516  * @class       Tine.Tinebase.Model.Tree_Node
517  * @extends     Tine.Tinebase.data.Record
518  */
519 Tine.Tinebase.Model.Tree_Node = Tine.Tinebase.data.Record.create(Tine.Tinebase.Model.Tree_NodeArray, {
520     appName: 'Tinebase',
521     modelName: 'Tree_Node',
522     idProperty: 'id',
523     titleProperty: 'name',
524     // ngettext('File', 'Files', n); gettext('File');
525     recordName: 'File',
526     recordsName: 'Files'
527 });
528
529 Tine.widgets.grid.RendererManager.register('Tinebase', 'Tree_Node', 'size', Tine.Tinebase.common.byteRenderer);
530 Tine.widgets.grid.RendererManager.register('Tinebase', 'Tree_Node', 'revision_size', Tine.Tinebase.common.byteRenderer);
531
532 Tine.Tinebase.Model.KeyFieldRecord = Tine.Tinebase.data.Record.create([
533     { name: 'id' },
534     { name: 'value' },
535     { name: 'i18nValue' },
536     { name: 'icon' },
537     { name: 'color' },
538     { name: 'system' }
539 ], {
540     appName: 'Tinebase',
541     modelName: 'KeyFieldRecord',
542     idProperty: 'id',
543     titleProperty: 'value'
544 });