commit dbbd9d34220c1dfaebac1698142c5269bb6a9b72
Author: Alessandro_N <alessandro.nastasi@ias.u-psud.fr>
Date:   Fri Apr 17 15:23:09 2015 +0200

    Change necessary to show the dates in the News column/window with format 'dd/mm/yyyy'

diff --git a/szcluster-db/workspace/client-public/js/feedsReader/atom1FeedsReader.js b/szcluster-db/workspace/client-public/js/feedsReader/atom1FeedsReader.js
new file mode 100644
index 0000000..001b899
--- /dev/null
+++ b/szcluster-db/workspace/client-public/js/feedsReader/atom1FeedsReader.js
@@ -0,0 +1,261 @@
+/***************************************
+* Copyright 2010-2014 CNES - CENTRE NATIONAL d'ETUDES SPATIALES
+* 
+* This file is part of SITools2.
+* 
+* SITools2 is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+* 
+* SITools2 is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with SITools2.  If not, see <http://www.gnu.org/licenses/>.
+***************************************/
+/*global Ext, sitools, i18n,document*/
+Ext.namespace('sitools.widget');
+
+/**
+ * Displays a grid of atom1 format feeds
+ * @class sitools.widget.atom1FeedReader
+ * @extends Ext.grid.GridPanel
+ * @cfg {string} datasetId The Dataset id,
+ * @cfg {string} urlFeed The url to request feed
+ * @cfg {string} datasetName The dataset name
+ * @cfg {string} feedSource
+ * @cfg {boolean} autoLoad store configuration
+ */
+sitools.widget.atom1FeedReader = function (config) {
+	Ext.apply(this);
+	this.layout = "fit";
+	this.storeFeedsRecords = new Ext.data.Store({
+        autoLoad : true,
+        sortInfo : {field : 'pubDate', direction : "DESC"},
+	    proxy : new Ext.data.HttpProxy({
+	        url : config.urlFeed,
+	        restful : true,
+            listeners : {
+                scope : this,
+                exception : onRequestFeedException
+            }
+	    // url : 'http://extjs.com/forum/external.php?type=RSS2'
+	    }),
+	    reader : new Ext.data.XmlReader({
+            record : 'entry'
+        }, [ 'title',
+             {
+                name : 'author', 
+                mapping : "author.name"
+             }, {
+            name : 'pubDate',
+            mapping : 'updated',
+            type : 'date'
+          }, {
+              name : 'link',
+              mapping: "link@href"
+             },
+             { 
+                 name : 'description',
+                 mapping : 'content'
+             },
+             'content',
+        	{
+               name : 'imageUrl',
+            	createAccessor : function (data, field) {
+            		var q = Ext.DomQuery;
+            		// select node link with attribute type like image%
+            		var node = q.selectNode("link[type^=image]", data);
+            		var result = {};
+            		if (Ext.isEmpty(node)) {
+            			return result;
+            		}
+            		Ext.each(node.attributes, function (attribute) {
+            			result[attribute.name] = attribute.value;
+            		});
+            		return result;
+            	}
+        	}
+        ])
+
+	});
+
+	var columns = [ {
+        id : 'image',
+        header : "Image",
+        dataIndex : 'imageUrl',
+        sortable : false,
+        width : 120
+        ,
+        renderer : this.imageRenderer
+    }, {
+        id : 'title',
+        header : "Title",
+        dataIndex : 'title',
+        sortable : true,
+        width : 460,
+        scope : this,
+        renderer : this.formatTitle
+    }, {
+        header : "Author",
+        dataIndex : 'author',
+        width : 100,
+        hidden : true,
+        sortable : true
+    }, {
+        id : 'last',
+        header : "Date",
+        dataIndex : 'pubDate',
+        width : 150,
+        renderer : this.formatDate,
+        sortable : true,
+        hidden : true
+    } ];
+
+	sitools.widget.atom1FeedReader.superclass.constructor.call(this, {
+	    // height : 300,
+	    columns : columns,
+	    store : this.storeFeedsRecords,
+	    loadMask : {
+            msg : i18n.get("label.loadingFeed")
+        },
+	    sm : new Ext.grid.RowSelectionModel({
+		    singleSelect : true
+	    }),
+	    autoExpandColumn : 'title',
+	    hideHeaders : true,
+	    viewConfig : {
+	        forceFit : true,
+	        enableRowBody : true,
+	        showPreview : true,
+	        getRowClass : this.applyRowClass
+	    },
+        listeners : config.listeners
+	});
+};
+
+Ext.extend(sitools.widget.atom1FeedReader, Ext.grid.GridPanel, {
+    /**
+     * Load the feeds with the given url
+     * @param {string} url
+     */
+    loadFeed : function (url) {
+        this.store.baseParams = {
+            feed : url
+        };
+        this.store.load();
+    },
+
+    /**
+     * switch from preview to complete view
+     * @param {boolean} show
+     */
+    togglePreview : function (show) {
+        this.view.showPreview = show;
+        this.view.refresh();
+    },
+
+    /**
+     * override the method getRowClass 
+     * @param {Record} record The {@link Ext.data.Record} corresponding to the current row.
+     * @param {Number} index The row index.
+     * @param {Object} rowParams A config object that is passed to the row template during rendering that allows
+     * customization of various aspects of a grid row.
+     * <p>If {@link #enableRowBody} is configured <b><tt></tt>true</b>, then the following properties may be set
+     * by this function, and will be used to render a full-width expansion row below each grid row:</p>
+     * <ul>
+     * <li><code>body</code> : String <div class="sub-desc">An HTML fragment to be used as the expansion row's body content (defaults to '').</div></li>
+     * <li><code>bodyStyle</code> : String <div class="sub-desc">A CSS style specification that will be applied to the expansion row's &lt;tr> element. (defaults to '').</div></li>
+     * </ul>
+     * The following property will be passed in, and may be appended to:
+     * <ul>
+     * <li><code>tstyle</code> : String <div class="sub-desc">A CSS style specification that willl be applied to the &lt;table> element which encapsulates
+     * both the standard grid row, and any expansion row.</div></li>
+     * </ul>
+     * @param {Store} store The {@link Ext.data.Store} this grid is bound to
+     */
+    applyRowClass : function (record, rowIndex, p, ds) {
+        if (this.showPreview) {
+            var xf = Ext.util.Format;
+            if (record.data.summary != "" && record.data.summary != undefined){
+                p.body = '<p class=sous-titre-flux>' + xf.ellipsis(xf.stripTags(record.data.summary), 300) + '</p>';
+                return 'x-grid3-row-expanded';
+            }
+        }
+        return 'x-grid3-row-collapsed';
+    },
+
+    /**
+     * Custom date format
+     * @param {Date} date the input date
+     * @return {String} the date formated
+     */
+    formatDate : function (date) {
+        if (!date) {
+            return '';
+        }
+        var now = new Date();
+        var d = now.clearTime(true);
+        if (date instanceof Date){
+            var notime = date.clearTime(true).getTime();
+            if (notime == d.getTime()) {
+                return 'Today ' + date.dateFormat('g:i a');
+            }
+            d = d.add('d', -6);
+            if (d.getTime() <= notime) {
+                //return date.dateFormat('D g:i a');
+ 		return date.dateFormat('d/m/Y');
+            }
+            //return date.dateFormat('n/j g:i a');
+            return date.dateFormat('d/m/Y');
+        }
+        else {
+            return date;
+        }
+    },
+
+    /**
+     * Custom renderer for title columns
+     * @param {} value the value to format
+     * @param {} p
+     * @param {Ext.data.Record} record
+     * @return {String} The title value formatted.
+     */
+    formatTitle : function (value, p, record) {
+        var author = (record.data.author.name !== undefined) ? record.data.author.name : "";
+        var link = record.data.link;
+        var xf = Ext.util.Format;
+        var dateFormat = this.formatDate(record.data.updated);
+        var author = (record.data.author.name !== undefined) ? record.data.author.name : "";
+        var authorEmail = (record.data.author.email !== undefined) ? record.data.author.email : "";
+        var res = "";
+        if (link !== undefined && link !== "") {
+            res = String.format('<div class="topic"><a href="{0}" title="{1}" target="_blank"><span class="rss_feed_title">{2}</span></a><br/><span class="author">{3}</span></div>', link, value, 
+                    xf.ellipsis(xf.stripTags(value), 50), author);
+        } else {
+            res = String.format('<div class="topic"><span class="rss_feed_title">{0}</span><br/><span class="author">{1}</span></div>', xf.ellipsis(xf.stripTags(value), 50), author);
+        }
+        if (dateFormat != "" && dateFormat != undefined ){
+            res += String.format('<p id="feeds-date">{0}</p>', dateFormat);
+        }
+        return res;
+
+    }, 
+    imageRenderer : function (value, p, record) {
+    	if (Ext.isEmpty(value) || Ext.isEmpty(value.href)) {
+            return "";
+        }
+        if (value.type.substr(0, 5) != "image") {
+        	return "";
+        }
+		return String.format('<img src="{0}" width="50px">', value.href);
+    },
+    
+    sortByDate : function (direction){
+        this.storeFeedsRecords.sort('pubDate', direction);
+    }
+
+});
diff --git a/szcluster-db/workspace/client-public/js/feedsReader/feedItemDetails.js b/szcluster-db/workspace/client-public/js/feedsReader/feedItemDetails.js
new file mode 100644
index 0000000..cfabd66
--- /dev/null
+++ b/szcluster-db/workspace/client-public/js/feedsReader/feedItemDetails.js
@@ -0,0 +1,177 @@
+/***************************************
+* Copyright 2010-2014 CNES - CENTRE NATIONAL d'ETUDES SPATIALES
+* 
+* This file is part of SITools2.
+* 
+* SITools2 is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+* 
+* SITools2 is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with SITools2.  If not, see <http://www.gnu.org/licenses/>.
+***************************************/
+/*global Ext, sitools, i18n,document*/
+Ext.namespace('sitools.widget');
+
+/**
+ * @param urlFeed :
+ *            The feed URL
+ */
+sitools.widget.feedItemDetails = Ext.extend(Ext.Panel, {
+
+    initComponent : function () {
+
+        this.layout = "fit";
+
+        var record = this.record;
+        
+        if (!Ext.isEmpty(record)) {
+            
+            this.store = new Ext.data.JsonStore({
+                idProperty: 'title',
+                fields: [
+                    {name : 'title'},
+                    {name : 'pubDate', type: 'date', dateFormat: 'timestamp'},
+                    {name : 'published', type: 'date', dateFormat: 'timestamp'},
+                    {name : 'author'}, 
+                    {name : 'link'},
+                    {name : 'description'},
+                    {name : 'imageUrl'},
+                    {name : 'image'}
+                ],
+                listeners : {
+                    scope : this,
+                    add : function (store, records, ind){
+                        if (record.data.imageUrl == undefined && record.data.image != undefined){
+                            record.data.image = record.data.imageUrl;
+                        }
+                        if (records[0].data.pubDate != ""){
+                            records[0].data.pubDate = this.formatDate(records[0].data.pubDate);
+                        }
+                    }
+                }
+            });
+            
+            this.store.add(record);
+            
+            this.tpl = new Ext.XTemplate(
+                    '<tpl for=".">',
+                        '<div class="feed-article">',
+                            '<tpl if="this.isDisplayable(imageUrl)">',
+                                '<div class="feed-img">',
+                                    '<img src="{imageUrl}" title="{title}" width="70" height="70"/>',
+                                '</div>',
+                            '</tpl>',
+                            '<p class="feed-title"> {title} </p>',
+                            '<tpl if="this.isDisplayable(pubDate)">',
+                                '<div class="feed-date-detail">',
+                                    '<b> Date : </b> {pubDate} ',
+                                '</div>',
+                            '</tpl>',
+                            '<tpl if="this.isDisplayable(author)">',
+                                '<div class="feed-author">',
+                                    '<b> Author : </b> {author} ',
+                                '</div>',
+                            '</tpl>',
+                            '<div class="feed-description">',
+                                '{description}',
+                            '</div>',
+                            '<div class="feed-complementary">',
+                                '<p style="padding-bottom: 3px;"> <b> Link : </b> <a href="{link}" target="_blank" title="{title}">{link}</a> </p>',
+                                '<tpl if="this.isDisplayable(imageUrl)">',
+                                    '<p> <b> Image Url : </b> <a href="{imageUrl}" target="_blank">{imageUrl}</a> </p>',
+                                '</tpl>',
+                            '</div>',
+                        '</div>',
+                    '</tpl>',
+                    {
+                        compiled : true,
+                        isDisplayable : function (item) {
+                            if (item != "" && item != undefined){
+                                return true;
+                            }
+                            else {
+                                return false;
+                            }
+                        }
+                    }
+            );
+            
+            this.feedsDataview = new Ext.DataView({
+              id: 'detailFeed-view',
+              autoScroll : true,
+              layout: 'fit',
+              store : this.store,
+              tpl : this.tpl,
+              cls : 'detailFeed-view',
+              emptyText: i18n.get('label.nothingToDisplay')
+            });
+
+            this.componentType = 'feedDetails';
+            this.items = [ this.feedsDataview ];
+        }
+
+        sitools.widget.feedItemDetails.superclass.initComponent.call(this);
+    },
+    
+    formatDate : function (date) {
+        if (!date) {
+            return '';
+        }
+        var now = new Date();
+        var d = now.clearTime(true);
+        if (date instanceof Date){
+            var notime = date.clearTime(true).getTime();
+            if (notime == d.getTime()) {
+                return 'Today ' + date.dateFormat('g:i a');
+            }
+            d = d.add('d', -6);
+            if (d.getTime() <= notime) {
+                //return date.dateFormat('D g:i a');
+		return date.dateFormat('d/m/Y g:i a');
+            }
+            //return date.dateFormat('n/j g:i a');
+	    return date.dateFormat('d/m/Y g:i a');
+        }
+        else {
+            return date;
+        }
+    }, 
+    /**
+     * Method called when trying to show this component with fixed navigation
+     * 
+     * @param {sitools.user.component.viewDataDetail} me the dataDetail view
+     * @param {} config config options
+     * @returns
+     */
+    showMeInFixedNav : function (me, config) {
+        Ext.apply(config.windowSettings, {
+            width : config.windowSettings.winWidth || DEFAULT_WIN_WIDTH,
+            height : config.windowSettings.winHeight || DEFAULT_WIN_HEIGHT
+        });
+        SitoolsDesk.openModalWindow(me, config);
+    }, 
+    /**
+     * Method called when trying to show this component with Desktop navigation
+     * 
+     * @param {sitools.user.component.viewDataDetail} me the dataDetail view
+     * @param {} config config options
+     * @returns
+     */
+    showMeInDesktopNav : function (me, config) {
+        Ext.apply(config.windowSettings, {
+            width : config.windowSettings.winWidth || DEFAULT_WIN_WIDTH,
+            height : config.windowSettings.winHeight || DEFAULT_WIN_HEIGHT
+        });
+        SitoolsDesk.openModalWindow(me, config);
+    }
+    
+    
+    
+});
diff --git a/szcluster-db/workspace/client-public/js/feedsReader/rss2FeedsReader.js b/szcluster-db/workspace/client-public/js/feedsReader/rss2FeedsReader.js
new file mode 100644
index 0000000..5473a4c
--- /dev/null
+++ b/szcluster-db/workspace/client-public/js/feedsReader/rss2FeedsReader.js
@@ -0,0 +1,198 @@
+/***************************************
+* Copyright 2010-2014 CNES - CENTRE NATIONAL d'ETUDES SPATIALES
+* 
+* This file is part of SITools2.
+* 
+* SITools2 is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+* 
+* SITools2 is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with SITools2.  If not, see <http://www.gnu.org/licenses/>.
+***************************************/
+/*global Ext, sitools, i18n,document,window,SitoolsDesk*/
+Ext.namespace('sitools.widget');
+
+/**
+ * @param urlFeed :
+ *            The feed URL
+ */
+sitools.widget.rss2FeedReader = function (config) {
+    Ext.apply(this);
+    this.layout = "fit";
+    this.storeFeedsRecords = new Ext.data.Store({
+        autoLoad : true,
+        sortInfo : {field : 'pubDate', direction : "DESC"},
+        proxy : new Ext.data.HttpProxy({
+            url : config.urlFeed,
+            restful : true,
+            listeners : {
+                scope : this,
+                exception : onRequestFeedException
+            }
+        }),
+        reader : new Ext.data.XmlReader({
+            record : 'item'
+        }, [ 'title', 'author', {
+            name : 'pubDate',
+            type : 'date'
+        }, 'link', 'description', 'content', 'guid', {
+        	name : 'imageUrl',
+        	mapping : "enclosure@url"
+        }, {
+        	name : 'imageType',
+        	mapping : "enclosure@type"
+        }])
+    });
+
+    var columns = [ {
+        id : 'image',
+        header : "Image",
+        dataIndex : 'imageUrl',
+        sortable : false,
+        width : 120
+        ,
+        renderer : this.imageRenderer
+    }, {
+        id : 'title',
+        header : "Title",
+        dataIndex : 'title',
+        sortable : true,
+        width : 460,
+        scope : this,
+        renderer : this.formatTitle
+    }, {
+        header : "Author",
+        dataIndex : 'author',
+        width : 100,
+        hidden : true,
+        sortable : true
+    }, {
+        id : 'last',
+        header : "Date",
+        dataIndex : 'pubDate',
+        width : 150,
+        renderer : this.formatDate,
+        sortable : true,
+        hidden : true
+    } ];
+    
+    sitools.widget.rss2FeedReader.superclass.constructor.call(this, {
+        // height : 300,
+        columns : columns,
+        store : this.storeFeedsRecords,
+        loadMask : {
+            msg : i18n.get("label.loadingFeed")
+        },
+        sm : new Ext.grid.RowSelectionModel({
+            singleSelect : true
+        }),
+        autoExpandColumn : 'title',
+        hideHeaders : true,
+        viewConfig : {
+            forceFit : true,
+            enableRowBody : true,
+            showPreview : true,
+            getRowClass : this.applyRowClass
+        },
+        listeners : config.listeners
+        
+    });
+
+    // this.on('rowcontextmenu', this.onContextClick, this);
+    // this.on('beforeShow',this.loadData);
+};
+
+Ext.extend(sitools.widget.rss2FeedReader, Ext.grid.GridPanel, {
+
+   
+    loadData : function () {
+        this.loadFeed('http://feeds.feedburner.com/extblog');
+        this.doLayout();
+    },
+
+    loadFeed : function (url) {
+        this.store.baseParams = {
+            feed : url
+        };
+        this.store.load();
+    },
+
+    togglePreview : function (show) {
+        this.view.showPreview = show;
+        this.view.refresh();
+    },
+
+    // within this function "this" is actually the GridView
+    applyRowClass : function (record, rowIndex, p, ds) {
+        if (this.showPreview) {
+            var xf = Ext.util.Format;
+            //p.body = '<p class=sous-titre-flux>' + record.data.description + '</p>';
+            p.body = '<p class=sous-titre-flux>' + xf.ellipsis(xf.stripTags(record.data.description), 300) + '</p>';
+            return 'x-grid3-row-expanded';
+        }
+        return 'x-grid3-row-collapsed';
+    },
+
+    formatDate : function (date) {
+        if (!date) {
+            return '';
+        }
+        var now = new Date();
+        var d = now.clearTime(true);
+        if (date instanceof Date){
+            var notime = date.clearTime(true).getTime();
+            if (notime == d.getTime()) {
+                return 'Today ' + date.dateFormat('g:i a');
+            }
+            d = d.add('d', -0);//-6
+            if (d.getTime() <= notime) {
+                //return date.dateFormat('D g:i a');
+		return date.dateFormat('d/m/Y');
+            }
+            //return date.dateFormat('n/j g:i a');
+            return date.dateFormat('d/m/Y');
+        }
+        else {
+            return date;
+        }
+    },
+
+    formatTitle : function (value, p, record) {
+        var link = record.data.link;
+        var xf = Ext.util.Format;
+        var author = (Ext.isEmpty(record.data.author)) ? "" : record.data.author;
+        var dateFormat = this.formatDate(record.data.pubDate);
+        var res = "";
+        if (link !== undefined && link !== "") {
+            res = String.format('<div class="topic"><a href="{0}" title="{1}" target="_blank"><span class="rss_feed_title">{2}</span></a><br/><span class="author">{3}</span></div>', link, value, 
+                    xf.ellipsis(xf.stripTags(value), 50), author);
+        } else {
+            res = String.format('<div class="topic"><span class="rss_feed_title">{0}</span><br/><span class="author">{1}</span></div>', xf.ellipsis(xf.stripTags(value), 50), author);
+        }
+        if (dateFormat != "" && dateFormat != null ){
+            res += String.format('<p id="feeds-date">{0}</p>', dateFormat);
+        }
+        return res;
+    }, 
+    
+    imageRenderer : function (value, p, record) {
+    	if (Ext.isEmpty(value) || Ext.isEmpty(record.data.imageType)) {
+            return "";
+        }
+        if (record.data.imageType.substr(0, 5) != "image") {
+        	return "";
+        }
+		return String.format('<img src="{0}" width="50px">', value);
+    },
+    
+    sortByDate : function (direction){
+        this.storeFeedsRecords.sort('pubDate', direction);
+    }
+});
