0012742: Refactor detailspanel
authorMichael Spahn <m.spahn@metaways.de>
Fri, 3 Mar 2017 15:01:10 +0000 (16:01 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Tue, 14 Mar 2017 13:12:07 +0000 (14:12 +0100)
https://forge.tine20.org/view.php?id=12742

Change-Id: Ife599c16a47d627bfd7a98a76c1d966e732efcc6
Reviewed-on: http://gerrit.tine20.com/customers/4283
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
15 files changed:
tine20/Addressbook/Addressbook.jsb2
tine20/Addressbook/js/AddressRenderer.js [new file with mode: 0644]
tine20/Addressbook/js/ContactGridDetailsPanel.js
tine20/Addressbook/js/ContactSearchCombo.js
tine20/Addressbook/js/CountryRenderer.js [new file with mode: 0644]
tine20/Addressbook/js/ImageRenderer.js [new file with mode: 0644]
tine20/Addressbook/js/ListSearchCombo.js
tine20/Addressbook/js/MailAddressRenderer.js [new file with mode: 0644]
tine20/Addressbook/js/UrlRenderer.js [new file with mode: 0644]
tine20/Tinebase/Tinebase.jsb2
tine20/Tinebase/css/ux/display/DisplayPanel.css
tine20/Tinebase/css/widgets/PreviewPanel.css
tine20/Tinebase/js/EncodingHelper.js [new file with mode: 0644]
tine20/Tinebase/js/ux/display/DisplayPanel.js
tine20/Tinebase/js/ux/form/ImageField.js

index f118357..86fb589 100644 (file)
           "path": "js/"
         },
         {
+          "text": "AddressRenderer.js",
+          "path": "js/"
+        },
+        {
+          "text": "CountryRenderer.js",
+          "path": "js/"
+        },
+        {
+          "text": "MailAddressRenderer.js",
+          "path": "js/"
+        },
+        {
+          "text": "ImageRenderer.js",
+          "path": "js/"
+        },
+        {
+          "text": "UrlRenderer.js",
+          "path": "js/"
+        },
+        {
           "text": "ContactGridDetailsPanel.js",
           "path": "js/"
         },
diff --git a/tine20/Addressbook/js/AddressRenderer.js b/tine20/Addressbook/js/AddressRenderer.js
new file mode 100644 (file)
index 0000000..f29daf4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Tine 2.0
+ *
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+Ext.ns('Tine.Addressbook');
+
+/**
+ * Render given addresss
+ *
+ * You need to pass the record and a config to use this renderer.
+ * The config contains a mapping, which fields from the record should have which place in the template.
+ * Undefined fields won't be rendered, this keeps it well reusable for all address like purposes.
+ *
+ * @namespace   Tine.Addressbook
+ * @class       Tine.Addressbook.AddressRenderer
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @singleton
+ */
+Tine.Addressbook.AddressRenderer = function () {
+    var template = new Ext.XTemplate(
+        '<tpl for="." class="address">' +
+            '<tpl if="street">{street} <br /></tpl>' +
+            '<tpl if="street2">{street2} <br /></tpl>' +
+            '<tpl if="postalcode">{postalcode}</tpl> <tpl if="locality">{locality}</tpl><br />' +
+            '<tpl if="region">{region} <br /></tpl>' +
+            '<tpl if="country">{country}</tpl>' +
+        '</tpl>');
+    template.compile();
+
+    return {
+        renderer: function (v, metadata, record, store, a, b, config) {
+            var local = Object.assign({}, config);
+            var keys = Object.keys(local);
+
+            // According to config, resolve the given fields from record
+            keys.forEach(function(key) {
+                local[key] = Tine.Tinebase.EncodingHelper.encode(record.get(local[key]));
+
+                // Country code to country name
+                // @todo: Wouldn't it be cool, if this could be managed by the modelconfig as well?
+                if (key === 'country') {
+                    var countryRenderer = Tine.widgets.grid.RendererManager.get("Addressbook", "Addressbook_Model_Contact", "country", "displayPanel");
+                    local[key] = countryRenderer(local[key]);
+                }
+            });
+
+            return template.applyTemplate(local);
+        }
+    };
+}();
+
+Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'addressblock', Tine.Addressbook.AddressRenderer.renderer, 'displayPanel');
\ No newline at end of file
index a8cefe6..1f770cb 100644 (file)
 /**
  * Tine 2.0
- * 
+ *
  * @package     Addressbook
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Philipp Schuele <p.schuele@metaways.de>
- * @copyright   Copyright (c) 2007-2009 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2007-2017 Metaways Infosystems GmbH (http://www.metaways.de)
  *
  * TODO         add preference for sending mails with felamimail or mailto?
  */
