d2b2a0bea42776a85f8325557932199e5687507d
[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: 'downloadGrant',type: 'boolean'},
125     {name: 'publishGrant', type: 'boolean'},
126     {name: 'adminGrant',   type: 'boolean'}
127 ]);
128
129 /**
130  * Model of a tag
131  * 
132  * @constructor {Tine.Tinebase.data.Record}
133  */
134 Tine.Tinebase.Model.Tag = Tine.Tinebase.data.Record.create(Tine.Tinebase.Model.modlogFields.concat([
135     {name: 'id'         },
136     {name: 'app'        },
137     {name: 'owner'      },
138     {name: 'name'       },
139     {name: 'type'       },
140     {name: 'description'},
141     {name: 'color'      },
142     {name: 'occurrence' },
143     {name: 'rights'     },
144     {name: 'contexts'   },
145     {name: 'selection_occurrence', type: 'number'}
146 ]), {
147     appName: 'Tinebase',
148     modelName: 'Tag',
149     idProperty: 'id',
150     titleProperty: 'name',
151     // ngettext('Tag', 'Tags', n); gettext('Tag');
152     recordName: 'Tag',
153     recordsName: 'Tags'
154 });
155
156 /**
157  * replace template fields with data
158  * @static
159  */
160 Tine.Tinebase.Model.Tag.replaceTemplateField = function(tagData) {
161     if (Ext.isArray(tagData)) {
162         return Ext.each(tagData, Tine.Tinebase.Model.Tag.replaceTemplateField);
163     }
164     
165     if (Ext.isFunction(tagData.beginEdit)) {
166         tagData = tagData.data;
167     }
168     
169     var replace = {
170         'CURRENTDATE': Tine.Tinebase.common.dateRenderer(new Date()),
171         'CURRENTTIME': Tine.Tinebase.common.timeRenderer(new Date()),
172         'USERFULLNAME': Tine.Tinebase.registry.get('currentAccount').accountDisplayName
173     };
174     
175     Ext.each(['name', 'description'], function(field) {
176         for(var token in replace) {
177             if (replace.hasOwnProperty(token) && Ext.isString(tagData[field])) {
178                 tagData[field] = tagData[field].replace(new RegExp('###' + token + '###', 'g'), replace[token]);
179             }
180         }
181     }, this);
182     
183 };
184
185 /**
186  * Model of a PickerRecord
187  * 
188  * @constructor {Ext.data.Record}
189  * 
190  * @deprecated
191  */
192 Tine.Tinebase.PickerRecord = Ext.data.Record.create([
193     {name: 'id'}, 
194     {name: 'name'}, 
195     {name: 'data'}
196 ]);
197
198 /**
199  * Model of a note
200  * 
201  * @constructor {Ext.data.Record}
202  */
203 Tine.Tinebase.Model.Note = Ext.data.Record.create([
204     {name: 'id'             },
205     {name: 'note_type_id'   },
206     {name: 'note'           },
207     {name: 'creation_time', type: 'date', dateFormat: Date.patterns.ISO8601Long },
208     {name: 'created_by'     }
209 ]);
210
211 /**
212  * Model of a note type
213  * 
214  * @constructor {Ext.data.Record}
215  */
216 Tine.Tinebase.Model.NoteType = Ext.data.Record.create([
217     {name: 'id'             },
218     {name: 'name'           },
219     {name: 'icon'           },
220     {name: 'icon_class'     },
221     {name: 'description'    },
222     {name: 'is_user_type'   }
223 ]);
224
225 /**
226  * Model of a customfield definition
227  */
228 Tine.Tinebase.Model.Customfield = Ext.data.Record.create([
229     { name: 'id'             },
230     { name: 'application_id' },
231     { name: 'model'          },
232     { name: 'name'           },
233     { name: 'definition'     },
234     { name: 'account_grants' }
235 ]);
236
237 /**
238  * Model of a customfield value
239  */
240 Tine.Tinebase.Model.CustomfieldValue = Ext.data.Record.create([
241     { name: 'record_id'      },
242     { name: 'customfield_id' },
243     { name: 'value'          }
244 ]);
245
246 /**
247  * Model of a preference
248  * 
249  * @constructor {Ext.data.Record}
250  */
251 Tine.Tinebase.Model.Preference = Ext.data.Record.create([
252     {name: 'id'             },
253     {name: 'name'           },
254     {name: 'value'          },
255     {name: 'type'           },
256     {name: 'label'          },
257     {name: 'description'    },
258     {name: 'personal_only',         type: 'boolean' },
259     {name: 'locked',                type: 'boolean' },
260     {name: 'uiconfig'       },
261     {name: 'options'        }
262 ]);
263
264 /**
265  * Model of an alarm
266  * 
267  * @constructor {Ext.data.Record}
268  */
269 Tine.Tinebase.Model.Alarm = Tine.Tinebase.data.Record.create([
270     {name: 'id'             },
271     {name: 'record_id'      },
272     {name: 'model'          },
273     {name: 'alarm_time',      type: 'date', dateFormat: Date.patterns.ISO8601Long },
274     {name: 'minutes_before',  sortType: Ext.data.SortTypes.asInt},
275     {name: 'sent_time',       type: 'date', dateFormat: Date.patterns.ISO8601Long },
276     {name: 'sent_status'    },
277     {name: 'sent_message'   },
278     {name: 'options'        }
279 ], {
280     appName: 'Tinebase',
281     modelName: 'Alarm',
282     idProperty: 'id',
283     titleProperty: 'minutes_before',
284     // ngettext('Alarm', 'Alarms', n); gettext('Alarm');
285     recordName: 'Alarm',
286     recordsName: 'Alarms',
287     getOption: function(name) {
288         var encodedOptions = this.get('options'),
289             options = encodedOptions ? Ext.decode(encodedOptions) : {};
290         
291         return options[name];
292     },
293     setOption: function(name, value) {
294         var encodedOptions = this.get('options'),
295             options = encodedOptions ? Ext.decode(encodedOptions) : {};
296         
297         options[name] = value;
298         this.set('options', Ext.encode(options));
299     }
300 });
301
302 /**
303  * @namespace Tine.Tinebase.Model
304  * @class     Tine.Tinebase.Model.ImportJob
305  * @extends   Tine.Tinebase.data.Record
306  * 
307  * Model of an import job
308  */
309 Tine.Tinebase.Model.ImportJob = Tine.Tinebase.data.Record.create([
310     {name: 'files'                  },
311     {name: 'import_definition_id'   },
312     {name: 'model'                  },
313     {name: 'import_function'        },
314     {name: 'container_id'           },
315     {name: 'dry_run'                },
316     {name: 'options'                }
317 ], {
318     appName: 'Tinebase',
319     modelName: 'Import',
320     idProperty: 'id',
321     titleProperty: 'model',
322     // ngettext('Import', 'Imports', n); gettext('Import');
323     recordName: 'Import',
324     recordsName: 'Imports'
325 });
326
327 /**
328  * @namespace Tine.Tinebase.Model
329  * @class     Tine.Tinebase.Model.ExportJob
330  * @extends   Tine.Tinebase.data.Record
331  * 
332  * Model of an export job
333  */
334 Tine.Tinebase.Model.ExportJob = Tine.Tinebase.data.Record.create([
335     {name: 'scope'                  },
336     {name: 'filter'                 },
337     {name: 'export_definition_id'   },
338     {name: 'format'                 },
339     {name: 'exportFunction'         },
340     {name: 'recordsName'            },
341     {name: 'model'                  },
342     {name: 'count', type: 'int'     },
343     {name: 'options'                }
344 ], {
345     appName: 'Tinebase',
346     modelName: 'Export',
347     idProperty: 'id',
348     titleProperty: 'model',
349     // ngettext('Export', 'Export', n); gettext('Export');
350     recordName: 'Export',
351     recordsName: 'Exports'
352 });
353
354 /**
355  * Model of an export/import definition
356  * 
357  * @constructor {Ext.data.Record}
358  */
359 Tine.Tinebase.Model.ImportExportDefinition = Ext.data.Record.create(Tine.Tinebase.Model.genericFields.concat([
360     {name: 'id'             },
361     {name: 'name'           },
362     {name: 'label', sortType: Ext.data.SortTypes.asUCText },
363     {name: 'filename'       },
364     {name: 'plugin'         },
365     {name: 'description'    },
366     {name: 'model'          },
367     {name: 'plugin_options' }
368 ]));
369
370 /**
371  * @namespace Tine.Tinebase.Model
372  * @class     Tine.Tinebase.Model.Credentials
373  * @extends   Tine.Tinebase.data.Record
374  * 
375  * Model of user credentials
376  */
377 Tine.Tinebase.Model.Credentials = Tine.Tinebase.data.Record.create([
378     {name: 'id'},
379     {name: 'username'},
380     {name: 'password'}
381 ], {
382     appName: 'Tinebase',
383     modelName: 'Credentials',
384     idProperty: 'id',
385     titleProperty: 'username',
386     // ngettext('Credentials', 'Credentials', n); gettext('Credentials');
387     recordName: 'Credentials',
388     recordsName: 'Credentials'
389 });
390
391 /**
392  * @namespace Tine.Tinebase.Model
393  * @class     Tine.Tinebase.Model.Relation
394  * @extends   Tine.Tinebase.data.Record
395  * 
396  * Model of a Relation
397  */
398 Tine.Tinebase.Model.Relation = Tine.Tinebase.data.Record.create([
399     {name: 'id'},
400     {name: 'own_model'},
401     {name: 'own_id'},
402     {name: 'related_model'},
403     {name: 'related_id'},
404     {name: 'type'},
405     {name: 'remark'},
406     {name: 'related_record', sortType: Tine.Tinebase.common.recordSortType},
407     {name: 'creation_time'}
408 ], {
409     appName: 'Tinebase',
410     modelName: 'Relation',
411     idProperty: 'id',
412     titleProperty: 'related_model',
413     // ngettext('Relation', 'Relations', n); gettext('Relation');
414     recordName: 'Relation',
415     recordsName: 'Relations'
416 });
417
418 /**
419  * find duplicate relation in store
420  *
421  * @param store
422  * @param record
423  * @return int index in store
424  */
425 Tine.Tinebase.Model.Relation.findDuplicate = function(store, record) {
426     return store.findBy(function(r) {
427         return r.get('related_model') == record.get('related_model') &&
428             r.get('related_id') == record.get('related_id') &&
429             r.get('type') == record.get('type');
430     }, this);
431 };
432
433 /**
434  * @namespace Tine.Tinebase.Model
435  * @class     Tine.Tinebase.Model.Department
436  * @extends   Tine.Tinebase.data.Record
437  * 
438  * Model of a Department
439  */
440 Tine.Tinebase.Model.Department = Tine.Tinebase.data.Record.create([
441     {name: 'id'},
442     {name: 'name'},
443     {name: 'description'}
444 ], {
445     appName: 'Tinebase',
446     modelName: 'Department',
447     idProperty: 'id',
448     titleProperty: 'name',
449     // ngettext('Department', 'Departments', n); gettext('Department');
450     recordName: 'Department',
451     recordsName: 'Departments'
452 });
453
454 Tine.Tinebase.Model.Department.getFilterModel = function() {
455     return [
456         {label: i18n._('Name'),          field: 'name',       operators: ['contains']}
457     ];
458 };
459
460 /**
461  * @namespace Tine.Tinebase.Model
462  * @class     Tine.Tinebase.Model.Config
463  * @extends   Tine.Tinebase.data.Record
464  * 
465  * Model of a application config settings
466  */
467 Tine.Tinebase.Model.Config = Tine.Tinebase.data.Record.create([
468     {name: 'id'},
469     {name: 'application_id'},
470     {name: 'name'},
471     {name: 'value'},
472     {name: 'label'},
473     {name: 'description'},
474     {name: 'type'},
475     {name: 'clientRegistryInclude'},
476     {name: 'setByAdminModule'},
477     {name: 'setBySetupModule'},
478     {name: 'default'},
479     {name: 'source'}
480     //{name: 'settings'}
481 ], {
482     appName: 'Tinebase',
483     modelName: 'Config',
484     idProperty: 'id',
485     titleProperty: 'name',
486     // ngettext('Config', 'Configs', n); gettext('Configs');
487     recordName: 'Config',
488     recordsName: 'Configs'
489 });
490
491 Tine.Tinebase.Model.Tree_NodeArray = Tine.Tinebase.Model.modlogFields.concat([
492     { name: 'id' },
493     { name: 'name', label: 'Name' }, // _('Name')
494     { name: 'path', label: 'Path' }, // _('Path')
495     { name: 'size', label: 'Size' }, // _('Size')
496     { name: 'revision', label: 'Revision' }, // _('Revision')
497     { name: 'available_revisions', label: 'Available Revision' }, // _('Available Revision')
498     { name: 'type', label: 'Type' }, // _('Type')
499     { name: 'contenttype', label: 'Content Type' }, // _('Content Type')
500     { name: 'description', label: 'Description' }, // _('Description')
501     { name: 'account_grants' },
502     { name: 'grants' },
503     { name: 'acl_node' },
504     { name: 'object_id'},
505     { name: 'revision_size', label: 'Revision Size' }, // _('Revision Size')
506     { name: 'preview_count', label: 'Preview Count' }, // _('Preview Count')
507     { name: 'isIndexed', label: 'Indexed' }, // _('Indexed')
508
509     { name: 'relations' },
510     { name: 'customfields' },
511     { name: 'notes' },
512     { name: 'tags' },
513
514     { name: 'revisionProps' },
515     { name: 'notificationProps' }
516 ]);
517 /**
518  * @namespace   Tine.Tinebase.Model
519  * @class       Tine.Tinebase.Model.Tree_Node
520  * @extends     Tine.Tinebase.data.Record
521  */
522 Tine.Tinebase.Model.Tree_Node = Tine.Tinebase.data.Record.create(Tine.Tinebase.Model.Tree_NodeArray, {
523     appName: 'Tinebase',
524     modelName: 'Tree_Node',
525     idProperty: 'id',
526     titleProperty: 'name',
527     // ngettext('File', 'Files', n); gettext('File');
528     recordName: 'File',
529     recordsName: 'Files'
530 });
531
532 Tine.widgets.grid.RendererManager.register('Tinebase', 'Tree_Node', 'size', Tine.Tinebase.common.byteRenderer);
533 Tine.widgets.grid.RendererManager.register('Tinebase', 'Tree_Node', 'revision_size', Tine.Tinebase.common.byteRenderer);
534
535 Tine.Tinebase.Model.KeyFieldRecord = Tine.Tinebase.data.Record.create([
536     { name: 'id' },
537     { name: 'value' },
538     { name: 'i18nValue' },
539     { name: 'icon' },
540     { name: 'color' },
541     { name: 'system' }
542 ], {
543     appName: 'Tinebase',
544     modelName: 'KeyFieldRecord',
545     idProperty: 'id',
546     titleProperty: 'value'
547 });