+
 Ext.ns('Tine.Addressbook');
 
 /**
  * the details panel (shows contact details)
- * 
+ *
  * @namespace   Tine.Addressbook
  * @class       Tine.Addressbook.ContactGridDetailsPanel
  * @extends     Tine.widgets.grid.DetailsPanel
  */
 Tine.Addressbook.ContactGridDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {
-    
+
     il8n: null,
     felamimail: false,
-    
-    /**
-     * init
-     */
-    initComponent: function() {
 
-        // init templates
-        this.initTemplate();
-        this.initDefaultTemplate();
-        
-        Tine.Addressbook.ContactGridDetailsPanel.superclass.initComponent.call(this);
+    recordClass: Tine.Addressbook.Model.Contact,
+
+    getSingleRecordPanel: function() {
+        var me = this;
+        if (! this.singleRecordPanel) {
+            this.singleRecordPanel = new Tine.widgets.display.RecordDisplayPanel({
+                recordClass: this.recordClass,
+                getBodyItems: function() {
+                    return [{
+                        layout: 'hbox',
+                        flex: 1,
+                        border: false,
+                        layoutConfig: {
+                            padding: '0',
+                            align: 'stretch'
+                        },
+                        defaults: {
+                            margins: '0 5 0 0'
+                        },
+                        items: [{
+                            width: 90,
+                            layout: 'ux.display',
+                            layoutConfig: {
+                                background: 'solid'
+                            },
+                            items: [{
+                                xtype: 'ux.displayfield',
+                                name: 'jpegphoto',
+                                cls: 'preview-panel-image',
+                                anchor:'100% 100%',
+                                hideLabel: true,
+                                htmlEncode: false,
+                                renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'image', 'displayPanel').createDelegate(me)
+                            }]
+                        }, {
+                            flex: 1,
+                            layout: 'ux.display',
+                            labelWidth: 60,
+                            layoutConfig: {
+                                background: 'solid'
+                            },
+                            items: [{
+                                layout: 'hbox',
+                                border: false,
+                                anchor: '100% 100%',
+                                layoutConfig: {
+                                    align: 'stretch'
+                                },
+                                items: [{
+                                    layout: 'ux.display',
+                                    layoutConfig: {
+                                        background: 'inner',
+                                        labelLWidth: 100,
+                                        declaration: this.app.i18n._('Business')
+                                    },
+                                    labelAlign: 'top',
+                                    border: false,
+                                    flex: 1,
+                                    items: [{
+                                        xtype: 'ux.displayfield',
+                                        name: 'org_name',
+                                        hideLabel: true,
+                                        htmlEncode: false,
+                                        renderer: function(value) {
+                                            return '<b>' + value + '</b>';
+                                        }
+                                    }, {
+                                        xtype: 'ux.displayfield',
+                                        name: 'dtstart',
+                                        hideLabel: true,
+                                        htmlEncode: false,
+                                        renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'addressblock', 'displayPanel').createDelegate(me, {
+                                            'street': 'adr_one_street',
+                                            'street2': 'adr_one_street2',
+                                            'postalcode': 'adr_one_postalcode',
+                                            'locality': 'adr_one_locality',
+                                            'region': 'adr_one_region',
+                                            'country': 'adr_one_countryname'
+                                        }, true)
+                                    }]
+                                }, {
+                                    layout: 'ux.display',
+                                    layoutConfig: {
+                                        background: 'inner'
+                                    },
+                                    labelWidth: 50,
+                                    flex: 1,
+                                    border: false,
+                                    items: [{
+                                        xtype: 'ux.displayfield',
+                                        name: 'tel_work',
+                                        fieldLabel: this.app.i18n._('Phone')
+                                    }, {
+                                        xtype: 'ux.displayfield',
+                                        name: 'tel_cell',
+                                        fieldLabel: this.app.i18n._('Mobile')
+                                    }, {
+                                        xtype: 'ux.displayfield',
+                                        name: 'tel_fax',
+                                        fieldLabel: this.app.i18n._('Fax')
+                                    }, {
+                                        xtype: 'ux.displayfield',
+                                        name: 'email',
+                                        fieldLabel: this.app.i18n._('E-Mail'),
+                                        htmlEncode: false,
+                                        renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'email', 'displayPanel').createDelegate(me)
+                                    }, {
+                                        xtype: 'ux.displayfield',
+                                        name: 'url',
+                                        fieldLabel: this.app.i18n._('Web'),
+                                        htmlEncode: false,
+                                        renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'url', 'displayPanel').createDelegate(me)
+                                    }]
+                                }]
+                            }]
+                        }, {
+                            flex: 1,
+                            layout: 'ux.display',
+                            labelAlign: 'top',
+                            autoScroll: true,
+                            layoutConfig: {
+                                background: 'solid',
+                                declaration: this.app.i18n._('Private')
+                            },
+
+                            // @todo: this field doesn't actually require a certain field, there should be two methods for RenderManager:
+                            //  + get()
+                            //  + getBlock() // block actually doesn't specify a certain field and only an record, the field declaration should come from the modelconfig later
+                            items: [{
+                                xtype: 'ux.displayfield',
+                                name: 'attendee',
+                                hideLabel: true,
+                                htmlEncode: false,
+                                renderer: Tine.widgets.grid.RendererManager.get('Addressbook', 'Addressbook_Model_Contact', 'addressblock', 'displayPanel').createDelegate(me, {
+                                    'street': 'adr_two_street',
+                                    'street2': 'adr_two_street2',
+                                    'postalcode': 'adr_two_postalcode',
+                                    'locality': 'adr_two_locality',
+                                    'region': 'adr_two_region',
+                                    'country': 'adr_two_countryname'
+                                }, true)
+                            }]
+                        }, {
+                            flex: 1,
+                            layout: 'fit',
+
+                            border: false,
+                            items: [{
+                                cls: 'x-ux-display-background-border',
+                                xtype: 'ux.displaytextarea',
+                                name: 'note'
+                            }]
+                        }]
+                    }];
+                }
+            });
+        }
+
+        return this.singleRecordPanel;
     },
 
     /**
@@ -40,243 +189,17 @@ Tine.Addressbook.ContactGridDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsP
      */
     afterRender: function() {
         Tine.Addressbook.ContactGridDetailsPanel.superclass.afterRender.apply(this, arguments);
-        
+
         if (this.felamimail === true) {
             this.body.on('click', this.onClick, this);
         }
     },
-    
-    /**
-     * init default template
-     */
-    initDefaultTemplate: function() {
-        
-        this.defaultTpl = new Ext.XTemplate(
-            '<div class="preview-panel-timesheet-nobreak">',    
-                '<!-- Preview contacts -->',
-                '<div class="preview-panel preview-panel-timesheet-left">',
-                    '<div class="bordercorner_1"></div>',
-                    '<div class="bordercorner_2"></div>',
-                    '<div class="bordercorner_3"></div>',
-                    '<div class="bordercorner_4"></div>',
-                    '<div class="preview-panel-declaration">' + this.il8n._('Contacts') + '</div>',
-                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
-                        '<span class="preview-panel-bold">',
-                            this.il8n._('Select contact') + '<br/>',
-                            '<br/>',
-                            '<br/>',
-                            '<br/>',
-                        '</span>',
-                    '</div>',
-                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
-                        '<span class="preview-panel-nonbold">',
-                            '<br/>',
-                            '<br/>',
-                            '<br/>',
-                            '<br/>',
-                        '</span>',
-                    '</div>',
-                '</div>',
-                '<!-- Preview xxx -->',
-                '<div class="preview-panel-timesheet-right">',
-                    '<div class="bordercorner_gray_1"></div>',
-                    '<div class="bordercorner_gray_2"></div>',
-                    '<div class="bordercorner_gray_3"></div>',
-                    '<div class="bordercorner_gray_4"></div>',
-                    '<div class="preview-panel-declaration"></div>',
-                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
-                        '<span class="preview-panel-bold">',
-                            '<br/>',
-                            '<br/>',
-                            '<br/>',
-                            '<br/>',
-                        '</span>',
-                    '</div>',
-                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
-                        '<span class="preview-panel-nonbold">',
-                            '<br/>',
-                            '<br/>',
-                            '<br/>',
-                            '<br/>',
-                        '</span>',
-                    '</div>',
-                '</div>',
-            '</div>'        
-        );
-    },
-    
-    /**
-     * init single contact template (this.tpl)
-     */
-    initTemplate: function() {
-        this.tpl = new Ext.XTemplate(
-            '<tpl for=".">',
-                '<div class="preview-panel-adressbook-nobreak">',
-                '<div class="preview-panel-left">',                
-                    '<!-- Preview image -->',
-                    '<div class="preview-panel preview-panel-left preview-panel-image">',
-                        '<div class="bordercorner_1"></div>',
-                        '<div class="bordercorner_2"></div>',
-                        '<div class="bordercorner_3"></div>',
-                        '<div class="bordercorner_4"></div>',
-                        '<img src="{[this.getImageUrl(values.jpegphoto, 90, 113, values)]}"/>',
-                    '</div>',
-                
-                    '<!-- Preview office -->',
-                    '<div class="preview-panel preview-panel-office preview-panel-left">',                
-                        '<div class="bordercorner_1"></div>',
-                        '<div class="bordercorner_2"></div>',
-                        '<div class="bordercorner_3"></div>',
-                        '<div class="bordercorner_4"></div>',
-                        '<div class="preview-panel-declaration">' + this.il8n._('Company') + '</div>',
-                        '<div class="preview-panel-address preview-panel-left">',
-                            '<span class="preview-panel-bold">{[this.encode(values.org_name, "mediumtext")]}{[this.encode(values.org_unit, "prefix", " / ")]}</span><br/>',
-                            '{[this.encode(values.adr_one_street)]}<br/>',
-                            '{[this.encode(values.adr_one_postalcode, " ")]}{[this.encode(values.adr_one_locality)]}<br/>',
-                            '{[this.encode(values.adr_one_region, " / ")]}{[this.encode(values.adr_one_countryname, "country")]}<br/>',
-                        '</div>',
-                        '<div class="preview-panel-contact preview-panel-right">',
-                            '<span class="preview-panel-symbolcompare">' + this.il8n._('Phone') + '</span>{[this.encode(values.tel_work)]}<br/>',
-                            '<span class="preview-panel-symbolcompare">' + this.il8n._('Mobile') + '</span>{[this.encode(values.tel_cell)]}<br/>',
-                            '<span class="preview-panel-symbolcompare">' + this.il8n._('Fax') + '</span>{[this.encode(values.tel_fax)]}<br/>',
-                            '<span class="preview-panel-symbolcompare">' + this.il8n._('E-Mail') 
-                                + '</span>{[this.getMailLink(values.email, ' + this.felamimail + ')]}<br/>',
-                            '<span class="preview-panel-symbolcompare">' + this.il8n._('Web') + '</span><a href="{[this.encode(values.url, "href")]}" target="_blank">{[this.encode(values.url, "shorttext")]}</a><br/>',
-                        '</div>',
-                    '</div>',
-                '</div>',
-
-                '<!-- Preview privat -->',
-                '<div class="preview-panel preview-panel-privat preview-panel-left">',                
-                    '<div class="bordercorner_1"></div>',
-                    '<div class="bordercorner_2"></div>',
-                    '<div class="bordercorner_3"></div>',
-                    '<div class="bordercorner_4"></div>',
-                    '<div class="preview-panel-declaration">' + this.il8n._('Private') + '</div>',
-                    '<div class="preview-panel-address preview-panel-left">',
-                        '<span class="preview-panel-bold">{[this.encode(values.n_fn)]}</span><br/>',
-                        '{[this.encode(values.adr_two_street)]}<br/>',
-                        '{[this.encode(values.adr_two_postalcode, " ")]}{[this.encode(values.adr_two_locality)]}<br/>',
-                        '{[this.encode(values.adr_two_region, " / ")]}{[this.encode(values.adr_two_countryname, "country")]}<br/>',
-                    '</div>',
-                    '<div class="preview-panel-contact preview-panel-right">',
-                        '<span class="preview-panel-symbolcompare">' + this.il8n._('Phone') + '</span>{[this.encode(values.tel_home)]}<br/>',
-                        '<span class="preview-panel-symbolcompare">' + this.il8n._('Mobile') + '</span>{[this.encode(values.tel_cell_private)]}<br/>',
-                        '<span class="preview-panel-symbolcompare">' + this.il8n._('Fax') + '</span>{[this.encode(values.tel_fax_home)]}<br/>',
-                        '<span class="preview-panel-symbolcompare">' + this.il8n._('E-Mail') 
-                            + '</span>{[this.getMailLink(values.email_home, ' + this.felamimail + ')]}<br/>',
-                        '<span class="preview-panel-symbolcompare">' + this.il8n._('Web') + '</span><a href="{[this.encode(values.url, "href")]}" target="_blank">{[this.encode(values.url_home, "shorttext")]}</a><br/>',
-                    '</div>',                
-                '</div>',
-                
-                '<!-- Preview info -->',
-                '<div class="preview-panel-description preview-panel-left" ext:qtip="{[this.encode(values.note)]}">',
-                    '<div class="bordercorner_gray_1"></div>',
-                    '<div class="bordercorner_gray_2"></div>',
-                    '<div class="bordercorner_gray_3"></div>',
-                    '<div class="bordercorner_gray_4"></div>',
-                    '<div class="preview-panel-declaration">' + this.il8n._('Info') + '</div>',
-                    '{[this.encode(values.note, "longtext")]}',
-                '</div>',
-                '</div>',
-                //  '{[this.getTags(values.tags)]}',
-            '</tpl>',
-            {
-                /**
-                 * encode
-                 */
-                encode: function(value, type, prefix) {
-                    //var metrics = Ext.util.TextMetrics.createInstance('previewPanel');
-                    if (value) {
-                        if (type) {
-                            switch (type) {
-                                case 'country':
-                                    value = Locale.getTranslationData('CountryList', value);
-                                    break;
-                                case 'longtext':
-                                    value = Ext.util.Format.ellipsis(value, 135);
-                                    break;
-                                case 'mediumtext':
-                                    value = Ext.util.Format.ellipsis(value, 30);
-                                    break;
-                                case 'shorttext':
-                                    //console.log(metrics.getWidth(value));
-                                    value = Ext.util.Format.ellipsis(value, 18);
-                                    break;
-                                case 'prefix':
-                                    if (prefix) {
-                                        value = prefix + value;
-                                    }
-                                    break;
-                                case 'href':
-                                    if (! String(value).match(/^(https?|ftps?)/)) {
-                                        var adb = Tine.Tinebase.appMgr.get('Addressbook');
-                                        return "javascript:Ext.Msg.alert('" + adb.i18n._('Insecure link') + "', '" + adb.i18n._('Please review this link in edit dialog.') + "');";
-                                    }
-                                    break;
-                                default:
-                                    value += type;
-                            }
-                        }
-                        value = Ext.util.Format.htmlEncode(value);
-                        return Ext.util.Format.nl2br(value);
-                    } else {
-                        return '';
-                    }
-                },
-                
-                /**
-                 * get tags
-                 * 
-                 * TODO make it work
-                 */
-                getTags: function(value) {
-                    var result = '';
-                    for (var i=0; i<value.length; i++) {
-                        result += value[i].name + ' ';
-                    }
-                    return result;
-                },
-                
-                /**
-                 * get image url
-                 */
-                getImageUrl: function(url, width, height, contact) {
-                    var mtime = contact.last_modified_time || contact.creation_time;
-                    if (url.match(/&/)) {
-                        url = Ext.ux.util.ImageURL.prototype.parseURL(url);
-                        url.width = width;
-                        url.height = height;
-                        url.ratiomode = 0;
-                        url.mtime = Ext.isDate(mtime) ? mtime.getTime() : new Date().getTime();
-                    }
-                    return url;
-                },
 
-                /**
-                 * get email link
-                 */
-                getMailLink: function(email, felamimail) {
-                    if (! email) {
-                        return '';
-                    }
-                    
-                    email = this.encode(email);
-                    var link = (felamimail === true) ? '#' : 'mailto:' + email;
-                    var id = Ext.id() + ':' + email;
-                    
-                    return '<a href="' + link + '" class="tinebase-email-link" id="' + id + '">'
-                        + Ext.util.Format.ellipsis(email, 18) + '</a>';
-                }
-            }
-        );
-    },
-    
     /**
      * on click for compose mail
-     * 
+     *
      * @param {} e
-     * 
+     *
      * TODO check if account is configured?
      * TODO generalize that
      */
@@ -287,9 +210,10 @@ Tine.Addressbook.ContactGridDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsP
             var defaults = Tine.Felamimail.Model.Message.getDefaultData();
             defaults.to = [email];
             defaults.body = Tine.Felamimail.getSignature();
-            
+
             var record = new Tine.Felamimail.Model.Message(defaults, 0);
-            var popupWindow = Tine.Felamimail.MessageEditDialog.openWindow({
+
+            Tine.Felamimail.MessageEditDialog.openWindow({
                 record: record
             });
         }
index 3f5449a..7fd9afc 100644 (file)
@@ -121,10 +121,10 @@ Tine.Addressbook.ContactSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.Reco
                         '<tr>',
                             '<td style="min-width: 20px;">{[Tine.Addressbook.ContactGridPanel.contactTypeRenderer(null, null, values)]}</td>',
                             '<td width="30%"><b>{[Tine.Addressbook.ContactGridPanel.displayNameRenderer(values.n_fileas)]}</b><br/>,' +
-                                '{[this.encode(values.org_name)]}</td>',
-                            '<td width="25%">{[this.encode(values.adr_one_street)]}<br/>',
-                                '{[this.encode(values.adr_one_postalcode)]} {[this.encode(values.adr_one_locality)]}</td>',
-                            '<td width="25%">{[this.encode(values.tel_work)]}<br/>{[this.encode(values.tel_cell)]}</td>',
+                                '{[Tinebase.Tine.EncodingHelper.encode(values.org_name)]}</td>',
+                            '<td width="25%">{[Tinebase.Tine.EncodingHelper.encode(values.adr_one_street)]}<br/>',
+                                '{[Tinebase.Tine.EncodingHelper.encode(values.adr_one_postalcode)]} {[this.encode(values.adr_one_locality)]}</td>',
+                            '<td width="25%">{[Tinebase.Tine.EncodingHelper.encode(values.tel_work)]}<br/>{[Tinebase.Tine.EncodingHelper.encode(values.tel_cell)]}</td>',
                             '<td width="50px">',
                                 '<img width="45px" height="39px" src="{jpegphoto}" />',
                             '</td>',
diff --git a/tine20/Addressbook/js/CountryRenderer.js b/tine20/Addressbook/js/CountryRenderer.js
new file mode 100644 (file)
index 0000000..ec3a758
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Tine 2.0
+ *
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+Ext.ns('Tine.Addressbook');
+
+/**
+ * Render country name by it's iso code
+ *
+ * @namespace   Tine.Addressbook
+ * @class       Tine.Addressbook.CountryRenderer
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @singleton
+ */
+Tine.Addressbook.CountryRenderer = function () {
+    return {
+        renderer: function (v) {
+            return Locale.getTranslationData('CountryList', v);
+        }
+    };
+}();
+
+Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'country', Tine.Addressbook.CountryRenderer.renderer, 'displayPanel');
\ No newline at end of file
diff --git a/tine20/Addressbook/js/ImageRenderer.js b/tine20/Addressbook/js/ImageRenderer.js
new file mode 100644 (file)
index 0000000..bc4b8dc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Tine 2.0
+ *
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+Ext.ns('Tine.Addressbook');
+
+/**
+ * Render given image
+ *
+ * @namespace   Tine.Addressbook
+ * @class       Tine.Addressbook.ImageRenderer
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @singleton
+ */
+Tine.Addressbook.ImageRenderer = function () {
+    function getImageUrl(url, width, height, contact) {
+        var mtime = contact.last_modified_time || contact.creation_time;
+        if (url.match(/&/)) {
+            url = Ext.ux.util.ImageURL.prototype.parseURL(url);
+            url.width = width;
+            url.height = height;
+            url.ratiomode = 0;
+            url.mtime = Ext.isDate(mtime) ? mtime.getTime() : new Date().getTime();
+        }
+        return url;
+    }
+
+    return {
+        renderer: function(jpegphoto, metadata, record) {
+            var url = getImageUrl(jpegphoto, 90, 113, record.data);
+            return '<img src="' + url + '" />';
+        }
+    };
+}();
+
+Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'image', Tine.Addressbook.ImageRenderer.renderer, 'displayPanel');
\ No newline at end of file
index 8d18e16..f47c652 100644 (file)
@@ -67,7 +67,7 @@ Tine.Addressbook.ListSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordP
                         '<table>',
                             '<tr>',
                                 '<td style="min-width: 20px;">{[Tine.Addressbook.ListGridPanel.listTypeRenderer(null, null, values)]}</td>',
-                                '<td width="100%">{[this.encode(values.name)]}</td>',
+                                '<td width="100%">{[Tinebase.Tine.EncodingHelper.encode(values.name)]}</td>',
                             '</tr>',
                         '</table>',
                         '{[Tine.widgets.path.pathsRenderer(values.paths, this.lastQuery)]}',
diff --git a/tine20/Addressbook/js/MailAddressRenderer.js b/tine20/Addressbook/js/MailAddressRenderer.js
new file mode 100644 (file)
index 0000000..7122175
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Tine 2.0
+ *
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+Ext.ns('Tine.Addressbook');
+
+/**
+ * Render given MailAddresss
+ *
+ * @namespace   Tine.Addressbook
+ * @class       Tine.Addressbook.MailAddressRenderer
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @singleton
+ */
+Tine.Addressbook.MailAddressRenderer = function () {
+    return {
+        renderer: function (email) {
+            if (!email) {
+                return '';
+            }
+
+            email = Tine.Tinebase.EncodingHelper.encode(email);
+            var link = (this.felamimail === true) ? '#' : 'mailto:' + email;
+            var id = Ext.id() + ':' + email;
+
+            return '<a href="' + link + '" class="tinebase-email-link" id="' + id + '">'
+                + Ext.util.Format.ellipsis(email, 18) + '</a>';
+        }
+    };
+}();
+
+Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'email', Tine.Addressbook.MailAddressRenderer.renderer, 'displayPanel');
+
diff --git a/tine20/Addressbook/js/UrlRenderer.js b/tine20/Addressbook/js/UrlRenderer.js
new file mode 100644 (file)
index 0000000..5c63763
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Tine 2.0
+ *
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+Ext.ns('Tine.Addressbook');
+
+/**
+ * Render given URL as html
+ *
+ * @namespace   Tine.Addressbook
+ * @class       Tine.Addressbook.UrlRenderer
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @singleton
+ */
+Tine.Addressbook.UrlRenderer = function () {
+    return {
+        renderer: function(url) {
+            return '<a href=' + Tine.Tinebase.EncodingHelper.encode(url, 'href')  + ' target="_blank">' + Tine.Tinebase.EncodingHelper.encode(url, 'shorttext') + '</a>';
+        }
+    };
+}();
+
+Tine.widgets.grid.RendererManager.register('Addressbook', 'Addressbook_Model_Contact', 'url', Tine.Addressbook.UrlRenderer.renderer, 'displayPanel');
\ No newline at end of file
index a098002..5a5b88d 100644 (file)
           "path": "js/"
         },
         {
+          "text": "EncodingHelper.js",
+          "path": "js/"
+        },
+        {
           "text": "common.js",
           "path": "js/"
         },
index 2b088cd..11fbb07 100644 (file)
@@ -5,10 +5,10 @@
 
 .x-ux-display label.x-form-item-label {
     color:#A0A0A0;
-    padding-right:5px;
     text-align:right;
     font-size:11px;
-    padding: 0;
+    padding-left: 5px;
+    padding-bottom: 1px;
 }
 
 .x-ux-display .x-form-element {
     -moz-border-radius: 8px;
     -webkit-border-radius: 8px;
     -khtml-border-radius: 8px;
-    padding-left: 2px;
+}
+
+.x-ux-display .x-ux-display-background-inner {
+    border: 0;
+    background-color: #e5e6fe;
+    -moz-border-radius: 0px;
+    -webkit-border-radius: 0px;
+    -khtml-border-radius: 0px;
 }
 
 .x-ux-display .x-ux-display-background-border {
     bottom:6px;
 }
 
+.x-ux-display .x-form-item {
+    padding-left: 2px;
+}
+
+.x-ux-display .x-form-element {
+    padding-left: 5px !important;
+}
+
 .tw-editdialog .x-form-item .x-form-display-field {
     border: 1px solid #b5b8c8;
     padding: 3px;
index f3ec671..2965508 100644 (file)
@@ -8,6 +8,9 @@
     }
 .preview-panel img {
     vertical-align: middle;
+    -moz-border-radius: 8px;
+    -webkit-border-radius: 8px;
+    -khtml-border-radius: 8px;
     }
 .preview-panel-left{
     float:left;
     font-weight: bold;
     }
 .preview-panel-image{
-    vertical-align:middle;
-    margin:5px 2px 5px 5px;
-    width:90px;
-    height:113px;
-    padding:0px
+    padding:0px;
+    display: table-cell;
+    vertical-align: middle;
+    position: relative;
+    left: -2px;
     }
 .preview-panel-office{
     width:360px;
diff --git a/tine20/Tinebase/js/EncodingHelper.js b/tine20/Tinebase/js/EncodingHelper.js
new file mode 100644 (file)
index 0000000..aceb026
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Tine 2.0
+ *
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+Ext.ns('Tine.Tinebase');
+
+/**
+ * Encapsuple string escaping and subsituting methods
+ *
+ * @namespace   Tine.Tinebase
+ * @class       Tine.Tinebase.EncodingHelper
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @singleton
+ * @return {string}
+ */
+Tine.Tinebase.EncodingHelper = {
+    /**
+     * Encode string
+     *
+     * @param value
+     */
+    encode: function(value) {
+        if (!value) {
+            return '';
+        }
+
+        value = Ext.util.Format.htmlEncode(value);
+        return Ext.util.Format.nl2br(value);
+    }
+};
+
+
index 556a464..897303b 100644 (file)
@@ -39,8 +39,7 @@ Ext.ux.display.DisplayPanel = Ext.extend(Ext.Panel, {
         Ext.ux.display.DisplayPanel.superclass.initComponent.call(this);
         
         this.fields = new Ext.util.MixedCollection();
-        this.fields.addAll(this.findByType('ux.displayfield'));
-        this.fields.addAll(this.findByType('ux.displaytextarea'));
+        this.fields.addAll(this.findBy(function(c) {return Ext.isFunction(c.setValue)}));
     },
     
     /**
index 902a8fa..94c4b27 100644 (file)
@@ -311,6 +311,7 @@ Ext.ux.form.ImageField = Ext.extend(Ext.form.Field, {
         Ext.ux.form.ImageField.superclass.onDestroy.call(this);
     }
 });
+Ext.reg('ux.imagefield', Ext.ux.form.ImageField);
 
 Ext.ns('Ext.ux.util');